首先,我从技术的angular度来问这个问题,而不是图书馆代码用户的angular度。 不同之处在于共享对象包含程序头文件,普通对象文件不包含程序头文件。 其他的区别是什么?
至于我的问题的目的,我试图找出哪些内容将需要从共享对象文件中删除,让链接器将其视为一个普通的对象文件,并尝试重新定位和静态链接到生成的可执行文件文件,而不是将其标识为共享库并生成DT_NEEDED引用。 这反过来又是将共享库原始“转换”为静态链接的第一步(然而,可能还需要进一步的工作以使重定位可满足)。
编译libstdc ++版本与系统版本
链接到应用程序时共享库的variables存储在哪里?
在运行时加载Linux库
你会发现一个主要的区别是,在最后的链接阶段,一些C库组件被静态地链接到库中,形成了INIT和FINI符号等等。 这些通过程序头中的DT_INIT和DT_FINI条目来指定; 您将需要将这些转换为静态构造函数/析构函数条目。 DT_NEEDED条目将在转换为.o时丢失; 您将需要手动重新添加它们。
在最后的链接阶段生成的plt需要与最终的输出文件合并,或者转换回普通的重定位。 这是不平凡的,因为plt就是代码。 GOT也是一个问题; 它位于.text段的固定相对偏移处,并包含指向数据成员的指针。 但是,它也包含一个指向_DYNAMIC结构的指针,其中每个库或可执行文件只能有一个。 而且你不能改变GOT中的偏移量,因为它们是直接从代码中引用的。
所以将.so再次转换成真实的.o是非常困难的。 信息在转换到plt / GOT时丢失了。 更好的方法可能是更改C库中的动态链接程序,以支持将已经映射到内存中的共享库链接为静态图像。 也就是说,只要将.so转换成一个页面对齐的只读部分,就可以将.so转换为.o。 然后将其传递给动态链接器以重新映射适当的权限并执行正常的共享库初始化。 然后添加一个静态构造函数来调用C库来初始化共享库。 最后,添加适当的导出符号以对应共享库的.text段中的动态符号。
但是,这种方法的一个问题是,静态构造函数可能在初始化你的假solib的静态构造函数之前运行。 在这种情况下,他们不能尝试从solib调用函数,否则可能会崩溃,因为solib尚未初始化。 这可以通过将导出的符号指向蹦床函数来确保solib被初始化(尽管数据符号并不那么容易!
你也可能会发现, 这个以前的问题可能对你有一些用处。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。