xref: /trueos/lib/libdwarf/dwarf_dump.c (revision b972b67ed72b5687a023c92602aaef64163b2f59)
1 /*-
2  * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #include <stdlib.h>
30 #include <string.h>
31 #include "_libdwarf.h"
32 
33 const char *
get_sht_desc(uint32_t sh_type)34 get_sht_desc(uint32_t sh_type)
35 {
36 	switch (sh_type) {
37 	case SHT_NULL:
38 		return "inactive";
39 	case SHT_PROGBITS:
40 		return "program defined information";
41 	case SHT_SYMTAB:
42 		return "symbol table section";
43 	case SHT_STRTAB:
44 		return "string table section";
45 	case SHT_RELA:
46 		return "relocation section with addends";
47 	case SHT_HASH:
48 		return "symbol hash table section";
49 	case SHT_DYNAMIC:
50 		return "dynamic section";
51 	case SHT_NOTE:
52 		return "note section";
53 	case SHT_NOBITS:
54 		return "no space section";
55 	case SHT_REL:
56 		return "relocation section - no addends";
57 	case SHT_SHLIB:
58 		return "reserved - purpose unknown";
59 	case SHT_DYNSYM:
60 		return "dynamic symbol table section";
61 	case SHT_INIT_ARRAY:
62 		return "Initialization function pointers.";
63 	case SHT_FINI_ARRAY:
64 		return "Termination function pointers.";
65 	case SHT_PREINIT_ARRAY:
66 		return "Pre-initialization function ptrs.";
67 	case SHT_GROUP:
68 		return "Section group.";
69 	case SHT_SYMTAB_SHNDX:
70 		return "Section indexes (see SHN_XINDEX).";
71 	case SHT_GNU_verdef:
72 		return "Symbol versions provided";
73 	case SHT_GNU_verneed:
74 		return "Symbol versions required";
75 	case SHT_GNU_versym:
76 		return "Symbol version table";
77 	case SHT_AMD64_UNWIND:
78 		return "AMD64 unwind";
79 	default:
80 		return "Unknown";
81 	}
82 }
83 
84 const char *
get_attr_desc(uint32_t attr)85 get_attr_desc(uint32_t attr)
86 {
87 	switch (attr) {
88 	case DW_AT_abstract_origin:
89 		return "DW_AT_abstract_origin";
90 	case DW_AT_accessibility:
91 		return "DW_AT_accessibility";
92 	case DW_AT_address_class:
93 		return "DW_AT_address_class";
94 	case DW_AT_artificial:
95 		return "DW_AT_artificial";
96 	case DW_AT_base_types:
97 		return "DW_AT_base_types";
98 	case DW_AT_bit_offset:
99 		return "DW_AT_bit_offset";
100 	case DW_AT_bit_size:
101 		return "DW_AT_bit_size";
102 	case DW_AT_byte_size:
103 		return "DW_AT_byte_size";
104 	case DW_AT_calling_convention:
105 		return "DW_AT_calling_convention";
106 	case DW_AT_common_reference:
107 		return "DW_AT_common_reference";
108 	case DW_AT_comp_dir:
109 		return "DW_AT_comp_dir";
110 	case DW_AT_const_value:
111 		return "DW_AT_const_value";
112 	case DW_AT_containing_type:
113 		return "DW_AT_containing_type";
114 	case DW_AT_count:
115 		return "DW_AT_count";
116 	case DW_AT_data_member_location:
117 		return "DW_AT_data_member_location";
118 	case DW_AT_decl_column:
119 		return "DW_AT_decl_column";
120 	case DW_AT_decl_file:
121 		return "DW_AT_decl_file";
122 	case DW_AT_decl_line:
123 		return "DW_AT_decl_line";
124 	case DW_AT_declaration:
125 		return "DW_AT_declaration";
126 	case DW_AT_default_value:
127 		return "DW_AT_default_value";
128 	case DW_AT_discr:
129 		return "DW_AT_discr";
130 	case DW_AT_discr_list:
131 		return "DW_AT_discr_list";
132 	case DW_AT_discr_value:
133 		return "DW_AT_discr_value";
134 	case DW_AT_element_list:
135 		return "DW_AT_element_list";
136 	case DW_AT_encoding:
137 		return "DW_AT_encoding";
138 	case DW_AT_external:
139 		return "DW_AT_external";
140 	case DW_AT_frame_base:
141 		return "DW_AT_frame_base";
142 	case DW_AT_friend:
143 		return "DW_AT_friend";
144 	case DW_AT_high_pc:
145 		return "DW_AT_high_pc";
146 	case DW_AT_identifier_case:
147 		return "DW_AT_identifier_case";
148 	case DW_AT_import:
149 		return "DW_AT_import";
150 	case DW_AT_inline:
151 		return "DW_AT_inline";
152 	case DW_AT_is_optional:
153 		return "DW_AT_is_optional";
154 	case DW_AT_language:
155 		return "DW_AT_language";
156 	case DW_AT_location:
157 		return "DW_AT_location";
158 	case DW_AT_low_pc:
159 		return "DW_AT_low_pc";
160 	case DW_AT_lower_bound:
161 		return "DW_AT_lower_bound";
162 	case DW_AT_macro_info:
163 		return "DW_AT_macro_info";
164 	case DW_AT_member:
165 		return "DW_AT_member";
166 	case DW_AT_name:
167 		return "DW_AT_name";
168 	case DW_AT_namelist_item:
169 		return "DW_AT_namelist_item";
170 	case DW_AT_ordering:
171 		return "DW_AT_ordering";
172 	case DW_AT_priority:
173 		return "DW_AT_priority";
174 	case DW_AT_producer:
175 		return "DW_AT_producer";
176 	case DW_AT_prototyped:
177 		return "DW_AT_prototyped";
178 	case DW_AT_return_addr:
179 		return "DW_AT_return_addr";
180 	case DW_AT_segment:
181 		return "DW_AT_segment";
182 	case DW_AT_sibling:
183 		return "DW_AT_sibling";
184 	case DW_AT_specification:
185 		return "DW_AT_specification";
186 	case DW_AT_start_scope:
187 		return "DW_AT_start_scope";
188 	case DW_AT_static_link:
189 		return "DW_AT_static_link";
190 	case DW_AT_stmt_list:
191 		return "DW_AT_stmt_list";
192 	case DW_AT_stride_size:
193 		return "DW_AT_stride_size";
194 	case DW_AT_string_length:
195 		return "DW_AT_string_length";
196 	case DW_AT_subscr_data:
197 		return "DW_AT_subscr_data";
198 	case DW_AT_type:
199 		return "DW_AT_type";
200 	case DW_AT_upper_bound:
201 		return "DW_AT_upper_bound";
202 	case DW_AT_use_location:
203 		return "DW_AT_use_location";
204 	case DW_AT_variable_parameter:
205 		return "DW_AT_variable_parameter";
206 	case DW_AT_virtuality:
207 		return "DW_AT_virtuality";
208 	case DW_AT_visibility:
209 		return "DW_AT_visibility";
210 	case DW_AT_vtable_elem_location:
211 		return "DW_AT_vtable_elem_location";
212 	default:
213 		break;
214 	}
215 
216 	return "Unknown attribute";
217 }
218 
219 const char *
get_form_desc(uint32_t form)220 get_form_desc(uint32_t form)
221 {
222 	switch (form) {
223 	case DW_FORM_addr:
224 		return "DW_FORM_addr";
225 	case DW_FORM_block:
226 		return "DW_FORM_block";
227 	case DW_FORM_block1:
228 		return "DW_FORM_block1";
229 	case DW_FORM_block2:
230 		return "DW_FORM_block2";
231 	case DW_FORM_block4:
232 		return "DW_FORM_block4";
233 	case DW_FORM_data1:
234 		return "DW_FORM_data1";
235 	case DW_FORM_data2:
236 		return "DW_FORM_data2";
237 	case DW_FORM_data4:
238 		return "DW_FORM_data4";
239 	case DW_FORM_data8:
240 		return "DW_FORM_data8";
241 	case DW_FORM_flag:
242 		return "DW_FORM_flag";
243 	case DW_FORM_flag_present:
244 		return "DW_FORM_flag_present";
245 	case DW_FORM_indirect:
246 		return "DW_FORM_indirect";
247 	case DW_FORM_ref1:
248 		return "DW_FORM_ref1";
249 	case DW_FORM_ref2:
250 		return "DW_FORM_ref2";
251 	case DW_FORM_ref4:
252 		return "DW_FORM_ref4";
253 	case DW_FORM_ref8:
254 		return "DW_FORM_ref8";
255 	case DW_FORM_ref_addr:
256 		return "DW_FORM_ref_addr";
257 	case DW_FORM_ref_udata:
258 		return "DW_FORM_ref_udata";
259 	case DW_FORM_sdata:
260 		return "DW_FORM_sdata";
261 	case DW_FORM_string:
262 		return "DW_FORM_string";
263 	case DW_FORM_strp:
264 		return "DW_FORM_strp";
265 	case DW_FORM_udata:
266 		return "DW_FORM_udata";
267 	default:
268 		break;
269 	}
270 
271 	return "Unknown attribute";
272 }
273 
274 const char *
get_tag_desc(uint32_t tag)275 get_tag_desc(uint32_t tag)
276 {
277 	switch (tag) {
278 	case DW_TAG_access_declaration:
279 		return "DW_TAG_access_declaration";
280 	case DW_TAG_array_type:
281 		return "DW_TAG_array_type";
282 	case DW_TAG_base_type:
283 		return "DW_TAG_base_type";
284 	case DW_TAG_catch_block:
285 		return "DW_TAG_catch_block";
286 	case DW_TAG_class_type:
287 		return "DW_TAG_class_type";
288 	case DW_TAG_common_block:
289 		return "DW_TAG_common_block";
290 	case DW_TAG_common_inclusion:
291 		return "DW_TAG_common_inclusion";
292 	case DW_TAG_compile_unit:
293 		return "DW_TAG_compile_unit";
294 	case DW_TAG_condition:
295 		return "DW_TAG_condition";
296 	case DW_TAG_const_type:
297 		return "DW_TAG_const_type";
298 	case DW_TAG_constant:
299 		return "DW_TAG_constant";
300 	case DW_TAG_dwarf_procedure:
301 		return "DW_TAG_dwarf_procedure";
302 	case DW_TAG_entry_point:
303 		return "DW_TAG_entry_point";
304 	case DW_TAG_enumeration_type:
305 		return "DW_TAG_enumeration_type";
306 	case DW_TAG_enumerator:
307 		return "DW_TAG_enumerator";
308 	case DW_TAG_formal_parameter:
309 		return "DW_TAG_formal_parameter";
310 	case DW_TAG_friend:
311 		return "DW_TAG_friend";
312 	case DW_TAG_imported_declaration:
313 		return "DW_TAG_imported_declaration";
314 	case DW_TAG_imported_module:
315 		return "DW_TAG_imported_module";
316 	case DW_TAG_imported_unit:
317 		return "DW_TAG_imported_unit";
318 	case DW_TAG_inheritance:
319 		return "DW_TAG_inheritance";
320 	case DW_TAG_inlined_subroutine:
321 		return "DW_TAG_inlined_subroutine";
322 	case DW_TAG_interface_type:
323 		return "DW_TAG_interface_type";
324 	case DW_TAG_label:
325 		return "DW_TAG_label";
326 	case DW_TAG_lexical_block:
327 		return "DW_TAG_lexical_block";
328 	case DW_TAG_member:
329 		return "DW_TAG_member";
330 	case DW_TAG_module:
331 		return "DW_TAG_module";
332 	case DW_TAG_namelist:
333 		return "DW_TAG_namelist";
334 	case DW_TAG_namelist_item:
335 		return "DW_TAG_namelist_item";
336 	case DW_TAG_namespace:
337 		return "DW_TAG_namespace";
338 	case DW_TAG_packed_type:
339 		return "DW_TAG_packed_type";
340 	case DW_TAG_partial_unit:
341 		return "DW_TAG_partial_unit";
342 	case DW_TAG_pointer_type:
343 		return "DW_TAG_pointer_type";
344 	case DW_TAG_ptr_to_member_type:
345 		return "DW_TAG_ptr_to_member_type";
346 	case DW_TAG_reference_type:
347 		return "DW_TAG_reference_type";
348 	case DW_TAG_restrict_type:
349 		return "DW_TAG_restrict_type";
350 	case DW_TAG_set_type:
351 		return "DW_TAG_set_type";
352 	case DW_TAG_shared_type:
353 		return "DW_TAG_shared_type";
354 	case DW_TAG_string_type:
355 		return "DW_TAG_string_type";
356 	case DW_TAG_structure_type:
357 		return "DW_TAG_structure_type";
358 	case DW_TAG_subprogram:
359 		return "DW_TAG_subprogram";
360 	case DW_TAG_subrange_type:
361 		return "DW_TAG_subrange_type";
362 	case DW_TAG_subroutine_type:
363 		return "DW_TAG_subroutine_type";
364 	case DW_TAG_template_type_parameter:
365 		return "DW_TAG_template_type_parameter";
366 	case DW_TAG_template_value_parameter:
367 		return "DW_TAG_template_value_parameter";
368 	case DW_TAG_thrown_type:
369 		return "DW_TAG_thrown_type";
370 	case DW_TAG_try_block:
371 		return "DW_TAG_try_block";
372 	case DW_TAG_typedef:
373 		return "DW_TAG_typedef";
374 	case DW_TAG_union_type:
375 		return "DW_TAG_union_type";
376 	case DW_TAG_unspecified_parameters:
377 		return "DW_TAG_unspecified_parameters";
378 	case DW_TAG_unspecified_type:
379 		return "DW_TAG_unspecified_type";
380 	case DW_TAG_variable:
381 		return "DW_TAG_variable";
382 	case DW_TAG_variant:
383 		return "DW_TAG_variant";
384 	case DW_TAG_variant_part:
385 		return "DW_TAG_variant_part";
386 	case DW_TAG_volatile_type:
387 		return "DW_TAG_volatile_type";
388 	case DW_TAG_with_stmt:
389 		return "DW_TAG_with_stmt";
390 	default:
391 		break;
392 	}
393 
394 	return "Unknown tag";
395 }
396 
397 void
dwarf_dump_abbrev(Dwarf_Debug dbg)398 dwarf_dump_abbrev(Dwarf_Debug dbg)
399 {
400 	Dwarf_Abbrev a;
401 	Dwarf_Attribute at;
402 	Dwarf_CU cu;
403 
404 	printf("Contents of the .debug_abbrev section:\n\nEntry Tag\n");
405 
406 	STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
407 		STAILQ_FOREACH(a, &cu->cu_abbrev, a_next) {
408 			printf("%5lu %-30s [%s children]\n",
409 			    (u_long) a->a_entry, get_tag_desc(a->a_tag),
410 			    (a->a_children == DW_CHILDREN_yes) ? "has" : "no");
411 
412 			STAILQ_FOREACH(at, &a->a_attrib, at_next)
413 				printf("      %-30s %s\n", get_attr_desc(at->at_attrib),
414 				    get_form_desc(at->at_form));
415 		}
416 	}
417 }
418 #ifdef DOODAD
419     case DW_AT_inline:
420       switch (uvalue)
421 	{
422 	case DW_INL_not_inlined:
423 	  printf (_("(not inlined)"));
424 	  break;
425 	case DW_INL_inlined:
426 	  printf (_("(inlined)"));
427 	  break;
428 	case DW_INL_declared_not_inlined:
429 	  printf (_("(declared as inline but ignored)"));
430 	  break;
431 	case DW_INL_declared_inlined:
432 	  printf (_("(declared as inline and inlined)"));
433 	  break;
434 	default:
435 	  printf (_("  (Unknown inline attribute value: %lx)"), uvalue);
436 	  break;
437 	}
438       break;
439 
440     case DW_AT_language:
441       switch (uvalue)
442 	{
443 	case DW_LANG_C:			printf ("(non-ANSI C)"); break;
444 	case DW_LANG_C89:		printf ("(ANSI C)"); break;
445 	case DW_LANG_C_plus_plus:	printf ("(C++)"); break;
446 	case DW_LANG_Fortran77:		printf ("(FORTRAN 77)"); break;
447 	case DW_LANG_Fortran90:		printf ("(Fortran 90)"); break;
448 	case DW_LANG_Modula2:		printf ("(Modula 2)"); break;
449 	case DW_LANG_Pascal83:		printf ("(ANSI Pascal)"); break;
450 	case DW_LANG_Ada83:		printf ("(Ada)"); break;
451 	case DW_LANG_Cobol74:		printf ("(Cobol 74)"); break;
452 	case DW_LANG_Cobol85:		printf ("(Cobol 85)"); break;
453 	  /* DWARF 2.1 values.	*/
454 	case DW_LANG_C99:		printf ("(ANSI C99)"); break;
455 	case DW_LANG_Ada95:		printf ("(ADA 95)"); break;
456 	case DW_LANG_Fortran95:		printf ("(Fortran 95)"); break;
457 	  /* MIPS extension.  */
458 	case DW_LANG_Mips_Assembler:	printf ("(MIPS assembler)"); break;
459 	  /* UPC extension.  */
460 	case DW_LANG_Upc:		printf ("(Unified Parallel C)"); break;
461 	default:
462 	  printf ("(Unknown: %lx)", uvalue);
463 	  break;
464 	}
465       break;
466 
467     case DW_AT_encoding:
468       switch (uvalue)
469 	{
470 	case DW_ATE_void:		printf ("(void)"); break;
471 	case DW_ATE_address:		printf ("(machine address)"); break;
472 	case DW_ATE_boolean:		printf ("(boolean)"); break;
473 	case DW_ATE_complex_float:	printf ("(complex float)"); break;
474 	case DW_ATE_float:		printf ("(float)"); break;
475 	case DW_ATE_signed:		printf ("(signed)"); break;
476 	case DW_ATE_signed_char:	printf ("(signed char)"); break;
477 	case DW_ATE_unsigned:		printf ("(unsigned)"); break;
478 	case DW_ATE_unsigned_char:	printf ("(unsigned char)"); break;
479 	  /* DWARF 2.1 value.  */
480 	case DW_ATE_imaginary_float:	printf ("(imaginary float)"); break;
481 	default:
482 	  if (uvalue >= DW_ATE_lo_user
483 	      && uvalue <= DW_ATE_hi_user)
484 	    printf ("(user defined type)");
485 	  else
486 	    printf ("(unknown type)");
487 	  break;
488 	}
489       break;
490 
491     case DW_AT_accessibility:
492       switch (uvalue)
493 	{
494 	case DW_ACCESS_public:		printf ("(public)"); break;
495 	case DW_ACCESS_protected:	printf ("(protected)"); break;
496 	case DW_ACCESS_private:		printf ("(private)"); break;
497 	default:
498 	  printf ("(unknown accessibility)");
499 	  break;
500 	}
501       break;
502 
503     case DW_AT_visibility:
504       switch (uvalue)
505 	{
506 	case DW_VIS_local:		printf ("(local)"); break;
507 	case DW_VIS_exported:		printf ("(exported)"); break;
508 	case DW_VIS_qualified:		printf ("(qualified)"); break;
509 	default:			printf ("(unknown visibility)"); break;
510 	}
511       break;
512 
513     case DW_AT_virtuality:
514       switch (uvalue)
515 	{
516 	case DW_VIRTUALITY_none:	printf ("(none)"); break;
517 	case DW_VIRTUALITY_virtual:	printf ("(virtual)"); break;
518 	case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
519 	default:			printf ("(unknown virtuality)"); break;
520 	}
521       break;
522 
523     case DW_AT_identifier_case:
524       switch (uvalue)
525 	{
526 	case DW_ID_case_sensitive:	printf ("(case_sensitive)"); break;
527 	case DW_ID_up_case:		printf ("(up_case)"); break;
528 	case DW_ID_down_case:		printf ("(down_case)"); break;
529 	case DW_ID_case_insensitive:	printf ("(case_insensitive)"); break;
530 	default:			printf ("(unknown case)"); break;
531 	}
532       break;
533 
534     case DW_AT_calling_convention:
535       switch (uvalue)
536 	{
537 	case DW_CC_normal:	printf ("(normal)"); break;
538 	case DW_CC_program:	printf ("(program)"); break;
539 	case DW_CC_nocall:	printf ("(nocall)"); break;
540 	default:
541 	  if (uvalue >= DW_CC_lo_user
542 	      && uvalue <= DW_CC_hi_user)
543 	    printf ("(user defined)");
544 	  else
545 	    printf ("(unknown convention)");
546 	}
547       break;
548 
549     case DW_AT_ordering:
550       switch (uvalue)
551 	{
552 	case -1: printf ("(undefined)"); break;
553 	case 0:  printf ("(row major)"); break;
554 	case 1:  printf ("(column major)"); break;
555 	}
556       break;
557 
558     case DW_AT_frame_base:
559     case DW_AT_location:
560     case DW_AT_data_member_location:
561     case DW_AT_vtable_elem_location:
562     case DW_AT_allocated:
563     case DW_AT_associated:
564     case DW_AT_data_location:
565     case DW_AT_stride:
566     case DW_AT_upper_bound:
567     case DW_AT_lower_bound:
568       if (block_start)
569 	{
570 	  printf ("(");
571 	  decode_location_expression (block_start, pointer_size, uvalue);
572 	  printf (")");
573 	}
574       else if (form == DW_FORM_data4 || form == DW_FORM_data8)
575 	{
576 	  printf ("(");
577 	  printf ("location list");
578 	  printf (")");
579 	}
580       break;
581 #endif
582 
583 static void
dwarf_dump_av_attr(Dwarf_Die die __unused,Dwarf_AttrValue av)584 dwarf_dump_av_attr(Dwarf_Die die __unused, Dwarf_AttrValue av)
585 {
586 	switch (av->av_attrib) {
587 	case DW_AT_accessibility:
588 		break;
589 
590 	case DW_AT_calling_convention:
591 		break;
592 
593 	case DW_AT_encoding:
594 		break;
595 
596 	case DW_AT_identifier_case:
597 		break;
598 
599 	case DW_AT_inline:
600 		break;
601 
602 	case DW_AT_language:
603 		break;
604 
605 	case DW_AT_ordering:
606 		break;
607 
608 	case DW_AT_virtuality:
609 		break;
610 
611 	case DW_AT_visibility:
612 		break;
613 
614 	case DW_AT_frame_base:
615 	case DW_AT_location:
616 	case DW_AT_data_member_location:
617 	case DW_AT_vtable_elem_location:
618 	case DW_AT_upper_bound:
619 	case DW_AT_lower_bound:
620 		break;
621 
622 	default:
623 		break;
624 	}
625 }
626 
627 void
dwarf_dump_av(Dwarf_Die die,Dwarf_AttrValue av)628 dwarf_dump_av(Dwarf_Die die, Dwarf_AttrValue av)
629 {
630 	uint64_t i;
631 
632 	printf("      %-30s : %-16s ",
633 	    get_attr_desc(av->av_attrib),
634 	    get_form_desc(av->av_form));
635 
636 	switch (av->av_form) {
637 	case DW_FORM_addr:
638 		printf("0x%llx", (unsigned long long) av->u[0].u64);
639 		break;
640 	case DW_FORM_block:
641 	case DW_FORM_block1:
642 	case DW_FORM_block2:
643 	case DW_FORM_block4:
644 		printf("%lu byte block:", (u_long) av->u[0].u64);
645 		for (i = 0; i < av->u[0].u64; i++)
646 			printf(" %02x", av->u[1].u8p[i]);
647 		break;
648 	case DW_FORM_data1:
649 	case DW_FORM_data2:
650 	case DW_FORM_data4:
651 	case DW_FORM_data8:
652 	case DW_FORM_flag:
653 	case DW_FORM_flag_present:
654 		printf("%llu", (unsigned long long) av->u[0].u64);
655 		break;
656 	case DW_FORM_ref1:
657 	case DW_FORM_ref2:
658 	case DW_FORM_ref4:
659 	case DW_FORM_ref8:
660 	case DW_FORM_ref_udata:
661 		printf("<%llx>", (unsigned long long) (av->u[0].u64 +
662 		    die->die_cu->cu_offset));
663 		break;
664 	case DW_FORM_string:
665 		printf("%s", av->u[0].s);
666 		break;
667 	case DW_FORM_strp:
668 		printf("(indirect string, offset 0x%llx): %s",
669 		    (unsigned long long) av->u[0].u64, av->u[1].s);
670 		break;
671 	default:
672 		printf("unknown form");
673 		break;
674 	}
675 
676 	/* Dump any extra attribute-specific information. */
677 	dwarf_dump_av_attr(die, av);
678 
679 	printf("\n");
680 }
681 
682 void
dwarf_dump_die_at_offset(Dwarf_Debug dbg,Dwarf_Off off)683 dwarf_dump_die_at_offset(Dwarf_Debug dbg, Dwarf_Off off)
684 {
685 	Dwarf_CU cu;
686 	Dwarf_Die die;
687 
688 	if (dbg == NULL)
689 		return;
690 
691 	STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
692 		STAILQ_FOREACH(die, &cu->cu_die, die_next) {
693 			if ((off_t) die->die_offset == off) {
694 				dwarf_dump_die(die);
695 				return;
696 			}
697 		}
698 	}
699 }
700 
701 void
dwarf_dump_die(Dwarf_Die die)702 dwarf_dump_die(Dwarf_Die die)
703 {
704 	Dwarf_AttrValue av;
705 
706 	printf("<%d><%llx>: Abbrev number: %llu (%s)\n",
707 	    die->die_level, (unsigned long long) die->die_offset,
708 	    (unsigned long long) die->die_abnum,
709 	    get_tag_desc(die->die_a->a_tag));
710 
711 	STAILQ_FOREACH(av, &die->die_attrval, av_next)
712 		dwarf_dump_av(die, av);
713 }
714 
715 void
dwarf_dump_raw(Dwarf_Debug dbg)716 dwarf_dump_raw(Dwarf_Debug dbg)
717 {
718 	Dwarf_CU cu;
719 	char *p = (char *) dbg;
720 	int i;
721 
722 	printf("dbg %p\n",dbg);
723 
724 	if (dbg == NULL)
725 		return;
726 
727 	for (i = 0; i < (int) sizeof(*dbg); i++) {
728 		if (*p >= 0x20 && *p < 0x7f) {
729 			printf(" %c",*p++ & 0xff);
730 		} else {
731 			printf(" %02x",*p++ & 0xff);
732 		}
733 	}
734 	printf("\n");
735 
736 	STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
737 		p = (char *) cu;
738 		printf("cu %p\n",cu);
739 		for (i = 0; i < (int) sizeof(*cu); i++) {
740 			if (*p >= 0x20 && *p < 0x7f) {
741 				printf(" %c",*p++ & 0xff);
742 			} else {
743 				printf(" %02x",*p++ & 0xff);
744 			}
745 		}
746 		printf("\n");
747 	}
748 }
749 
750 static void
dwarf_dump_tree_dies(Dwarf_Debug dbg,Dwarf_Die die,Dwarf_Error * error)751 dwarf_dump_tree_dies(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Error *error)
752 {
753 	Dwarf_Die child;
754 	int ret;
755 
756 	do {
757 		dwarf_dump_die(die);
758 
759 		if ((ret = dwarf_child(die, &child, error) == DWARF_E_NO_ENTRY)) {
760 			/* No children. */
761 		} else if (ret != DWARF_E_NONE) {
762 			printf("Error %s\n", dwarf_errmsg(error));
763 			return;
764 		} else
765 			dwarf_dump_tree_dies(dbg, child, error);
766 
767 		if (dwarf_siblingof(dbg, die, &die, error) != DWARF_E_NONE)
768 			die = NULL;
769 
770 	} while (die != NULL);
771 }
772 
773 void
dwarf_dump_tree(Dwarf_Debug dbg)774 dwarf_dump_tree(Dwarf_Debug dbg)
775 {
776 	Dwarf_CU cu;
777 	Dwarf_Die die;
778 	Dwarf_Error error;
779 	Dwarf_Half cu_pointer_size;
780 	Dwarf_Half cu_version;
781 	Dwarf_Unsigned cu_abbrev_offset;
782 	Dwarf_Unsigned cu_header_length;
783 	Dwarf_Unsigned cu_next_offset;
784 
785 	STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
786 		printf ("\nCompilation Unit @ offset %llx:\n",
787 		    (unsigned long long) cu->cu_offset);
788 		printf ("    Length:          %lu\n", (u_long) cu->cu_length);
789 		printf ("    Version:         %hu\n", cu->cu_version);
790 		printf ("    Abbrev Offset:   %lu\n", (u_long) cu->cu_abbrev_offset);
791 		printf ("    Pointer Size:    %u\n", (u_int) cu->cu_pointer_size);
792 
793 		if (dwarf_next_cu_header(dbg, &cu_header_length,
794 		    &cu_version, &cu_abbrev_offset, &cu_pointer_size,
795 		    &cu_next_offset, &error) != DWARF_E_NONE) {
796 			printf("Error %s\n", dwarf_errmsg(&error));
797 			return;
798 		}
799 
800 		if (dwarf_siblingof(dbg, NULL, &die, &error) != DWARF_E_NONE) {
801 			printf("Error %s\n", dwarf_errmsg(&error));
802 			return;
803 		}
804 
805 		dwarf_dump_tree_dies(dbg, die, &error);
806 
807 	}
808 }
809 
810 void
dwarf_dump_info(Dwarf_Debug dbg)811 dwarf_dump_info(Dwarf_Debug dbg)
812 {
813 	Dwarf_CU cu;
814 	Dwarf_Die die;
815 
816 	printf("Contents of the .debug_info section:\n");
817 
818 	STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
819 		printf ("\nCompilation Unit @ offset %llx:\n",
820 		    (unsigned long long) cu->cu_offset);
821 		printf ("    Length:          %lu\n", (u_long) cu->cu_length);
822 		printf ("    Version:         %hu\n", cu->cu_version);
823 		printf ("    Abbrev Offset:   %lu\n", (u_long) cu->cu_abbrev_offset);
824 		printf ("    Pointer Size:    %u\n", (u_int) cu->cu_pointer_size);
825 
826 		STAILQ_FOREACH(die, &cu->cu_die, die_next)
827 			dwarf_dump_die(die);
828 	}
829 }
830 
831 
832 void
dwarf_dump_shstrtab(Dwarf_Debug dbg)833 dwarf_dump_shstrtab(Dwarf_Debug dbg)
834 {
835 	char *name;
836 	int indx = 0;
837 
838 	printf("---------------------\nSection header string table contents:\n");
839 	while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, indx)) != NULL) {
840 		printf("%5d '%s'\n",indx,name);
841 		indx += strlen(name) + 1;
842 	}
843 }
844 
845 void
dwarf_dump_strtab(Dwarf_Debug dbg)846 dwarf_dump_strtab(Dwarf_Debug dbg)
847 {
848 	char *name;
849 	int indx = 0;
850 
851 	printf("---------------------\nString table contents:\n");
852 	while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, indx)) != NULL) {
853 		printf("%5d '%s'\n",indx,name);
854 		indx += strlen(name) + 1;
855 	}
856 }
857 
858 void
dwarf_dump_dbgstr(Dwarf_Debug dbg)859 dwarf_dump_dbgstr(Dwarf_Debug dbg)
860 {
861 	char *name;
862 	int indx = 0;
863 
864 	printf("---------------------\nDebug string table contents:\n");
865 	while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_debug_str].s_shnum, indx)) != NULL) {
866 		printf("%5d '%s'\n",indx,name);
867 		indx += strlen(name) + 1;
868 	}
869 }
870 
871 void
dwarf_dump_symtab(Dwarf_Debug dbg)872 dwarf_dump_symtab(Dwarf_Debug dbg)
873 {
874 	GElf_Sym sym;
875 	char *name;
876 	int indx = 0;
877 
878 	printf("---------------------\nSymbol table contents:\n");
879 	while (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data,  indx++, &sym) != NULL) {
880 		if ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, sym.st_name)) == NULL)
881 			printf("sym.st_name %u indx %d sym.st_size %lu\n",sym.st_name,indx,(u_long) sym.st_size);
882 		else
883 			printf("'%s' sym.st_name %u indx %d sym.st_size %lu\n",name,sym.st_name,indx,(u_long) sym.st_size);
884 	}
885 }
886 
887 void
dwarf_dump(Dwarf_Debug dbg)888 dwarf_dump(Dwarf_Debug dbg)
889 {
890 	dwarf_dump_strtab(dbg);
891 	dwarf_dump_shstrtab(dbg);
892 	dwarf_dump_dbgstr(dbg);
893 	dwarf_dump_symtab(dbg);
894 	dwarf_dump_info(dbg);
895 }
896