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