relocation truncated to fit: R_MIPS_CALL16 问题!

本文解决了在broadcom7309 MIPS平台上编译链接库时遇到的relocation truncated to fit错误。通过使用-Wa,-xgot重新编译所有库,并采用动态链接的方式,成功解决了由静态库符号表不一致引起的问题。

我在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>好的,我现在需要帮助用户解决在MIPS架构下遇到的perf_debug_hook相关的链接错误问题。用户提到了“MIPS relocation R_MIPS_26 perf_debug_hook_for_hooks undefined reference”这个具体的错误信息,并且之前已经讨论过类似的问题,但这次是在MIPS架构下出现的。 首先,我得回顾之前的对话内容。用户之前遇到的是在x86架构下的链接错误,我提供了检查符号定义、验证内核配置、检查编译日志以及临时补丁等方法。现在用户的问题转移到MIPS架构,可能涉及不同的内核配置和编译选项,尤其是与MIPS相关的部分。 接下来,我需要理解用户当前的错误信息。错误信息中的“R_MIPS_26 relocation”说明在MIPS架构下,链接器在处理重定位时遇到了问题。R_MIPS_26是MIPS特定的重定位类型,通常与函数调用相关,表示在26位地址空间中的跳转指令无法正确解析符号地址。而“perf_debug_hook_for_hooks undefined reference”说明符号perf_debug_hook_for_hooks未定义,导致链接失败。 可能的原因包括: 1. 内核配置中未启用与perf_debug_hook相关的选项,特别是针对MIPS架构的配置。 2. 相关代码在MIPS架构下未被正确编译,可能是由于条件编译宏(如#ifdef CONFIG_MIPS)未正确包含实现代码。 3. 依赖的模块或子系统在MIPS下未正确链接,或者符号的可见性(如导出符号)存在问题。 4. 编译器或链接器的参数在MIPS架构下需要调整,比如使用特定的ABI或优化选项。 我需要根据这些可能性逐步分析。首先,建议用户检查内核配置,确保CONFIG_PERF_EVENTS和针对MIPS的性能调试选项已启用。然后,检查相关代码是否在MIPS架构下被编译,可能需要查看Makefile中的架构相关部分。此外,可能需要确认符号是否被正确导出,或者是否存在依赖的模块未正确链接的情况。 用户之前提供的引用中提到了安装一些开发工具,这可能与编译环境有关,但在MIPS架构下可能需要额外的工具链支持,比如交叉编译工具链是否正确安装。此外,用户可能需要检查是否使用了正确的编译器参数,例如-march=mips32r2或其他适合目标平台的选项。 另外,考虑到MIPS架构的特殊性,可能存在平台相关的代码路径或补丁需要应用。例如,某些内核版本在MIPS上可能需要特定的补丁来修复类似的问题。用户可能需要查阅内核的邮件列表或提交记录,寻找与perf_debug_hook在MIPS下相关的修复。 最后,如果上述方法都无法解决问题,可能需要临时添加空函数实现来绕过链接错误,但这只是临时解决方案,正式修复仍需确保符号正确定义和链接。 在生成回答时,需要结构清晰,分步骤指导用户检查配置、代码、编译日志和工具链,确保覆盖MIPS架构的特殊性,并提供具体的命令示例,如grep命令查找符号,检查.config文件,以及可能的编译选项调整。同时,引用之前的建议但根据MIPS的情况进行调整,确保用户能够逐步排查问题。</think>### 分步解决方案(MIPS架构专用) #### 问题定位 错误`R_MIPS_26 relocation`和`undefined reference to perf_debug_hook_for_hooks`表明: 1. **符号未定义**:`perf_debug_hook_for_hooks`未在目标文件中实现 2. **架构特殊性**:MIPS的26位跳转指令重定位失败(常见于未正确导出的符号或跨模块调用) 3. **内核版本关联性**:可能涉及内核版本与MIPS架构的兼容性问题[^1] --- ### 步骤1:验证MIPS内核配置 MIPS架构需要特殊配置,重点检查以下选项: ```bash # 检查内核配置文件 grep -E "CONFIG_PERF_EVENTS|CONFIG_KPROBES|CONFIG_DEBUG_KERNEL" .config ``` - **必须启用**: ```ini CONFIG_PERF_EVENTS=y # 核心性能事件支持 CONFIG_KPROBES=y # 动态插桩(可能依赖) CONFIG_DEBUG_KERNEL=y # 调试符号支持 ``` - **MIPS专用调试**: ```ini CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y # MIPS性能计数器共享 ``` --- ### 步骤2:检查符号实现与导出 1. **查找符号定义**: ```bash # 在源码树中搜索符号声明和实现 grep -rn "perf_debug_hook_for_hooks" arch/mips/ kernel/ ``` - 确认存在`extern void perf_debug_hook_for_hooks(...);`声明(通常在`include/linux/perf_event.h`) - 确认存在实现(如`arch/mips/kernel/perf_event_mips.c`) 2. **检查符号导出**: ```bash # 查看符号是否被导出到内核符号表 grep "perf_debug_hook_for_hooks" System.map ``` - 若未找到,需在代码中添加导出标记: ```c // 在函数定义处添加 EXPORT_SYMBOL(perf_debug_hook_for_hooks); ``` --- ### 步骤3:分析MIPS重定位限制 MIPS的R_MIPS_26重定位要求目标符号地址在256MB范围内[^2]: 1. **检查符号地址范围**: ```bash nm net/built-in.o | grep br_handle_frame_finish nm kernel/perf_event.o | grep perf_debug_hook_for_hooks ``` - 计算两个符号地址差值是否超过`0x10000000`(256MB) - 若超出,需通过以下方式修正: ```makefile # 在Makefile中强制模块合并 obj-y += net/ kernel/perf_event.o ``` --- ### 步骤4:编译选项调整 针对MIPS架构添加编译参数: ```makefile # 在arch/mips/Makefile中添加 KBUILD_CFLAGS += -G0 # 禁用全局指针优化 KBUILD_CFLAGS += -mno-shared # 禁用共享库调用约定 ``` --- ### 步骤5:临时补丁(验证用) 若确认符号未实现,添加桩函数: ```c // 在arch/mips/kernel/perf_event_mips.c末尾添加 void __weak perf_debug_hook_for_hooks(void) {} EXPORT_SYMBOL(perf_debug_hook_for_hooks); ``` *注意:此方法仅用于验证,正式修复需通过内核补丁* --- ### 最终解决方案 1. **应用官方补丁** 查询LKML(Linux内核邮件列表)中MIPS相关修复: ```bash git log --grep="perf_debug_hook_for_hooks" --oneline arch/mips ``` - 典型补丁示例: ```diff diff --git a/arch/mips/kernel/perf_event_mips.c b/arch/mips/kernel/perf_event_mips.c +void perf_debug_hook_for_hooks(void) {} +EXPORT_SYMBOL(perf_debug_hook_for_hooks); ``` 2. **重新编译验证** ```bash make ARCH=mips CROSS_COMPILE=mips-linux-gnu- clean make ARCH=mips CROSS_COMPILE=mips-linux-gnu- -j$(nproc) ``` --- ### MIPS架构相关问题 1. 如何分析MIPS的重定位错误模式? 2. MIPS内核调试需要哪些特殊工具链配置? 3. 如何为MIPS架构编写兼容的perf事件子系统?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值