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

链接C与NASM目标文件遇.text段重定位警告的技术问询

解决32位共享库中C与NASM汇编链接的DT_TEXTREL警告

问题场景

现有C代码调用NASM汇编实现的asm_func,汇编函数内部又调用C实现的c_func,编译链接生成32位共享对象时,出现以下警告:

/usr/bin/ld: obj/asm_file.asm.o: warning: relocation against `c_func' in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a shared object

编译链接命令如下:

gcc -Wall -Wextra -Ofast -m32 -fPIC -c -o obj/c_file.c.o src/c_file.c
nasm -f elf32 -o obj/asm_file.asm.o src/asm_file.asm
gcc -Wall -Wextra -Ofast -m32 -fPIC -shared -o libtest.so obj/c_file.c.o obj/asm_file.asm.o -lm

原因分析

在32位PIC(位置无关代码)模式下,直接使用call c_func会生成绝对地址重定位。由于.text段是只读的,加载共享库时需要修改这段只读内存来绑定函数地址,链接器因此触发警告——DT_TEXTREL表示共享库包含需要修改文本段的重定位,这会降低加载效率且存在安全风险。

另外,将extern c_func放在.data段是错误的:extern是声明外部符号,与数据段无关,应放在.text段或全局作用域。

解决方案

修改NASM汇编代码,采用PIC兼容的方式调用外部C函数,通过PLT(过程链接表)间接调用,避免修改.text段。

修改后的汇编代码

section .text
    extern c_func
    global asm_func

asm_func:
    ; 这里添加你的参数准备逻辑(遵循C调用约定:栈参数从右到左入栈)
    ; 示例:传递参数a=5、b=10
    push 10
    push 5

    ; 使用PLT调用c_func,避免绝对重定位
    call c_func WRT ..plt

    ; cdecl调用约定下,调用者负责清理栈参数
    add esp, 8

    ; 其他业务逻辑
    ret

关键修改点

  • 用call c_func WRT ..plt替代直接call c_func:NASM会生成PLT相关的相对重定位,无需修改.text段。
  • 确保extern c_func声明在.text段内(或全局),不要放在.data段。

验证

重新执行编译链接命令,原有的relocation和DT_TEXTREL警告会消失,生成符合PIC规范的32位共享库。

内容的提问来源于stack exchange,提问作者trxgnyp1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:55:15