gpt4 book ai didi

linux - 在 Linux 上创建 .SO 文件而不使用 PIC(位置无关代码)(x86 32 位)

转载 作者:太空狗 更新时间:2023-10-29 11:45:40 24 4
gpt4 key购买 nike

据我所知,x86 汇编代码在很大程度上受到寄存器数量的限制。

当我了解到在 Linux 上,要创建一个 .so 文件,必须向 gcc 指定 -fPIC 命令行参数才能创建与位置无关的代码时,我一开始简直不敢相信。

据我所知,elf 文件格式支持重定位,就像 - 在我看来更好 - Windows DLL 系统的工作原理:在 Windows 上,如果有必要,链接器会重定位 DLL 中的所有偏移量。

我认为加载 SO 文件或 DLL 文件所需的时间,以及用于保持不同重定位的 .so 文件的内存量并不像一直缺少整个寄存器那么糟糕它指向 GOT 并具有所有这些间接跳转。

我也根本不关心 ALSR 等。对于我想到的应用程序,我只关心库中的代码要尽可能优化。

1) 为什么 Linux 不像 Windows 那样支持更多的动态库加载,而 Windows 应该会生成性能更高的代码?

到目前为止,我还没有找到真正的解释。只是一些类似的事情,重新定位代码会非常糟糕和缓慢(当然,对于在台式机上加载文字处理器,加载速度有多快很重要,我完全接受这一点。但对于计算密集型服务器进程(不处理来自互联网的恶意数据),我想拥有我能得到的所有性能和寄存器!

2) 我可以在 Linux 上创建 NOT -fPIC 编译的 SO 文件吗?我可以离开 -fPIC 吗?是否有任何关于此主题的方法、手册或项目可以在不浪费整个寄存器的情况下仍然动态加载库?

如果我在编译 .so 文件时只删除 -fPIC 会怎样?

最佳答案

What happens if I just drop the -fPIC when compiling a .so-file?

生成的共享对象 ELF 文件将(很可能)在半随机(即不可预测的)页面地址处动态加载(例如,因为 mmap 系统调用将遇到 ASLR)。

而且链接器会产生大量的重定位操作。因此动态链接器 (ld.so) 将不得不缓慢地处理大量重定位,因此您的文本段将不得不被重写(并且不会与其他进程有效地只读共享使用相同的 .so 文件)。

所以在实践中,忘记共享对象(即动态链接库)上的 -fPIC 通常是一个坏主意,即使这是可能的。

阅读Drepper's HowTo do Dynamic Shared Libraries纸和惠勒的 Program Library Howto

顺便说一句,position independent code在 x86(32 位)上比在 x86-64 上成本高得多。但这是值得的(在 x86 32 位上,PIC 代码可能比非 PIC 代码最多慢 5% 到 10%)。

关于linux - 在 Linux 上创建 .SO 文件而不使用 PIC(位置无关代码)(x86 32 位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17900463/

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