gpt4 book ai didi

c - ELF 对象文件和共享对象之间的 ELF header 有哪些区别?

转载 作者:IT王子 更新时间:2023-10-29 00:19:52 31 4
gpt4 key购买 nike

首先,我是从技术角度而不是库代码用户的角度来问这个问题。差异的一个例子是共享对象包含程序头,而普通对象文件不包含。还有哪些区别?

至于我的问题的目的,我试图弄清楚需要从共享目标文件中删除哪些内容才能让链接器将其视为普通目标文件并尝试将其重新定位和静态链接到生成的可执行文件,而不是将其标识为共享库并生成 DT_NEEDED 引用。这反过来又是将共享库原始“转换”为可以静态链接的东西的第一步(但是,可能需要进一步的工作来使重定位可满足)。

最佳答案

您会发现其中一个主要区别是,在最后的链接阶段,许多 C 库组件静态链接到库中,形成 INIT 和 FINI 符号等。这些由程序头中的 DT_INITDT_FINI 条目指定;您需要将它们转换为静态构造函数/析构函数条目。 DT_NEEDED 条目将在转换为 .o 时丢失;您将需要手动重新添加它们。

在最终链接阶段生成的PLT需要与最终输出文件合并,或者转换回普通重定位;这很重要,因为 PLT 只是代码。 GOT也是一个问题;它位于距 .text 段固定的相对偏移处,并包含指向数据成员的指针。但是,它还包含一个指向 _DYNAMIC 结构的指针,每个库或可执行文件只能有一个。而且您无法更改 GOT 中的偏移量,因为它们是直接从代码中引用的。

所以很难再次将 .so 转换为真正的 .o;信息在转换为 PLT/GOT 时丢失了。更好的方法可能是更改 C 库中的动态链接器以支持链接已作为静态图像映射到内存中的共享库。也就是说,您只需将 .so 转换为页面对齐的只读部分即可将其转换为 .o;然后将其传递给动态链接器以使用适当的权限重新映射并执行正常的共享库初始化。然后添加一个静态构造函数调用C库来初始化共享库。最后,添加适当的导出符号以对应共享库的 .text 段中的动态符号。

不过,这种方法的一个问题是静态构造函数可能会在初始化您的假 solib 的静态构造函数之前运行。在这种情况下,它们不得尝试从 solib 调用函数,否则您可能会崩溃,因为 solib 尚未初始化。这可以通过使导出的符号指向一个确保首先初始化 solib 的蹦床函数来避免(尽管数据符号不那么容易!)

您可能还会发现 this previous question可能对你有用。

关于c - ELF 对象文件和共享对象之间的 ELF header 有哪些区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6625097/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com