解决Mips下编译C++程序链接报错:‘ relocation truncated to fit: R_MIPS_CALL16 against ‘

前言

最近在MIPS架构下编译程序遇到了奇怪的问题,同样的环境,以前版本的代码可以编译链接成功,但新版本代码却无法链接成功,报错则是以下:

../lib/libproto37.a(edrMessage.pb.cc.o):在函数‘InitDefaultsscc_info_EdrMessage_AgentBaselineStatus_edrMessage_2eproto()’中:
edrMessage.pb.cc:(.text+0x350): relocation truncated to fit: R_MIPS_CALL16 against `google::protobuf::internal::VerifyVersion(int, int, char const*)'
edrMessage.pb.cc:(.text+0x3f4): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
../lib/libproto37.a(edrMessage.pb.cc.o):在函数‘InitDefaultsscc_info_EdrMessage_AgentUpdate_edrMessage_2eproto()’中:
edrMessage.pb.cc:(.text+0x458): relocation truncated to fit: R_MIPS_CALL16 against `google::protobuf::internal::VerifyVersion(int, int, char const*)'
edrMessage.pb.cc:(.text+0x4fc): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
../lib/libproto37.a(edrMessage.pb.cc.o):在函数‘InitDefaultsscc_info_EdrMessage_AgentUpdate_AgentUpdateRequest_edrMessage_2eproto()’中:
edrMessage.pb.cc:(.text+0x560): additional relocation overflows omitted from the output
collect2: 错误:ld 返回 1
CMakeFiles/sniper.dir/build.make:1244: recipe for target '../bin/sniper' failed
make[2]: *** [../bin/sniper] Error 1
CMakeFiles/Makefile2:82: recipe for target 'CMakeFiles/sniper.dir/all' failed
make[1]: *** [CMakeFiles/sniper.dir/all] Error 2
make[1]: *** 正在等待未完成的任务....
解决问题

经过一番google,最终了解查到这是mips下的常见问题,并且指出需要使用gcc的"-mxgot"选项,文档如下:

-mxgot
-mno-xgot
Lift (do not lift) the usual restrictions on the size of the global offset table.
GCC normally uses a single instruction to load values from the GOT. While
this is relatively efficient, it will only work if the GOT is smaller than about
64k. Anything larger will cause the linker to report an error such as:

	relocation truncated to fit: R_MIPS_GOT16 foobar

If this happens, you should recompile your code with ‘-mxgot’. It should then
work with very large GOTs, although it will also be less efficient, since it will
take three instructions to fetch the value of a global symbol.

Note that some linkers can create multiple GOTs. If you have such a linker,
you should only need to use ‘-mxgot’ when a single object file accesses more
than 64k’s worth of GOT entries. Very few do.

These options have no effect unless GCC is generating position independent code.

大致意思就是GOT(global offset table|全局偏移表)大小有限制,gcc使用一条指令去加载只能支持大约64K,因此要么使用-O1,减少调试信息从而减小表大小,要么就使用"-mxgot"取消表大小的限制,但是这样会导致效率的降低。所以-O1能解决的时候,尽量不用-mxgot。这个解决的就是单个目标文件的GOT超过了64K限制时的问题,而且也只在生成位置无关代码(-fPIC)时候有效。

针对我这个问题分析就是libproto37.a中的一个pb协议文件超出了限制,因此编译这个库时,给CFLAGS和CXXFLAGS添加-O1或者-mxgot即可解决。所以才会出现以前版本能链接,现在不行的问题,因为协议字段的增加导致pb文件变大,从而达到了限制大小引发了这个链接问题。

结束语

如果本篇文章对你有用的话,可以点赞支持一下。如果我哪里没说对也欢迎指出,共同进步!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值