gpt4 book ai didi

c - 制作共享对象错误时如何修复局部符号'不能使用?

转载 作者:行者123 更新时间:2023-12-04 08:30:46 24 4
gpt4 key购买 nike

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

libservices.a(protocol.o): relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
libservices.a: error adding symbols: Bad value collect2.exe:
error: ld returned 1 exit status

除了在源目录中添加了一个额外的文件之外,我没有做任何更改,然后就开始折腾了。即使我没有使用 -fPIC 选项,它也可以在没有这些警告的情况下正常工作。由于我没有对 make 文件进行任何更改,所以我很想知道为什么会出现此错误,这是什么意思,以及如何解决此问题。感谢您的帮助。

最佳答案

您应该使用 -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”没有被任何东西使用,但是你添加的任何东西都使用了它。

关于c - 制作共享对象错误时如何修复局部符号'不能使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43487520/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com