本页目录
链接器脚本与重定位
覆盖: ld script 语法 → relocation types → GOT/PLT relocation → linker relaxation → LLD vs GNU ld vs gold → R_AARCH64_ADR_GOT_PAGE 适用: binutils ld, LLD, 静态/动态链接
重定位: 链接器的工作
编译时 (gcc -c):
.o 中有 RELA entries → 记录了"这个地址需要填充, 目标符号是这个"
例: R_X86_64_PLT32: 这个 4-byte offset 需要填入符号的 PLT 地址
链接时 (ld):
遍历所有 .o 的 RELA → 解析符号 → 填充地址
如果是动态符号 → 生成 .rela.plt (运行时由 ld.so 解析)
常见重定位类型
// x86-64 (AMD64):
R_X86_64_64: 直接 64-bit 绝对地址
R_X86_64_PC32: 32-bit PC
R_X86_64_PLT32: 类似 PC32 但目标在 PLT 中
R_X86_64_GOTPCREL: GOT 条目的 PC 相对偏移
R_X86_64_COPY: 将共享库中的变量复制到主程序 .bss
// ARM64 (AArch64):
R_AARCH64_ABS64: 绝对地址
R_AARCH64_ADR_PREL_PG_HI21: PC 相对, page
R_AARCH64_ADD_ABS_LO12_NC:
R_AARCH64_LDST64_ABS_LO12_NC: 加载/存储, 页内偏移
R_AARCH64_ADR_GOT_PAGE: GOT 条目的 PC 相对, page 粒度 + 加载
ld script: 链接器脚本
/* 默认 ld script: /usr/lib/ldscripts/elf_x86_64.x */
SECTIONS
{
/* 起始: 代码段 (Read + Execute) */
. = 0x400000 + SIZEOF_HEADERS; /* 非 PIE */
.text : { *(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*) }
/* 只读数据 */
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
. = ALIGN(0x1000);
__init_array_start = .;
.init_array : { *(.init_array) }
__init_array_end = .;
/* 可读写段 (下一页开始) */
. = ALIGN(0x1000);
.data : { *(.data .data.* .gnu.linkonce.d.*) }
.bss : { *(.bss .bss.* .gnu.linkonce.b.*) }
}
LLD vs GNU ld vs gold
| GNU ld (BFD) | gold | LLD (LLVM) | |
|---|---|---|---|
| 速度 | 基准 | 2-3x faster | 3-5x faster |
| 内存 | 高 | 更低 | 低 |
| LTO | 支持 (GCC LTO) | 支持 (GCC LTO) | 支持 (ThinLTO) |
| 链接器脚本 | 完整支持 | 部分 | 大部分 |
| 默认 | 传统 | 不维护 | 未来 |
Linker Relaxation
某些重定位可以通过"放松"优化:
RISC-V / ARM64 支持:
如: R_RISCV_CALL → 链接时能看到目标距离 → 用更短的指令序列
→ call (32-bit offset) → jal (20-bit offset) 如果距离够
→ 代码更短 + 更快
x86 不支持 relaxation (指令固定大小, 无可优化)
调试
# 查看重定位表
# 查看默认 ld script
|
# 链接过程追踪
# 未定义的符号
|
参考
- 文档:
info ld, ELF spec (System V ABI, Chapter 4) - 源码:
binutils/ld/,lld/ELF/ - LWN: "Linker relaxation"
关键词: relocation, R_X86_64_PLT32, R_AARCH64_ADR_GOT_PAGE, ld script, LLD, gold, linker relaxation