32位x86代码是否需要为共享库文件进行特殊的图编译?

时间:2021-12-10 02:54:08

Compiling code to an object file needs to be done position-independent if the object file is intended to be loaded as a shared library (.so), because the base virtual address that the shared object file is loaded into in different processes may be different.

将代码编译到对象文件需要独立于位置(如果目标文件打算作为共享库加载的话),因为共享对象文件在不同进程中加载的基本虚拟地址可能不同。

Now I didn't encounter errors when I tried to load an .so file compiled and linked without the -fpic GCC option on 32bit x86 computers, while it fails on 64bit bit x86 computers.

现在,当我试图在32位x86计算机上加载一个没有-fpic GCC选项的.so文件时,我没有遇到错误,而在64位x86计算机上,它失败了。

Random websites I found say that I don't need -fpic on 32bit because code compiled without -fpic works by coincidence according to the X86 32bit ABI also when used in a position-independent manner. But I still found software that ship with separate versions of libraries in their 32bit versions: One for PIC, and one for non-PIC. For example, the intel compiler ships with libirc.a and libirc_pic.a, the latter being compiled for position-independent mode (if one wants to link that .a file into an .so file).

我发现的随机网站说,我不需要-fpic在32位,因为没有-fpic的代码是巧合的,根据X86 32bit ABI,也可以在一个位置独立的方式使用。但我还是找到了一种软件,它附带了32位版本的库:一个用于PIC,一个用于非PIC。例如,intel编译器附带libirc。一个和libirc_pic。a,后者被编译为位置无关的模式(如果有人想把那个。a文件链接到。so文件)。

I wonder what the precise difference between using -fpic and not using it is for 32bit code, and why some packages, like the intel compiler, still ship with separate versions of libraries?

我想知道使用-fpic和不使用它之间的确切区别是32位代码,为什么有些包,像intel编译器一样,仍然带有不同版本的库?

2 个解决方案

#1


10  

It's not that non-PIC code works "by coincidence" on x86 (32-bit). It's that the dynamic linker for x86 supports the necessary "textrels" needed to make it work. This comes at a very high cost in memory consumption and startup time, since basically the entire code segment must be patched up at load time (and thus becomes non-shareable memory).

并不是说非pic代码在x86(32位)上是“巧合”的。x86的动态链接器支持使其工作所需的“textrels”。这在内存消耗和启动时间方面的成本非常高,因为基本上整个代码段都必须在加载时进行修补(从而成为不可共享内存)。

The dynamic linker maintainers claim that non-PIC shared libraries can't be supported on x86_64 because of fundamental issues in the architecture (immediate address displacements can't be larger than 32-bit) but this issue could be easily solved by just always loading libraries in the first 4gb of virtual address space. Of course PIC code is very inexpensive on x86_64 (PIC isn't a performance-killer like it is on 32-bit x86) so they're probably right to keep it unsupported and prevent fools from making non-PIC libraries...

动态链接器维护人员声称,由于体系结构中的基本问题(即时地址置换不能大于32位),在x86_64上不能支持非pic共享库,但是只要始终在第一个4gb的虚拟地址空间中加载库,就可以很容易地解决这个问题。当然,在x86_64上PIC是非常便宜的(PIC并不像32位x86上那样是性能杀手),所以它们可能是正确的,因为它们不支持PIC,并且防止愚人创建非PIC库……

#2


0  

the base virtual address that the shared object file is loaded into in different processes may be different

在不同进程中加载共享对象文件的基本虚拟地址可能不同

Because shared objects usually load at their preferred address, they may appear to work correctly. But fPIC is a good idea for all shared code.

因为共享对象通常在其首选地址加载,所以它们可能看起来工作正确。但是对于所有共享代码来说,fPIC是一个好主意。

I believe the reason that there aren't often two versions of the library is that many distributions use fPIC as the default for all code.

我认为这个库通常没有两个版本的原因是许多发行版都使用fPIC作为所有代码的默认值。

#1


10  

It's not that non-PIC code works "by coincidence" on x86 (32-bit). It's that the dynamic linker for x86 supports the necessary "textrels" needed to make it work. This comes at a very high cost in memory consumption and startup time, since basically the entire code segment must be patched up at load time (and thus becomes non-shareable memory).

并不是说非pic代码在x86(32位)上是“巧合”的。x86的动态链接器支持使其工作所需的“textrels”。这在内存消耗和启动时间方面的成本非常高,因为基本上整个代码段都必须在加载时进行修补(从而成为不可共享内存)。

The dynamic linker maintainers claim that non-PIC shared libraries can't be supported on x86_64 because of fundamental issues in the architecture (immediate address displacements can't be larger than 32-bit) but this issue could be easily solved by just always loading libraries in the first 4gb of virtual address space. Of course PIC code is very inexpensive on x86_64 (PIC isn't a performance-killer like it is on 32-bit x86) so they're probably right to keep it unsupported and prevent fools from making non-PIC libraries...

动态链接器维护人员声称,由于体系结构中的基本问题(即时地址置换不能大于32位),在x86_64上不能支持非pic共享库,但是只要始终在第一个4gb的虚拟地址空间中加载库,就可以很容易地解决这个问题。当然,在x86_64上PIC是非常便宜的(PIC并不像32位x86上那样是性能杀手),所以它们可能是正确的,因为它们不支持PIC,并且防止愚人创建非PIC库……

#2


0  

the base virtual address that the shared object file is loaded into in different processes may be different

在不同进程中加载共享对象文件的基本虚拟地址可能不同

Because shared objects usually load at their preferred address, they may appear to work correctly. But fPIC is a good idea for all shared code.

因为共享对象通常在其首选地址加载,所以它们可能看起来工作正确。但是对于所有共享代码来说,fPIC是一个好主意。

I believe the reason that there aren't often two versions of the library is that many distributions use fPIC as the default for all code.

我认为这个库通常没有两个版本的原因是许多发行版都使用fPIC作为所有代码的默认值。