【发布时间】:2019-08-28 20:49:29
【问题描述】:
我在程序集中定义了一个调用 libc 函数 (swapcontext) 的函数。我从我的 C 代码中调用该函数。为了创建可重现的示例,我使用“puts”代替:
foo.S:
.globl foo
foo:
call puts
ret
test.c:
void foo(char *str);
int main() {
foo("Hello World\n");
return 0;
}
编译:
gcc test.c foo.S -o test
这编译得很好。然而,反汇编结果二进制显示链接器没有插入有效的调用指令:
objdump -dR:
0000000000000671 <foo>:
671: e8 00 00 00 00 callq 676 <foo+0x5>
672: R_X86_64_PC32 puts@GLIBC_2.2.5-0x4
676: c3 retq
677: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
67e: 00 00
0000000000000530 <puts@plt>:
530: ff 25 9a 0a 20 00 jmpq *0x200a9a(%rip) # 200fd0 <puts@GLIBC_2.2.5>
536: 68 00 00 00 00 pushq $0x0
53b: e9 e0 ff ff ff jmpq 520 <.plt>
执行:
./test1: Symbol `puts' causes overflow in R_X86_64_PC32 relocation
Segmentation fault
有什么想法吗?
【问题讨论】:
-
objdump -dR test可能很有启发性。另外,在foo的定义中不需要ret吗?还有,swapcontext有异常的控制流,需要特别小心才能安全调用。 -
似乎你 OBJDUMP'ed 一个具有重定位的目标文件。尝试使用
-r选项 OBJDUMPing 最终可执行文件或 OBJDUMP.o文件以显示重定位条目。 -
minimal reproducible example,拜托。这不会重现行为,并且在运行时不起作用。
-
... 那么
# 200fd0 <swapcontext@GLIBC_2.2.5>是什么? -
我已经更新了原始示例,通过将 puts 与存储在 %rdi 中的参数一起使用使其有效。我在运行时也指出了失败。