Я пытаюсь получить местоположение переменных из кода C (x86_64) с помощью libdwarf, но GCC даже с отключенной оптимизацией (-O0) генерирует базу кадров относительно DW_OP_call_frame_cfa
.В свою очередь, clang использует DW_OP_reg6
, что указывает на rbp в x86_64 ABI.
Я прочитал стандарт DWARF-4, но не могу понять, как получить фактический адрес относительно стека или базыуказатель.Я также сталкивался с подобным вопросом Что мне делать здесь с DW_OP_call_frame_cfa , но безуспешно.
Простой код вроде:
int main()
{
int va = 1;
int vb = 2;
va = va + vb;
return (va);
}
выдаст следующий вывод вdwarfdump:
< 1><0x0000002d> DW_TAG_subprogram
DW_AT_external yes(1)
DW_AT_name main
DW_AT_decl_file 0x00000001 file.c
DW_AT_decl_line 0x00000001
DW_AT_type <0x00000069>
DW_AT_low_pc 0x00400620
DW_AT_high_pc <offset-from-lowpc>29
DW_AT_frame_base len 0x0001: 9c: DW_OP_call_frame_cfa
DW_AT_GNU_all_call_sites yes(1)
DW_AT_sibling <0x00000069>
< 2><0x0000004e> DW_TAG_variable
DW_AT_name va
DW_AT_decl_file 0x00000001 file.c
DW_AT_decl_line 0x00000003
DW_AT_type <0x00000069>
DW_AT_location len 0x0002: 916c: DW_OP_fbreg -20
< 2><0x0000005b> DW_TAG_variable
DW_AT_name vb
DW_AT_decl_file 0x00000001 file.c
DW_AT_decl_line 0x00000004
DW_AT_type <0x00000069>
DW_AT_location len 0x0002: 9168: DW_OP_fbreg -24
и следующую информацию в readelf -wf file
00000070 000000000000001c 00000044 FDE cie=00000030 pc=0000000000400620..000000000040063d
DW_CFA_advance_loc: 1 to 0000000000400621
DW_CFA_def_cfa_offset: 16
DW_CFA_offset: r6 (rbp) at cfa-16
DW_CFA_advance_loc: 3 to 0000000000400624
DW_CFA_def_cfa_register: r6 (rbp)
DW_CFA_advance_loc: 24 to 000000000040063c
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
из того, что я прочитал, я должен реализовать машину с минимальным стеком, но я даже не знаю, какпроанализируйте это вручную.
Есть ли способ заставить GCC не использовать DW_OP_call_frame_cfa и использовать простой регистр, или мне действительно нужно интерпретировать информацию кадра?и если да, то как?