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

编写x86_64汇编共享对象时如何处理R_X86_64_PC32重定位错误

解决x86_64共享对象中受保护符号的R_X86_64_PC32重定位错误

直接在汇编源码中添加.note.gnu.property节并设置GNU_PROPERTY_NO_COPY_ON_PROTECTED属性,即可解决链接错误。以下是完整的可运行汇编代码示例:

# 定义GNU属性节,设置NO_COPY_ON_PROTECTED
.section .note.gnu.property,"a"
    .align 8
    .long 4               # 名称长度("GNU"的字节数)
    .long 0x10            # 描述数据长度(后续4个long的总字节数)
    .long 5               # Note类型:GNU_PROPERTY_TYPE_0
    .asciz "GNU"          # 属性名称
    .long 0xc0000000      # 属性掩码:GNU_PROPERTY_NO_COPY_ON_PROTECTED
    .long 4               # 数据大小
    .long 0               # 保留字段

# 数据段:受保护的全局符号g
.section .data
.protected g
.globl g
g:
    .quad 0xdeadbeef

# 代码段:引用g的函数f
.section .text
.globl f
.type f, @function
f:
    # RIP相对寻址访问g
    movq g(%rip), %rax
    ret

关键部分说明

  • .note.gnu.property节:这是GNU工具链专属的ELF note节,用于向链接器传递目标文件属性。节属性"a"表示该节会被分配到输出文件中。
    • 属性值0xc0000000对应GNU_PROPERTY_NO_COPY_ON_PROTECTED(第30位为1),告诉链接器不对受保护符号启用copy-on-write机制,从而允许使用R_X86_64_PC32重定位。
  • 符号声明顺序:必须先写.protected g再声明.globl g,确保符号的受保护属性被正确标记。
  • RIP相对寻址:g(%rip)是x86_64下访问全局符号的标准RIP相对方式,会生成R_X86_64_PC32重定位,现在能被链接器正常处理。

编译验证

使用GNU工具链编译链接:

as -o test.o test.s
ld -shared -o libtest.so test.o

链接过程不会再出现重定位R_X86_64_PC32无法用于受保护符号g的错误。可以通过以下命令确认属性和符号:

  • readelf -n libtest.so:查看.note.gnu.property节的属性设置
  • objdump -x libtest.so | grep g:确认g的符号属性为PROTECTED

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 22:58:36