relocation truncated to fit: R_MIPS_CALL16 问题!

转载出处:http://blog.youkuaiyun.com/yirui/article/details/1672503

我在broadcom7309上编译链接库生成程序时,出现以下链接问题。链接库时,出现以下很多类似的错误:
relocation truncated to fit: R_MIPS_CALL16 against 'IsHealthy()'
relocation truncated to fit: R_MIPS_GOT16 against `g_dwCommsClock'
relocation truncated to fit: R_MIPS_CALL16 against `SetScreenPixelFormat'

原来这此函数都可正常运行,就是链接上我们的一个库后,出现这个问题。

查询网上的解决方法:
http://www.linux-mips.org/archives/linux-mips/2003-05/msg00243.html

http://sourceware.org/ml/binutils/2003-08/msg00128.html

-mxgot是mips专用的gcc 选项,但mipsel-uclibc-g++没有这个选项

参考:
-Wa,optionlist Asm
The optionlist is a list of one or more comma separated lists of options to be passed to
the assembler. The options are split at the commas and each one is provided to the
assembler as a command line option.
Also see -Wp and -Wl. This option can be written as --for-assembler

-G number
Puts global and static items less than or equal to number bytes in size into the small
data or bss section instead of the normal data or bss section. This allows the assembler
to emit one-word memory reference instructions based on the global pointer (gp or
$28), instead of the normal two words used. By default, number is 8 when the MIPS
assembler is used and 0 when the GNU assembler is used.
This option setting is also passed to the assembler and linker, so all modules should
be compiled with the same number value. 

-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

 

最后解决方法:

1.使用-Wa,-xgot重新编译所有的库,包括pthread,libc.

2.使用动态库链接

分析原因:静态库的符号表存储方式不一样,一个库使用32位方式,另一个库使用16位方式,导致调用时不同而造成此问题。

<think>好的,我现在需要解决用户遇到的VxWorks编译错误:“relocation truncated to fit R_AARCH64_CALL26 usrIdleTaskStkProtect”。首先,我需要理解这个错误的含义。R_AARCH64_CALL26是AArch64架构中的一种重定位类型,用于处理函数调用时的地址偏移。当链接器发现某个函数调用的目标地址超出了26位有符号整数能表示的范围时,就会报这个错误。 接下来,用户提到的usrIdleTaskStkProtect可能与任务栈保护有关,可能是一个函数或符号。需要确认这个符号的定义位置和链接情况。可能的原因包括地址空间过大、内存布局不合理,或者代码中存在长跳转。 首先想到的解决方案是检查链接脚本或内存布局,确保代码段和符号的地址在合理范围内。如果符号定义在某个库中,可能需要调整库的加载地址,或者重新编译库以使用位置无关代码(PIC),这样可以通过相对跳转减少绝对地址的需求。 另外,26位偏移的限制是±128MB,如果目标函数距离调用点超过这个范围,就会出错。可以尝试将频繁调用的函数或关键模块放置在靠近调用者的内存区域,或者使用分支指令的变种,比如用ADRP和ADD组合来扩大跳转范围。 还可能涉及编译选项,比如GCC的-mcmodel=large选项支持更大的地址范围,但需要确认VxWorks工具链是否支持。此外,检查是否有函数指针或动态链接的问题,确保所有符号都能正确解析,并且地址不会超出限制。 参考用户提供的引用内容,之前遇到过类似的重定位问题,解决方法是调整编译选项或内存布局。可能需要具体查看usrIdleTaskStkProtect的定义位置,调整其所在段的地址,或者优化代码结构,减少长距离调用。 总结可能的解决步骤:1. 检查链接脚本,确保代码段地址范围合适;2. 使用位置无关编译选项;3. 调整函数或模块的内存布局;4. 修改代码,避免远距离调用;5. 更新工具链或应用补丁。需要逐一排查这些可能性,并验证解决方案是否有效。</think>### VxWorks编译重定位截断错误解决方案 当在AArch64架构下编译VxWorks时,遇到`Relocation truncated to fit: R_AARCH64_CALL26 against symbol 'usrIdleTaskStkProtect'`错误,通常是由于函数调用跳转范围超出26位地址偏移限制(±128MB)。以下是分步解决方案: --- #### **1. 检查内存布局与链接脚本** - **问题根源**:函数`usrIdleTaskStkProtect`的地址与调用点的距离超过26位偏移范围。 - **解决方法**: 1. 确认链接脚本(`.ld`文件)中代码段(如`.text`)的起始地址是否合理,避免代码段跨越过大地址空间。 2. 将频繁调用的函数或关键模块(如任务栈保护相关代码)集中放置在靠近调用者的内存区域。 --- #### **2. 使用位置无关代码(PIC)** - **原理**:通过相对地址跳转减少绝对地址依赖。 - **操作步骤**: 1. 在编译选项中添加`-fPIC`(GCC)或`-qpic`(Wind River工具链),例如: ```bash CFLAGS += -fPIC ``` 2. 重新编译目标模块,确保生成与位置无关的代码[^1]。 --- #### **3. 调整函数调用方式** - **长跳转替代方案**:若必须跨大范围跳转,可将函数调用拆分为`ADRP`+`ADD`指令组合,例如在汇编中手动优化: ```assembly adrp x0, usrIdleTaskStkProtect // 加载高26位地址 add x0, x0, :lo12:usrIdleTaskStkProtect // 加载低12位偏移 blr x0 // 调用函数 ``` - **代码隔离**:将`usrIdleTaskStkProtect`与调用者置于同一代码段或邻近段。 --- #### **4. 检查工具链与编译选项** - **工具链兼容性**:确认使用的VxWorks工具链(如Wind River Compiler)是否支持AArch64的大地址模型。 - **尝试大地址模式**:若支持,添加编译选项`-mcmodel=large`(需验证工具链兼容性): ```bash CFLAGS += -mcmodel=large ``` --- #### **5. 验证符号定义与依赖** - **符号可见性**:确认`usrIdleTaskStkProtect`是否正确定义且未被覆盖。 ```bash nm <object_file> | grep usrIdleTaskStkProtect # 检查符号地址 ``` - **第三方库问题**:若符号来自外部库,需检查其编译是否与当前项目地址模型一致。 --- #### **6. 更新补丁与版本** - **已知问题**:某些VxWorks版本可能存在工具链缺陷,建议升级至最新补丁或联系Wind River技术支持。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值