R_X86_64_64重定位疑惑:按ABI规则计算地址为何不正确?
关于R_X86_64_64重定位的疑惑
根据System V ABI规定,R_X86_64_64重定位的计算方式为:
R_X86_64_64 | S + A (即 Symbol value + Addend)
我编写并汇编了以下共享对象与PIE可执行文件:
PIE可执行文件代码
; PIE可执行文件 global _start extern msg section .text _start: mov rdi, 1 ; stdout 文件描述符 mov rsi, msg mov rdx, 9 ; 8个字符 + 换行符 mov rax, 1 ; write系统调用 syscall xor rdi, rdi ; 返回码0 mov rax, 60 ; exit系统调用 syscall
共享对象代码
; 共享对象 global msg:data msg.end-msg section .data msg: db "hi there", 10 .end:
对该PIE可执行文件执行readelf命令后,在.rela.dyn段中得到以下重定位条目:
000000001007 000100000001 R_X86_64_64 0000000000003000 msg + 0 000000003000 000100000005 R_X86_64_COPY 0000000000003000 msg + 00
我的理解如下:
- R_X86_64_64在.text段内执行重定位,将位于内存偏移0x1007处的操作数修改为指定符号的值(此处为0x3000)
- R_X86_64_COPY指示动态链接器在共享对象中查找动态符号,然后将该符号的值复制到符号指定的地址(此处为0x3000)加上对象加载基址的位置
但按照ABI规定的方式应用R_X86_64_64重定位时,得到的msg地址仅为0x3000,这显然不正确!难道我不需要在此处添加加载基址吗?我是否遗漏了什么内容?
内容的提问来源于stack exchange,提问作者roeegg
相关产品推荐
相关产品推荐

