1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3*4d9fdb46SRobert Mustacchi Portions Copyright (C) 2009-2019 David Anderson. All Rights Reserved.
4bc1f688bSRobert Mustacchi
5bc1f688bSRobert Mustacchi This program is free software; you can redistribute it and/or modify it
6bc1f688bSRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
7bc1f688bSRobert Mustacchi as published by the Free Software Foundation.
8bc1f688bSRobert Mustacchi
9bc1f688bSRobert Mustacchi This program is distributed in the hope that it would be useful, but
10bc1f688bSRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
11bc1f688bSRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12bc1f688bSRobert Mustacchi
13bc1f688bSRobert Mustacchi Further, this software is distributed without any warranty that it is
14bc1f688bSRobert Mustacchi free of the rightful claim of any third person regarding infringement
15bc1f688bSRobert Mustacchi or the like. Any license provided herein, whether implied or
16bc1f688bSRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
17bc1f688bSRobert Mustacchi any, provided herein do not apply to combinations of this program with
18bc1f688bSRobert Mustacchi other software, or any other product whatsoever.
19bc1f688bSRobert Mustacchi
20bc1f688bSRobert Mustacchi You should have received a copy of the GNU Lesser General Public
21bc1f688bSRobert Mustacchi License along with this program; if not, write the Free Software
22bc1f688bSRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23bc1f688bSRobert Mustacchi USA.
24bc1f688bSRobert Mustacchi
25bc1f688bSRobert Mustacchi */
26bc1f688bSRobert Mustacchi
27bc1f688bSRobert Mustacchi #include "config.h"
28bc1f688bSRobert Mustacchi #include <stdio.h>
29*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
30bc1f688bSRobert Mustacchi #include "dwarf_abbrev.h"
31*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
32*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
33*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
34*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
35*4d9fdb46SRobert Mustacchi
36*4d9fdb46SRobert Mustacchi #define TRUE 1
37*4d9fdb46SRobert Mustacchi #define FALSE 0
38*4d9fdb46SRobert Mustacchi
39*4d9fdb46SRobert Mustacchi /* This is used to print a .debug_abbrev section without
40*4d9fdb46SRobert Mustacchi knowing about the DIEs that use the abbrevs.
41*4d9fdb46SRobert Mustacchi
42*4d9fdb46SRobert Mustacchi dwarf_get_abbrev() and,
43*4d9fdb46SRobert Mustacchi in dwarf_util.c, _dwarf_get_abbrev_for_code()
44*4d9fdb46SRobert Mustacchi
45*4d9fdb46SRobert Mustacchi
46*4d9fdb46SRobert Mustacchi When we have a simple .o
47*4d9fdb46SRobert Mustacchi there is at least a hope of iterating through
48*4d9fdb46SRobert Mustacchi the abbrevs meaningfully without knowing
49*4d9fdb46SRobert Mustacchi a CU context.
50*4d9fdb46SRobert Mustacchi
51*4d9fdb46SRobert Mustacchi This often fails or gets incorrect info
52*4d9fdb46SRobert Mustacchi because there is no guarantee the .debug_abbrev
53*4d9fdb46SRobert Mustacchi section is free of garbage bytes.
54*4d9fdb46SRobert Mustacchi
55*4d9fdb46SRobert Mustacchi In an object with multiple CU/TUs the
56*4d9fdb46SRobert Mustacchi output is difficult/impossible to usefully interpret.
57*4d9fdb46SRobert Mustacchi
58*4d9fdb46SRobert Mustacchi In a dwp (Package File) it is really impossible
59*4d9fdb46SRobert Mustacchi to associate abbrevs with a CU.
60*4d9fdb46SRobert Mustacchi
61*4d9fdb46SRobert Mustacchi */
62*4d9fdb46SRobert Mustacchi
63*4d9fdb46SRobert Mustacchi int
_dwarf_count_abbrev_entries(Dwarf_Debug dbg,Dwarf_Byte_Ptr abbrev_ptr,Dwarf_Byte_Ptr abbrev_section_end,Dwarf_Unsigned * abbrev_count_out,Dwarf_Byte_Ptr * abbrev_ptr_out,Dwarf_Error * error)64*4d9fdb46SRobert Mustacchi _dwarf_count_abbrev_entries(Dwarf_Debug dbg,
65*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr abbrev_ptr,
66*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr abbrev_section_end,
67*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *abbrev_count_out,
68*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr *abbrev_ptr_out,
69*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
70*4d9fdb46SRobert Mustacchi {
71*4d9fdb46SRobert Mustacchi Dwarf_Unsigned abbrev_count = 0;
72*4d9fdb46SRobert Mustacchi Dwarf_Unsigned attr_name = 0;
73*4d9fdb46SRobert Mustacchi Dwarf_Unsigned attr_form = 0;
74*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Unsigned implicit_const = 0;
75*4d9fdb46SRobert Mustacchi
76*4d9fdb46SRobert Mustacchi /* The abbreviations table ends with an entry with a single
77*4d9fdb46SRobert Mustacchi byte of zero for the abbreviation code.
78*4d9fdb46SRobert Mustacchi Padding bytes following that zero are allowed, but
79*4d9fdb46SRobert Mustacchi here we simply stop looking past that zero abbrev.
80*4d9fdb46SRobert Mustacchi
81*4d9fdb46SRobert Mustacchi We also stop looking if the block/section ends,
82*4d9fdb46SRobert Mustacchi though the DWARF2 and later standards do not specifically
83*4d9fdb46SRobert Mustacchi allow section/block end to terminate an abbreviations
84*4d9fdb46SRobert Mustacchi list. */
85*4d9fdb46SRobert Mustacchi
86*4d9fdb46SRobert Mustacchi do {
87*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_name,
88*4d9fdb46SRobert Mustacchi dbg,error,abbrev_section_end);
89*4d9fdb46SRobert Mustacchi if (attr_name > DW_AT_hi_user) {
90*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT);
91*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
92*4d9fdb46SRobert Mustacchi }
93*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_form,
94*4d9fdb46SRobert Mustacchi dbg,error,abbrev_section_end);
95*4d9fdb46SRobert Mustacchi if (!_dwarf_valid_form_we_know(attr_form,attr_name)) {
96*4d9fdb46SRobert Mustacchi dwarfstring m;
97*4d9fdb46SRobert Mustacchi
98*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
99*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
100*4d9fdb46SRobert Mustacchi "DW_DLE_UNKNOWN_FORM: Abbrev invalid form 0x%"
101*4d9fdb46SRobert Mustacchi DW_PR_DUx,attr_form);
102*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
103*4d9fdb46SRobert Mustacchi " with attribute 0x%" DW_PR_DUx,attr_name);
104*4d9fdb46SRobert Mustacchi dwarfstring_append(&m," so abbreviations unusable. ");
105*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_UNKNOWN_FORM,
106*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
107*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
108*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
109*4d9fdb46SRobert Mustacchi }
110*4d9fdb46SRobert Mustacchi if (attr_form == DW_FORM_implicit_const) {
111*4d9fdb46SRobert Mustacchi /* The value is here, not in a DIE. */
112*4d9fdb46SRobert Mustacchi DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const,
113*4d9fdb46SRobert Mustacchi dbg,error,abbrev_section_end);
114*4d9fdb46SRobert Mustacchi }
115*4d9fdb46SRobert Mustacchi abbrev_count++;
116*4d9fdb46SRobert Mustacchi } while ((abbrev_ptr < abbrev_section_end) &&
117*4d9fdb46SRobert Mustacchi (attr_name != 0 || attr_form != 0));
118*4d9fdb46SRobert Mustacchi /* We counted one too high,we included the 0,0 */
119*4d9fdb46SRobert Mustacchi *abbrev_count_out = abbrev_count-1;
120*4d9fdb46SRobert Mustacchi *abbrev_ptr_out = abbrev_ptr;
121*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
122*4d9fdb46SRobert Mustacchi }
123bc1f688bSRobert Mustacchi
124bc1f688bSRobert Mustacchi int
dwarf_get_abbrev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Abbrev * returned_abbrev,Dwarf_Unsigned * length,Dwarf_Unsigned * abbr_count,Dwarf_Error * error)125bc1f688bSRobert Mustacchi dwarf_get_abbrev(Dwarf_Debug dbg,
126bc1f688bSRobert Mustacchi Dwarf_Unsigned offset,
127bc1f688bSRobert Mustacchi Dwarf_Abbrev * returned_abbrev,
128bc1f688bSRobert Mustacchi Dwarf_Unsigned * length,
129bc1f688bSRobert Mustacchi Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
130bc1f688bSRobert Mustacchi {
131*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr abbrev_ptr = 0;
132*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr abbrev_ptr_out = 0;
133*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr abbrev_section_end = 0;
134bc1f688bSRobert Mustacchi Dwarf_Abbrev ret_abbrev = 0;
135bc1f688bSRobert Mustacchi Dwarf_Unsigned labbr_count = 0;
136bc1f688bSRobert Mustacchi Dwarf_Unsigned utmp = 0;
137*4d9fdb46SRobert Mustacchi int res = 0;
138bc1f688bSRobert Mustacchi
139*4d9fdb46SRobert Mustacchi if (!dbg) {
140bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
141*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
142bc1f688bSRobert Mustacchi }
143bc1f688bSRobert Mustacchi if (dbg->de_debug_abbrev.dss_data == 0) {
144bc1f688bSRobert Mustacchi /* Loads abbrev section (and .debug_info as we do those
145bc1f688bSRobert Mustacchi together). */
146*4d9fdb46SRobert Mustacchi res = _dwarf_load_debug_info(dbg, error);
147bc1f688bSRobert Mustacchi
148bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
149bc1f688bSRobert Mustacchi return res;
150bc1f688bSRobert Mustacchi }
151bc1f688bSRobert Mustacchi }
152bc1f688bSRobert Mustacchi
153bc1f688bSRobert Mustacchi if (offset >= dbg->de_debug_abbrev.dss_size) {
154*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
155bc1f688bSRobert Mustacchi }
156bc1f688bSRobert Mustacchi ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
157bc1f688bSRobert Mustacchi if (ret_abbrev == NULL) {
158bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
159*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
160bc1f688bSRobert Mustacchi }
161*4d9fdb46SRobert Mustacchi ret_abbrev->dab_dbg = dbg;
162bc1f688bSRobert Mustacchi if (returned_abbrev == 0 || abbr_count == 0) {
163bc1f688bSRobert Mustacchi dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
164bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
165*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
166bc1f688bSRobert Mustacchi }
167bc1f688bSRobert Mustacchi
168bc1f688bSRobert Mustacchi
169bc1f688bSRobert Mustacchi *abbr_count = 0;
170*4d9fdb46SRobert Mustacchi if (length) {
171bc1f688bSRobert Mustacchi *length = 1;
172*4d9fdb46SRobert Mustacchi }
173*4d9fdb46SRobert Mustacchi
174bc1f688bSRobert Mustacchi
175bc1f688bSRobert Mustacchi abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset;
176bc1f688bSRobert Mustacchi abbrev_section_end =
177bc1f688bSRobert Mustacchi dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size;
178*4d9fdb46SRobert Mustacchi #if 0
179*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp,
180*4d9fdb46SRobert Mustacchi dbg,error,abbrev_section_end);
181*4d9fdb46SRobert Mustacchi #endif
182*4d9fdb46SRobert Mustacchi res = _dwarf_leb128_uword_wrapper(dbg,&abbrev_ptr,
183*4d9fdb46SRobert Mustacchi abbrev_section_end,&utmp,error);
184*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
185*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
186*4d9fdb46SRobert Mustacchi return res;
187*4d9fdb46SRobert Mustacchi }
188*4d9fdb46SRobert Mustacchi ret_abbrev->dab_code = utmp;
189*4d9fdb46SRobert Mustacchi if (ret_abbrev->dab_code == 0) {
190bc1f688bSRobert Mustacchi *returned_abbrev = ret_abbrev;
191bc1f688bSRobert Mustacchi *abbr_count = 0;
192bc1f688bSRobert Mustacchi if (length) {
193bc1f688bSRobert Mustacchi *length = 1;
194bc1f688bSRobert Mustacchi }
195*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
196bc1f688bSRobert Mustacchi }
197bc1f688bSRobert Mustacchi
198*4d9fdb46SRobert Mustacchi #if 0
199*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp,
200*4d9fdb46SRobert Mustacchi dbg,error,abbrev_section_end);
201*4d9fdb46SRobert Mustacchi #endif
202*4d9fdb46SRobert Mustacchi res = _dwarf_leb128_uword_wrapper(dbg,&abbrev_ptr,
203*4d9fdb46SRobert Mustacchi abbrev_section_end,&utmp,error);
204*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
205*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
206*4d9fdb46SRobert Mustacchi return res;
207*4d9fdb46SRobert Mustacchi }
208*4d9fdb46SRobert Mustacchi if (utmp > DW_TAG_hi_user) {
209*4d9fdb46SRobert Mustacchi return _dwarf_format_TAG_err_msg(dbg,
210*4d9fdb46SRobert Mustacchi utmp,"DW_DLE_TAG_CORRUPT",
211*4d9fdb46SRobert Mustacchi error);
212*4d9fdb46SRobert Mustacchi }
213*4d9fdb46SRobert Mustacchi ret_abbrev->dab_tag = utmp;
214*4d9fdb46SRobert Mustacchi if (abbrev_ptr >= abbrev_section_end) {
215*4d9fdb46SRobert Mustacchi dwarfstring m;
216*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
217bc1f688bSRobert Mustacchi
218*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
219*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(&m,
220*4d9fdb46SRobert Mustacchi "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end "
221*4d9fdb46SRobert Mustacchi "of the abbrev section reading tag, starting at"
222*4d9fdb46SRobert Mustacchi " abbrev section offset 0x%x",offset);
223*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error,
224*4d9fdb46SRobert Mustacchi DW_DLE_ABBREV_DECODE_ERROR,
225*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
226*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
227*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
228*4d9fdb46SRobert Mustacchi }
229*4d9fdb46SRobert Mustacchi ret_abbrev->dab_has_child = *(abbrev_ptr++);
230*4d9fdb46SRobert Mustacchi ret_abbrev->dab_abbrev_ptr = abbrev_ptr;
231*4d9fdb46SRobert Mustacchi ret_abbrev->dab_next_ptr = abbrev_ptr;
232*4d9fdb46SRobert Mustacchi ret_abbrev->dab_next_index = 0;
233*4d9fdb46SRobert Mustacchi res = _dwarf_count_abbrev_entries(dbg,abbrev_ptr,
234*4d9fdb46SRobert Mustacchi abbrev_section_end,&labbr_count,&abbrev_ptr_out,error);
235*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
236*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
237*4d9fdb46SRobert Mustacchi return res;
238*4d9fdb46SRobert Mustacchi }
239*4d9fdb46SRobert Mustacchi abbrev_ptr = abbrev_ptr_out;
240bc1f688bSRobert Mustacchi
241*4d9fdb46SRobert Mustacchi /* Global section offset. */
242*4d9fdb46SRobert Mustacchi ret_abbrev->dab_goffset = offset;
243*4d9fdb46SRobert Mustacchi ret_abbrev->dab_count = labbr_count;
244bc1f688bSRobert Mustacchi if (abbrev_ptr > abbrev_section_end) {
245bc1f688bSRobert Mustacchi dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
246*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error,
247*4d9fdb46SRobert Mustacchi DW_DLE_ABBREV_DECODE_ERROR,
248*4d9fdb46SRobert Mustacchi "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end "
249*4d9fdb46SRobert Mustacchi "of the abbrev section reading abbrev_entries.");
250bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
251*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
252bc1f688bSRobert Mustacchi }
253*4d9fdb46SRobert Mustacchi if (length) {
254bc1f688bSRobert Mustacchi *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
255*4d9fdb46SRobert Mustacchi }
256bc1f688bSRobert Mustacchi *returned_abbrev = ret_abbrev;
257bc1f688bSRobert Mustacchi *abbr_count = labbr_count;
258*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
259bc1f688bSRobert Mustacchi }
260bc1f688bSRobert Mustacchi
261bc1f688bSRobert Mustacchi int
dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,Dwarf_Unsigned * returned_code,Dwarf_Error * error)262bc1f688bSRobert Mustacchi dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
263bc1f688bSRobert Mustacchi Dwarf_Unsigned * returned_code,
264bc1f688bSRobert Mustacchi Dwarf_Error * error)
265bc1f688bSRobert Mustacchi {
266bc1f688bSRobert Mustacchi if (abbrev == NULL) {
267bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
268*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
269bc1f688bSRobert Mustacchi }
270bc1f688bSRobert Mustacchi
271*4d9fdb46SRobert Mustacchi *returned_code = abbrev->dab_code;
272*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
273bc1f688bSRobert Mustacchi }
274bc1f688bSRobert Mustacchi
275bc1f688bSRobert Mustacchi /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
276bc1f688bSRobert Mustacchi over 16 bits. */
277bc1f688bSRobert Mustacchi int
dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,Dwarf_Half * returned_tag,Dwarf_Error * error)278bc1f688bSRobert Mustacchi dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
279bc1f688bSRobert Mustacchi Dwarf_Half * returned_tag, Dwarf_Error * error)
280bc1f688bSRobert Mustacchi {
281bc1f688bSRobert Mustacchi if (abbrev == NULL) {
282bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
283bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
284bc1f688bSRobert Mustacchi }
285bc1f688bSRobert Mustacchi
286*4d9fdb46SRobert Mustacchi *returned_tag = abbrev->dab_tag;
287bc1f688bSRobert Mustacchi return (DW_DLV_OK);
288bc1f688bSRobert Mustacchi }
289bc1f688bSRobert Mustacchi
290bc1f688bSRobert Mustacchi
291bc1f688bSRobert Mustacchi int
dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,Dwarf_Signed * returned_flag,Dwarf_Error * error)292bc1f688bSRobert Mustacchi dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
293bc1f688bSRobert Mustacchi Dwarf_Signed * returned_flag,
294bc1f688bSRobert Mustacchi Dwarf_Error * error)
295bc1f688bSRobert Mustacchi {
296bc1f688bSRobert Mustacchi if (abbrev == NULL) {
297bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
298bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
299bc1f688bSRobert Mustacchi }
300bc1f688bSRobert Mustacchi
301*4d9fdb46SRobert Mustacchi *returned_flag = abbrev->dab_has_child;
302bc1f688bSRobert Mustacchi return (DW_DLV_OK);
303bc1f688bSRobert Mustacchi }
304bc1f688bSRobert Mustacchi
305bc1f688bSRobert Mustacchi
306*4d9fdb46SRobert Mustacchi /* This does not return the implicit const, nor
307*4d9fdb46SRobert Mustacchi does it return all bits of the uleb attribute
308*4d9fdb46SRobert Mustacchi nor does it return all bits of the uleb form
309*4d9fdb46SRobert Mustacchi value.
310*4d9fdb46SRobert Mustacchi See dwarf_get_abbrev_entry_b().
311*4d9fdb46SRobert Mustacchi */
312*4d9fdb46SRobert Mustacchi
313bc1f688bSRobert Mustacchi int
dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,Dwarf_Signed indx,Dwarf_Half * returned_attr_num,Dwarf_Signed * returned_form,Dwarf_Off * returned_offset,Dwarf_Error * error)314bc1f688bSRobert Mustacchi dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
315*4d9fdb46SRobert Mustacchi Dwarf_Signed indx,
316bc1f688bSRobert Mustacchi Dwarf_Half * returned_attr_num,
317*4d9fdb46SRobert Mustacchi Dwarf_Signed * returned_form,
318*4d9fdb46SRobert Mustacchi Dwarf_Off * returned_offset,
319*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
320*4d9fdb46SRobert Mustacchi {
321*4d9fdb46SRobert Mustacchi int res;
322*4d9fdb46SRobert Mustacchi Dwarf_Unsigned attr = 0;
323*4d9fdb46SRobert Mustacchi Dwarf_Unsigned form = 0;
324*4d9fdb46SRobert Mustacchi Dwarf_Signed implicitconst = 0;
325*4d9fdb46SRobert Mustacchi Dwarf_Unsigned uindex = (Dwarf_Unsigned)indx;
326*4d9fdb46SRobert Mustacchi Dwarf_Bool filter_outliers = TRUE;
327*4d9fdb46SRobert Mustacchi
328*4d9fdb46SRobert Mustacchi res = dwarf_get_abbrev_entry_b(abbrev,
329*4d9fdb46SRobert Mustacchi uindex,
330*4d9fdb46SRobert Mustacchi filter_outliers,
331*4d9fdb46SRobert Mustacchi &attr,
332*4d9fdb46SRobert Mustacchi &form,
333*4d9fdb46SRobert Mustacchi &implicitconst,
334*4d9fdb46SRobert Mustacchi returned_offset,
335*4d9fdb46SRobert Mustacchi error);
336*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
337*4d9fdb46SRobert Mustacchi return res;
338*4d9fdb46SRobert Mustacchi }
339*4d9fdb46SRobert Mustacchi /* returned_offset already set by dwarf_get_abbrev_entry_b; */
340*4d9fdb46SRobert Mustacchi if (returned_attr_num) {
341*4d9fdb46SRobert Mustacchi *returned_attr_num = (Dwarf_Half)attr;
342*4d9fdb46SRobert Mustacchi }
343*4d9fdb46SRobert Mustacchi if (returned_form) {
344*4d9fdb46SRobert Mustacchi *returned_form = (Dwarf_Signed)form;
345*4d9fdb46SRobert Mustacchi }
346*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
347*4d9fdb46SRobert Mustacchi }
348*4d9fdb46SRobert Mustacchi
349*4d9fdb46SRobert Mustacchi /* If filter_outliers is non-zero then
350*4d9fdb46SRobert Mustacchi the routine will return DW_DLV_ERROR
351*4d9fdb46SRobert Mustacchi if the leb reading generates a number that
352*4d9fdb46SRobert Mustacchi is so large it cannot be correct.
353*4d9fdb46SRobert Mustacchi
354*4d9fdb46SRobert Mustacchi If filter_outliers is 0 the uleb/sleb
355*4d9fdb46SRobert Mustacchi values read are returned, even if
356*4d9fdb46SRobert Mustacchi the values are unreasonable. This is
357*4d9fdb46SRobert Mustacchi a useful option if one wishes to
358*4d9fdb46SRobert Mustacchi have callers examine the return values
359*4d9fdb46SRobert Mustacchi in greater detail than the checking here
360*4d9fdb46SRobert Mustacchi provides.
361*4d9fdb46SRobert Mustacchi
362*4d9fdb46SRobert Mustacchi */
363*4d9fdb46SRobert Mustacchi int
dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev,Dwarf_Unsigned indx,Dwarf_Bool filter_outliers,Dwarf_Unsigned * returned_attr_num,Dwarf_Unsigned * returned_form,Dwarf_Signed * returned_implicitconst,Dwarf_Off * offset,Dwarf_Error * error)364*4d9fdb46SRobert Mustacchi dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev,
365*4d9fdb46SRobert Mustacchi Dwarf_Unsigned indx,
366*4d9fdb46SRobert Mustacchi Dwarf_Bool filter_outliers,
367*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * returned_attr_num,
368*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * returned_form,
369*4d9fdb46SRobert Mustacchi Dwarf_Signed * returned_implicitconst,
370*4d9fdb46SRobert Mustacchi Dwarf_Off * offset,
371*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
372bc1f688bSRobert Mustacchi {
373bc1f688bSRobert Mustacchi Dwarf_Byte_Ptr abbrev_ptr = 0;
374bc1f688bSRobert Mustacchi Dwarf_Byte_Ptr abbrev_end = 0;
375bc1f688bSRobert Mustacchi Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
376*4d9fdb46SRobert Mustacchi Dwarf_Unsigned attr = 0;
377*4d9fdb46SRobert Mustacchi Dwarf_Unsigned form = 0;
378*4d9fdb46SRobert Mustacchi Dwarf_Unsigned implicitconst = 0;
379*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg = 0;
380*4d9fdb46SRobert Mustacchi Dwarf_Signed local_indx = (Dwarf_Signed)indx;
381bc1f688bSRobert Mustacchi
382bc1f688bSRobert Mustacchi if (abbrev == NULL) {
383bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
384bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
385bc1f688bSRobert Mustacchi }
386*4d9fdb46SRobert Mustacchi if (abbrev->dab_code == 0) {
387bc1f688bSRobert Mustacchi return (DW_DLV_NO_ENTRY);
388bc1f688bSRobert Mustacchi }
389bc1f688bSRobert Mustacchi
390*4d9fdb46SRobert Mustacchi if (abbrev->dab_dbg == NULL) {
391bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
392bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
393bc1f688bSRobert Mustacchi }
394*4d9fdb46SRobert Mustacchi dbg = abbrev->dab_dbg;
395*4d9fdb46SRobert Mustacchi abbrev_ptr = abbrev->dab_abbrev_ptr;
396*4d9fdb46SRobert Mustacchi abbrev_end = dbg->de_debug_abbrev.dss_data +
397*4d9fdb46SRobert Mustacchi dbg->de_debug_abbrev.dss_size;
398*4d9fdb46SRobert Mustacchi if ((Dwarf_Unsigned)local_indx >= abbrev->dab_next_index) {
399*4d9fdb46SRobert Mustacchi /* We want a part not yet scanned ,
400*4d9fdb46SRobert Mustacchi so we can start closer to the desired value. */
401*4d9fdb46SRobert Mustacchi abbrev_ptr = abbrev->dab_next_ptr;
402*4d9fdb46SRobert Mustacchi local_indx -= abbrev->dab_next_index;
403*4d9fdb46SRobert Mustacchi }
404bc1f688bSRobert Mustacchi
405*4d9fdb46SRobert Mustacchi for (attr = 1, form = 1;
406*4d9fdb46SRobert Mustacchi local_indx >= 0 && abbrev_ptr < abbrev_end &&
407*4d9fdb46SRobert Mustacchi (attr != 0 || form != 0);
408*4d9fdb46SRobert Mustacchi local_indx--) {
409bc1f688bSRobert Mustacchi
410bc1f688bSRobert Mustacchi mark_abbrev_ptr = abbrev_ptr;
411*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_CK(abbrev_ptr, attr,dbg,
412*4d9fdb46SRobert Mustacchi error,abbrev_end);
413*4d9fdb46SRobert Mustacchi if (filter_outliers && attr > DW_AT_hi_user) {
414*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT);
415*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
416*4d9fdb46SRobert Mustacchi }
417*4d9fdb46SRobert Mustacchi DECODE_LEB128_UWORD_CK(abbrev_ptr, form,dbg,
418*4d9fdb46SRobert Mustacchi error,abbrev_end);
419*4d9fdb46SRobert Mustacchi if (filter_outliers &&
420*4d9fdb46SRobert Mustacchi !_dwarf_valid_form_we_know(form,attr)) {
421*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
422*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR);
423*4d9fdb46SRobert Mustacchi }
424*4d9fdb46SRobert Mustacchi if (form == DW_FORM_implicit_const) {
425*4d9fdb46SRobert Mustacchi /* The value is here, not in a DIE. */
426*4d9fdb46SRobert Mustacchi DECODE_LEB128_SWORD_CK( abbrev_ptr, implicitconst,
427*4d9fdb46SRobert Mustacchi dbg,error,abbrev_end);
428*4d9fdb46SRobert Mustacchi } else {
429*4d9fdb46SRobert Mustacchi implicitconst = 0;
430*4d9fdb46SRobert Mustacchi }
431bc1f688bSRobert Mustacchi }
432bc1f688bSRobert Mustacchi
433bc1f688bSRobert Mustacchi if (abbrev_ptr >= abbrev_end) {
434*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error,
435*4d9fdb46SRobert Mustacchi DW_DLE_ABBREV_DECODE_ERROR,
436*4d9fdb46SRobert Mustacchi "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end "
437*4d9fdb46SRobert Mustacchi "of the abbrev section reading abbrev entries..");
438*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
439bc1f688bSRobert Mustacchi }
440bc1f688bSRobert Mustacchi
441*4d9fdb46SRobert Mustacchi if (local_indx >= 0) {
442*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
443bc1f688bSRobert Mustacchi }
444bc1f688bSRobert Mustacchi
445*4d9fdb46SRobert Mustacchi if (returned_form != NULL) {
446*4d9fdb46SRobert Mustacchi *returned_form = form;
447*4d9fdb46SRobert Mustacchi }
448*4d9fdb46SRobert Mustacchi if (offset != NULL) {
449*4d9fdb46SRobert Mustacchi *offset = mark_abbrev_ptr - dbg->de_debug_abbrev.dss_data;
450*4d9fdb46SRobert Mustacchi }
451*4d9fdb46SRobert Mustacchi if (returned_attr_num) {
452*4d9fdb46SRobert Mustacchi *returned_attr_num = attr;
453*4d9fdb46SRobert Mustacchi }
454*4d9fdb46SRobert Mustacchi if (returned_implicitconst) {
455*4d9fdb46SRobert Mustacchi /* Callers should only examine implict const value
456*4d9fdb46SRobert Mustacchi if the form is DW_FORM_implicit_const. */
457*4d9fdb46SRobert Mustacchi *returned_implicitconst = implicitconst;
458*4d9fdb46SRobert Mustacchi }
459*4d9fdb46SRobert Mustacchi abbrev->dab_next_ptr = abbrev_ptr;
460*4d9fdb46SRobert Mustacchi abbrev->dab_next_index = (Dwarf_Unsigned)local_indx ;
461bc1f688bSRobert Mustacchi return DW_DLV_OK;
462bc1f688bSRobert Mustacchi }
463*4d9fdb46SRobert Mustacchi
464*4d9fdb46SRobert Mustacchi /* This function is not entirely safe to call.
465*4d9fdb46SRobert Mustacchi The problem is that the DWARF[234] specification does not insist
466*4d9fdb46SRobert Mustacchi that bytes in .debug_abbrev that are not referenced by .debug_info
467*4d9fdb46SRobert Mustacchi or .debug_types need to be initialized to anything specific.
468*4d9fdb46SRobert Mustacchi Any garbage bytes may cause trouble. Not all compilers/linkers
469*4d9fdb46SRobert Mustacchi leave unreferenced garbage bytes in .debug_abbrev, so this may
470*4d9fdb46SRobert Mustacchi work for most objects.
471*4d9fdb46SRobert Mustacchi In case of error could return a bogus value, there is
472*4d9fdb46SRobert Mustacchi no documented way to detect error.
473*4d9fdb46SRobert Mustacchi */
474*4d9fdb46SRobert Mustacchi int
dwarf_get_abbrev_count(Dwarf_Debug dbg)475*4d9fdb46SRobert Mustacchi dwarf_get_abbrev_count(Dwarf_Debug dbg)
476*4d9fdb46SRobert Mustacchi {
477*4d9fdb46SRobert Mustacchi Dwarf_Abbrev ab;
478*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset = 0;
479*4d9fdb46SRobert Mustacchi Dwarf_Unsigned length = 0;
480*4d9fdb46SRobert Mustacchi Dwarf_Unsigned attr_count = 0;
481*4d9fdb46SRobert Mustacchi Dwarf_Unsigned abbrev_count = 0;
482*4d9fdb46SRobert Mustacchi int abres = DW_DLV_OK;
483*4d9fdb46SRobert Mustacchi Dwarf_Error err = 0;
484*4d9fdb46SRobert Mustacchi
485*4d9fdb46SRobert Mustacchi while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
486*4d9fdb46SRobert Mustacchi &length, &attr_count,
487*4d9fdb46SRobert Mustacchi &err)) == DW_DLV_OK) {
488*4d9fdb46SRobert Mustacchi
489*4d9fdb46SRobert Mustacchi ++abbrev_count;
490*4d9fdb46SRobert Mustacchi offset += length;
491*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
492*4d9fdb46SRobert Mustacchi }
493*4d9fdb46SRobert Mustacchi if (err) {
494*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,err,DW_DLA_ERROR);
495*4d9fdb46SRobert Mustacchi err = 0;
496*4d9fdb46SRobert Mustacchi }
497*4d9fdb46SRobert Mustacchi return abbrev_count;
498*4d9fdb46SRobert Mustacchi }
499