在.cfi_escape

时间:2016-08-12 11:34:18

标签: gnu gas dwarf

我有一个用程序集编写的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,我不关心可移植性。

0 个答案:

没有答案