我有一个用程序集编写的trampoline,需要在这样的全局变量中隐藏函数的返回地址:
#define DW_CFA_expression 0x10
#define DW_OP_addr 0x03
#define DW_OP_deref 0x06
trampoline:
.cfi_startproc
pop ret_addr // store return address in global var named ret_addr
.cfi_escape DW_CFA_expression, DW_OP_addr, ret_addr, DW_OP_deref
// do stuff
jmp *ret_addr // return to the stored address
.cfi_endproc
.globl trampoline
.type trampoline, @function
.data
ret_addr:
.zero 4
我需要堆栈展开才能使用这个蹦床。使用没有选项的gcc编译该代码会给出:
$ gcc trampoline.S just_main.c
/tmp/ccZuu7aa.o:(.eh_frame+0x2d): relocation truncated to fit: R_X86_64_8 against `.data'
collect2: error: ld returned 1 exit status
汇编程序似乎已正确指示链接器将ret_addr
中的.cfi_escape
替换为该符号的地址。但是,.cfi_escape
需要逗号分隔的字节列表,因此发出的重定位是8位,这太小了。
如何在.cfi_escape
指令中引用变量的地址?这有可能吗?如果有可能,有没有办法进一步发展并让ret_addr
成为在不同模块中定义的线程局部变量?
我正在研究最新的amd64 Ubuntu GNU / Linux,如果这有所作为的话。整个工具链是GNU,我不关心可移植性。