Linux内核如何确定ld.so的加载地址?

时间:2015-04-24 19:38:16

标签: linux linux-kernel x86-64 elf dynamic-linking

我知道动态链接器使用mmap()来加载库。我想是内核将可执行文件及其.interp reter加载到同一地址空间,但它如何确定在哪里?我注意到ld.so禁用ASLR的加载地址是0x555555554000(在x86_64上) - 这个地址来自哪里?我试着遵循do_execve()的代码路径,但它对我来说太过分枝,不会被混淆为地狱。

1 个答案:

答案 0 :(得分:2)

详细了解ELF,特别是elf(5)以及execve(2)系统调用。

ELF文件可能包含解释器。 elf(5)提及:

  

PT_INTERP数组元素指定位置和      要调用的以null结尾的路径名的大小     作为翻译。此细分类型是      仅对可执行文件有意义(但是      它可能发生在共享对象上)。不过它    可能不会在文件中出现多次。如果     它存在,它必须先于任何可加载的   分段录入。

该翻译实际上几乎总是ld-linux(8)(例如使用GNU glibc),更确切地说(在我的Debian / Sid上)/lib64/ld-linux-x86-64.so.2。如果您编译musl-libc然后使用它构建一些软件,您将获得一个不同的解释器/lib/ld-musl-x86_64.so.1。那个ELF解释器是dynamic linker

execve(2)系统调用正在使用该解释器:

  

如果可执行文件是动态链接的ELF可执行文件,则          PT_INTERP段中命名的解释器用于加载所需的解释器          共享库。这个解释器通常是/lib/ld-linux.so.2          与glibc链接的二进制文件。

另见Levine关于Linkers and loadersDrepper's paper: How To Write Shared Libraries

的书

请注意execve也在处理shebang(即以#!开头的第一行);请参阅execve(2)解释器脚本部分。顺便说一下,对于ELF二进制文件,execve正在某些段上执行mmap(2)等效

另请阅读vdso(7)proc(5)& ASLR。在shell中输入cat /proc/self/maps

(我猜,但我不确定,0x55​​5555554000地址是在你的可执行文件的ELF程序头中,或者是ld-linux.so;它也可能来自内核,因为0x55555555似乎出现在内核源代码中)