1 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc. 2 Written by Ulrich Drepper <drepper (at) redhat.com>, 1998. 3 4 This program is Open Source software; you can redistribute it and/or 5 modify it under the terms of the Open Software License version 1.0 as 6 published by the Open Source Initiative. 7 8 You should have received a copy of the Open Software License along 9 with this program; if not, you may obtain a copy of the Open Software 10 License version 1.0 from http://www.opensource.org/licenses/osl.php or 11 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 12 3001 King Ranch Road, Ukiah, CA 95482. */ 13 14 #include <config.h> 15 16 #include <fcntl.h> 17 #include <inttypes.h> 18 #include <libdw.h> 19 #include <stdio.h> 20 #include <unistd.h> 21 22 23 int 24 main (int argc, char *argv[]) 25 { 26 int cnt; 27 28 for (cnt = 1; cnt < argc; ++cnt) 29 { 30 int fd = open (argv[cnt], O_RDONLY); 31 Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ); 32 if (dbg == NULL) 33 { 34 printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1)); 35 close (fd); 36 continue; 37 } 38 39 Dwarf_Off cuoff = 0; 40 Dwarf_Off old_cuoff = 0; 41 size_t hsize; 42 while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, NULL, NULL, NULL) == 0) 43 { 44 /* Get the DIE for the CU. */ 45 Dwarf_Die die; 46 if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL) 47 /* Something went wrong. */ 48 break; 49 50 Dwarf_Off offset = 0; 51 52 while (1) 53 { 54 size_t length; 55 Dwarf_Abbrev *abbrev = dwarf_getabbrev (&die, offset, &length); 56 if (abbrev == NULL) 57 /* End of the list. */ 58 break; 59 60 unsigned tag = dwarf_getabbrevtag (abbrev); 61 if (tag == 0) 62 { 63 printf ("dwarf_getabbrevtag at offset %llu returned error: %s\n", 64 (unsigned long long int) offset, 65 dwarf_errmsg (-1)); 66 break; 67 } 68 69 unsigned code = dwarf_getabbrevcode (abbrev); 70 if (code == 0) 71 { 72 printf ("dwarf_getabbrevcode at offset %llu returned error: %s\n", 73 (unsigned long long int) offset, 74 dwarf_errmsg (-1)); 75 break; 76 } 77 78 int children = dwarf_abbrevhaschildren (abbrev); 79 if (children < 0) 80 { 81 printf ("dwarf_abbrevhaschildren at offset %llu returned error: %s\n", 82 (unsigned long long int) offset, 83 dwarf_errmsg (-1)); 84 break; 85 } 86 87 printf ("abbrev[%llu]: code = %u, tag = %u, children = %d\n", 88 (unsigned long long int) offset, code, tag, children); 89 90 size_t attrcnt; 91 if (dwarf_getattrcnt (abbrev, &attrcnt) != 0) 92 { 93 printf ("dwarf_getattrcnt at offset %llu returned error: %s\n", 94 (unsigned long long int) offset, 95 dwarf_errmsg (-1)); 96 break; 97 } 98 99 unsigned int attr_num; 100 unsigned int attr_form; 101 Dwarf_Off aboffset; 102 size_t j; 103 for (j = 0; j < attrcnt; ++j) 104 if (dwarf_getabbrevattr (abbrev, j, &attr_num, &attr_form, 105 &aboffset)) 106 printf ("dwarf_getabbrevattr for abbrev[%llu] and index %zu failed\n", 107 (unsigned long long int) offset, j); 108 else 109 printf ("abbrev[%llu]: attr[%zu]: code = %u, form = %u, offset = %" PRIu64 "\n", 110 (unsigned long long int) offset, j, attr_num, 111 attr_form, (uint64_t) aboffset); 112 113 offset += length; 114 } 115 116 old_cuoff = cuoff; 117 } 118 119 if (dwarf_end (dbg) != 0) 120 printf ("dwarf_end failed for %s: %s\n", argv[cnt], 121 dwarf_errmsg (-1)); 122 123 close (fd); 124 } 125 126 return 0; 127 } 128