如何修复aarch64架构Android端编译项目时出现的DT_TEXTREL问题
操作正确性判断
你的排查流程没有问题,添加-Wl,--no-fatal-warnings保留带问题的共享库、用scanelf定位TEXTREL偏移、再通过objdump匹配对应代码段的操作,是排查这类链接问题的标准方案。
问题根因说明
你遇到的DT_TEXTREL和你贴出的CBZ指令没有关系,从objdump的输出可以看到问题根源:
- 偏移
0x7ba4和0x7cd4处的两条ldr x3, 7d20/ldr x3, 7d28是直接加载绝对地址到寄存器的写法 - 这两个绝对地址被存放在代码段的
0x7d20和0x7d28位置,链接阶段需要根据实际加载地址修改这两个位置的数值,因此触发了代码段重定位,也就是DT_TEXTREL警告 - 因为这两个存储位置刚好落在
abort_self_signal符号后面的空隙中,所以scanelf的输出会关联到abort_self_signal符号上,造成是这段分支代码导致问题的假象。
关于替换CBZ的疑问
不能通过把CBZ替换为BR解决问题,原因有两个:
- 二者功能完全不同:
CBZ是「比较寄存器值为0则跳转到立即数偏移地址」的条件分支指令,BR是「跳转到寄存器存储的地址」的无条件跳转指令,直接替换会完全破坏原有逻辑。 - TEXTREL的产生和
CBZ没有任何关联,修改这条指令不会对链接警告产生任何作用。
正确修复方案
找到代码中那两条使用绝对地址加载的指令,修改为AArch64平台的位置无关写法即可:
- 把类似
ldr x3, =符号名的绝对地址加载语法,替换为adrp x3, 符号名+add x3, x3, :lo12:符号名的组合 - 确认编译选项已经开启
-fPIC,没有禁用位置无关代码的相关参数。
内容的提问来源于stack exchange,提问作者alijandro
相关产品推荐
相关产品推荐

