Linux ELF64加载程序如何知道更新.get.plt中的初始地址?
考虑以下程序Linux ELF64加载程序如何知道更新.get.plt中的初始地址?,linux,elf,glibc,Linux,Elf,Glibc,考虑以下程序hello.c: #include <stdio.h> int main(int argc, char** argv) { printf("hello"); return 0; } 这是对应PLT条目中第二条指令相对于段开始的偏移量 用starti启动并链接程序后,p'printf@got.plt“现在给出 $2 = (<text from jump slot in .got.plt, no debug info>) 0x555555555
hello.c
:
#include <stdio.h>
int main(int argc, char** argv)
{
printf("hello");
return 0;
}
这是对应PLT条目中第二条指令相对于段开始的偏移量
用starti
启动并链接程序后,p'printf@got.plt“
现在给出
$2 = (<text from jump slot in .got.plt, no debug info>) 0x555555555036 <printf@plt+6>
和readelf-r simple
显示此地址的重新定位条目
Relocation section '.rela.plt' at offset 0x550 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000004018 000200000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
但我对第76页的理解是,这些重定位条目仅在LD_BIND_NOW
为非空时使用。是否有我遗漏的其他搬迁条目?相对于GOT的最终地址,重定偏移量的机制是什么?根据Drepper的说法,动态链接器重新定位两种依赖关系:
R_X86_64_JUMP_SLOT
重定位(elf/do rel.h:elf_dynamic_do_rel
)中循环,并增加它们包含的偏移量(sysdeps/X86_64/dl machine.h:elf_machine\u lazy_rel
):
使用延迟PLT绑定时(默认情况)。根据Drepper的说法,动态链接器会重新定位两种依赖关系:
R_X86_64_JUMP_SLOT
重定位(elf/do rel.h:elf_dynamic_do_rel
)中循环,并增加它们包含的偏移量(sysdeps/X86_64/dl machine.h:elf_machine\u lazy_rel
):
当使用延迟PLT绑定时(默认情况)。在进一步挖掘之后,在我看来,链接器/加载器确实使用
R\u X86\u 64\u JUMP\u SLO
重定位条目,在加载包含.PLT.get
的段时,将偏移量重设到PLT中。相关的源代码似乎位于glibc中的elf/do rel.h:elf\u dynamic\u do\u rel
和sysdeps/x86\u 64/dl machine.h:elf\u machine\u lazy\u rel
。由于我不完全理解elf加载程序代码,欢迎任何专家对此进行确认!解释得很透彻,也许没有答案能做得更好。谢谢@MaximeGroushkin。我通读了你建议的参考资料,我想你可能是对的。我已经用我目前理解的所有内容添加了一个答案。在进一步挖掘之后,在我看来,链接器/加载器确实使用了R\u X86\u 64\u JUMP\u SLO
重定位条目,以便在加载包含.PLT.get
的段时将偏移量重设为PLT。相关的源代码似乎位于glibc中的elf/do rel.h:elf\u dynamic\u do\u rel
和sysdeps/x86\u 64/dl machine.h:elf\u machine\u lazy\u rel
。由于我不完全理解elf加载程序代码,欢迎任何专家对此进行确认!解释得很透彻,也许没有答案能做得更好。谢谢@MaximeGroushkin。我通读了你建议的参考资料,我想你可能是对的。我已经添加了一个答案,包含了我目前理解的所有内容。
$1 = (<text from jump slot in .got.plt, no debug info> *) 0x4018 <printf@got.plt>
Relocation section '.rela.plt' at offset 0x550 contains 1 entry:
Offset Info Type Sym. Value Sym. Name + Addend
000000004018 000200000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
if (__glibc_likely (r_type == R_X86_64_JUMP_SLOT))
{
/* Prelink has been deprecated. */
if (__glibc_likely (map->l_mach.plt == 0))
*reloc_addr += l_addr;
else
...