使用GCC编译x86_64汇编时mov指令为何导致动态段大小设置失败?
解决PIE模式下x86_64汇编的R_X86_64_32S重定位错误
问题原因
你遇到的R_X86_64_32S重定位错误,核心原因是PIE(位置独立可执行文件)强制要求所有内存地址引用必须是位置无关的:
- 直接写
mov rdi, f时,汇编器会生成32位绝对地址的重定位(R_X86_64_32S),但PIE程序的加载基址是随机的,32位偏移无法覆盖64位地址空间,且动态链接器不允许这种绝对地址引用。 - 移除该行后没有绝对地址引用,所以编译流程能正常完成。
解决方案
要在PIE模式下正确获取标签f的地址,必须使用RIP相对寻址,用lea指令替代mov:
mov rdi, f # 错误:生成32位绝对重定位 lea rdi, [f] # 正确:生成RIP相对的位置无关重定位
替换后的完整代码如下:
.intel_syntax noprefix .globl main .section .rodata .text f: # Exits thread mov rdi, 0 mov rax, 60 syscall main: call create_thread_stack pop rsi # -- sub rsi, 8 # | Put function pointer onto lea rdi, [f] # | new stack(修正此处) push rdi # -- pop qword ptr [rsi] # Put function pointer onto new stack mov rdi, -2147479808 # Flags mov rax, 56 # Sys_clone syscall ret create_thread_stack: # Mmaps stack for cloned process mov rdi, 0 mov rsi, 4194304 # Size of stack mov rdx, 3 mov r10, 290 mov r9, 0 mov r8, -1 mov rax, 9 # Sys_mmap syscall add rax, 4194304 push rax # Return base pointer of new stack ret
额外说明
- 你尝试的
mov rdi, [f]是读取f地址处的内存内容,而非f的地址本身,不符合需求; mov rdi, offset f在Intel语法中仍会生成绝对地址重定位,无法满足PIE的位置无关要求;- 编译时需确保同时传递
-fPIE和-pie参数给GCC(gcc -fPIE -pie your_code.s -o output),前者告诉汇编器生成PIE兼容的目标文件,后者告诉链接器生成PIE可执行文件。
内容的提问来源于stack exchange,提问作者FlappyToucan
相关产品推荐
相关产品推荐

