GCC:关于-fpatchable-function-entry的一个issue

2090阅读 0评论2021-01-21 静默梧桐
分类:LINUX

发现一个gcc的问题:在使能-fpatchable-function-entry的情况下,DW_AT_low_pc的值与对应的函数entry address不一致。

       -fpatchable-function-entry=N[,M]
           Generate N NOPs right at the beginning of each function, with the function entry point before the Mth NOP.  If M is omitted, it defaults to 0 so the function entry points to the address just at the first NOP. 
也就是说在每个函数的开始处生成N个NOP指令;
举一个简单的例子来描述这个问题:
1.Compile the source file toy_exam.c 
$ gcc -o toy_exam.gcc toy_exam.c  -g -gdwarf-4 -fpatchable-function-entry=2 -save-temps


2.Check the symbolic address of the function fun_a
$ readelf -s  toy_exam.gcc  |grep -w fun_a
    95: 00000000000007f0    80 FUNC    GLOBAL DEFAULT   13 fun_a

3.Display assembler contents
objdump -d toy_exam.gcc |grep -A 8  -w \:
00000000000007f0 :
 7f0:   d503201f        nop
 7f4:   d503201f        nop
 7f8:   a9be7bfd        stp     x29, x30, [sp, #-32]!
 7fc:   910003fd        mov     x29, sp
 800:   52800040        mov     w0, #0x2                        // #2
 804:   b90017e0        str     w0, [sp, #20]
 808:   528000a0        mov     w0, #0x5                        // #5
 80c:   b9001be0        str     w0, [sp, #24]
4.dump dwarf info
$ llvm-dwarfdump toy_exam.gcc  |grep -C 10 -w fun_a
0x00000315:   DW_TAG_subprogram
                DW_AT_external  (true)
                DW_AT_name      ("fun_a")
                DW_AT_decl_file ("/home/jianlin/code/test/toy_exam.c")
                DW_AT_decl_line (14)
                DW_AT_decl_column       (0x06)
                DW_AT_low_pc    (0x00000000000007f8)
                DW_AT_high_pc   (0x0000000000000840)
                DW_AT_frame_base        (DW_OP_call_frame_cfa)
                DW_AT_GNU_all_tail_call_sites   (true)
                DW_AT_sibling   (0x0000035d)


5. Assembler code
fun_a:
        .section        __patchable_function_entries
        .8byte  .LPFE2
        .text
.LPFE2:
        nop
        nop
.LFB7:
        .loc 1 15 1
        .cfi_startproc
        stp     x29, x30, [sp, -32]!
        .cfi_def_cfa_offset 32
        .cfi_offset 29, -32
        .cfi_offset 30, -24
        mov     x29, sp
        .loc 1 16 13


DW_AT_low_pc 比函数入口地址大8个字节,也就是两个NOP指令的空间(arm64上)

若使用clang编译是不会出现这个问题的DW_AT_low_pc和函数entry地址是一致的。
    $ clang -o toy_exam.clang toy_exam.c  -g -gdwarf-4 -fpatchable-function-entry=2

我已经将这个问题提交到gcc Bugzilla。






上一篇:ebpf程序实例
下一篇:kretprobe: 关于offline module的一个bug