ELF 目标文件和共享对象之间的 ELF 标头有何区别?

发布于 2024-11-18 21:06:16 字数 234 浏览 3 评论 0原文

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

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

First of all, I'm asking this from a technical perspective, not a perspective of the user of library code. One example of a difference is that shared objects contain program headers and ordinary object files don't. What are the other differences?

As to the purpose of my question, I'm trying to figure out what content would need to be removed from a shared object file to have the linker treat it as an ordinary object file and attempt to relocate and static link it into the generated executable file, rather than identifying it as a shared library and generating a DT_NEEDED reference. This in turn is the first step to primitive "conversion" of a shared library to something that can be statically linked (further work to make the relocations satisfiable may be required, however).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

日暮斜阳 2024-11-25 21:06:16

您会发现的主要区别之一是,在最后的链接阶段,许多 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(不过,对于数据符号来说并不那么容易!)

您可能还会发现 上一个问题可能对您有用。

One of the major differences you'll find is that, during the final link stage, a number of C library components are statically linked into the library, forming the INIT and FINI symbols among other things. These are specified with DT_INIT and DT_FINI entries in the program header; you will need to transform these into static constructor/destructor entries. DT_NEEDED entries will be lost in a transformation into a .o; you will need to re-add them manually.

The PLT generated in the final link stage needs to be either merged with the final output file, or transformed back into ordinary relocations; this is non-trivial, as the PLT is just code. The GOT is also an issue; it's located at a fixed relative offset from the .text segment, and contains pointers to data members. It also, however, contains a pointer to the _DYNAMIC structure, of which there can only be one per library or executable. And you can't change offsets in the GOT, because they're referenced directly from code.

So it's quite difficult to convert a .so to a true .o again; information has been lost in the conversion to PLT/GOTs. A better approach might be to alter the dynamic linker in the C library to support linking a shared library that's already mapped in memory as a static image. That is, you'd convert the .so to a .o simply by converting it to a page-aligned read-only section; then pass this to the dynamic linker to remap with appropriate permissions and perform normal shared library initialization. Then add a static constructor to call into the C library to initialize the shared library. Finally, add appropriate exported symbols to correspond to dynamic symbols in the shared library's .text segment.

One problem with this approach, though, is that static constructors might run before the static constructor that initializes your fake solib. In this case, they must not attempt to call functions from the solib, or you'll probably crash, as the solib is not yet initialized. This could potentially be avoided by making the exported symbols point into a trampoline function that ensures the solib is initialized first (not so easy with data symbols, though!)

You might also find that this previous question might be of some use to you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文