【问题标题】:Mixing fPIC and non-fPIC object modules混合 fPIC 和非 fPIC 对象模块
【发布时间】:2017-11-07 18:59:53
【问题描述】:

环境:Ubuntu 16.04

在我的实验中,我运行了以下命令:

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

我需要公开的函数都在 2.c 中通过extern "C" 声明定义。这些函数在内部调用 1.c 中定义的其他函数。

请注意,我没有将-fPIC 应用于 1.c。一切似乎都可以正常编译/链接,没有任何警告。

我们能否得出结论,-fPIC 必须仅应用于那些公开外部函数的源文件?

在大图中,我有一堆可能没有使用-fPIC 标志编译的存档 (.a) 文件。我需要创建一个与这些存档文件链接的自定义共享库。如果我的假设是有效的,我认为可以链接到这些存档文件。欣赏你的想法。问候。

【问题讨论】:

    标签: c gcc compilation shared-libraries position-independent-code


    【解决方案1】:

    我们能否得出结论 -fPIC 必须仅应用于那些源文件 暴露外部函数?

    不,我们不能。 -fPIC 的唯一目的是确保生成的机器代码可以链接到与位置无关的二进制文件中。尽管如此,即使源代码是在没有-fPIC 的情况下编译的,也有可能某些代码似乎是 PIC 就绪的。它可能是没有外部依赖的简短的自包含函数,无论在生成的目标文件中不需要辅助数据结构,如 PLT 和 GOT 条目。

    如果您的目标文件无法链接到与位置无关的二进制文件,则无论如何链接器都会失败并显示全面的错误消息。你需要用这个神奇的选项重新编译它。

    因此,您应该始终将共享库的-fPIC 放在CFLAGS 中,以节省您自己的时间并避免浪费性的重新编译。

    【讨论】:

      【解决方案2】:

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

      -fPIC 需要生成与位置无关的代码:

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

      此外,在 Linux/x86-32 上编译/链接没有 -fPIC 的目标文件时,您可能会在没有任何警告或错误的情况下逃脱;但在某些架构上是不可能做到这一点的。

      【讨论】:

        猜你喜欢
        • 2011-04-02
        • 2011-07-15
        • 2012-02-26
        • 2023-03-29
        • 2021-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多