2017-05-28 97 views
0

如果动态链接器/加载器本身就是一个共享对象文件,它是如何正确加载到动态链接程序的过程映像空间(如果它尚未存在的话)?这是否是某种捕捉22的东西?加载动态链接器

+0

见[当/ Linux如何加载共享库的地址空间?(https://stackoverflow.com/questions/5130654/) –

+0

从您的链接,发帖者说:“图书馆是由ld.so加载“,但是,我的问题是,如果ld.so本身是一个”库“(共享对象文件),它是如何加载的... –

+0

而讨论_'的部分被声明为”解释器“(INTERP; .interp部分)所有动态链接的ELF二进制文件。所以,当你启动程序时,Linux会启动一个ld.so(加载到内存并跳转到它的入口点),然后ld.so将你的程序加载到内存中,准备好并运行它。您也可以使用 '/lib/ld-linux.so.2 ./your_program your_prog_params'__启动动态程序。内核加载并运行它,然后解释二进制文件,从而避免了Catch-22,因为内核会处理动态加载器的加载。注意我没有使用Mjölnir! “ –

回答

3

This answer提供了一些细节(虽然有技术错误)。

这是一种捕捉22的东西吗?

是:ld.so特殊 - 这是一个自搬迁二进制。

它从仔细执行不需要任何重定位的代码开始。该代码本身重新定位ld.so。在完成自我重新定位/引导过程后,ld.so将继续作为常规共享库。

+0

已就业,您是否可以通过编辑链接的答案或回答技术上正确的答案来纠正一些错误? – osgx

1

请参考 Oracle Solaris 11.1 Linkers and Libraries Guide 这是我遇到的最好的连接器参考,简洁并且很好地解释了事情。

在第89页:

由于动态可执行文件的初始化和执行的一部分, 一个解释被调用来完成应用程序的结合 它的依赖。在Oracle Solaris OS中,此解释器为 ,称为运行时链接程序。

在动态可执行文件的链接编辑过程中,会创建一个特殊的.interp节以及一个 关联的程序头。本部分包含一个路径 名称,指定程序的解释器。链接编辑器提供的默认名称 是运行时链接程序的名称:/usr/lib/ld.so.1 (适用于32位可执行文件)和/usr/lib/64/ld.so.1适用于64位 可执行文件。

注 - ld.so.1是共享对象的特例。这里,使用 的版本号。但是,以后的Oracle Solaris OS 版本可能会提供更高的版本号。

在 执行动态对象的过程中,内核加载文件并读取程序头信息。请参阅第371页的“程序标题”。从 此信息,内核找到所需的 解释程序的名称。内核加载并将控制转移给此解释器,传递足够的信息以使解释器 继续执行应用程序。