### GNU Linker (LD) 手册概览与关键技术知识点 #### 一、概述 **GNU Linker**(简称 LD)是 GNU 工具链中的一个关键组件,它主要用于将多个目标文件链接成一个可执行文件或库。LD 支持多种处理器架构,并且能够处理各种复杂的链接任务。本文档旨在详细介绍 LD 的主要功能、使用方法以及相关技术细节。 #### 二、调用方式 ##### 2.1 命令行选项 **2.1.1 针对 i386 PE 目标的具体选项** - **/ALIGN**: 设置对齐方式。 - **/BASE**: 设置可执行文件的基础地址。 - **/DLL**: 创建 DLL 文件。 - **/ENTRY**: 指定入口点。 - **/FIXED**: 禁止重定位。 - **/FORCE**: 强制执行某些操作。 - **/IMPLIB**: 生成导入库文件。 - **/MERGE**: 合并段。 - **/NOLOGO**: 禁止显示版权信息。 - **/OUT**: 指定输出文件名。 **2.1.2 针对 C6Xu/Clinux 目标的具体选项** - **--entry**: 指定程序的入口点。 - **--gc-sections**: 允许删除未使用的节。 - **--strip-all**: 删除所有符号表信息。 - **--hash-style**: 控制哈希表风格。 - **--wrap**: 包装未定义的符号。 - **--as-needed**: 只加载真正需要的动态库。 **2.1.3 针对 Motorola 68HC11 和 68HC12 目标的具体选项** - **--relax**: 允许链接器优化代码。 - **--tramp**: 生成跳板代码。 **2.1.4 针对 Motorola 68K 目标的具体选项** - **--no-undefined**: 禁止未定义的引用。 - **--warn-common**: 警告常见符号的重复定义。 **2.1.5 针对 MIPS 目标的具体选项** - **-R**: 添加运行时搜索路径。 - **-T**: 使用指定的链接脚本。 - **-Wl,**: 传递选项给链接器。 ##### 2.2 环境变量 - **LD_LIBRARY_PATH**: 设置运行时库搜索路径。 - **LD_PRELOAD**: 指定预加载库。 #### 三、链接器脚本 ##### 3.1 基本概念 链接器脚本用于控制链接器的行为,可以用来定义内存布局、初始化数据段、控制输出格式等。 ##### 3.2 格式 链接器脚本通常包含以下几个部分: - **MEMORY**: 定义内存区域及其属性。 - **SECTIONS**: 描述输出段的布局和内容。 - **PHDRS**: 定义程序头表。 - **VERSION**: 版本控制指令。 ##### 3.3 简单示例 ```linker-script OUTPUT_FORMAT("elf32-i386") ENTRY(_start) SECTIONS { .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } } ``` ##### 3.4 基本命令 **3.4.1 设置入口点** ```linker-script ENTRY(symbol) ``` **3.4.2 文件相关命令** - **INPUT(file)**: 将指定文件作为输入。 - **GROUP(file1 file2 ...)**: 将多个文件视为一个组。 **3.4.3 对象文件格式相关命令** - **OUTPUT_ARCH(architecture)**: 设置输出文件的目标架构。 - **OUTPUT_FORMAT(format)**: 设置输出文件格式。 **3.4.4 分配别名到内存区域** ```linker-script MEMORY { rom (rx) : ORIGIN = 0x80000000, LENGTH = 4M ram (rwx) : ORIGIN = 0x20000000, LENGTH = 1M } ``` **3.4.5 其他命令** - **OUTPUT(file)**: 设置输出文件名。 - **KEEP(symbol)**: 保留指定符号。 - **DISCARD(symbol)**: 删除指定符号。 ##### 3.5 给符号赋值 **3.5.1 简单赋值** ```linker-script symbol = value; ``` **3.5.2 HIDDEN** ```linker-script HIDDEN(symbol) ``` **3.5.3 PROVIDE** ```linker-script PROVIDE(symbol = value); ``` **3.5.4 PROVIDE_HIDDEN** ```linker-script PROVIDE_HIDDEN(symbol = value); ``` **3.5.5 源码引用** ```linker-script EXTERN(symbol) ``` ##### 3.6 SECTIONS 命令 **3.6.1 输出段描述** ```linker-script SECTIONS { section_name : { section_content } } ``` **3.6.2 输出段名称** ```linker-script section_name ``` **3.6.3 输出段地址** ```linker-script : AT(address) ``` **3.6.4 输入段描述** **3.6.4.1 输入段基础** ```linker-script *(.text) ``` **3.6.4.2 输入段通配符模式** ```linker-script *(.data .data*) ``` **3.6.4.3 输入段共用符号** ```linker-script COMMON ``` **3.6.4.4 输入段与垃圾回收** ```linker-script *(.bss .bss*) ``` **3.6.4.5 输入段示例** ```linker-script SECTIONS { .text : { *(.text) } } ``` **3.6.5 输出段数据** ```linker-script section_name : { data } ``` **3.6.6 输出段关键词** - **ALIGNED**: 指定对齐方式。 - **KEEP**: 保持指定数据。 - **DISCARD**: 丢弃指定数据。 - **GROUP**: 将多个文件视为一个组。 **3.6.7 输出段剔除** ```linker-script *(NOLOAD discard) ``` **3.6.8 输出段属性** **3.6.8.1 输出段类型** ```linker-script type ``` **3.6.8.2 输出段 LMA** ```linker-script : LMA address ``` **3.6.8.3 强制输出对齐** ```linker-script : ALIGN (alignment) ``` **3.6.8.4 强制输入对齐** ```linker-script *(ALIGN (alignment)) ``` **3.6.8.5 输出段约束** ```linker-script : CONSTRAINT ``` **3.6.8.6 输出段区域** ```linker-script : REGION region ``` **3.6.8.7 输出段 Phdr** ```linker-script : PHDR ``` **3.6.8.8 输出段填充** ```linker-script : FILL (fill_value) ``` **3.6.9 覆盖描述** ```linker-script OVERLAY ``` ##### 3.7 MEMORY 命令 ```linker-script MEMORY { region_name (permissions) : { origin_address, length } } ``` ##### 3.8 PHDRS 命令 ```linker-script PHDRS { phdr_section_name : { phdr_section_content } } ``` ##### 3.9 VERSION 命令 ```linker-script VERSION { symbol : { version } } ``` ##### 3.10 表达式在链接器脚本中的应用 **3.10.1 常量** - **INTEGER**: 整型常量。 - **STRING**: 字符串常量。 **3.10.2 符号常量** ```linker-script SYMBOL_NAME ``` **3.10.3 符号名** ```linker-script symbol ``` **3.10.4 孤立段** ```linker-script ORPHAN ``` **3.10.5 位置计数器** ```linker-script * : { KEEP(*(.text)) } ``` **3.10.6 运算符** - **+**: 加法。 - **-**: 减法。 - **\***: 乘法。 - **/**: 除法。 - **%**: 取模。 **3.10.7 评估** ```linker-script EVALUATE(expression) ``` **3.10.8 表达式的段** ```linker-script SECTION(symbol) ``` **3.10.9 内置函数** - **MAX(a, b)**: 返回 a 和 b 中的最大值。 - **MIN(a, b)**: 返回 a 和 b 中的最小值。 - **ROUNDUP(a, b)**: 向上取整。 ##### 3.11 隐含的链接器脚本 - **DEFAULT**:默认脚本。 #### 四、机器依赖特性 ##### 4.1 ld 与 H8/300 - **--relax**: 优化代码。 - **--gc-sections**: 删除未使用的段。 ##### 4.2 ld 与 Intel 960 家族 - **--defsym**: 定义符号。 ##### 4.3 ld 与 Motorola 68HC11 和 68HC12 家族 **4.3.1 链接器优化** - **--relax**: 优化代码。 - **--tramp**: 生成跳板代码。 **4.3.2 跳板代码生成** - **--tramp**: 为间接调用生成跳板代码。 ##### 4.4 ld 与 ARM 家族 - **--thumb**: 指定 ARM 指令集。 - **--fp**: 设置浮点处理单元。 ##### 4.5 ld 与 HPPA 32 位 ELF 支持 - **--eh-frame**: 生成异常处理帧信息。 - **--init**: 指定初始化函数。 ##### 4.6 ld 与 Motorola 68K - **--no-undefined**: 禁止未定义的引用。 - **--warn-common**: 警告常见符号的重复定义。 以上是 GNU Linker LD 的主要技术和知识点概述,通过掌握这些内容,开发者可以更有效地使用 LD 来完成复杂的链接任务。
剩余230页未读,继续阅读
- 粉丝: 1
- 资源: 1
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助