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
。
我正在为 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
。