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