我正在为ARM / ARM64编写Elf Loader。在处理动态重定位时,我对我遵循的documentation中的某些术语/符号感到有些困惑。 在第14页上指出,
“ S(当单独使用时)是符号的地址。” “ P是要重定位的地方的地址(源自r_offset)。”
“ Delta(S)如果S是正常符号,则解析为S的静态链接地址与S的静态链接地址之间的差。 S的执行地址。如果S为空符号(ELF符号索引0),则解析为 P的静态链接地址和P的执行地址。”
根据我的收集,我相信S(或P)的“执行地址”是该进程在内存空间中符号的地址,但不确定“静态链接地址”是什么意思。
如果有人可以澄清很棒的术语,谢谢。
答案 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
。