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

时间:2019-01-25 19:27:17

标签: linker arm elf arm64 relocation

我正在为ARM / ARM64编写Elf Loader。在处理动态重定位时,我对我遵循的documentation中的某些术语/符号感到有些困惑。 在第14页上指出,

“ S(当单独使用时)是符号的地址。” “ P是要重定位的地方的地址(源自r_offset)。”

“ Delta(S)如果S是正常符号,则解析为S的静态链接地址与S的静态链接地址之间的差。 S的执行地址。如果S为空符号(ELF符号索引0),则解析为 P的静态链接地址和P的执行地址。”

根据我的收集,我相信S(或P)的“执行地址”是该进程在内存空间中符号的地址,但不确定“静态链接地址”是什么意思。

如果有人可以澄清很棒的术语,谢谢。

1 个答案:

答案 0 :(得分:0)

  

“静态链接地址”是什么意思。

链接非PIE可执行文件以在特定地址加载。例如,在x86_64的Linux上,默认的静态链接地址为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

此二进制文件与0x400000的静态链接地址链接,并且其中的符号反映出:

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

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

请注意,默认的非PIE静态链接地址

  • 对于不同的体系结构(i386默认为0x8048000)有所不同,并且
  • 可以在静态链接时通过链接描述文件和/或链接标志进行更改。

将其与PIE可执行文件进行对比,该文件通常在静态链接地址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的静态链接地址在非PIE情况下为0x400487,在PIE情况下为0x5fa