gcc 混合fPIC和非fPIC对象模块

mzaanser  于 2022-12-23  发布在  其他
关注(0)|答案(2)|浏览(153)

环境:Ubuntu 16.04
在我的实验中,我运行了以下命令:

gcc -c 1.c
gcc -c -fPIC 2.c
gcc -shared 1.o 2.o -o libmyxxx.so

我需要公开的函数都是在Python 2.c中通过extern "C"声明定义的,这些函数在内部调用Python 1.c中定义的其他函数。
请注意,我没有将-fPIC应用到1.c。尽管如此,所有内容似乎都编译/链接良好,没有任何警告。
我们是否可以得出结论,-fPIC必须仅应用于那些公开外部函数的源文件?
从更大的Angular 来看,我有一堆可能没有使用-fPIC标记编译的存档(. a)文件。我需要创建一个自定义共享库,它将与这些存档文件链接。如果我的假设是正确的,我认为与这些存档文件链接是可以的。感谢您的想法。问候。

sqserrrh

sqserrrh1#

我们是否可以得出结论,-fPIC必须只应用于那些公开外部函数的源文件?
不,我们不能。-fPIC的唯一目的是确保生成的机器码可以链接到位置无关的二进制。然而,即使源代码是在没有-fPIC的情况下编译的,一些代码也可能看起来是PIC就绪的。它可能是简短的自包含函数,没有外部依赖项,无论如何,都不需要生成的目标文件中的辅助数据结构,如PLT和GOT条目。
无论如何,如果你的目标文件不能被链接成位置无关的二进制文件,链接器会失败并显示错误信息,你需要用这个神奇的选项重新编译它。
因此,您应该始终将共享库的-fPIC放到CFLAGS中,以保存您自己的时间并避免浪费的重新编译。

xbp102n0

xbp102n02#

如果在可执行文件中有一个目标文件,它是在没有-fPIC标志的情况下编译的,则会有一些程序文本页具有 * 位置相关的内存引用 *。这些页在运行时将无法重新定位到合适的虚拟内存地址(这主要是共享对象的用途)。当您在其他机器上构建代码或将.so链接到其他代码时,这些位置相关的内存引用将会出现并吸引你。
-fPIC需要生成位置独立代码,用于:

  • 全局变量
  • 静态变量
  • 外部变量
  • 串常数
  • 获取函数的地址

此外,在Linux/x86-32上编译/链接没有-fPIC的目标文件时,可能不会出现任何警告或错误;但是在某些体系结构上不可能做到这一点。

相关问题