1da0c48c4Sopenharmony_ci/* Copyright (C) 1998-2002, 2004, 2006, 2012, 2015 Red Hat, Inc.
2da0c48c4Sopenharmony_ci   This file is part of elfutils.
3da0c48c4Sopenharmony_ci   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
4da0c48c4Sopenharmony_ci
5da0c48c4Sopenharmony_ci   This file is free software; you can redistribute it and/or modify
6da0c48c4Sopenharmony_ci   it under the terms of the GNU General Public License as published by
7da0c48c4Sopenharmony_ci   the Free Software Foundation; either version 3 of the License, or
8da0c48c4Sopenharmony_ci   (at your option) any later version.
9da0c48c4Sopenharmony_ci
10da0c48c4Sopenharmony_ci   elfutils is distributed in the hope that it will be useful, but
11da0c48c4Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
12da0c48c4Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13da0c48c4Sopenharmony_ci   GNU General Public License for more details.
14da0c48c4Sopenharmony_ci
15da0c48c4Sopenharmony_ci   You should have received a copy of the GNU General Public License
16da0c48c4Sopenharmony_ci   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17da0c48c4Sopenharmony_ci
18da0c48c4Sopenharmony_ci#include <config.h>
19da0c48c4Sopenharmony_ci
20da0c48c4Sopenharmony_ci#include <dwarf.h>
21da0c48c4Sopenharmony_ci#include <inttypes.h>
22da0c48c4Sopenharmony_ci#include <libelf.h>
23da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(dw)
24da0c48c4Sopenharmony_ci#include <fcntl.h>
25da0c48c4Sopenharmony_ci#include <stdio.h>
26da0c48c4Sopenharmony_ci#include <string.h>
27da0c48c4Sopenharmony_ci#include <unistd.h>
28da0c48c4Sopenharmony_ci
29da0c48c4Sopenharmony_ci#include "../libdw/known-dwarf.h"
30da0c48c4Sopenharmony_ci
31da0c48c4Sopenharmony_cistatic const char *
32da0c48c4Sopenharmony_cidwarf_tag_string (unsigned int tag)
33da0c48c4Sopenharmony_ci{
34da0c48c4Sopenharmony_ci  switch (tag)
35da0c48c4Sopenharmony_ci    {
36da0c48c4Sopenharmony_ci#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
37da0c48c4Sopenharmony_ci      DWARF_ALL_KNOWN_DW_TAG
38da0c48c4Sopenharmony_ci#undef DWARF_ONE_KNOWN_DW_TAG
39da0c48c4Sopenharmony_ci    default:
40da0c48c4Sopenharmony_ci      return NULL;
41da0c48c4Sopenharmony_ci    }
42da0c48c4Sopenharmony_ci}
43da0c48c4Sopenharmony_ci
44da0c48c4Sopenharmony_cistatic const char *
45da0c48c4Sopenharmony_cidwarf_attr_string (unsigned int attrnum)
46da0c48c4Sopenharmony_ci{
47da0c48c4Sopenharmony_ci  switch (attrnum)
48da0c48c4Sopenharmony_ci    {
49da0c48c4Sopenharmony_ci#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
50da0c48c4Sopenharmony_ci      DWARF_ALL_KNOWN_DW_AT
51da0c48c4Sopenharmony_ci#undef DWARF_ONE_KNOWN_DW_AT
52da0c48c4Sopenharmony_ci    default:
53da0c48c4Sopenharmony_ci      return NULL;
54da0c48c4Sopenharmony_ci    }
55da0c48c4Sopenharmony_ci}
56da0c48c4Sopenharmony_ci
57da0c48c4Sopenharmony_ci
58da0c48c4Sopenharmony_civoid
59da0c48c4Sopenharmony_cihandle (Dwarf *dbg, Dwarf_Die *die, int n)
60da0c48c4Sopenharmony_ci{
61da0c48c4Sopenharmony_ci  Dwarf_Die child;
62da0c48c4Sopenharmony_ci  unsigned int tag;
63da0c48c4Sopenharmony_ci  const char *str;
64da0c48c4Sopenharmony_ci  char buf[30];
65da0c48c4Sopenharmony_ci  const char *name;
66da0c48c4Sopenharmony_ci  Dwarf_Off off;
67da0c48c4Sopenharmony_ci  Dwarf_Off cuoff;
68da0c48c4Sopenharmony_ci  size_t cnt;
69da0c48c4Sopenharmony_ci  Dwarf_Addr addr;
70da0c48c4Sopenharmony_ci  int i;
71da0c48c4Sopenharmony_ci
72da0c48c4Sopenharmony_ci  tag = dwarf_tag (die);
73da0c48c4Sopenharmony_ci  if (tag != DW_TAG_invalid)
74da0c48c4Sopenharmony_ci    {
75da0c48c4Sopenharmony_ci      str = dwarf_tag_string (tag);
76da0c48c4Sopenharmony_ci      if (str == NULL)
77da0c48c4Sopenharmony_ci	{
78da0c48c4Sopenharmony_ci	  snprintf (buf, sizeof buf, "%#x", tag);
79da0c48c4Sopenharmony_ci	  str = buf;
80da0c48c4Sopenharmony_ci	}
81da0c48c4Sopenharmony_ci    }
82da0c48c4Sopenharmony_ci  else
83da0c48c4Sopenharmony_ci    str = "* NO TAG *";
84da0c48c4Sopenharmony_ci
85da0c48c4Sopenharmony_ci  name = dwarf_diename (die);
86da0c48c4Sopenharmony_ci  if (name == 0)
87da0c48c4Sopenharmony_ci    name = "* NO NAME *";
88da0c48c4Sopenharmony_ci
89da0c48c4Sopenharmony_ci  off = dwarf_dieoffset (die);
90da0c48c4Sopenharmony_ci  cuoff = dwarf_cuoffset (die);
91da0c48c4Sopenharmony_ci
92da0c48c4Sopenharmony_ci  printf ("%*sDW_TAG_%s\n", n * 5, "", str);
93da0c48c4Sopenharmony_ci  printf ("%*s Name      : %s\n", n * 5, "", name);
94da0c48c4Sopenharmony_ci  printf ("%*s Offset    : %lld\n", n * 5, "", (long long int) off);
95da0c48c4Sopenharmony_ci  printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff);
96da0c48c4Sopenharmony_ci
97da0c48c4Sopenharmony_ci  printf ("%*s Attrs     :", n * 5, "");
98da0c48c4Sopenharmony_ci  for (cnt = 0; cnt < 0xffff; ++cnt)
99da0c48c4Sopenharmony_ci    if (dwarf_hasattr (die, cnt))
100da0c48c4Sopenharmony_ci      printf (" %s", dwarf_attr_string (cnt) ?: "<unknown>");
101da0c48c4Sopenharmony_ci  puts ("");
102da0c48c4Sopenharmony_ci
103da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0)
104da0c48c4Sopenharmony_ci    {
105da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
106da0c48c4Sopenharmony_ci      Dwarf_Addr addr2;
107da0c48c4Sopenharmony_ci      printf ("%*s low PC    : %#llx\n",
108da0c48c4Sopenharmony_ci	      n * 5, "", (unsigned long long int) addr);
109da0c48c4Sopenharmony_ci
110da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL
111da0c48c4Sopenharmony_ci	  || dwarf_formaddr (&attr, &addr2) != 0
112da0c48c4Sopenharmony_ci	  || addr != addr2)
113da0c48c4Sopenharmony_ci	puts ("************* DW_AT_low_pc verify failed ************");
114da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_addr))
115da0c48c4Sopenharmony_ci	puts ("************* DW_AT_low_pc form failed ************");
116da0c48c4Sopenharmony_ci      else if (dwarf_whatform (&attr) != DW_FORM_addr)
117da0c48c4Sopenharmony_ci	puts ("************* DW_AT_low_pc form (2) failed ************");
118da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_low_pc)
119da0c48c4Sopenharmony_ci	puts ("************* DW_AT_low_pc attr failed ************");
120da0c48c4Sopenharmony_ci    }
121da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0)
122da0c48c4Sopenharmony_ci    {
123da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
124da0c48c4Sopenharmony_ci      Dwarf_Addr addr2;
125da0c48c4Sopenharmony_ci      printf ("%*s high PC   : %#llx\n",
126da0c48c4Sopenharmony_ci	      n * 5, "", (unsigned long long int) addr);
127da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL
128da0c48c4Sopenharmony_ci	  || dwarf_formaddr (&attr, &addr2) != 0
129da0c48c4Sopenharmony_ci	  || addr != addr2)
130da0c48c4Sopenharmony_ci	puts ("************* DW_AT_high_pc verify failed ************");
131da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_addr))
132da0c48c4Sopenharmony_ci	puts ("************* DW_AT_high_pc form failed ************");
133da0c48c4Sopenharmony_ci      else if (dwarf_whatform (&attr) != DW_FORM_addr)
134da0c48c4Sopenharmony_ci	puts ("************* DW_AT_high_pc form (2) failed ************");
135da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_high_pc)
136da0c48c4Sopenharmony_ci	puts ("************* DW_AT_high_pc attr failed ************");
137da0c48c4Sopenharmony_ci    }
138da0c48c4Sopenharmony_ci
139da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1)
140da0c48c4Sopenharmony_ci    {
141da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
142da0c48c4Sopenharmony_ci      Dwarf_Word u2;
143da0c48c4Sopenharmony_ci      unsigned int u;
144da0c48c4Sopenharmony_ci      printf ("%*s byte size : %d\n", n * 5, "", i);
145da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL
146da0c48c4Sopenharmony_ci	  || dwarf_formudata (&attr, &u2) != 0
147da0c48c4Sopenharmony_ci	  || i != (int) u2)
148da0c48c4Sopenharmony_ci	puts ("************* DW_AT_byte_size verify failed ************");
149da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_data1)
150da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data2)
151da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data4)
152da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data8)
153da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
154da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_udata))
155da0c48c4Sopenharmony_ci	puts ("************* DW_AT_byte_size form failed ************");
156da0c48c4Sopenharmony_ci      else if ((u = dwarf_whatform (&attr)) == 0
157da0c48c4Sopenharmony_ci	       || (u != DW_FORM_data1
158da0c48c4Sopenharmony_ci		   && u != DW_FORM_data2
159da0c48c4Sopenharmony_ci		   && u != DW_FORM_data4
160da0c48c4Sopenharmony_ci		   && u != DW_FORM_data8
161da0c48c4Sopenharmony_ci		   && u != DW_FORM_sdata
162da0c48c4Sopenharmony_ci		   && u != DW_FORM_udata))
163da0c48c4Sopenharmony_ci	puts ("************* DW_AT_byte_size form (2) failed ************");
164da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_byte_size)
165da0c48c4Sopenharmony_ci	puts ("************* DW_AT_byte_size attr failed ************");
166da0c48c4Sopenharmony_ci    }
167da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1)
168da0c48c4Sopenharmony_ci    {
169da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
170da0c48c4Sopenharmony_ci      Dwarf_Word u2;
171da0c48c4Sopenharmony_ci      unsigned int u;
172da0c48c4Sopenharmony_ci      printf ("%*s bit size  : %d\n", n * 5, "", i);
173da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL
174da0c48c4Sopenharmony_ci	  || dwarf_formudata (&attr, &u2) != 0
175da0c48c4Sopenharmony_ci	  || i != (int) u2)
176da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_size test failed ************");
177da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_data1)
178da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data2)
179da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data4)
180da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data8)
181da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
182da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_udata))
183da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_size form failed ************");
184da0c48c4Sopenharmony_ci      else if ((u = dwarf_whatform (&attr)) == 0
185da0c48c4Sopenharmony_ci	       || (u != DW_FORM_data1
186da0c48c4Sopenharmony_ci		   && u != DW_FORM_data2
187da0c48c4Sopenharmony_ci		   && u != DW_FORM_data4
188da0c48c4Sopenharmony_ci		   && u != DW_FORM_data8
189da0c48c4Sopenharmony_ci		   && u != DW_FORM_sdata
190da0c48c4Sopenharmony_ci		   && u != DW_FORM_udata))
191da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_size form (2) failed ************");
192da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_bit_size)
193da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_size attr failed ************");
194da0c48c4Sopenharmony_ci    }
195da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_bit_offset)
196da0c48c4Sopenharmony_ci      && (i = dwarf_bitoffset (die)) != -1)
197da0c48c4Sopenharmony_ci    {
198da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
199da0c48c4Sopenharmony_ci      Dwarf_Word u2;
200da0c48c4Sopenharmony_ci      unsigned int u;
201da0c48c4Sopenharmony_ci      printf ("%*s bit offset: %d\n", n * 5, "", i);
202da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL
203da0c48c4Sopenharmony_ci	  || dwarf_formudata (&attr, &u2) != 0
204da0c48c4Sopenharmony_ci	  || i != (int) u2)
205da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_offset test failed ************");
206da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_data1)
207da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data2)
208da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data4)
209da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data8)
210da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
211da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_udata))
212da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_offset form failed ************");
213da0c48c4Sopenharmony_ci      else if ((u = dwarf_whatform (&attr)) == 0
214da0c48c4Sopenharmony_ci	       || (u != DW_FORM_data1
215da0c48c4Sopenharmony_ci		   && u != DW_FORM_data2
216da0c48c4Sopenharmony_ci		   && u != DW_FORM_data4
217da0c48c4Sopenharmony_ci		   && u != DW_FORM_data8
218da0c48c4Sopenharmony_ci		   && u != DW_FORM_sdata
219da0c48c4Sopenharmony_ci		   && u != DW_FORM_udata))
220da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_offset form (2) failed ************");
221da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_bit_offset)
222da0c48c4Sopenharmony_ci	puts ("************* DW_AT_bit_offset attr failed ************");
223da0c48c4Sopenharmony_ci    }
224da0c48c4Sopenharmony_ci
225da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1)
226da0c48c4Sopenharmony_ci    {
227da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
228da0c48c4Sopenharmony_ci      Dwarf_Word u2;
229da0c48c4Sopenharmony_ci      unsigned int u;
230da0c48c4Sopenharmony_ci      printf ("%*s language  : %d\n", n * 5, "", i);
231da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_language, &attr) == NULL
232da0c48c4Sopenharmony_ci	  || dwarf_formudata (&attr, &u2) != 0
233da0c48c4Sopenharmony_ci	  || i != (int) u2)
234da0c48c4Sopenharmony_ci	puts ("************* DW_AT_language test failed ************");
235da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_data1)
236da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data2)
237da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data4)
238da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data8)
239da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
240da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_udata))
241da0c48c4Sopenharmony_ci	puts ("************* DW_AT_language form failed ************");
242da0c48c4Sopenharmony_ci      else if ((u = dwarf_whatform (&attr)) == 0
243da0c48c4Sopenharmony_ci	       || (u != DW_FORM_data1
244da0c48c4Sopenharmony_ci		   && u != DW_FORM_data2
245da0c48c4Sopenharmony_ci		   && u != DW_FORM_data4
246da0c48c4Sopenharmony_ci		   && u != DW_FORM_data8
247da0c48c4Sopenharmony_ci		   && u != DW_FORM_sdata
248da0c48c4Sopenharmony_ci		   && u != DW_FORM_udata))
249da0c48c4Sopenharmony_ci	puts ("************* DW_AT_language form (2) failed ************");
250da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_language)
251da0c48c4Sopenharmony_ci	puts ("************* DW_AT_language attr failed ************");
252da0c48c4Sopenharmony_ci    }
253da0c48c4Sopenharmony_ci
254da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_ordering)
255da0c48c4Sopenharmony_ci      && (i = dwarf_arrayorder (die)) != -1)
256da0c48c4Sopenharmony_ci    {
257da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
258da0c48c4Sopenharmony_ci      Dwarf_Word u2;
259da0c48c4Sopenharmony_ci      unsigned int u;
260da0c48c4Sopenharmony_ci      printf ("%*s ordering  : %d\n", n * 5, "", i);
261da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL
262da0c48c4Sopenharmony_ci	  || dwarf_formudata (&attr, &u2) != 0
263da0c48c4Sopenharmony_ci	  || i != (int) u2)
264da0c48c4Sopenharmony_ci	puts ("************* DW_AT_ordering test failed ************");
265da0c48c4Sopenharmony_ci      else if (! dwarf_hasform (&attr, DW_FORM_data1)
266da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data2)
267da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data4)
268da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_data8)
269da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
270da0c48c4Sopenharmony_ci	       && ! dwarf_hasform (&attr, DW_FORM_udata))
271da0c48c4Sopenharmony_ci	puts ("************* DW_AT_ordering failed ************");
272da0c48c4Sopenharmony_ci      else if ((u = dwarf_whatform (&attr)) == 0
273da0c48c4Sopenharmony_ci	       || (u != DW_FORM_data1
274da0c48c4Sopenharmony_ci		   && u != DW_FORM_data2
275da0c48c4Sopenharmony_ci		   && u != DW_FORM_data4
276da0c48c4Sopenharmony_ci		   && u != DW_FORM_data8
277da0c48c4Sopenharmony_ci		   && u != DW_FORM_sdata
278da0c48c4Sopenharmony_ci		   && u != DW_FORM_udata))
279da0c48c4Sopenharmony_ci	puts ("************* DW_AT_ordering form (2) failed ************");
280da0c48c4Sopenharmony_ci      else if (dwarf_whatattr (&attr) != DW_AT_ordering)
281da0c48c4Sopenharmony_ci	puts ("************* DW_AT_ordering attr failed ************");
282da0c48c4Sopenharmony_ci    }
283da0c48c4Sopenharmony_ci
284da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_comp_dir))
285da0c48c4Sopenharmony_ci    {
286da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
287da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL
288da0c48c4Sopenharmony_ci	  || (name = dwarf_formstring (&attr)) == NULL)
289da0c48c4Sopenharmony_ci	puts ("************* DW_AT_comp_dir attr failed ************");
290da0c48c4Sopenharmony_ci      else
291da0c48c4Sopenharmony_ci	printf ("%*s directory : %s\n", n * 5, "", name);
292da0c48c4Sopenharmony_ci    }
293da0c48c4Sopenharmony_ci
294da0c48c4Sopenharmony_ci  if (dwarf_hasattr (die, DW_AT_producer))
295da0c48c4Sopenharmony_ci    {
296da0c48c4Sopenharmony_ci      Dwarf_Attribute attr;
297da0c48c4Sopenharmony_ci      if (dwarf_attr (die, DW_AT_producer, &attr) == NULL
298da0c48c4Sopenharmony_ci	  || (name = dwarf_formstring (&attr)) == NULL)
299da0c48c4Sopenharmony_ci	puts ("************* DW_AT_comp_dir attr failed ************");
300da0c48c4Sopenharmony_ci      else
301da0c48c4Sopenharmony_ci	printf ("%*s producer  : %s\n", n * 5, "", name);
302da0c48c4Sopenharmony_ci    }
303da0c48c4Sopenharmony_ci
304da0c48c4Sopenharmony_ci  if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0)
305da0c48c4Sopenharmony_ci    handle (dbg, &child, n + 1);
306da0c48c4Sopenharmony_ci  if (dwarf_siblingof (die, die) == 0)
307da0c48c4Sopenharmony_ci    handle (dbg, die, n);
308da0c48c4Sopenharmony_ci}
309da0c48c4Sopenharmony_ci
310da0c48c4Sopenharmony_ci
311da0c48c4Sopenharmony_ciint
312da0c48c4Sopenharmony_cimain (int argc, char *argv[])
313da0c48c4Sopenharmony_ci{
314da0c48c4Sopenharmony_ci int cnt;
315da0c48c4Sopenharmony_ci
316da0c48c4Sopenharmony_ci  for (cnt = 1; cnt < argc; ++cnt)
317da0c48c4Sopenharmony_ci    {
318da0c48c4Sopenharmony_ci      int fd = open (argv[cnt], O_RDONLY);
319da0c48c4Sopenharmony_ci      Dwarf *dbg;
320da0c48c4Sopenharmony_ci
321da0c48c4Sopenharmony_ci      printf ("file: %s\n", basename (argv[cnt]));
322da0c48c4Sopenharmony_ci
323da0c48c4Sopenharmony_ci      dbg = dwarf_begin (fd, DWARF_C_READ);
324da0c48c4Sopenharmony_ci      if (dbg == NULL)
325da0c48c4Sopenharmony_ci	{
326da0c48c4Sopenharmony_ci	  printf ("%s not usable\n", argv[cnt]);
327da0c48c4Sopenharmony_ci	  close (fd);
328da0c48c4Sopenharmony_ci	  continue;
329da0c48c4Sopenharmony_ci	}
330da0c48c4Sopenharmony_ci
331da0c48c4Sopenharmony_ci      Dwarf_Off off = 0;
332da0c48c4Sopenharmony_ci      Dwarf_Off old_off = 0;
333da0c48c4Sopenharmony_ci      size_t hsize;
334da0c48c4Sopenharmony_ci      Dwarf_Off abbrev;
335da0c48c4Sopenharmony_ci      uint8_t addresssize;
336da0c48c4Sopenharmony_ci      uint8_t offsetsize;
337da0c48c4Sopenharmony_ci      while (dwarf_nextcu (dbg, off, &off, &hsize, &abbrev, &addresssize,
338da0c48c4Sopenharmony_ci			   &offsetsize) == 0)
339da0c48c4Sopenharmony_ci	{
340da0c48c4Sopenharmony_ci	  printf ("New CU: off = %llu, hsize = %zu, ab = %llu, as = %" PRIu8
341da0c48c4Sopenharmony_ci		  ", os = %" PRIu8 "\n",
342da0c48c4Sopenharmony_ci		  (unsigned long long int) old_off, hsize,
343da0c48c4Sopenharmony_ci		  (unsigned long long int) abbrev, addresssize,
344da0c48c4Sopenharmony_ci		  offsetsize);
345da0c48c4Sopenharmony_ci
346da0c48c4Sopenharmony_ci	  Dwarf_Die die;
347da0c48c4Sopenharmony_ci	  if (dwarf_offdie (dbg, old_off + hsize, &die) != NULL)
348da0c48c4Sopenharmony_ci	    handle (dbg, &die, 1);
349da0c48c4Sopenharmony_ci
350da0c48c4Sopenharmony_ci	  old_off = off;
351da0c48c4Sopenharmony_ci	}
352da0c48c4Sopenharmony_ci
353da0c48c4Sopenharmony_ci      dwarf_end (dbg);
354da0c48c4Sopenharmony_ci      close (fd);
355da0c48c4Sopenharmony_ci    }
356da0c48c4Sopenharmony_ci
357da0c48c4Sopenharmony_ci  return 0;
358da0c48c4Sopenharmony_ci}
359