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