Home | History | Annotate | Download | only in tests
      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 (at) 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 
     38 static 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 
    102 const 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 
    224 void
    225 handle (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 
    478 int
    479 main (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