解决GCC连接器(lld)出现问题 relocation truncated to fit (重定向截断)

152 篇文章 1 订阅
本文讨论了C/C++在MIPS架构上常见的连接器错误,主要由于编译后的obj文件过大。提供了包括拆分源文件、调整编译器选项(-mlong-calls)、禁用链接器功能等在内的解决方案。
摘要由CSDN通过智能技术生成

本文大致提点这个问题,有哪些可行的解决方案。

这是常见 C/C++ 的一类连接器错误,我们需要知道它一般是怎么产生的,才能知道如何正确的解决它。

例如:(当发生这类问题时,连接器通常会输出这样的信息)

[build] /usr/mips64el-linux-gnuabi64/include/c++/7/mips64el-linux-gnuabi64/bits/gthr-default.h:251:(.text+0x1c): relocation truncated to fit: R_MIPS_GOT_DISP against `__pthread_key_create@@GLIBC_2.0'

[build] CMakeFiles/xxx.dir/xxx/net/asio/websocket.cpp.o: In function `__gthread_mutex_lock(pthread_mutex_t*)':

[build] /usr/mips64el-linux-gnuabi64/include/c++/7/mips64el-linux-gnuabi64/bits/gthr-default.h:748:(.text+0x90): relocation truncated to fit: R_MIPS_CALL16 against `pthread_mutex_lock@@GLIBC_2.0'

[build] CMakeFiles/xxx.dir/xxx/net/asio/websocket.cpp.o: In function `__gthread_mutex_unlock(pthread_mutex_t*)': [build] /usr/mips64el-linux-gnuabi64/include/c++/7/mips64el-linux-gnuabi64/bits/gthr-default.h:778:(.text+0x114): relocation truncated to fit: R_MIPS_CALL16 against `pthread_mutex_unlock@@GLIBC_2.0'

通常出现这类连接器问题,多数是C++编译器编译CC/CPP源文件出来的 .obj(*.o)文件太大了,导致超出了一些平台CPU可以短链接重定向的范围。

注意:这个问题可能会在 MIPS、MIPS64 CPU架构上面较容易出现。

以下是可以采纳的解决方案(逐个试)

1、拆分引起连接器暴这个错误的 cpp 文件(XXX.o 对应那个CPP文件)把这个源文件自己分析,按着拆分到多个 cpp 文件之中在编译

2、按需配置C语言、C++ 语言的编译器选项,增加编译器选项 -mlong-calls

     -mlong-calls 编译器选项是指:要求编译器适用VA绝对地址(长地址)来调用跳转,这样呢,可以显著解决因为 XXX.o 编译出来的二进制太大,导致连接器无法连接上的问题。

    但是缺点肯定是有的,那就是效率肯定没有RVA相对地址(短地址)跳转速度块,因为绝对地址都是需要先放在寄存器之中的,在按照寄存器的值跳转,不能直接JMP到绝对地址上面的,相当于每次都要多走一些流程,并且在CPU之中相对寻址本来就比随机的绝对寻址要快的。

3、配置连接器选项,增加选项

1、尝试使用 -Wl,--no-relax 选项来禁用链接器的放松(relocation relaxation)功能,这可能有助于解决一些符号重定位(truncated relocation)的问题。

2、使用 -Wl,--no-merge-exidx-entries 选项来禁止合并 .ARM.exidx 表条目,这可能有助于解决某些链接问题。

这条会有限制,C++ 17 直接没法用了,而且 C++ 11 的一些模板展开特性也会受到限制,基本不是很推荐通过这条指令来解决,但如果真的必须要,无可避免、退无可退的情况下,您或许可以考虑设置它到连接器上面试试看,的确是有效的。

4、调整编译器选项,增加选项

1、考虑添加 -fPIC 选项以生成位置无关代码(Position Independent Code),这有助于减少一些链接时的问题。


2、也可以尝试添加 -ffunction-sections -fdata-sections 选项来将函数和数据放置到单独的段(section)中,这有助于优化链接器的处理。

在这些解决方案之中,相对更亲民靠谱的解决方案还是编译器增加选项: -mlong-calls,另外就是手动拆分C/CPP源文件到多个之中了,毕竟平台及编译器限制也是没有办法不是。

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值