【问题标题】:how to fix a local symbol' can not be used when making a shared object error?发生共享对象错误时如何修复本地符号'不能使用?
【发布时间】:2017-09-15 04:46:00
【问题描述】:

我的c源文件编译失败,出现以下错误:

libservices.a(protocol.o): 重定位 R_ARM_MOVW_ABS_NC 对 `a local symbol' 在制作共享对象时不能使用;使用 -fPIC 重新编译
libservices.a:添加符号时出错:错误值 collect2.exe:
错误:ld 返回 1 个退出状态

除了在源目录中添加一个额外的文件之外,我没有做任何更改,事情发生了翻天覆地的变化。即使我没有使用-fPIC 选项,它也可以在没有这些警告的情况下正常工作。由于我没有对文件进行任何更改,我很想知道为什么会出现这个错误,这是什么意思,以及如何摆脱这个问题。感谢您的帮助。

【问题讨论】:

    标签: c makefile arm linker-errors


    【解决方案1】:

    您应该使用 -fPIC 进行编译。见how to recompile with -fPIC

    非 PIC 代码在迁移到另一个地址时需要修改。二进制代码和数据的这些修改称为重定位。有许多不同类型的搬迁。它们可能涉及将符号的绝对地址放入数据字中,或修改 MOVW 或 MOVT 指令的某些位以将部分常量放入指令本身。后一个是你的问题。

    当您链接可执行文件时,静态链接器将执行所有这些重定位。如果您使用共享库,则动态链接器必须在可执行文件运行并动态链接到共享库时执行这些操作。

    动态链接器可能不支持某些类型的重定位,称为文本重定位或 TEXTRELS。这些涉及使用实际代码修改文本段,并将值放入指令中。由于它修改了代码,共享库的那部分将不再在进程之间共享。您应该通过 -fPIC 使库位置独立,因此动态链接器不需要进行文本重定位。

    您之前的代码可能没有导致编译器发出任何需要不受支持的重定位的内容。然后你添加的文件中有一些东西。例如,访问全局变量可以在 ARM 上触发。

    int x = 1;
    void foo(void) { x=42; }
    

    编译为:

        movw    r3, #:lower16:x
        mov     r2, #42
        movt    r3, #:upper16:x
        str     r2, [r3]
        bx      lr
    

    x的地址的下半部分和上半部分需要放入movw和movt指令中。动态链接器不支持这一点。如果代码是使用 -fPIC(或 -mword-relocations)编译的,编译器会产生不需要这些重定位的不同输出。

    “protocol.o”具有不受支持的重定位,并且在您进行更改之前它不存在,或者没有使用,或者没有它们。如果 libservice.a 已经存在,请记住,静态库中的代码仅在使用时才包含在内。也许“protocol.o”没有被任何东西使用,但是你添加的任何东西都使用了它。

    【讨论】:

      【解决方案2】:

      这取决于您将哪种文件添加到源文件夹中。 例如,如果您添加一个新的库文件并且该新库文件是针对 -fPIC 构建选项构建的,您可能会遇到类似的情况。

      实际上,错误消息为您提供了足够的信息来解决它。 通过“-fPIC”构建选项重新编译就可以了。

      • 如果您通过命令行构建,请在命令中附加“-fPIC” 行。
      • 如果您是通过 Makefiles 构建,请按如下方式修改 makefile:

        CFLAGS += -fPIC

      • ARM编译器请参考

      http://infocenter.arm.com/help/topic/com.arm.doc.dui0804b/CHDECFHF.html?resultof=%22%2d%66%70%69%63%22%20

      • GCC编译器请参考

      https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html

      【讨论】:

      • 我在我的应用程序中添加了新的 .c 源文件我没有添加任何新的库文件,在这种情况下我不必将它们构建为与位置无关的二进制文件,不是吗,因为它以前不在那里
      猜你喜欢
      • 1970-01-01
      • 2021-05-17
      • 2020-07-09
      • 2011-04-25
      • 1970-01-01
      • 2015-07-20
      • 2021-01-17
      • 1970-01-01
      • 2020-10-16
      相关资源
      最近更新 更多