我想生成以下指令。什么 C 源代码将编译成这个 asm?
call *get_func@GOTPCREL(%rip)
cmpq func@GOTPCREL(%rip), %rax
最佳答案
看起来像是对使用 -fno-plt
编译的 get_func()
的调用,然后将返回值与另一个函数的地址进行比较。
我使用了 void*
而不是声明一个返回函数指针的函数,因为这样更容易。这是c问题,以便所有内容都可以从 void*
转换为/而无需强制转换。
void func();
void *get_func(void); // returns a function pointer
int foo(void) {
return func == get_func();
}
# gcc7.2 -O3 -fno-plt
subq $8, %rsp
# your lines verbatim in the compiler output
call *get_func@GOTPCREL(%rip)
cmpq func@GOTPCREL(%rip), %rax
sete %al
addq $8, %rsp
movzbl %al, %eax
ret
无论有没有 PLT,函数地址都将来自 GOT,但使用传统的 -fplt
(这仍然是默认值),call
指令将来自 GOT。是对此可执行文件或共享对象中的 PLT 的 rel32
调用。
例如仅使用 -fPIC
:
call get_func@PLT
cmpq func@GOTPCREL(%rip), %rax
或没有其中之一(仅对于位置相关的可执行文件,因此 func
的地址是链接时间常量):
call get_func # converted at link-time to a PLT call if it's in a shared lib
cmpq $func, %rax
相关:32-bit absolute addresses no longer allowed in x86-64 Linux?许多发行版让 gcc 默认启用 -pie
/-fPIE
。
clang 更聪明,并且在 cmp 之前将 eax
进行异或清零,因此关键路径上没有 movzbl
。但call/cmp基本是一样的。
clang 没有 no-PLT 选项。
关于c - 什么 C 源代码将编译为针对 GOT 中另一个指针的调用 *get_func@GOTPCREL(%rip) 和 cmp?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47524637/