1 /* Get abbreviation at given offset.
2 Copyright (C) 2003, 2004, 2005, 2006 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2003.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
41 __libdw_getabbrev (dbg, cu, offset, lengthp, result)
48 /* Don't fail if there is not .debug_abbrev section. */
49 if (dbg->sectiondata[IDX_debug_abbrev] == NULL)
52 if (offset >= dbg->sectiondata[IDX_debug_abbrev]->d_size)
54 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
58 const unsigned char *abbrevp
59 = (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset;
62 /* We are past the last entry. */
63 return DWARF_END_ABBREV;
65 /* 7.5.3 Abbreviations Tables
67 [...] Each declaration begins with an unsigned LEB128 number
68 representing the abbreviation code itself. [...] The
69 abbreviation code is followed by another unsigned LEB128
70 number that encodes the entry's tag. [...]
72 [...] Following the tag encoding is a 1-byte value that
73 determines whether a debugging information entry using this
74 abbreviation has child entries or not. [...]
76 [...] Finally, the child encoding is followed by a series of
77 attribute specifications. Each attribute specification
78 consists of two parts. The first part is an unsigned LEB128
79 number representing the attribute's name. The second part is
80 an unsigned LEB128 number representing the attribute's form. */
81 const unsigned char *start_abbrevp = abbrevp;
83 get_uleb128 (code, abbrevp);
85 /* Check whether this code is already in the hash table. */
87 Dwarf_Abbrev *abb = NULL;
89 || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL)) == NULL)
92 abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
100 assert (abb->offset == offset);
102 /* If the caller doesn't need the length we are done. */
107 /* If there is already a value in the hash table we are going to
108 overwrite its content. This must not be a problem, since the
109 content better be the same. */
111 get_uleb128 (abb->tag, abbrevp);
112 abb->has_children = *abbrevp++ == DW_CHILDREN_yes;
113 abb->attrp = (unsigned char *) abbrevp;
114 abb->offset = offset;
116 /* Skip over all the attributes and count them while doing so. */
118 unsigned int attrname;
119 unsigned int attrform;
122 get_uleb128 (attrname, abbrevp);
123 get_uleb128 (attrform, abbrevp);
125 while (attrname != 0 && attrform != 0 && ++abb->attrcnt);
127 /* Return the length to the caller if she asked for it. */
129 *lengthp = abbrevp - start_abbrevp;
131 /* Add the entry to the hash table. */
132 if (cu != NULL && ! foundit)
133 (void) Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb);
141 dwarf_getabbrev (die, offset, lengthp)
146 return __libdw_getabbrev (die->cu->dbg, die->cu,
147 die->cu->orig_abbrev_offset + offset, lengthp,