Elf 加载器中的静态地址与执行地址

Static Address vs. Execution Address In An Elf Loader

我正在为 ARM/ARM64 编写一个 Elf Loader。在处理动态重定位时,我对我正在关注的 documentation 中的某些 terms/symbols 感到有点困惑。 在第 14 页上指出,

"S (when used on its own) is the address of the symbol." "P is the address of the place being relocated (derived from r_offset)."

"Delta(S) 如果 S 是普通符号,则解析为 S 的静态 link 地址与 S 的执行地址。如果 S 是空符号(ELF 符号索引 0),则解析为 P的静态link地址和P的执行地址."

据我所知,我认为 S(或 P)的 "execution address" 是进程内存中符号的地址 space 但我不确定 [=24] 是什么意思=].

如果有人能解释一下术语就太好了,谢谢。

what is meant by "static link address".

非 PIE 可执行文件被 linked 加载到特定地址。例如,在 x86_64 Linux 默认静态 link 地址是 0x400000:

echo "int main() { return 0; }" | gcc -xc - -no-pie

readelf -Wl a.out | grep LOAD
  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x000618 0x000618 R E 0x200000
  LOAD           0x000e50 0x0000000000600e50 0x0000000000600e50 0x0001d8 0x0001e0 RW  0x200000

此二进制文件 link 使用 0x400000 的静态 link 地址编辑,其中的符号反映:

nm a.out | grep ' main'
0000000000400487 T main

此可执行文件 必须 0x400000 加载,如果在其他任何地方加载将无法正常工作。

注意默认非 PIE 静态 link 地址

  • 对于不同的架构是不同的(i386默认是0x8048000),而
  • 可以在静态 link 时间通过 linker 脚本 and/or linker 标志进行更改。

将此与 PIE 可执行文件进行对比,PIE 可执行文件通常 linked 在静态 link 地址 0:

echo "int main() { return 0; }" | gcc -xc - -fPIE -pie
 readelf -Wl a.out | grep LOAD
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0007d8 0x0007d8 R E 0x200000
  LOAD           0x000e18 0x0000000000200e18 0x0000000000200e18 0x000210 0x000218 RW  0x200000

nm a.out | grep ' main'
00000000000005fa T main

因此main的静态link地址在非PIE情况下是0x400487,在PIE情况下是0x5fa