繁体   English   中英

动态链接器如何更改进程的文本段?

[英]How does dynamic linker changes text segment of process?

如果我正确理解当用户尝试执行动态链接的可执行文件(使用execve("foo", "", "") )而不是加载“foo”的文本段时,会加载动态链接器(ld-linux.so.2)和执行。 它必须加载程序所需的库(“foo”)来运行并更改“foo”中的一些地址并将控制传递给foo,但这是如何完成的?

如何(它使用什么系统调用)以及动态加载器在内存中加载库和“foo”代码和数据的位置(我猜它不能简单地使用malloc或mmap然后跳转到代码,因为那应该是不可能的,对吧?它似乎也不太可能创建完整可执行文件的临时文件(如静态链接的)和再次调用。)。

实际的实现非常复杂,因为它建立在ELF之上,由于它试图适应许多场景,因此非常复杂,但从概念上讲它非常简单。

基本上(在库依赖项被定位并open ),它是几个mmapmprotect ,通过绑定符号实现链接的一些修改(可以延迟),然后跳转到代码。

理想情况下,链接的共享库将使用-fpic / -fPIC进行编译,这将允许链接器将它们放在进程地址空间中的任何位置,而无需写入库的.text部分(=可执行代码)。 这样的库/可执行文件将通过可修改的表调用来自其他库的函数,链接器将修复(可能是懒惰)以指向它已加载依赖库的实际位置。 从一个共享库到另一个共享库的变量访问同样是间接的。

尽可能限制修改库数据/代码允许将代码段标记为只读(通过MMU / mprotect系统调用)并映射到在使用该特定库的所有进程之间共享的内存中。


要了解在系统调用级别发生的事情,您可以尝试例如:

strace /bin/echo hello world

并且所有包含sbrk的系统调用(=设置堆/ .data段)应该是动态链接器的操作。


malloc确实对链接器不可用,因为malloc是c库的一个特性,而不是系统malloc是关于增长和管理堆部分,并且可能对其他单独的块进行mmap ping并管理那些以及可写的“堆”,并且动态链接器不关心过程映像的这些部分,主要是它的可写间接表以及它映射库的位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM