Linker 动态链接器如何确定在Linux上调用哪个例程?
我有一个关于Linux上的动态链接的问题。考虑下面的ARM二进制拆分。< /P>Linker 动态链接器如何确定在Linux上调用哪个例程?,linker,elf,dynamic-linking,binaries,Linker,Elf,Dynamic Linking,Binaries,我有一个关于Linux上的动态链接的问题。考虑下面的ARM二进制拆分。< /P> 8300 <printf@plt-0x40>: .... 8320: e28fc600 add ip, pc, #0, 12 8324: e28cca08 add ip, ip, #8, 20 ; 0x8000 8328: e5bcf344 ldr pc, [ip, #836]! ; 0x344 .... 83fc <main>:
8300 <printf@plt-0x40>:
....
8320: e28fc600 add ip, pc, #0, 12
8324: e28cca08 add ip, ip, #8, 20 ; 0x8000
8328: e5bcf344 ldr pc, [ip, #836]! ; 0x344
....
83fc <main>:
...
8424:ebffffbd bl 8320 <_init+0x2c>
Main函数在8424:bl 8320处调用printf。8320是上面显示的.plt中的地址。现在.plt中的代码调用动态链接器来调用printf例程。我的问题是动态链接器如何能够说这是对printf的调用?.rela.plt包含printf的地址,以通知动态链接器从何处找到printf
查看此链接以了解非常容易消化的详细信息。本文还阐明了首先通过共享库访问变量,然后通过函数访问变量的过程 .rela.plt包含printf的地址,用于通知动态链接器从何处找到printf
查看此链接以了解非常容易消化的详细信息。本文还阐明了首先通过共享库访问变量,然后通过函数访问变量的过程 详细描述了动态链接的过程 TL;DR:在静态链接时,ld在特殊部分创建一组表,如.rel.dyn、.rel.plt等,这些部分告诉运行时加载程序在运行时要做什么
您可以使用nm-D、readelf-Wr、objdump-R等检查这些表。动态链接的过程描述得非常详细 TL;DR:在静态链接时,ld在特殊部分创建一组表,如.rel.dyn、.rel.plt等,这些部分告诉运行时加载程序在运行时要做什么
您可以使用nm-D、readelf-Wr、objdump-R等检查这些表。TLDR;PLT通过传递以下消息调用动态链接器: IP和PLTGOT[n+3]中GOT条目的地址 &PLTGOT[2]位于LR中 此外,PLTGOT[1]标识共享对象/可执行文件 动态链接器使用它来查找重新定位条目plt_relocation_table[n],从而找到符号printf PLT输入代码的说明 这在以下几方面得到了解释: 委员会注意到: 当平台像ARM Linux一样支持惰性函数绑定时 此ABI需要ip来寻址相应的 PLT通过其调用的点处的PLTGOT入口。 要求PLT的行为如同以LDR pc[ip]结束一样 从GOT中查找重新定位条目 现在,从GOT地址找到重新定位条目的方式还不清楚。可以使用二进制搜索,但不方便。GNU ld.so是否与glibc/sysdeps/arm/dl trampoline.S类似:
dl_runtime_resolve:
cfi_adjust_cfa_offset (4)
cfi_rel_offset (lr, 0)
@ we get called with
@ stack[0] contains the return address from this call
@ ip contains &GOT[n+3] (pointer to function)
@ lr points to &GOT[2]
@ Save arguments. We save r4 to realign the stack.
push {r0-r4}
cfi_adjust_cfa_offset (20)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
cfi_rel_offset (r2, 8)
cfi_rel_offset (r3, 12)
@ get pointer to linker struct
ldr r0, [lr, #-4]
@ prepare to call _dl_fixup()
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each
sub r1, ip, lr
sub r1, r1, #4
add r1, r1, r1
[...]
第二个GOT条目的地址在LR中。我猜这是donebyt。PLT0:
从这两个GET地址中,动态链接器可以在PLT重定位表中找到GET偏移量和偏移量
从&GOT[2],动态链接器可以找到PLTGOT-GOT[1]的第二个条目,其中包含链接器结构的地址,动态链接器使用该引用来识别此共享对象/可执行文件
我不知道这是在哪里指定的:它似乎不是基本臂ABI规范的一部分。TLDR;PLT通过传递以下消息调用动态链接器: IP和PLTGOT[n+3]中GOT条目的地址 &PLTGOT[2]位于LR中 此外,PLTGOT[1]标识共享对象/可执行文件 动态链接器使用它来查找重新定位条目plt_relocation_table[n],从而找到符号printf PLT输入代码的说明 这在以下几方面得到了解释: 委员会注意到: 当平台像ARM Linux一样支持惰性函数绑定时 此ABI需要ip来寻址相应的 PLT通过其调用的点处的PLTGOT入口。 要求PLT的行为如同以LDR pc[ip]结束一样 从GOT中查找重新定位条目 现在,从GOT地址找到重新定位条目的方式还不清楚。可以使用二进制搜索,但不方便。GNU ld.so是否与glibc/sysdeps/arm/dl trampoline.S类似:
dl_runtime_resolve:
cfi_adjust_cfa_offset (4)
cfi_rel_offset (lr, 0)
@ we get called with
@ stack[0] contains the return address from this call
@ ip contains &GOT[n+3] (pointer to function)
@ lr points to &GOT[2]
@ Save arguments. We save r4 to realign the stack.
push {r0-r4}
cfi_adjust_cfa_offset (20)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
cfi_rel_offset (r2, 8)
cfi_rel_offset (r3, 12)
@ get pointer to linker struct
ldr r0, [lr, #-4]
@ prepare to call _dl_fixup()
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each
sub r1, ip, lr
sub r1, r1, #4
add r1, r1, r1
[...]
第二个GOT条目的地址在LR中。我猜这是donebyt。PLT0:
从这两个GET地址中,动态链接器可以在PLT重定位表中找到GET偏移量和偏移量
从&GOT[2],动态链接器可以找到PLTGOT-GOT[1]的第二个条目,其中包含链接器结构的地址,动态链接器使用该引用来识别此共享对象/可执行文件
我不知道这是在哪里指定的:它似乎不是基本ARM ABI规范的一部分。但我认为.rel.dyn仅用于变量,而不用于函数。动态函数包含在.rel.pltb中,但我认为.rel.dyn仅用于变量,而不用于函数。动态函数位于.rel.plt中。这与您上一个问题非常相似。这与您上一个问题非常相似。 Offset Info Type Sym. Value Sym. Name 0001066c 00000116 R_ARM_JUMP_SLOT 00000000 printf
dl_runtime_resolve:
cfi_adjust_cfa_offset (4)
cfi_rel_offset (lr, 0)
@ we get called with
@ stack[0] contains the return address from this call
@ ip contains &GOT[n+3] (pointer to function)
@ lr points to &GOT[2]
@ Save arguments. We save r4 to realign the stack.
push {r0-r4}
cfi_adjust_cfa_offset (20)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
cfi_rel_offset (r2, 8)
cfi_rel_offset (r3, 12)
@ get pointer to linker struct
ldr r0, [lr, #-4]
@ prepare to call _dl_fixup()
@ change &GOT[n+3] into 8*n NOTE: reloc are 8 bytes each
sub r1, ip, lr
sub r1, r1, #4
add r1, r1, r1
[...]
00015b84 :
15b84: e52de004 push {lr} ; (str lr, [sp, #-4]!)
15b88: e59fe004 ldr lr, [pc, #4] ; 15b94
15b8c: e08fe00e add lr, pc, lr
15b90: e5bef008 ldr pc, [lr, #8]!
15b94: 0012f46c andseq pc, r2, ip, ror #8