1 #include <r_util.h>
2 #include "minunit.h"
3 #include <r_bin.h>
4 #include <r_bin_dwarf.h>
5
6 #define MODE 2
7
8
9 #define check_attr_string(attr_idx, expect_string) \
10 mu_assert_streq (cu.dies[i].attr_values[attr_idx].string.content, expect_string, "Wrong string attribute information")
11
12 #define check_attr_name(attr_idx, expect_name) \
13 mu_assert_eq (cu.dies[i].attr_values[attr_idx].attr_name, expect_name, "Wrong attribute name")
14
15 #define check_attr_address(attr_idx, expect_addr) \
16 mu_assert_eq (cu.dies[i].attr_values[attr_idx].address, expect_addr, "Wrong attribute name")
17
18 #define check_attr_form(attr_idx, expect_form) \
19 mu_assert_eq (cu.dies[i].attr_values[attr_idx].attr_form, expect_form, "Wrong attribute name")
20
21 #define check_attr_data(attr_idx, expect_data) \
22 mu_assert_eq (cu.dies[i].attr_values[attr_idx].uconstant, expect_data, "Wrong attribute data")
23
24 #define check_attr_block_length(attr_idx, expect_len) \
25 mu_assert_eq (cu.dies[i].attr_values[attr_idx].block.length, expect_len, "Wrong attribute block length")
26
27 #define check_attr_block_data(attr_idx, data_idx, expect_data) \
28 mu_assert_eq (cu.dies[i].attr_values[attr_idx].block.data[data_idx], expect_data, "Wrong attribute block data")
29
30 #define check_attr_reference(attr_idx, expect_ref) \
31 mu_assert_eq (cu.dies[i].attr_values[attr_idx].reference, expect_ref, "Wrong attribute reference")
32
33 #define check_attr_flag(attr_idx, expect_flag) \
34 mu_assert_eq (cu.dies[i].attr_values[attr_idx].flag, expect_flag, "Wrong attribute flag")
35
36 #define check_die_abbr_code(expect_code) \
37 mu_assert_eq (cu.dies[i].abbrev_code, expect_code, "Wrong abbrev code")
38
39 #define check_die_length(len) \
40 mu_assert_eq (cu.dies[i].count, len, "Wrong DIE length information")
41
42 #define check_die_tag(tg) \
43 mu_assert_eq (cu.dies[i].tag, tg, "Wrong DIE tag")
44
45 #define check_basic_unit_header(vers, len, is64bit, addr_size, abbr_offset) \
46 do { \
47 mu_assert_eq (hdr.version, vers, "Wrong header version information"); \
48 mu_assert_eq (hdr.length, len, "Wrong header length information"); \
49 mu_assert_eq (hdr.is_64bit, is64bit, "Wrong header is_64bit information"); \
50 mu_assert_eq (hdr.address_size, addr_size, "Wrong header address_size information"); \
51 mu_assert_eq (hdr.abbrev_offset, abbr_offset, "Wrong header abbrev_offset information"); \
52 } while (0)
53
test_dwarf3_c(void)54 bool test_dwarf3_c(void) {
55 RBin *bin = r_bin_new ();
56 RIO *io = r_io_new ();
57 r_io_bind (io, &bin->iob);
58
59 RBinOptions opt = { 0 };
60 bool res = r_bin_open (bin, "bins/elf/dwarf3_c.elf", &opt);
61 mu_assert ("dwarf3_c.elf binary could not be opened", res);
62
63 RBinDwarfDebugAbbrev *da = r_bin_dwarf_parse_abbrev (bin, MODE);
64 mu_assert_eq (da->count, 7, "Incorrect number of abbreviation");
65 RBinDwarfDebugInfo *info = r_bin_dwarf_parse_info (da, bin, MODE);
66 mu_assert_eq (info->count, 1, "Incorrect number of info compilation units");
67
68 // check header
69 RBinDwarfCompUnit cu = info->comp_units[0];
70 RBinDwarfCompUnitHdr hdr = cu.hdr;
71
72 check_basic_unit_header (3, 0xa9, false, 8, 0x0);
73
74 mu_assert_eq (cu.count, 11, "Wrong attribute information");
75 mu_assert_eq (cu.offset, 0x0, "Wrong attribute information");
76 // check some of the attributes
77 int i = 0;
78 check_die_abbr_code (1);
79
80 check_die_length (7);
81 check_die_tag (DW_TAG_compile_unit);
82
83 check_attr_name (0, DW_AT_producer);
84 check_attr_string (2, "main.c");
85 i++;
86 check_die_abbr_code (2);
87 i++;
88 check_die_abbr_code (3);
89 i++;
90 check_die_abbr_code (4);
91 i++;
92 check_die_abbr_code (5);
93 i++;
94 check_die_abbr_code (0);
95 i++;
96 check_die_abbr_code (6);
97 i++;
98 check_die_abbr_code (7);
99
100 check_attr_string (0, "b");
101 check_attr_data (3, 15);
102
103 i++;
104 check_die_abbr_code (7);
105 i++;
106 check_die_abbr_code (0);
107 i++;
108 check_die_abbr_code (0);
109
110 r_bin_dwarf_free_debug_info (info);
111 r_bin_dwarf_free_debug_abbrev (da);
112 r_bin_free (bin);
113 r_io_free (io);
114 mu_end;
115 }
116
test_dwarf4_cpp_multiple_modules(void)117 bool test_dwarf4_cpp_multiple_modules(void) {
118 RBin *bin = r_bin_new ();
119 RIO *io = r_io_new ();
120 r_io_bind (io, &bin->iob);
121
122 RBinOptions opt = { 0 };
123 bool res = r_bin_open (bin, "bins/elf/dwarf4_many_comp_units.elf", &opt);
124 mu_assert ("dwarf4_many_comp_units.elf binary could not be opened", res);
125
126 RBinDwarfDebugAbbrev *da = r_bin_dwarf_parse_abbrev (bin, MODE);
127 mu_assert_eq (da->count, 37, "Incorrect number of abbreviation");
128 RBinDwarfDebugInfo *info = r_bin_dwarf_parse_info (da, bin, MODE);
129 mu_assert_notnull (info, "Failed parsing of debug_info");
130 mu_assert_eq (info->count, 2, "Incorrect number of info compilation units");
131
132 // check header
133 RBinDwarfCompUnit cu = info->comp_units[0];
134 RBinDwarfCompUnitHdr hdr = cu.hdr;
135 check_basic_unit_header (4, 0x2c0, false, 8, 0x0);
136
137 // check some of the attributes
138 mu_assert_eq (cu.count, 73, "Wrong attribute information");
139 mu_assert_eq (cu.offset, 0x0, "Wrong attribute information");
140
141 int i = 0;
142 check_die_abbr_code (1);
143 check_die_length (7);
144 check_die_tag (DW_TAG_compile_unit);
145
146 check_attr_name (0, DW_AT_producer);
147 check_attr_string (2, "../main.cpp");
148 check_attr_name (6, DW_AT_ranges);
149 check_attr_reference (6, 0x0);
150
151 i++;
152 check_die_abbr_code (2);
153 i++;
154 check_die_abbr_code (3);
155 i++;
156 check_die_abbr_code (3);
157 i++;
158 check_die_abbr_code (3);
159 i++;
160 check_die_abbr_code (0);
161 i++;
162 // i == 6
163 check_die_abbr_code (4);
164 check_attr_reference (0, 0x6e);
165 check_attr_data (1, 4);
166 check_attr_string (2, "Bird");
167 check_attr_data (3, 8);
168 check_attr_data (4, 1);
169 check_attr_data (5, 9);
170 i++;
171 check_die_abbr_code (5);
172 check_die_tag (DW_TAG_member);
173 check_attr_string (0, "_vptr$Bird");
174 check_attr_reference (1, 0xc5);
175 check_attr_data (2, 0);
176 check_attr_flag (3, true);
177
178 i++;
179 check_die_abbr_code (6);
180 i++;
181 check_die_abbr_code (7);
182 i++;
183 check_die_abbr_code (0);
184 i++;
185 check_die_abbr_code (8);
186 i++;
187 check_die_abbr_code (7);
188 i++;
189 check_die_abbr_code (0);
190 i++;
191 check_die_abbr_code (9);
192 check_die_tag (DW_TAG_subprogram);
193 check_die_length (10);
194 check_attr_string (0, "_ZN4Bird3flyEv");
195 check_attr_string (1, "fly");
196 check_attr_data (2, 1);
197 check_attr_data (3, 12);
198 check_attr_reference (4, 0xd8);
199 check_attr_name (6, DW_AT_vtable_elem_location);
200 check_attr_form (7, DW_FORM_flag_present);
201 check_attr_flag (7, true);
202 check_attr_name (8, DW_AT_external);
203 check_attr_flag (8, true);
204 check_attr_name (9, DW_AT_containing_type);
205 check_attr_reference (9, 0x6e);
206 i++;
207 check_die_abbr_code (7);
208 mu_assert_eq (cu.dies[i].abbrev_code, 7, "Wrong attribute information");
209 i++;
210 check_die_abbr_code (0);
211 mu_assert_eq (cu.dies[i].abbrev_code, 0, "Wrong attribute information");
212 i++;
213 check_die_abbr_code (0);
214 mu_assert_eq (cu.dies[i].abbrev_code, 0, "Wrong attribute information");
215 i++;
216 check_die_abbr_code (10);
217 mu_assert_eq (cu.dies[i].abbrev_code, 10, "Wrong attribute information");
218 i++;
219 check_die_abbr_code (11);
220 mu_assert_eq (cu.dies[i].abbrev_code, 11, "Wrong attribute information");
221 i++;
222 check_die_abbr_code (12);
223 mu_assert_eq (cu.dies[i].abbrev_code, 12, "Wrong attribute information");
224 i++;
225 check_die_abbr_code (13);
226 check_die_tag (DW_TAG_base_type);
227 check_die_length (3);
228 i++;
229 check_die_abbr_code (10);
230 i++;
231 check_die_abbr_code (14);
232 i++;
233 check_die_abbr_code (15);
234 i++;
235 check_die_abbr_code (0);
236 i++;
237 check_die_abbr_code (4);
238 i = 66;
239 check_die_abbr_code (18);
240 check_die_length (5);
241 check_attr_reference (3, 0x2a7);
242 i++;
243 check_die_abbr_code (15);
244 check_die_length (4);
245 check_attr_block_length (0, 2);
246 check_attr_block_data (0, 0, 0x91);
247 check_attr_block_data (0, 1, 0x78);
248 check_attr_string (1, "this");
249 check_attr_reference (2, 0x2be);
250 check_attr_flag (3, true);
251 i++;
252 check_die_abbr_code (0);
253 i++;
254 check_die_abbr_code (10);
255 i++;
256 check_die_abbr_code (10);
257 check_die_tag (DW_TAG_pointer_type);
258 i++;
259 check_die_abbr_code (10);
260 i++;
261 check_die_abbr_code (0);
262 i++;
263
264 cu = info->comp_units[1];
265 hdr = cu.hdr;
266 check_basic_unit_header (4, 0x192, false, 8, 0xfd);
267
268 // check some of the attributes
269 mu_assert_eq (cu.count, 42, "Wrong attribute information");
270 mu_assert_eq (cu.offset, 0x2c4, "Wrong attribute information");
271
272 i = 0;
273 check_die_abbr_code (1);
274 check_die_length (7);
275 check_die_tag (DW_TAG_compile_unit);
276 check_attr_name (0, DW_AT_producer);
277 check_attr_string (0, "clang version 10.0.0-4ubuntu1 ");
278 check_attr_data (1, 33);
279 check_attr_string (2, "../mammal.cpp");
280 check_attr_address (5, 0x0);
281 check_attr_form (5, DW_FORM_addr);
282 check_attr_name (6, DW_AT_ranges);
283 check_attr_reference (6, 0xb0);
284 i++;
285 check_die_abbr_code (2);
286 i++;
287 check_die_abbr_code (3);
288 i++;
289 check_die_abbr_code (4);
290 i++;
291 check_die_abbr_code (5);
292 i++;
293 check_die_abbr_code (0);
294 i++;
295 check_die_abbr_code (6);
296 i++;
297 check_die_abbr_code (5);
298 i++;
299 check_die_abbr_code (0);
300 i = 35;
301 check_die_abbr_code (8);
302 check_die_tag (DW_TAG_pointer_type);
303 check_die_length (1);
304 check_attr_form (0, DW_FORM_ref4);
305 check_attr_reference (0, 0x407);
306 i++;
307 check_die_abbr_code (19);
308 check_die_tag (DW_TAG_subprogram);
309 check_die_length (5);
310 check_attr_name (2, DW_AT_frame_base);
311 check_attr_block_length (2, 1);
312 check_attr_block_data (2, 0, 0x56);
313 check_attr_reference (3, 0x442);
314 check_attr_reference (4, 0x410);
315 i=40;
316 check_die_abbr_code (8);
317 i++;
318 check_die_abbr_code (0);
319
320 r_bin_dwarf_free_debug_info (info);
321 r_bin_dwarf_free_debug_abbrev (da);
322 r_bin_free (bin);
323 r_io_free (io);
324 mu_end;
325 }
326
test_dwarf2_big_endian(void)327 bool test_dwarf2_big_endian(void) {
328 RBin *bin = r_bin_new ();
329 RIO *io = r_io_new ();
330 r_io_bind (io, &bin->iob);
331
332 RBinOptions opt = { 0 };
333 bool res = r_bin_open (bin, "bins/elf/ppc64_sudoku_dwarf", &opt);
334 mu_assert ("dwarf4_many_comp_units.elf binary could not be opened", res);
335
336 RBinDwarfDebugAbbrev *da = r_bin_dwarf_parse_abbrev (bin, MODE);
337 mu_assert_eq (da->count, 108, "Incorrect number of abbreviation");
338 RBinDwarfDebugInfo *info = r_bin_dwarf_parse_info (da, bin, MODE);
339 mu_assert_notnull (info, "Failed parsing of debug_info");
340 mu_assert_eq (info->count, 1, "Incorrect number of info compilation units");
341
342 // check header
343 RBinDwarfCompUnit cu = info->comp_units[0];
344 RBinDwarfCompUnitHdr hdr = cu.hdr;
345 check_basic_unit_header (2, 0x38b9, false, 8, 0x0);
346
347 int i = 0;
348 check_die_abbr_code (1);
349 check_die_length (7);
350 check_die_tag (DW_TAG_compile_unit);
351
352 check_attr_name (0, DW_AT_producer);
353 check_attr_string (0, "GNU C++14 9.3.0 -msecure-plt -mabi=elfv2 -mcpu=970 -gdwarf-2 -gstrict-dwarf -O1");
354 check_attr_name (1, DW_AT_language);
355 check_attr_data (1, DW_LANG_C_plus_plus);
356
357 check_attr_name (4, DW_AT_low_pc);
358 check_attr_reference (4, 0x0000000010000ec4);
359 check_attr_name (5, DW_AT_high_pc);
360 check_attr_reference (5, 0x0000000010001c48);
361 check_attr_name (6, DW_AT_stmt_list);
362 check_attr_reference (6, 0x0);
363
364 i+=2;
365 check_die_abbr_code (3);
366 check_die_tag (DW_TAG_base_type);
367
368 check_attr_name (0, DW_AT_byte_size);
369 check_attr_data (0, 0x08);
370
371 check_attr_name (1, DW_AT_encoding);
372 check_attr_data (1, DW_ATE_unsigned);
373
374 check_attr_name (2, DW_AT_name);
375 check_attr_string (2, "long unsigned int");
376
377 i++; check_die_abbr_code (4);
378 i++; check_die_abbr_code (2);
379 i++; check_die_abbr_code (3);
380 i++; check_die_abbr_code (2);
381 i++;
382 // i == 7
383 check_die_abbr_code (5);
384 check_die_tag (DW_TAG_structure_type);
385
386 check_attr_name (0, DW_AT_name);
387 check_attr_string (0, "_IO_FILE");
388
389 check_attr_name (1, DW_AT_byte_size);
390 check_attr_data (1, 0x01);
391
392 check_attr_name (2, DW_AT_decl_file);
393 check_attr_name (3, DW_AT_decl_line);
394 check_attr_name (4, DW_AT_decl_column);
395 check_attr_name (5, DW_AT_sibling);
396
397 i = 1668 - 4;
398 check_die_abbr_code (108);
399 check_die_tag (DW_TAG_subprogram);
400
401 check_attr_name (0, DW_AT_abstract_origin);
402 check_attr_reference (0, 0x2f32);
403
404 check_attr_name (1, DW_AT_MIPS_linkage_name);
405 check_attr_string (1, "_Z8isnumberc");
406
407 check_attr_name (2, DW_AT_low_pc);
408 check_attr_reference (2, 0x0000000010001aa4);
409
410 check_attr_name (3, DW_AT_high_pc);
411 check_attr_reference (3, 0x0000000010001ac8);
412
413 r_bin_dwarf_free_debug_info (info);
414 r_bin_dwarf_free_debug_abbrev (da);
415 r_bin_free (bin);
416 r_io_free (io);
417 mu_end;
418 }
419
all_tests()420 bool all_tests() {
421 mu_run_test (test_dwarf3_c);
422 mu_run_test (test_dwarf4_cpp_multiple_modules);
423 mu_run_test (test_dwarf2_big_endian);
424 return tests_passed != tests_run;
425 }
426
main(int argc,char ** argv)427 int main(int argc, char **argv) {
428 return all_tests ();
429 }
430