1 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 Red Hat, Inc. 2 This file is part of elfutils. 3 Written by Ulrich Drepper <drepper (at) 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 <fcntl.h> 21 #include <inttypes.h> 22 #include ELFUTILS_HEADER(dw) 23 #include <stdio.h> 24 #include <unistd.h> 25 26 27 int 28 main (int argc, char *argv[]) 29 { 30 int cnt; 31 32 for (cnt = 1; cnt < argc; ++cnt) 33 { 34 int fd = open (argv[cnt], O_RDONLY); 35 Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ); 36 if (dbg == NULL) 37 { 38 printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1)); 39 close (fd); 40 continue; 41 } 42 43 Dwarf_Off cuoff = 0; 44 Dwarf_Off old_cuoff = 0; 45 size_t hsize; 46 while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, NULL, NULL, NULL) == 0) 47 { 48 /* Get the DIE for the CU. */ 49 Dwarf_Die die; 50 if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL) 51 /* Something went wrong. */ 52 break; 53 54 Dwarf_Off offset = 0; 55 56 while (1) 57 { 58 size_t length; 59 Dwarf_Abbrev *abbrev = dwarf_getabbrev (&die, offset, &length); 60 if (abbrev == NULL || abbrev == DWARF_END_ABBREV) 61 /* End of the list. */ 62 break; 63 64 unsigned tag = dwarf_getabbrevtag (abbrev); 65 if (tag == 0) 66 { 67 printf ("dwarf_getabbrevtag at offset %llu returned error: %s\n", 68 (unsigned long long int) offset, 69 dwarf_errmsg (-1)); 70 break; 71 } 72 73 unsigned code = dwarf_getabbrevcode (abbrev); 74 if (code == 0) 75 { 76 printf ("dwarf_getabbrevcode at offset %llu returned error: %s\n", 77 (unsigned long long int) offset, 78 dwarf_errmsg (-1)); 79 break; 80 } 81 82 int children = dwarf_abbrevhaschildren (abbrev); 83 if (children < 0) 84 { 85 printf ("dwarf_abbrevhaschildren at offset %llu returned error: %s\n", 86 (unsigned long long int) offset, 87 dwarf_errmsg (-1)); 88 break; 89 } 90 91 printf ("abbrev[%llu]: code = %u, tag = %u, children = %d\n", 92 (unsigned long long int) offset, code, tag, children); 93 94 size_t attrcnt; 95 if (dwarf_getattrcnt (abbrev, &attrcnt) != 0) 96 { 97 printf ("dwarf_getattrcnt at offset %llu returned error: %s\n", 98 (unsigned long long int) offset, 99 dwarf_errmsg (-1)); 100 break; 101 } 102 103 unsigned int attr_num; 104 unsigned int attr_form; 105 Dwarf_Off aboffset; 106 size_t j; 107 for (j = 0; j < attrcnt; ++j) 108 if (dwarf_getabbrevattr (abbrev, j, &attr_num, &attr_form, 109 &aboffset)) 110 printf ("dwarf_getabbrevattr for abbrev[%llu] and index %zu failed\n", 111 (unsigned long long int) offset, j); 112 else 113 printf ("abbrev[%llu]: attr[%zu]: code = %u, form = %u, offset = %" PRIu64 "\n", 114 (unsigned long long int) offset, j, attr_num, 115 attr_form, (uint64_t) aboffset); 116 117 offset += length; 118 } 119 120 old_cuoff = cuoff; 121 } 122 123 if (dwarf_end (dbg) != 0) 124 printf ("dwarf_end failed for %s: %s\n", argv[cnt], 125 dwarf_errmsg (-1)); 126 127 close (fd); 128 } 129 130 return 0; 131 } 132