1/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Red Hat, Inc. 2 This file is part of Red Hat elfutils. 3 Written by Ulrich Drepper <drepper@redhat.com>, 1998. 4 5 Red Hat elfutils is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by the 7 Free Software Foundation; version 2 of the License. 8 9 Red Hat elfutils is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along 15 with Red Hat elfutils; if not, write to the Free Software Foundation, 16 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 17 18 Red Hat elfutils is an included package of the Open Invention Network. 19 An included package of the Open Invention Network is a package for which 20 Open Invention Network licensees cross-license their patents. No patent 21 license is granted, either expressly or impliedly, by designation as an 22 included package. Should you wish to participate in the Open Invention 23 Network licensing program, please visit www.openinventionnetwork.com 24 <http://www.openinventionnetwork.com>. */ 25 26#include <config.h> 27 28#include <dwarf.h> 29#include <inttypes.h> 30#include <libelf.h> 31#include ELFUTILS_HEADER(dw) 32#include <fcntl.h> 33#include <stdio.h> 34#include <string.h> 35#include <unistd.h> 36 37 38static const char *tagnames[] = 39{ 40 [DW_TAG_array_type] = "DW_TAG_array_type", 41 [DW_TAG_class_type] = "DW_TAG_class_type", 42 [DW_TAG_entry_point] = "DW_TAG_entry_point", 43 [DW_TAG_enumeration_type] = "DW_TAG_enumeration_type", 44 [DW_TAG_formal_parameter] = "DW_TAG_formal_parameter", 45 [DW_TAG_imported_declaration] = "DW_TAG_imported_declaration", 46 [DW_TAG_label] = "DW_TAG_label", 47 [DW_TAG_lexical_block] = "DW_TAG_lexical_block", 48 [DW_TAG_member] = "DW_TAG_member", 49 [DW_TAG_pointer_type] = "DW_TAG_pointer_type", 50 [DW_TAG_reference_type] = "DW_TAG_reference_type", 51 [DW_TAG_compile_unit] = "DW_TAG_compile_unit", 52 [DW_TAG_string_type] = "DW_TAG_string_type", 53 [DW_TAG_structure_type] = "DW_TAG_structure_type", 54 [DW_TAG_subroutine_type] = "DW_TAG_subroutine_type", 55 [DW_TAG_typedef] = "DW_TAG_typedef", 56 [DW_TAG_union_type] = "DW_TAG_union_type", 57 [DW_TAG_unspecified_parameters] = "DW_TAG_unspecified_parameters", 58 [DW_TAG_variant] = "DW_TAG_variant", 59 [DW_TAG_common_block] = "DW_TAG_common_block", 60 [DW_TAG_common_inclusion] = "DW_TAG_common_inclusion", 61 [DW_TAG_inheritance] = "DW_TAG_inheritance", 62 [DW_TAG_inlined_subroutine] = "DW_TAG_inlined_subroutine", 63 [DW_TAG_module] = "DW_TAG_module", 64 [DW_TAG_ptr_to_member_type] = "DW_TAG_ptr_to_member_type", 65 [DW_TAG_set_type] = "DW_TAG_set_type", 66 [DW_TAG_subrange_type] = "DW_TAG_subrange_type", 67 [DW_TAG_with_stmt] = "DW_TAG_with_stmt", 68 [DW_TAG_access_declaration] = "DW_TAG_access_declaration", 69 [DW_TAG_base_type] = "DW_TAG_base_type", 70 [DW_TAG_catch_block] = "DW_TAG_catch_block", 71 [DW_TAG_const_type] = "DW_TAG_const_type", 72 [DW_TAG_constant] = "DW_TAG_constant", 73 [DW_TAG_enumerator] = "DW_TAG_enumerator", 74 [DW_TAG_file_type] = "DW_TAG_file_type", 75 [DW_TAG_friend] = "DW_TAG_friend", 76 [DW_TAG_namelist] = "DW_TAG_namelist", 77 [DW_TAG_namelist_item] = "DW_TAG_namelist_item", 78 [DW_TAG_packed_type] = "DW_TAG_packed_type", 79 [DW_TAG_subprogram] = "DW_TAG_subprogram", 80 [DW_TAG_template_type_parameter] = "DW_TAG_template_type_parameter", 81 [DW_TAG_template_value_parameter] = "DW_TAG_template_value_parameter", 82 [DW_TAG_thrown_type] = "DW_TAG_thrown_type", 83 [DW_TAG_try_block] = "DW_TAG_try_block", 84 [DW_TAG_variant_part] = "DW_TAG_variant_part", 85 [DW_TAG_variable] = "DW_TAG_variable", 86 [DW_TAG_volatile_type] = "DW_TAG_volatile_type", 87 [DW_TAG_dwarf_procedure] = "DW_TAG_dwarf_procedure", 88 [DW_TAG_restrict_type] = "DW_TAG_restrict_type", 89 [DW_TAG_interface_type] = "DW_TAG_interface_type", 90 [DW_TAG_namespace] = "DW_TAG_namespace", 91 [DW_TAG_imported_module] = "DW_TAG_imported_module", 92 [DW_TAG_unspecified_type] = "DW_TAG_unspecified_type", 93 [DW_TAG_partial_unit] = "DW_TAG_partial_unit", 94 [DW_TAG_imported_unit] = "DW_TAG_imported_unit", 95 [DW_TAG_mutable_type] = "DW_TAG_mutable_type", 96 [DW_TAG_condition] = "DW_TAG_condition", 97 [DW_TAG_shared_type] = "DW_TAG_shared_type", 98}; 99#define ntagnames (sizeof (tagnames) / sizeof (tagnames[0])) 100 101 102const struct 103{ 104 int code; 105 const char *name; 106} attrs[] = 107{ 108 { DW_AT_sibling, "sibling" }, 109 { DW_AT_location, "location" }, 110 { DW_AT_name, "name" }, 111 { DW_AT_ordering, "ordering" }, 112 { DW_AT_subscr_data, "subscr_data" }, 113 { DW_AT_byte_size, "byte_size" }, 114 { DW_AT_bit_offset, "bit_offset" }, 115 { DW_AT_bit_size, "bit_size" }, 116 { DW_AT_element_list, "element_list" }, 117 { DW_AT_stmt_list, "stmt_list" }, 118 { DW_AT_low_pc, "low_pc" }, 119 { DW_AT_high_pc, "high_pc" }, 120 { DW_AT_language, "language" }, 121 { DW_AT_member, "member" }, 122 { DW_AT_discr, "discr" }, 123 { DW_AT_discr_value, "discr_value" }, 124 { DW_AT_visibility, "visibility" }, 125 { DW_AT_import, "import" }, 126 { DW_AT_string_length, "string_length" }, 127 { DW_AT_common_reference, "common_reference" }, 128 { DW_AT_comp_dir, "comp_dir" }, 129 { DW_AT_const_value, "const_value" }, 130 { DW_AT_containing_type, "containing_type" }, 131 { DW_AT_default_value, "default_value" }, 132 { DW_AT_inline, "inline" }, 133 { DW_AT_is_optional, "is_optional" }, 134 { DW_AT_lower_bound, "lower_bound" }, 135 { DW_AT_producer, "producer" }, 136 { DW_AT_prototyped, "prototyped" }, 137 { DW_AT_return_addr, "return_addr" }, 138 { DW_AT_start_scope, "start_scope" }, 139 { DW_AT_bit_stride, "bit_stride" }, 140 { DW_AT_upper_bound, "upper_bound" }, 141 { DW_AT_abstract_origin, "abstract_origin" }, 142 { DW_AT_accessibility, "accessibility" }, 143 { DW_AT_address_class, "address_class" }, 144 { DW_AT_artificial, "artificial" }, 145 { DW_AT_base_types, "base_types" }, 146 { DW_AT_calling_convention, "calling_convention" }, 147 { DW_AT_count, "count" }, 148 { DW_AT_data_member_location, "data_member_location" }, 149 { DW_AT_decl_column, "decl_column" }, 150 { DW_AT_decl_file, "decl_file" }, 151 { DW_AT_decl_line, "decl_line" }, 152 { DW_AT_declaration, "declaration" }, 153 { DW_AT_discr_list, "discr_list" }, 154 { DW_AT_encoding, "encoding" }, 155 { DW_AT_external, "external" }, 156 { DW_AT_frame_base, "frame_base" }, 157 { DW_AT_friend, "friend" }, 158 { DW_AT_identifier_case, "identifier_case" }, 159 { DW_AT_macro_info, "macro_info" }, 160 { DW_AT_namelist_item, "namelist_item" }, 161 { DW_AT_priority, "priority" }, 162 { DW_AT_segment, "segment" }, 163 { DW_AT_specification, "specification" }, 164 { DW_AT_static_link, "static_link" }, 165 { DW_AT_type, "type" }, 166 { DW_AT_use_location, "use_location" }, 167 { DW_AT_variable_parameter, "variable_parameter" }, 168 { DW_AT_virtuality, "virtuality" }, 169 { DW_AT_vtable_elem_location, "vtable_elem_location" }, 170 { DW_AT_allocated, "allocated" }, 171 { DW_AT_associated, "associated" }, 172 { DW_AT_data_location, "data_location" }, 173 { DW_AT_byte_stride, "byte_stride" }, 174 { DW_AT_entry_pc, "entry_pc" }, 175 { DW_AT_use_UTF8, "use_UTF8" }, 176 { DW_AT_extension, "extension" }, 177 { DW_AT_ranges, "ranges" }, 178 { DW_AT_trampoline, "trampoline" }, 179 { DW_AT_call_column, "call_column" }, 180 { DW_AT_call_file, "call_file" }, 181 { DW_AT_call_line, "call_line" }, 182 { DW_AT_description, "description" }, 183 { DW_AT_binary_scale, "binary_scale" }, 184 { DW_AT_decimal_scale, "decimal_scale" }, 185 { DW_AT_small, "small" }, 186 { DW_AT_decimal_sign, "decimal_sign" }, 187 { DW_AT_digit_count, "digit_count" }, 188 { DW_AT_picture_string, "picture_string" }, 189 { DW_AT_mutable, "mutable" }, 190 { DW_AT_threads_scaled, "threads_scaled" }, 191 { DW_AT_explicit, "explicit" }, 192 { DW_AT_object_pointer, "object_pointer" }, 193 { DW_AT_endianity, "endianity" }, 194 { DW_AT_elemental, "elemental" }, 195 { DW_AT_pure, "pure" }, 196 { DW_AT_recursive, "recursive" }, 197 { DW_AT_MIPS_fde, "MIPS_fde" }, 198 { DW_AT_MIPS_loop_begin, "MIPS_loop_begin" }, 199 { DW_AT_MIPS_tail_loop_begin, "MIPS_tail_loop_begin" }, 200 { DW_AT_MIPS_epilog_begin, "MIPS_epilog_begin" }, 201 { DW_AT_MIPS_loop_unroll_factor, "MIPS_loop_unroll_factor" }, 202 { DW_AT_MIPS_software_pipeline_depth, "MIPS_software_pipeline_depth" }, 203 { DW_AT_MIPS_linkage_name, "MIPS_linkage_name" }, 204 { DW_AT_MIPS_stride, "MIPS_stride" }, 205 { DW_AT_MIPS_abstract_name, "MIPS_abstract_name" }, 206 { DW_AT_MIPS_clone_origin, "MIPS_clone_origin" }, 207 { DW_AT_MIPS_has_inlines, "MIPS_has_inlines" }, 208 { DW_AT_MIPS_stride_byte, "MIPS_stride_byte" }, 209 { DW_AT_MIPS_stride_elem, "MIPS_stride_elem" }, 210 { DW_AT_MIPS_ptr_dopetype, "MIPS_ptr_dopetype" }, 211 { DW_AT_MIPS_allocatable_dopetype, "MIPS_allocatable_dopetype" }, 212 { DW_AT_MIPS_assumed_shape_dopetype, "MIPS_assumed_shape_dopetype" }, 213 { DW_AT_MIPS_assumed_size, "MIPS_assumed_size" }, 214 { DW_AT_sf_names, "sf_names" }, 215 { DW_AT_src_info, "src_info" }, 216 { DW_AT_mac_info, "mac_info" }, 217 { DW_AT_src_coords, "src_coords" }, 218 { DW_AT_body_begin, "body_begin" }, 219 { DW_AT_body_end, "body_end" }, 220}; 221#define nattrs (sizeof (attrs) / sizeof (attrs[0])) 222 223 224void 225handle (Dwarf *dbg, Dwarf_Die *die, int n) 226{ 227 Dwarf_Die child; 228 unsigned int tag; 229 const char *str; 230 char buf[30]; 231 const char *name; 232 Dwarf_Off off; 233 Dwarf_Off cuoff; 234 size_t cnt; 235 Dwarf_Addr addr; 236 int i; 237 238 tag = dwarf_tag (die); 239 if (tag != DW_TAG_invalid) 240 { 241 if (tag < ntagnames) 242 str = tagnames[tag]; 243 else 244 { 245 snprintf (buf, sizeof buf, "%#x", tag); 246 str = buf; 247 } 248 } 249 else 250 str = "* NO TAG *"; 251 252 name = dwarf_diename (die); 253 if (name == 0) 254 name = "* NO NAME *"; 255 256 off = dwarf_dieoffset (die); 257 cuoff = dwarf_cuoffset (die); 258 259 printf ("%*s%s\n", n * 5, "", str); 260 printf ("%*s Name : %s\n", n * 5, "", name); 261 printf ("%*s Offset : %lld\n", n * 5, "", (long long int) off); 262 printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff); 263 264 printf ("%*s Attrs :", n * 5, ""); 265 for (cnt = 0; cnt < nattrs; ++cnt) 266 if (dwarf_hasattr (die, attrs[cnt].code)) 267 printf (" %s", attrs[cnt].name); 268 puts (""); 269 270 if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0) 271 { 272 Dwarf_Attribute attr; 273 Dwarf_Addr addr2; 274 printf ("%*s low PC : %#llx\n", 275 n * 5, "", (unsigned long long int) addr); 276 277 if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL 278 || dwarf_formaddr (&attr, &addr2) != 0 279 || addr != addr2) 280 puts ("************* DW_AT_low_pc verify failed ************"); 281 else if (! dwarf_hasform (&attr, DW_FORM_addr)) 282 puts ("************* DW_AT_low_pc form failed ************"); 283 else if (dwarf_whatform (&attr) != DW_FORM_addr) 284 puts ("************* DW_AT_low_pc form (2) failed ************"); 285 else if (dwarf_whatattr (&attr) != DW_AT_low_pc) 286 puts ("************* DW_AT_low_pc attr failed ************"); 287 } 288 if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0) 289 { 290 Dwarf_Attribute attr; 291 Dwarf_Addr addr2; 292 printf ("%*s high PC : %#llx\n", 293 n * 5, "", (unsigned long long int) addr); 294 if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL 295 || dwarf_formaddr (&attr, &addr2) != 0 296 || addr != addr2) 297 puts ("************* DW_AT_high_pc verify failed ************"); 298 else if (! dwarf_hasform (&attr, DW_FORM_addr)) 299 puts ("************* DW_AT_high_pc form failed ************"); 300 else if (dwarf_whatform (&attr) != DW_FORM_addr) 301 puts ("************* DW_AT_high_pc form (2) failed ************"); 302 else if (dwarf_whatattr (&attr) != DW_AT_high_pc) 303 puts ("************* DW_AT_high_pc attr failed ************"); 304 } 305 306 if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1) 307 { 308 Dwarf_Attribute attr; 309 Dwarf_Word u2; 310 unsigned int u; 311 printf ("%*s byte size : %d\n", n * 5, "", i); 312 if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL 313 || dwarf_formudata (&attr, &u2) != 0 314 || i != (int) u2) 315 puts ("************* DW_AT_byte_size verify failed ************"); 316 else if (! dwarf_hasform (&attr, DW_FORM_data1) 317 && ! dwarf_hasform (&attr, DW_FORM_data2) 318 && ! dwarf_hasform (&attr, DW_FORM_data4) 319 && ! dwarf_hasform (&attr, DW_FORM_data8) 320 && ! dwarf_hasform (&attr, DW_FORM_sdata) 321 && ! dwarf_hasform (&attr, DW_FORM_udata)) 322 puts ("************* DW_AT_byte_size form failed ************"); 323 else if ((u = dwarf_whatform (&attr)) == 0 324 || (u != DW_FORM_data1 325 && u != DW_FORM_data2 326 && u != DW_FORM_data4 327 && u != DW_FORM_data8 328 && u != DW_FORM_sdata 329 && u != DW_FORM_udata)) 330 puts ("************* DW_AT_byte_size form (2) failed ************"); 331 else if (dwarf_whatattr (&attr) != DW_AT_byte_size) 332 puts ("************* DW_AT_byte_size attr failed ************"); 333 } 334 if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1) 335 { 336 Dwarf_Attribute attr; 337 Dwarf_Word u2; 338 unsigned int u; 339 printf ("%*s bit size : %d\n", n * 5, "", i); 340 if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL 341 || dwarf_formudata (&attr, &u2) != 0 342 || i != (int) u2) 343 puts ("************* DW_AT_bit_size test failed ************"); 344 else if (! dwarf_hasform (&attr, DW_FORM_data1) 345 && ! dwarf_hasform (&attr, DW_FORM_data2) 346 && ! dwarf_hasform (&attr, DW_FORM_data4) 347 && ! dwarf_hasform (&attr, DW_FORM_data8) 348 && ! dwarf_hasform (&attr, DW_FORM_sdata) 349 && ! dwarf_hasform (&attr, DW_FORM_udata)) 350 puts ("************* DW_AT_bit_size form failed ************"); 351 else if ((u = dwarf_whatform (&attr)) == 0 352 || (u != DW_FORM_data1 353 && u != DW_FORM_data2 354 && u != DW_FORM_data4 355 && u != DW_FORM_data8 356 && u != DW_FORM_sdata 357 && u != DW_FORM_udata)) 358 puts ("************* DW_AT_bit_size form (2) failed ************"); 359 else if (dwarf_whatattr (&attr) != DW_AT_bit_size) 360 puts ("************* DW_AT_bit_size attr failed ************"); 361 } 362 if (dwarf_hasattr (die, DW_AT_bit_offset) 363 && (i = dwarf_bitoffset (die)) != -1) 364 { 365 Dwarf_Attribute attr; 366 Dwarf_Word u2; 367 unsigned int u; 368 printf ("%*s bit offset: %d\n", n * 5, "", i); 369 if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL 370 || dwarf_formudata (&attr, &u2) != 0 371 || i != (int) u2) 372 puts ("************* DW_AT_bit_offset test failed ************"); 373 else if (! dwarf_hasform (&attr, DW_FORM_data1) 374 && ! dwarf_hasform (&attr, DW_FORM_data2) 375 && ! dwarf_hasform (&attr, DW_FORM_data4) 376 && ! dwarf_hasform (&attr, DW_FORM_data8) 377 && ! dwarf_hasform (&attr, DW_FORM_sdata) 378 && ! dwarf_hasform (&attr, DW_FORM_udata)) 379 puts ("************* DW_AT_bit_offset form failed ************"); 380 else if ((u = dwarf_whatform (&attr)) == 0 381 || (u != DW_FORM_data1 382 && u != DW_FORM_data2 383 && u != DW_FORM_data4 384 && u != DW_FORM_data8 385 && u != DW_FORM_sdata 386 && u != DW_FORM_udata)) 387 puts ("************* DW_AT_bit_offset form (2) failed ************"); 388 else if (dwarf_whatattr (&attr) != DW_AT_bit_offset) 389 puts ("************* DW_AT_bit_offset attr failed ************"); 390 } 391 392 if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1) 393 { 394 Dwarf_Attribute attr; 395 Dwarf_Word u2; 396 unsigned int u; 397 printf ("%*s language : %d\n", n * 5, "", i); 398 if (dwarf_attr (die, DW_AT_language, &attr) == NULL 399 || dwarf_formudata (&attr, &u2) != 0 400 || i != (int) u2) 401 puts ("************* DW_AT_language test failed ************"); 402 else if (! dwarf_hasform (&attr, DW_FORM_data1) 403 && ! dwarf_hasform (&attr, DW_FORM_data2) 404 && ! dwarf_hasform (&attr, DW_FORM_data4) 405 && ! dwarf_hasform (&attr, DW_FORM_data8) 406 && ! dwarf_hasform (&attr, DW_FORM_sdata) 407 && ! dwarf_hasform (&attr, DW_FORM_udata)) 408 puts ("************* DW_AT_language form failed ************"); 409 else if ((u = dwarf_whatform (&attr)) == 0 410 || (u != DW_FORM_data1 411 && u != DW_FORM_data2 412 && u != DW_FORM_data4 413 && u != DW_FORM_data8 414 && u != DW_FORM_sdata 415 && u != DW_FORM_udata)) 416 puts ("************* DW_AT_language form (2) failed ************"); 417 else if (dwarf_whatattr (&attr) != DW_AT_language) 418 puts ("************* DW_AT_language attr failed ************"); 419 } 420 421 if (dwarf_hasattr (die, DW_AT_ordering) 422 && (i = dwarf_arrayorder (die)) != -1) 423 { 424 Dwarf_Attribute attr; 425 Dwarf_Word u2; 426 unsigned int u; 427 printf ("%*s ordering : %d\n", n * 5, "", i); 428 if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL 429 || dwarf_formudata (&attr, &u2) != 0 430 || i != (int) u2) 431 puts ("************* DW_AT_ordering test failed ************"); 432 else if (! dwarf_hasform (&attr, DW_FORM_data1) 433 && ! dwarf_hasform (&attr, DW_FORM_data2) 434 && ! dwarf_hasform (&attr, DW_FORM_data4) 435 && ! dwarf_hasform (&attr, DW_FORM_data8) 436 && ! dwarf_hasform (&attr, DW_FORM_sdata) 437 && ! dwarf_hasform (&attr, DW_FORM_udata)) 438 puts ("************* DW_AT_ordering failed ************"); 439 else if ((u = dwarf_whatform (&attr)) == 0 440 || (u != DW_FORM_data1 441 && u != DW_FORM_data2 442 && u != DW_FORM_data4 443 && u != DW_FORM_data8 444 && u != DW_FORM_sdata 445 && u != DW_FORM_udata)) 446 puts ("************* DW_AT_ordering form (2) failed ************"); 447 else if (dwarf_whatattr (&attr) != DW_AT_ordering) 448 puts ("************* DW_AT_ordering attr failed ************"); 449 } 450 451 if (dwarf_hasattr (die, DW_AT_comp_dir)) 452 { 453 Dwarf_Attribute attr; 454 if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL 455 || (name = dwarf_formstring (&attr)) == NULL) 456 puts ("************* DW_AT_comp_dir attr failed ************"); 457 else 458 printf ("%*s directory : %s\n", n * 5, "", name); 459 } 460 461 if (dwarf_hasattr (die, DW_AT_producer)) 462 { 463 Dwarf_Attribute attr; 464 if (dwarf_attr (die, DW_AT_producer, &attr) == NULL 465 || (name = dwarf_formstring (&attr)) == NULL) 466 puts ("************* DW_AT_comp_dir attr failed ************"); 467 else 468 printf ("%*s producer : %s\n", n * 5, "", name); 469 } 470 471 if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0) 472 handle (dbg, &child, n + 1); 473 if (dwarf_siblingof (die, die) == 0) 474 handle (dbg, die, n); 475} 476 477 478int 479main (int argc, char *argv[]) 480{ 481 int cnt; 482 483 for (cnt = 1; cnt < argc; ++cnt) 484 { 485 int fd = open (argv[cnt], O_RDONLY); 486 Dwarf *dbg; 487 488 printf ("file: %s\n", basename (argv[cnt])); 489 490 dbg = dwarf_begin (fd, DWARF_C_READ); 491 if (dbg == NULL) 492 { 493 printf ("%s not usable\n", argv[cnt]); 494 close (fd); 495 continue; 496 } 497 498 Dwarf_Off off = 0; 499 Dwarf_Off old_off = 0; 500 size_t hsize; 501 Dwarf_Off abbrev; 502 uint8_t addresssize; 503 uint8_t offsetsize; 504 while (dwarf_nextcu (dbg, off, &off, &hsize, &abbrev, &addresssize, 505 &offsetsize) == 0) 506 { 507 printf ("New CU: off = %llu, hsize = %zu, ab = %llu, as = %" PRIu8 508 ", os = %" PRIu8 "\n", 509 (unsigned long long int) old_off, hsize, 510 (unsigned long long int) abbrev, addresssize, 511 offsetsize); 512 513 Dwarf_Die die; 514 if (dwarf_offdie (dbg, old_off + hsize, &die) != NULL) 515 handle (dbg, &die, 1); 516 517 old_off = off; 518 } 519 520 dwarf_end (dbg); 521 close (fd); 522 } 523 524 return 0; 525} 526