【问题标题】:linux g++ linking 64 bit shared library code to static librarieslinux g++将64位共享库代码链接到静态库
【发布时间】:2011-04-02 16:41:32
【问题描述】:

上下文:我可以创建一个链接到静态库的共享对象库,在 32 位 Linux 上没有任何问题。当我在 64 位 linux 上尝试相同的构建时,我看到了这个链接器错误:

  • 在制作共享对象时,不能使用针对“本地符号”的重定位 R_X86_64_32S;用 -fPIC 重新编译

这个错误在网络上很常见。解决方案是使用位置无关代码 (-fPIC) 编译静态链接库。

我不明白为什么 32 位版本不需要这样做。有人可以帮忙吗?

【问题讨论】:

    标签: linux 64-bit g++ linker 32-bit


    【解决方案1】:

    如果您的目标模块将在共享库中使用,则始终需要“位置无关代码”。它高度依赖于平台,并且会产生一些开销。

    您必须在 amd64 而不是 x386 上显式指定它的原因仅仅是它恰好是 x86 的默认值,而不是 amd64 的默认值。

    还要注意“-fpic”和“-fPIC”的区别:

    -fpic
        Generate position-independent code (PIC) suitable for use in a 
        shared library, if supported for the target machine. Such code 
        accesses all constant addresses through a global offset table 
        (GOT). The dynamic loader resolves the GOT entries when the pro-
        gram starts (the dynamic loader is not part of GCC; it is part
        of the operating system). If the GOT size for the linked execu-
        table exceeds a machine-specific maximum size, you get an error 
        message from the linker indicating that -fpic does not work; in 
        that case, recompile with -fPIC instead. (These maximums are 8k 
        on the SPARC and 32k on the m68k and RS/6000. The 386 has no 
        such limit.)
    
        Position-independent code requires special support, and there
        fore works only on certain machines. For the 386, GCC supports 
        PIC for System V but not for the Sun 386i. Code generated for 
        the IBM RS/6000 is always position-independent.
    
        When this flag is set, the macros __pic__ and __PIC__ are defined to 1.
    
    -fPIC
        If supported for the target machine, emit position-independent 
        code, suitable for dynamic linking and avoiding any limit on the 
        size of the global offset table. This option makes a difference 
        on the m68k, PowerPC and SPARC.
    
        Position-independent code requires special support, and therefore 
        works only on certain machines.
    
        When this flag is set, the macros __pic__ and __PIC__ are defined to 2. 
    

    【讨论】:

    • 很好的信息,但我找不到任何支持您断言 i386 代码默认为 fPIC 的断言。事实上,当我将一些代码编译为 fPIC 并将其与普通目标代码进行比较时,生成的目标文件之间存在显着差异
    • 嗨 - 你是对的。 i386 代码默认是可重定位,但不是位置独立。您在下面引用的链接很好地解释了这种情况:technovelty.org/code/c/amd64-pic.html 具有讽刺意味的是,我通过谷歌搜索“可重定位与位置无关”找到了这个链接,这导致我进入了这个线程:stackoverflow.com/questions/3146744/…Your .. PSM
    【解决方案2】:

    好的答案在这里详细描述:http://www.technovelty.org/code/c/amd64-pic.html

    解释的基本要点是 i386 架构隐式地取消引用每个函数的帧指针(在链接页面的最后一段中解释)。这个过程会产生一些额外的开销,因此在新的 64 位架构中,这种取消引用开销作为优化被消除了。

    从链接的角度来看,这种优化的结果是,除非 64 位代码被显式编译为与位置无关的代码,否则它将生成带有执行上下文偏移量的硬编码代码。

    这是对链接页面内容的不完美解释,但足以满足我的目的。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多