xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_abbrev.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
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