链接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
相关产品推荐
相关产品推荐

