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@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 27int 28main (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 /* Test something obviously wrong. */ 55 Dwarf_Abbrev *a = dwarf_getabbrev (&die, (Dwarf_Off) -1, NULL); 56 if (a != NULL) 57 { 58 printf ("dwarf_getabbrev -1 succeeded?\n"); 59 break; 60 } 61 62 Dwarf_Off offset = 0; 63 64 while (1) 65 { 66 size_t length; 67 Dwarf_Abbrev *abbrev = dwarf_getabbrev (&die, offset, &length); 68 if (abbrev == NULL || abbrev == DWARF_END_ABBREV) 69 /* End of the list. */ 70 break; 71 72 unsigned tag = dwarf_getabbrevtag (abbrev); 73 if (tag == 0) 74 { 75 printf ("dwarf_getabbrevtag at offset %llu returned error: %s\n", 76 (unsigned long long int) offset, 77 dwarf_errmsg (-1)); 78 break; 79 } 80 81 unsigned code = dwarf_getabbrevcode (abbrev); 82 if (code == 0) 83 { 84 printf ("dwarf_getabbrevcode at offset %llu returned error: %s\n", 85 (unsigned long long int) offset, 86 dwarf_errmsg (-1)); 87 break; 88 } 89 90 int children = dwarf_abbrevhaschildren (abbrev); 91 if (children < 0) 92 { 93 printf ("dwarf_abbrevhaschildren at offset %llu returned error: %s\n", 94 (unsigned long long int) offset, 95 dwarf_errmsg (-1)); 96 break; 97 } 98 99 printf ("abbrev[%llu]: code = %u, tag = %u, children = %d\n", 100 (unsigned long long int) offset, code, tag, children); 101 102 size_t attrcnt; 103 if (dwarf_getattrcnt (abbrev, &attrcnt) != 0) 104 { 105 printf ("dwarf_getattrcnt at offset %llu returned error: %s\n", 106 (unsigned long long int) offset, 107 dwarf_errmsg (-1)); 108 break; 109 } 110 111 unsigned int attr_num; 112 unsigned int attr_form; 113 Dwarf_Off aboffset; 114 size_t j; 115 for (j = 0; j < attrcnt; ++j) 116 if (dwarf_getabbrevattr (abbrev, j, &attr_num, &attr_form, 117 &aboffset)) 118 printf ("dwarf_getabbrevattr for abbrev[%llu] and index %zu failed\n", 119 (unsigned long long int) offset, j); 120 else 121 printf ("abbrev[%llu]: attr[%zu]: code = %u, form = %u, offset = %" PRIu64 "\n", 122 (unsigned long long int) offset, j, attr_num, 123 attr_form, (uint64_t) aboffset); 124 125 offset += length; 126 } 127 128 old_cuoff = cuoff; 129 } 130 131 if (dwarf_end (dbg) != 0) 132 printf ("dwarf_end failed for %s: %s\n", argv[cnt], 133 dwarf_errmsg (-1)); 134 135 close (fd); 136 } 137 138 return 0; 139} 140