mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-26 17:15:38 +00:00
DWARF .debug_info parsing fix and improvement (#17007)
* Get .debug_info working for DWARF 2, 3 * Fill up missing information in abbrev string table * Add 64bit dwarf option into debug_info * Add DWARF4 and DWARF5 forms * Add unit tests * added basic test Co-authored-by: Riccardo Schirone <sirmy15@gmail.com>
This commit is contained in:
parent
2f78b9f5df
commit
914624a921
@ -78,7 +78,17 @@ R_API char *r_bin_addr2text(RBin *bin, ut64 addr, int origin) {
|
||||
// TODO: this is slow. must use a cached pool of mapped files and line:off entries
|
||||
out = r_file_slurp_line (file, line, 0);
|
||||
if (!out) {
|
||||
return r_str_newf ("%s:%d", file, line);
|
||||
if (origin > 1) {
|
||||
file_nopath = file;
|
||||
} else {
|
||||
file_nopath = strrchr (file, '/');
|
||||
if (file_nopath) {
|
||||
file_nopath++;
|
||||
} else {
|
||||
file_nopath = file;
|
||||
}
|
||||
}
|
||||
return r_str_newf ("%s:%d", file_nopath? file_nopath: "", line);
|
||||
}
|
||||
out2 = malloc ((strlen (file) + 64 + strlen (out)) * sizeof (char));
|
||||
if (origin > 1) {
|
||||
|
1530
libr/bin/dwarf.c
1530
libr/bin/dwarf.c
File diff suppressed because it is too large
Load Diff
@ -896,11 +896,13 @@ static int bin_dwarf(RCore *core, int mode) {
|
||||
// TODO: complete and speed-up support for dwarf
|
||||
RBinDwarfDebugAbbrev *da = NULL;
|
||||
da = r_bin_dwarf_parse_abbrev (core->bin, mode);
|
||||
r_bin_dwarf_parse_info (da, core->bin, mode);
|
||||
RBinDwarfDebugInfo *info = r_bin_dwarf_parse_info (da, core->bin, mode);
|
||||
// dig types out of into and then free
|
||||
r_bin_dwarf_free_debug_info (info);
|
||||
|
||||
r_bin_dwarf_parse_aranges (core->bin, mode);
|
||||
list = ownlist = r_bin_dwarf_parse_line (core->bin, mode);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
free (da);
|
||||
}
|
||||
if (!list) {
|
||||
return false;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -431,7 +431,7 @@ pd 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
.blah:
|
||||
31ed xor ebp, ebp ; /builddir/glibc-2.19/csu/../sysdeps/x86_64//start.S:67
|
||||
31ed xor ebp, ebp ; start.S:67
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
@ -4081,6 +4081,7 @@ EXPECT=<<EOF
|
||||
[Source file]
|
||||
/home/landley/work/ab7/build/temp-armv6l/gcc-core/gcc/config/arm/ieee754-df.S
|
||||
/home/landley/work/ab7/build/temp-armv6l/gcc-core/gcc/config/arm/lib1funcs.asm
|
||||
/home/landley/work/ab7/build/temp-armv6l/build-gcc/gcc
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
@ -10,7 +10,7 @@ EXPECT=<<EOF
|
||||
; DATA XREF from entry0 @ 0x40045d
|
||||
/ 44: int main (int argc, char **argv, char **envp);
|
||||
| ; var int64_t var_4h @ rbp-0x4
|
||||
| 0x0040052d 55 push rbp ; /tmp/r2-regressions/.//dwarftest.c:4
|
||||
| 0x0040052d 55 push rbp ; dwarftest.c:4
|
||||
EOF
|
||||
RUN
|
||||
|
||||
@ -20,7 +20,7 @@ CMDS=<<EOF
|
||||
CL 0x0000a24e
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
file: TestRTTI/TestRTTI.cpp
|
||||
file: /Users/ftamagni/src/TestRTTI/TestRTTI//TestRTTI.cpp
|
||||
line: 18
|
||||
EOF
|
||||
RUN
|
||||
|
@ -8,22 +8,22 @@ s 0x00402c43
|
||||
pd 30
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
0x00402c43 lea rax, [rbp - 0xa0] ; .//ezpz.cpp:265
|
||||
0x00402c43 lea rax, [rbp - 0xa0] ; ezpz.cpp:265
|
||||
0x00402c4a mov rdi, rax
|
||||
0x00402c4d call sym MD5_Init(MD5_CTX*)
|
||||
0x00402c52 mov eax, dword [rbp - 0xb4] ; .//ezpz.cpp:266
|
||||
0x00402c52 mov eax, dword [rbp - 0xb4] ; ezpz.cpp:266
|
||||
0x00402c58 add eax, 1
|
||||
0x00402c5b movsxd rdx, eax
|
||||
0x00402c5e lea rax, [rbp - 0xa0]
|
||||
0x00402c65 mov esi, obj.Password
|
||||
0x00402c6a mov rdi, rax
|
||||
0x00402c6d call sym MD5_Update(MD5_CTX*, void const*, unsigned long)
|
||||
0x00402c72 lea rdx, [rbp - 0xa0] ; .//ezpz.cpp:267
|
||||
0x00402c72 lea rdx, [rbp - 0xa0] ; ezpz.cpp:267
|
||||
0x00402c79 lea rax, [rbp - 0xb0]
|
||||
0x00402c80 mov rsi, rdx
|
||||
0x00402c83 mov rdi, rax
|
||||
0x00402c86 call sym MD5_Final(unsigned char*, MD5_CTX*)
|
||||
0x00402c8b mov eax, dword [rbp - 0xb4] ; .//ezpz.cpp:269
|
||||
0x00402c8b mov eax, dword [rbp - 0xb4] ; ezpz.cpp:269
|
||||
0x00402c91 cdqe
|
||||
0x00402c93 shl rax, 4
|
||||
0x00402c97 lea rcx, [rax + obj.GoodHashes]
|
||||
@ -34,9 +34,9 @@ EXPECT=<<EOF
|
||||
0x00402cb0 call sym.imp.memcmp
|
||||
0x00402cb5 test eax, eax
|
||||
0x00402cb7 je 0x402cc2
|
||||
0x00402cb9 mov byte [obj.DrawGoodWork], 0 ; .//ezpz.cpp:270
|
||||
0x00402cb9 mov byte [obj.DrawGoodWork], 0 ; ezpz.cpp:270
|
||||
0x00402cc0 jmp 0x402cdd
|
||||
0x00402cc2 add dword [rbp - 0xb4], 1 ; .//ezpz.cpp:263
|
||||
0x00402cc2 add dword [rbp - 0xb4], 1 ; ezpz.cpp:263
|
||||
0x00402cc9 cmp dword [rbp - 0xb4], 0x14
|
||||
EOF
|
||||
RUN
|
||||
|
@ -80,7 +80,7 @@ NAME=C++ demangle relocs
|
||||
FILE=bins/elf/libstdc++.so.6
|
||||
CMDS=pd 1 @0x00091004
|
||||
EXPECT=<<EOF
|
||||
0x00091004 488b159d880f. mov rdx, qword [reloc.vtable_for_std::bad_alloc] ; /build/gcc/src/gcc/libstdc++-v3/libsupc++/new:57 ; [0x1898a8:8]=0
|
||||
0x00091004 488b159d880f. mov rdx, qword [reloc.vtable_for_std::bad_alloc] ; new:57 ; [0x1898a8:8]=0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
@ -20,6 +20,7 @@ if get_option('enable_tests')
|
||||
'debruijn',
|
||||
'diff',
|
||||
'dwarf',
|
||||
'dwarf_info',
|
||||
'esil_dfg_filter',
|
||||
'event',
|
||||
'flags',
|
||||
|
@ -12,17 +12,17 @@
|
||||
#define check_abbrev_tag(expected_tag) \
|
||||
mu_assert_eq (da->decls[i].tag, expected_tag, "Incorrect abbreviation tag")
|
||||
|
||||
#define check_abbrev_length(expected_length) \
|
||||
mu_assert_eq (da->decls[i].length, expected_length, "Incorrect abbreviation length")
|
||||
#define check_abbrev_count(expected_count) \
|
||||
mu_assert_eq (da->decls[i].count, expected_count, "Incorrect abbreviation count")
|
||||
|
||||
#define check_abbrev_children(expected_children) \
|
||||
mu_assert_eq (da->decls[i].has_children, expected_children, "Incorrect children flag")
|
||||
|
||||
#define check_abbrev_attr_name(expected_name) \
|
||||
mu_assert_eq (da->decls[i].specs[j].attr_name, expected_name, "Incorrect children flag");
|
||||
mu_assert_eq (da->decls[i].defs[j].attr_name, expected_name, "Incorrect children flag");
|
||||
|
||||
#define check_abbrev_attr_form(expected_form) \
|
||||
mu_assert_eq (da->decls[i].specs[j].attr_form, expected_form, "Incorrect children flag");
|
||||
mu_assert_eq (da->decls[i].defs[j].attr_form, expected_form, "Incorrect children flag");
|
||||
|
||||
/**
|
||||
* @brief Comparator to sort list of line statements by address(collection of DwarfRows)
|
||||
@ -57,7 +57,7 @@ bool test_dwarf3_c_basic(void) { // this should work for dwarf2 aswell
|
||||
// static void dump_r_bin_dwarf_debug_abbrev(FILE *f, RBinDwarfDebugAbbrev *da)
|
||||
// which prints out all the abbreviation
|
||||
da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
mu_assert_eq (da->length, 7, "Incorrect number of abbreviation");
|
||||
mu_assert_eq (da->count, 7, "Incorrect number of abbreviation");
|
||||
|
||||
// order matters
|
||||
// I nest scopes to make it more readable, (hopefully)
|
||||
@ -65,7 +65,7 @@ bool test_dwarf3_c_basic(void) { // this should work for dwarf2 aswell
|
||||
check_abbrev_tag (DW_TAG_compile_unit);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
{
|
||||
int j = 0;
|
||||
check_abbrev_attr_name (DW_AT_producer);
|
||||
@ -93,45 +93,43 @@ bool test_dwarf3_c_basic(void) { // this should work for dwarf2 aswell
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_variable);
|
||||
{
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
check_abbrev_children (false);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_base_type);
|
||||
{
|
||||
check_abbrev_length (4);
|
||||
check_abbrev_count (4);
|
||||
check_abbrev_children (false);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_length (12);
|
||||
check_abbrev_count (12);
|
||||
check_abbrev_children (true);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_variable);
|
||||
{
|
||||
check_abbrev_length (7);
|
||||
check_abbrev_count (7);
|
||||
check_abbrev_children (false);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_length (10);
|
||||
check_abbrev_count (10);
|
||||
check_abbrev_children (true);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_variable);
|
||||
{
|
||||
check_abbrev_length (6);
|
||||
check_abbrev_count (6);
|
||||
check_abbrev_children (false);
|
||||
}
|
||||
i++;
|
||||
|
||||
RList *line_list = NULL;
|
||||
|
||||
line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (line_list->length, 8, "Amount of line information parse doesn't match");
|
||||
RList *line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (r_list_length (line_list), 8, "Amount of line information parse doesn't match");
|
||||
|
||||
RBinDwarfRow *row;
|
||||
RListIter *iter;
|
||||
@ -155,6 +153,9 @@ bool test_dwarf3_c_basic(void) { // this should work for dwarf2 aswell
|
||||
mu_assert_eq (row->address, test_addresses[i++], "Line number statement address doesn't match");
|
||||
}
|
||||
|
||||
r_list_free (line_list);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
@ -183,7 +184,7 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
// static void dump_r_bin_dwarf_debug_abbrev(FILE *f, RBinDwarfDebugAbbrev *da)
|
||||
// which prints out all the abbreviation
|
||||
da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
mu_assert ("Incorrect number of abbreviation", da->length == 32);
|
||||
mu_assert ("Incorrect number of abbreviation", da->count == 32);
|
||||
|
||||
// order matters
|
||||
// I nest scopes to make it more readable, (hopefully)
|
||||
@ -191,7 +192,7 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
check_abbrev_tag (DW_TAG_compile_unit);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (9);
|
||||
check_abbrev_count (9);
|
||||
{
|
||||
/**
|
||||
* Everything commented out is something that is missing from being printed by `id` Radare
|
||||
@ -229,7 +230,7 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
check_abbrev_tag (DW_TAG_structure_type);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
{
|
||||
/**
|
||||
* Everything commented out is something that is missing from being printed by `id` Radare
|
||||
@ -264,31 +265,31 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (2);
|
||||
check_abbrev_count (2);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_member);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (5);
|
||||
check_abbrev_count (5);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (10);
|
||||
check_abbrev_count (10);
|
||||
}
|
||||
i++;
|
||||
|
||||
@ -296,7 +297,7 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (12);
|
||||
check_abbrev_count (12);
|
||||
{
|
||||
int j = 0;
|
||||
check_abbrev_attr_name (DW_AT_external);
|
||||
@ -337,155 +338,153 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (13);
|
||||
check_abbrev_count (13);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_const_type);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (2);
|
||||
check_abbrev_count (2);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_pointer_type);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_reference_type);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subroutine_type);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_unspecified_parameters);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (1);
|
||||
check_abbrev_count (1);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_base_type);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (4);
|
||||
check_abbrev_count (4);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_pointer_type);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (4);
|
||||
check_abbrev_count (4);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_structure_type);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_inheritance);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (10);
|
||||
check_abbrev_count (10);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (13);
|
||||
check_abbrev_count (13);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (12);
|
||||
check_abbrev_count (12);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_variable);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (7);
|
||||
check_abbrev_count (7);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_variable);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (7);
|
||||
check_abbrev_count (7);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (5);
|
||||
check_abbrev_count (5);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (5);
|
||||
check_abbrev_count (5);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (4);
|
||||
check_abbrev_count (4);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (9);
|
||||
check_abbrev_count (9);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
{
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (9);
|
||||
check_abbrev_count (9);
|
||||
}
|
||||
i++;
|
||||
check_abbrev_tag (DW_TAG_subprogram);
|
||||
{
|
||||
check_abbrev_children (true);
|
||||
check_abbrev_length (8);
|
||||
check_abbrev_count (8);
|
||||
}
|
||||
|
||||
// r_bin_dwarf_parse_info (da, core->bin, mode); Information not stored anywhere, not testable now?
|
||||
|
||||
// r_bin_dwarf_parse_aranges (core->bin, MODE); Information not stored anywhere, not testable now?
|
||||
|
||||
RList *line_list = NULL;
|
||||
|
||||
line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (line_list->length, 60, "Amount of line information parse doesn't match");
|
||||
RList *line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (r_list_length (line_list), 60, "Amount of line information parse doesn't match");
|
||||
|
||||
RBinDwarfRow *row;
|
||||
RListIter *iter;
|
||||
@ -563,6 +562,9 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell
|
||||
mu_assert_eq (row->address, test_addresses[i++], "Line number statement address doesn't match");
|
||||
}
|
||||
|
||||
r_list_free (line_list);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
@ -580,23 +582,21 @@ bool test_dwarf3_cpp_many_comp_units(void) {
|
||||
// static void dump_r_bin_dwarf_debug_abbrev(FILE *f, RBinDwarfDebugAbbrev *da)
|
||||
// which prints out all the abbreviation
|
||||
da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
mu_assert_eq (da->length, 58, "Incorrect number of abbreviation");
|
||||
mu_assert_eq (da->count, 58, "Incorrect number of abbreviation");
|
||||
int i = 18;
|
||||
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
check_abbrev_length (5);
|
||||
check_abbrev_count (5);
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_code (19);
|
||||
i = 41;
|
||||
check_abbrev_tag (DW_TAG_inheritance);
|
||||
check_abbrev_length (3);
|
||||
check_abbrev_count (3);
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_code (18);
|
||||
|
||||
RList *line_list = NULL;
|
||||
|
||||
line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (line_list->length, 64, "Amount of line information parse doesn't match");
|
||||
RList *line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (r_list_length (line_list), 64, "Amount of line information parse doesn't match");
|
||||
|
||||
RBinDwarfRow *row;
|
||||
RListIter *iter;
|
||||
@ -678,6 +678,9 @@ bool test_dwarf3_cpp_many_comp_units(void) {
|
||||
mu_assert_eq (row->address, test_addresses[i++], "Line number statement address doesn't match");
|
||||
}
|
||||
|
||||
r_list_free (line_list);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
@ -697,12 +700,10 @@ bool test_dwarf_cpp_empty_line_info(void) { // this should work for dwarf2 aswel
|
||||
// which prints out all the abbreviation
|
||||
da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
// not ignoring null entries -> 755 abbrevs
|
||||
mu_assert_eq (da->length, 731, "Incorrect number of abbreviation");
|
||||
mu_assert_eq (da->count, 731, "Incorrect number of abbreviation");
|
||||
|
||||
RList *line_list = NULL;
|
||||
|
||||
line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (line_list->length, 771, "Amount of line information parse doesn't match");
|
||||
RList *line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (r_list_length (line_list), 771, "Amount of line information parse doesn't match");
|
||||
|
||||
RBinDwarfRow *row;
|
||||
RListIter *iter;
|
||||
@ -744,6 +745,8 @@ bool test_dwarf_cpp_empty_line_info(void) { // this should work for dwarf2 aswel
|
||||
break;
|
||||
}
|
||||
|
||||
r_list_free (line_list);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
@ -762,24 +765,22 @@ bool test_dwarf2_cpp_many_comp_units(void) {
|
||||
// static void dump_r_bin_dwarf_debug_abbrev(FILE *f, RBinDwarfDebugAbbrev *da)
|
||||
// which prints out all the abbreviation
|
||||
da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
mu_assert_eq (da->length, 58, "Incorrect number of abbreviation");
|
||||
mu_assert_eq (da->count, 58, "Incorrect number of abbreviation");
|
||||
|
||||
int i = 18;
|
||||
|
||||
check_abbrev_tag (DW_TAG_formal_parameter);
|
||||
check_abbrev_length (5);
|
||||
check_abbrev_count (5);
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_code (19);
|
||||
i = 41;
|
||||
check_abbrev_tag (DW_TAG_inheritance);
|
||||
check_abbrev_length (4);
|
||||
check_abbrev_count (4);
|
||||
check_abbrev_children (false);
|
||||
check_abbrev_code (18);
|
||||
|
||||
RList *line_list = NULL;
|
||||
|
||||
line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (line_list->length, 64, "Amount of line information parse doesn't match");
|
||||
RList *line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (r_list_length (line_list), 64, "Amount of line information parse doesn't match");
|
||||
|
||||
RBinDwarfRow *row;
|
||||
RListIter *iter;
|
||||
@ -859,6 +860,9 @@ bool test_dwarf2_cpp_many_comp_units(void) {
|
||||
}
|
||||
|
||||
// add line information check
|
||||
r_list_free (line_list);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
@ -872,13 +876,10 @@ bool test_dwarf4_cpp_many_comp_units(void) {
|
||||
bool res = r_bin_open (bin, "bins/elf/dwarf4_many_comp_units.elf", &opt);
|
||||
mu_assert ("couldn't open file", res);
|
||||
|
||||
RBinDwarfDebugAbbrev *da = NULL;
|
||||
// TODO add abbrev checks
|
||||
|
||||
RList *line_list = NULL;
|
||||
|
||||
line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (line_list->length, 75, "Amount of line information parse doesn't match");
|
||||
RList *line_list = r_bin_dwarf_parse_line (bin, MODE);
|
||||
mu_assert_eq (r_list_length (line_list), 75, "Amount of line information parse doesn't match");
|
||||
|
||||
RBinDwarfRow *row;
|
||||
RListIter *iter;
|
||||
@ -968,6 +969,8 @@ bool test_dwarf4_cpp_many_comp_units(void) {
|
||||
mu_assert_eq (row->address, test_addresses[i++], "Line number statement address doesn't match");
|
||||
}
|
||||
|
||||
r_list_free (line_list);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
|
335
test/unit/test_dwarf_info.c
Normal file
335
test/unit/test_dwarf_info.c
Normal file
@ -0,0 +1,335 @@
|
||||
#include <r_util.h>
|
||||
#include "minunit.h"
|
||||
#include <r_bin.h>
|
||||
#include <r_bin_dwarf.h>
|
||||
|
||||
#define MODE 2
|
||||
|
||||
|
||||
#define check_attr_string(attr_idx, expect_string) \
|
||||
mu_assert_streq (cu.dies[i].attr_values[attr_idx].string.content, expect_string, "Wrong string attribute information")
|
||||
|
||||
#define check_attr_name(attr_idx, expect_name) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].attr_name, expect_name, "Wrong attribute name")
|
||||
|
||||
#define check_attr_address(attr_idx, expect_addr) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].address, expect_addr, "Wrong attribute name")
|
||||
|
||||
#define check_attr_form(attr_idx, expect_form) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].attr_form, expect_form, "Wrong attribute name")
|
||||
|
||||
#define check_attr_data(attr_idx, expect_data) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].data, expect_data, "Wrong attribute data")
|
||||
|
||||
#define check_attr_block_length(attr_idx, expect_len) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].block.length, expect_len, "Wrong attribute block length")
|
||||
|
||||
#define check_attr_block_data(attr_idx, data_idx, expect_data) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].block.data[data_idx], expect_data, "Wrong attribute block data")
|
||||
|
||||
#define check_attr_reference(attr_idx, expect_ref) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].reference, expect_ref, "Wrong attribute reference")
|
||||
|
||||
#define check_attr_flag(attr_idx, expect_flag) \
|
||||
mu_assert_eq (cu.dies[i].attr_values[attr_idx].flag, expect_flag, "Wrong attribute flag")
|
||||
|
||||
#define check_die_abbr_code(expect_code) \
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, expect_code, "Wrong abbrev code")
|
||||
|
||||
#define check_die_length(len) \
|
||||
mu_assert_eq (cu.dies[i].count, len, "Wrong DIE length information")
|
||||
|
||||
#define check_die_tag(tg) \
|
||||
mu_assert_eq (cu.dies[i].tag, tg, "Wrong DIE tag")
|
||||
|
||||
#define check_basic_unit_header(vers, len, is64bit, addr_size, abbr_offset) \
|
||||
do { \
|
||||
mu_assert_eq (hdr.version, vers, "Wrong header version information"); \
|
||||
mu_assert_eq (hdr.length, len, "Wrong header length information"); \
|
||||
mu_assert_eq (hdr.is_64bit, is64bit, "Wrong header is_64bit information"); \
|
||||
mu_assert_eq (hdr.address_size, addr_size, "Wrong header address_size information"); \
|
||||
mu_assert_eq (hdr.abbrev_offset, abbr_offset, "Wrong header abbrev_offset information"); \
|
||||
} while (0)
|
||||
|
||||
bool test_dwarf3_c(void) {
|
||||
RBin *bin = r_bin_new ();
|
||||
RIO *io = r_io_new ();
|
||||
r_io_bind (io, &bin->iob);
|
||||
|
||||
RBinOptions opt = { 0 };
|
||||
bool res = r_bin_open (bin, "bins/elf/dwarf3_c.elf", &opt);
|
||||
mu_assert ("dwarf3_c.elf binary could not be opened", res);
|
||||
|
||||
RBinDwarfDebugAbbrev *da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
mu_assert_eq (da->count, 7, "Incorrect number of abbreviation");
|
||||
RBinDwarfDebugInfo *info = r_bin_dwarf_parse_info (da, bin, MODE);
|
||||
mu_assert_eq (info->count, 1, "Incorrect number of info compilation units");
|
||||
|
||||
// check header
|
||||
RBinDwarfCompUnit cu = info->comp_units[0];
|
||||
RBinDwarfCompUnitHdr hdr = cu.hdr;
|
||||
|
||||
check_basic_unit_header (3, 0xa9, false, 8, 0x0);
|
||||
|
||||
mu_assert_eq (cu.count, 11, "Wrong attribute information");
|
||||
mu_assert_eq (cu.offset, 0x0, "Wrong attribute information");
|
||||
// check some of the attributes
|
||||
int i = 0;
|
||||
check_die_abbr_code (1);
|
||||
|
||||
check_die_length (7);
|
||||
check_die_tag (DW_TAG_compile_unit);
|
||||
|
||||
check_attr_name (0, DW_AT_producer);
|
||||
check_attr_string (2, "main.c");
|
||||
i++;
|
||||
check_die_abbr_code (2);
|
||||
i++;
|
||||
check_die_abbr_code (3);
|
||||
i++;
|
||||
check_die_abbr_code (4);
|
||||
i++;
|
||||
check_die_abbr_code (5);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (6);
|
||||
i++;
|
||||
check_die_abbr_code (7);
|
||||
|
||||
check_attr_string (0, "b");
|
||||
check_attr_data (3, 15);
|
||||
|
||||
i++;
|
||||
check_die_abbr_code (7);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
|
||||
r_bin_dwarf_free_debug_info (info);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool test_dwarf4_cpp_multiple_modules(void) {
|
||||
RBin *bin = r_bin_new ();
|
||||
RIO *io = r_io_new ();
|
||||
r_io_bind (io, &bin->iob);
|
||||
|
||||
RBinOptions opt = { 0 };
|
||||
bool res = r_bin_open (bin, "bins/elf/dwarf4_many_comp_units.elf", &opt);
|
||||
mu_assert ("dwarf4_many_comp_units.elf binary could not be opened", res);
|
||||
|
||||
RBinDwarfDebugAbbrev *da = r_bin_dwarf_parse_abbrev (bin, MODE);
|
||||
mu_assert_eq (da->count, 37, "Incorrect number of abbreviation");
|
||||
RBinDwarfDebugInfo *info = r_bin_dwarf_parse_info (da, bin, MODE);
|
||||
mu_assert_notnull (info, "Failed parsing of debug_info");
|
||||
mu_assert_eq (info->count, 2, "Incorrect number of info compilation units");
|
||||
|
||||
// check header
|
||||
RBinDwarfCompUnit cu = info->comp_units[0];
|
||||
RBinDwarfCompUnitHdr hdr = cu.hdr;
|
||||
check_basic_unit_header (4, 0x2c0, false, 8, 0x0);
|
||||
|
||||
// check some of the attributes
|
||||
mu_assert_eq (cu.count, 73, "Wrong attribute information");
|
||||
mu_assert_eq (cu.offset, 0x0, "Wrong attribute information");
|
||||
|
||||
int i = 0;
|
||||
check_die_abbr_code (1);
|
||||
check_die_length (7);
|
||||
check_die_tag (DW_TAG_compile_unit);
|
||||
|
||||
check_attr_name (0, DW_AT_producer);
|
||||
check_attr_string (2, "../main.cpp");
|
||||
check_attr_name (6, DW_AT_ranges);
|
||||
check_attr_reference (6, 0x0);
|
||||
|
||||
i++;
|
||||
check_die_abbr_code (2);
|
||||
i++;
|
||||
check_die_abbr_code (3);
|
||||
i++;
|
||||
check_die_abbr_code (3);
|
||||
i++;
|
||||
check_die_abbr_code (3);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
// i == 6
|
||||
check_die_abbr_code (4);
|
||||
check_attr_reference (0, 0x6e);
|
||||
check_attr_data (1, 4);
|
||||
check_attr_string (2, "Bird");
|
||||
check_attr_data (3, 8);
|
||||
check_attr_data (4, 1);
|
||||
check_attr_data (5, 9);
|
||||
i++;
|
||||
check_die_abbr_code (5);
|
||||
check_die_tag (DW_TAG_member);
|
||||
check_attr_string (0, "_vptr$Bird");
|
||||
check_attr_reference (1, 0xc5);
|
||||
check_attr_data (2, 0);
|
||||
check_attr_data (3, true);
|
||||
|
||||
i++;
|
||||
check_die_abbr_code (6);
|
||||
i++;
|
||||
check_die_abbr_code (7);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (8);
|
||||
i++;
|
||||
check_die_abbr_code (7);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (9);
|
||||
check_die_tag (DW_TAG_subprogram);
|
||||
check_die_length (10);
|
||||
check_attr_string (0, "_ZN4Bird3flyEv");
|
||||
check_attr_string (1, "fly");
|
||||
check_attr_data (2, 1);
|
||||
check_attr_data (3, 12);
|
||||
check_attr_reference (4, 0xd8);
|
||||
check_attr_name (6, DW_AT_vtable_elem_location);
|
||||
check_attr_form (7, DW_FORM_flag_present);
|
||||
check_attr_flag (7, true);
|
||||
check_attr_name (8, DW_AT_external);
|
||||
check_attr_flag (8, true);
|
||||
check_attr_name (9, DW_AT_containing_type);
|
||||
check_attr_reference (9, 0x6e);
|
||||
i++;
|
||||
check_die_abbr_code (7);
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, 7, "Wrong attribute information");
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, 0, "Wrong attribute information");
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, 0, "Wrong attribute information");
|
||||
i++;
|
||||
check_die_abbr_code (10);
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, 10, "Wrong attribute information");
|
||||
i++;
|
||||
check_die_abbr_code (11);
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, 11, "Wrong attribute information");
|
||||
i++;
|
||||
check_die_abbr_code (12);
|
||||
mu_assert_eq (cu.dies[i].abbrev_code, 12, "Wrong attribute information");
|
||||
i++;
|
||||
check_die_abbr_code (13);
|
||||
check_die_tag (DW_TAG_base_type);
|
||||
check_die_length (3);
|
||||
i++;
|
||||
check_die_abbr_code (10);
|
||||
i++;
|
||||
check_die_abbr_code (14);
|
||||
i++;
|
||||
check_die_abbr_code (15);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (4);
|
||||
i = 66;
|
||||
check_die_abbr_code (18);
|
||||
check_die_length (5);
|
||||
check_attr_reference (3, 0x2a7);
|
||||
i++;
|
||||
check_die_abbr_code (15);
|
||||
check_die_length (4);
|
||||
check_attr_block_length (0, 2);
|
||||
check_attr_block_data (0, 0, 0x91);
|
||||
check_attr_block_data (0, 1, 0x78);
|
||||
check_attr_string (1, "this");
|
||||
check_attr_reference (2, 0x2be);
|
||||
check_attr_flag (3, true);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (10);
|
||||
i++;
|
||||
check_die_abbr_code (10);
|
||||
check_die_tag (DW_TAG_pointer_type);
|
||||
i++;
|
||||
check_die_abbr_code (10);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
|
||||
cu = info->comp_units[1];
|
||||
hdr = cu.hdr;
|
||||
check_basic_unit_header (4, 0x192, false, 8, 0xfd);
|
||||
|
||||
// check some of the attributes
|
||||
mu_assert_eq (cu.count, 42, "Wrong attribute information");
|
||||
mu_assert_eq (cu.offset, 0x2c4, "Wrong attribute information");
|
||||
|
||||
i = 0;
|
||||
check_die_abbr_code (1);
|
||||
check_die_length (7);
|
||||
check_die_tag (DW_TAG_compile_unit);
|
||||
check_attr_name (0, DW_AT_producer);
|
||||
check_attr_string (0, "clang version 10.0.0-4ubuntu1 ");
|
||||
check_attr_data (1, 33);
|
||||
check_attr_string (2, "../mammal.cpp");
|
||||
check_attr_address (5, 0x0);
|
||||
check_attr_form (5, DW_FORM_addr);
|
||||
check_attr_name (6, DW_AT_ranges);
|
||||
check_attr_reference (6, 0xb0);
|
||||
i++;
|
||||
check_die_abbr_code (2);
|
||||
i++;
|
||||
check_die_abbr_code (3);
|
||||
i++;
|
||||
check_die_abbr_code (4);
|
||||
i++;
|
||||
check_die_abbr_code (5);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i++;
|
||||
check_die_abbr_code (6);
|
||||
i++;
|
||||
check_die_abbr_code (5);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
i = 35;
|
||||
check_die_abbr_code (8);
|
||||
check_die_tag (DW_TAG_pointer_type);
|
||||
check_die_length (1);
|
||||
check_attr_form (0, DW_FORM_ref4);
|
||||
check_attr_reference (0, 0x407);
|
||||
i++;
|
||||
check_die_abbr_code (19);
|
||||
check_die_tag (DW_TAG_subprogram);
|
||||
check_die_length (5);
|
||||
check_attr_name (2, DW_AT_frame_base);
|
||||
check_attr_block_length (2, 1);
|
||||
check_attr_block_data (2, 0, 0x56);
|
||||
check_attr_reference (3, 0x442);
|
||||
check_attr_reference (4, 0x410);
|
||||
i=40;
|
||||
check_die_abbr_code (8);
|
||||
i++;
|
||||
check_die_abbr_code (0);
|
||||
|
||||
r_bin_dwarf_free_debug_info (info);
|
||||
r_bin_dwarf_free_debug_abbrev (da);
|
||||
r_bin_free (bin);
|
||||
r_io_free (io);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool all_tests() {
|
||||
mu_run_test (test_dwarf3_c);
|
||||
mu_run_test (test_dwarf4_cpp_multiple_modules);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return all_tests ();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user