You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARMv7下Clang编译含LDR reg,=symbol的汇编生成共享库链接失败

解决ARMv7 FreeBSD下clang-16编译汇编代码生成共享库的R_ARM_ABS32重定位错误

问题原因

clang-16的ARM集成汇编器对PIC(位置无关代码)的处理逻辑与GNU汇编器(GAS)存在差异:LDR r12, =g_lumaFilter这类伪指令在PIC模式下,clang会生成R_ARM_ABS32类型的绝对重定位,而共享库不允许针对局部符号使用这种重定位;但GAS会自动将其转换为PC相对寻址或兼容PIC的GOT表访问方式,因此g++编译链接正常。

解决方案

方案1:强制clang使用GNU汇编器编译.S文件

直接让clang调用系统的GAS处理汇编代码,对齐g++的编译行为,无需修改汇编源码:

  • 编译汇编文件时添加-no-integrated-as参数:
    clang-16 -c -fPIC -no-integrated-as your_arm_asm.S -o your_arm_asm.o
    
  • 链接生成共享库时正常执行:
    clang-16 -shared -o libx265.so *.o
    

方案2:修改汇编代码为PIC兼容的寻址方式

如果需要使用clang的集成汇编器,将绝对加载伪指令替换为基于GOT表的PC相对寻址:

.global g_lumaFilter
.type g_lumaFilter, %object
g_lumaFilter:
    ; 符号定义内容

; 替换原有的 LDR r12, =g_lumaFilter
LDR r12, =__GLOBAL_OFFSET_TABLE__
ADD r12, pc, r12          ; 计算GOT表的PC相对地址
LDR r12, [r12, #:got_lo12:g_lumaFilter]  ; 从GOT表中加载符号地址

这种方式通过全局偏移表(GOT)间接访问符号,符合PIC规范,clang汇编器会生成合法的重定位类型。

方案3:完善符号声明属性

确保汇编中的全局符号明确声明类型,帮助clang正确识别符号属性:

.global g_lumaFilter
.type g_lumaFilter, %object  ; 声明为对象类型,若为函数则用%function
g_lumaFilter:
    ; 符号内容

内容的提问来源于stack exchange,提问作者Mikhail T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:22:42