我有一个简单的代码:
int main()
{
int a = 4;
printf("%d\n", a);
a = 8;
if (a == 8)
printf("%d\n", a);
return 0;
}
函数和变量的 DIE:
<1><32a>: Abbrev Number: 18 (DW_TAG_subprogram)
<32b> DW_AT_external : 1
<32b> DW_AT_name : (indirect string, offset: 0x19c): main
<32f> DW_AT_decl_file : 1
<330> DW_AT_decl_line : 4
<331> DW_AT_decl_column : 5
<332> DW_AT_type : <0x63>
<336> DW_AT_low_pc : 0x4004b2
<33e> DW_AT_high_pc : 0x4b
<346> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<348> DW_AT_GNU_all_tail_call_sites: 1
<2><348>: Abbrev Number: 19 (DW_TAG_variable)
<349> DW_AT_name : a
<34b> DW_AT_decl_file : 1
<34c> DW_AT_decl_line : 6
<34d> DW_AT_decl_column : 7
<34e> DW_AT_type : <0x63>
<352> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
和 objdump 输出相同:
00000000004004b2 <main>:
4004b2: 55 push rbp
4004b3: 48 89 e5 mov rbp,rsp
4004b6: 48 83 ec 10 sub rsp,0x10
4004ba: c7 45 fc 04 00 00 00 mov DWORD PTR [rbp-0x4],0x4
4004c1: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
4004c4: 89 c6 mov esi,eax
4004c6: bf 84 05 40 00 mov edi,0x400584
4004cb: b8 00 00 00 00 mov eax,0x0
4004d0: e8 db fe ff ff call 4003b0 <printf@plt>
4004d5: c7 45 fc 08 00 00 00 mov DWORD PTR [rbp-0x4],0x8
4004dc: 83 7d fc 08 cmp DWORD PTR [rbp-0x4],0x8
4004e0: 75 14 jne 4004f6 <main+0x44>
4004e2: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
4004e5: 89 c6 mov esi,eax
4004e7: bf 84 05 40 00 mov edi,0x400584
4004ec: b8 00 00 00 00 mov eax,0x0
4004f1: e8 ba fe ff ff call 4003b0 <printf@plt>
4004f6: b8 00 00 00 00 mov eax,0x0
4004fb: c9 leave
4004fc: c3 ret
4004fd: 0f 1f 00 nop DWORD PTR [rax]
我很好奇是否可以通过查看调试符号来检测 ebp 的变量偏移量(假设 ebp 是堆栈基础并且变量在堆栈上)。例如,在这种情况下,变量a存在于rbp-0x4。看起来标签DW_AT_location可以给我位置信息。但是,根据矮人文档 - DW_OP_fbreg0x91 属于 0x6C 属于DW_AT_const_expr. 我真的不明白这是什么意思。我还读到DW_AT_frame_base了该函数的框架基础。
我真的很感激任何帮助。