博客
关于我
Linux下的lds链接脚本详解
阅读量:54 次
发布时间:2019-02-25

本文共 2252 字,大约阅读时间需要 7 分钟。

链接脚本(ld脚本)详解

概述

链接脚本(Linker Script)是用于控制链接过程的文件,主要用于指定如何将输入文件的section合并到输出文件中,以及输出文件中各section在程序地址空间中的布局。链接脚本能够执行静态链接和动态链接任务,还能完成一些高级操作,如符号赋值和内存区域管理。


基本概念

输入文件与输出文件

  • 输入文件:通常是目标文件(如可执行文件或共享库),也可以是链接脚本文件。
  • 输出文件:通常是可执行文件或共享库。

目标文件的格式通常为ELF格式,包含多个section,如.text(代码)、.data(数据)、.bss(未初始化的全局变量)、.sym(符号表)、.note(注释信息)等。


链接脚本格式

结构

链接脚本由一系列命令组成,每个命令由关键字(后接参数)或对符号的赋值语句组成,命令由分号;分隔。文件名或格式名中若包含分号;或其他分隔符,需用引号"引用。注释用/* */之间的内容表示。

命令类型

  • 赋值语句:SYMBOL = EXPRESSION

    用于对目标文件中的符号赋值,符号为全局符号,可用于设置入口地址、函数地址等。

  • 输入文件引用:

    • INPUT(files):将括号内文件作为链接输入文件。
    • GROUP(files):指定需要重复搜索的文件组,常用于处理共享库的依赖。
  • 输出文件定义:OUTPUT(FILENAME)

    定义输出文件的名字,优先级高于命令行的-o选项。

  • 搜索路径:SEARCH_DIR(PATH)

    定义搜索路径,路径内文件优先被搜索。

  • 启动文件:STARTUP(filename)

    指定第一个输入文件。

  • 目标文件格式:OUTPUT_FORMAT(BFDNAME)

    设置输出文件的BFD格式。

  • 字节顺序设置:OUTPUT_FORMAT(DEFAULT,BIG,LITTLE)

    设置输出文件的字节顺序(默认为BIG)。

  • 输入文件的BFD格式:TARGET(BFDNAME)

    设置输入文件的BFD格式。

  • 断言:ASSERT(EXP, MESSAGE)

    在表达式EXP不为真时终止连接过程。

  • 符号处理:

    • EXTERN(SYMBOL ...):在输出文件中增加未定义的符号。
    • FORCE_COMMON_ALLOCATION:为通用符号分配空间。
  • 内存区域管理:MEMORY

    定义内存区域,用于限制未引用section的分配范围。

  • 覆盖图描述:OVERLAY

    实现多个section共享同一内存区域。

  • 程序头描述:PHDRS

    定义ELF目标文件的程序头信息。

  • 版本控制:VERSION

    定义符号的版本信息,适用于共享库。


  • 符号赋值

    示例

    a = 3;  /* 全局位置 */.text : { *(.text) }_bdata = (. + 3) & ~4;  /* SECTIONS命令内 */.data : { *(.data) }

    注意事项

    • 符号赋值只对全局变量起作用。
    • 赋值语句需包含四个部分:符号名、操作符、表达式、分号。

    SECTIONS命令

    格式

    SECTIONS {  SECTION-NAME [ADDRESS] [(TYPE)] : [AT(LMA)]  {    OUTPUT-SECTION-COMMAND    ...  }  ...}

    参数说明

    • SECTION-NAME:输出section的名字,需符合目标文件格式要求。
    • ADDRESS:section的VMA地址,可用表达式表示。
    • TYPE:section的类型(如NOLOAD)。
    • AT(LMA):section的LMA地址。

    示例

    SECTIONS {  .text : { *(.text) }  .data : { *(.data) }  .bss : { *(.bss) *(COMMON) }}

    特殊说明

    • 如果没有在SECTIONS命令中提到某section,该section会被直接拷贝到输出文件中。
    • 通用符号COMMON用于存储输入文件的通用符号。

    输入section与垃圾回收

    示例

    SECTIONS {  outputa : 0x10000 : { all.o }  foo.o(.input1)}

    处理方式

    • 如果某输入section未在SECTIONS命令中引用,链接器会将其直接拷贝到输出section中。
    • 使用KEEP()命令可强制保留特定section。

    内存区域命令

    示例

    MEMORY {  rom (rx) : ORIGIN = 0, LENGTH = 256K  ram (!rx) : org = 0x40000000, l = 4M}

    说明

    • rom区域用于只读section,ram区域用于可读写section。
    • 未引用section的section会被放置在指定区域内,若超出区域大小,连接器会报错。

    PHDRS命令

    示例

    PHDRS {  headers PT_PHDR PHDRS  interp PT_INTERP  text PT_LOAD FILEHDR PHDRS  data PT_LOAD  dynamic PT_DYNAMIC}

    说明

    • PHDRS命令用于定义ELF目标文件的程序头信息。
    • 每个PT_类型对应一个程序段,FILEHDR和PHDRS可选。

    结论

    链接脚本是链接过程中的核心文件,通过合理配置可以实现对目标文件section的精确控制,完成高级链接任务。理解链接脚本的语法和用法是高级程序员的必备技能。

    转载地址:http://tve.baihongyu.com/

    你可能感兴趣的文章
    python 实现字符串转整型
    查看>>
    Python 实现定时任务的八种方案!
    查看>>
    Python 实现自动化测试 dubbo 协议接口
    查看>>
    python 对json数据读取及保存与读取,对dump,dumps,load,loads的理解
    查看>>
    Python 对mysql数据库的操作
    查看>>
    Python 对象数据库列表
    查看>>
    Python 导入requests报错No module named requests
    查看>>
    python 将函数加到列表中进行调用
    查看>>
    python 将图片与字符串相互转换
    查看>>
    Python 嵌套字典全面指南
    查看>>
    Python 工具v简介
    查看>>
    python 常见内置函数setattr、getattr、delattr、setitem、getitem、delitem
    查看>>
    Python 常见的错误类型和继承关系
    查看>>
    python 常量_零基础学Python系列之一:Python的变量与常量
    查看>>
    Python 并发编程
    查看>>
    Python编程入门基础及高级技能、Web开发、数据分析和机器学习与人工智能
    查看>>
    python 序列化操作
    查看>>
    Python 开发者,这 7 个 VS Code 插件极力推荐
    查看>>
    python手把手视频_硬货 | 手把手带你构建视频分类模型(附Python演练))
    查看>>
    python 录音左右声道_Python分离立体声wav压缩文件的左右声道
    查看>>