• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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
handle(Dwarf * dbg,Dwarf_Die * die,int n)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
main(int argc,char * argv[])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