149d3bc91SRichard Lowe /*
207dc1947SRichard Lowe   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
3*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2009-2019 David Anderson. All Rights Reserved.
449d3bc91SRichard Lowe 
549d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
6*4d9fdb46SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
749d3bc91SRichard Lowe   as published by the Free Software Foundation.
849d3bc91SRichard Lowe 
949d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1049d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
11*4d9fdb46SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1249d3bc91SRichard Lowe 
1349d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
14*4d9fdb46SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
15*4d9fdb46SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
1649d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
17*4d9fdb46SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
18*4d9fdb46SRobert Mustacchi   other software, or any other product whatsoever.
1949d3bc91SRichard Lowe 
20*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
21*4d9fdb46SRobert Mustacchi   License along with this program; if not, write the Free Software
2207dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2349d3bc91SRichard Lowe   USA.
2449d3bc91SRichard Lowe 
25*4d9fdb46SRobert Mustacchi */
26*4d9fdb46SRobert Mustacchi 
27*4d9fdb46SRobert Mustacchi #include "config.h"
28*4d9fdb46SRobert Mustacchi #include <stdio.h>
29*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
30*4d9fdb46SRobert 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
3849d3bc91SRichard Lowe 
39*4d9fdb46SRobert Mustacchi /*  This is used to print a .debug_abbrev section without
40*4d9fdb46SRobert Mustacchi     knowing about the DIEs that use the abbrevs.
4149d3bc91SRichard Lowe 
42*4d9fdb46SRobert Mustacchi     dwarf_get_abbrev() and,
43*4d9fdb46SRobert Mustacchi     in dwarf_util.c,  _dwarf_get_abbrev_for_code()
4449d3bc91SRichard Lowe 
4549d3bc91SRichard Lowe 
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 
6107dc1947SRichard Lowe */
6207dc1947SRichard Lowe 
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;
7549d3bc91SRichard Lowe 
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.
8049d3bc91SRichard Lowe 
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. */
8549d3bc91SRichard Lowe 
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 }
12349d3bc91SRichard Lowe 
12449d3bc91SRichard Lowe int
dwarf_get_abbrev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Abbrev * returned_abbrev,Dwarf_Unsigned * length,Dwarf_Unsigned * abbr_count,Dwarf_Error * error)12549d3bc91SRichard Lowe dwarf_get_abbrev(Dwarf_Debug dbg,
12607dc1947SRichard Lowe     Dwarf_Unsigned offset,
12707dc1947SRichard Lowe     Dwarf_Abbrev * returned_abbrev,
12807dc1947SRichard Lowe     Dwarf_Unsigned * length,
12907dc1947SRichard Lowe     Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
13049d3bc91SRichard Lowe {
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;
13407dc1947SRichard Lowe     Dwarf_Abbrev ret_abbrev = 0;
13549d3bc91SRichard Lowe     Dwarf_Unsigned labbr_count = 0;
136*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned utmp     = 0;
137*4d9fdb46SRobert Mustacchi     int res = 0;
13849d3bc91SRichard Lowe 
139*4d9fdb46SRobert Mustacchi     if (!dbg) {
14007dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
141*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
14249d3bc91SRichard Lowe     }
14307dc1947SRichard Lowe     if (dbg->de_debug_abbrev.dss_data == 0) {
144*4d9fdb46SRobert Mustacchi         /*  Loads abbrev section (and .debug_info as we do those
145*4d9fdb46SRobert Mustacchi             together). */
146*4d9fdb46SRobert Mustacchi         res = _dwarf_load_debug_info(dbg, error);
14707dc1947SRichard Lowe 
14807dc1947SRichard Lowe         if (res != DW_DLV_OK) {
14907dc1947SRichard Lowe             return res;
15007dc1947SRichard Lowe         }
15149d3bc91SRichard Lowe     }
15249d3bc91SRichard Lowe 
15307dc1947SRichard Lowe     if (offset >= dbg->de_debug_abbrev.dss_size) {
154*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
15549d3bc91SRichard Lowe     }
15649d3bc91SRichard Lowe     ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
15749d3bc91SRichard Lowe     if (ret_abbrev == NULL) {
15807dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
159*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
16049d3bc91SRichard Lowe     }
161*4d9fdb46SRobert Mustacchi     ret_abbrev->dab_dbg = dbg;
16249d3bc91SRichard Lowe     if (returned_abbrev == 0 || abbr_count == 0) {
16307dc1947SRichard Lowe         dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
16407dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
165*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
16649d3bc91SRichard Lowe     }
16749d3bc91SRichard Lowe 
16849d3bc91SRichard Lowe 
16949d3bc91SRichard Lowe     *abbr_count = 0;
170*4d9fdb46SRobert Mustacchi     if (length) {
17107dc1947SRichard Lowe         *length = 1;
172*4d9fdb46SRobert Mustacchi     }
173*4d9fdb46SRobert Mustacchi 
17449d3bc91SRichard Lowe 
17507dc1947SRichard Lowe     abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset;
17649d3bc91SRichard Lowe     abbrev_section_end =
17707dc1947SRichard Lowe         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) {
19007dc1947SRichard Lowe         *returned_abbrev = ret_abbrev;
19107dc1947SRichard Lowe         *abbr_count = 0;
19207dc1947SRichard Lowe         if (length) {
19307dc1947SRichard Lowe             *length = 1;
19407dc1947SRichard Lowe         }
195*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
19649d3bc91SRichard Lowe     }
19749d3bc91SRichard Lowe 
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);
21749d3bc91SRichard Lowe 
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;
24049d3bc91SRichard Lowe 
241*4d9fdb46SRobert Mustacchi     /* Global section offset. */
242*4d9fdb46SRobert Mustacchi     ret_abbrev->dab_goffset = offset;
243*4d9fdb46SRobert Mustacchi     ret_abbrev->dab_count = labbr_count;
24449d3bc91SRichard Lowe     if (abbrev_ptr > abbrev_section_end) {
24507dc1947SRichard Lowe         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.");
25007dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
251*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
25249d3bc91SRichard Lowe     }
253*4d9fdb46SRobert Mustacchi     if (length) {
25407dc1947SRichard Lowe         *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
255*4d9fdb46SRobert Mustacchi     }
25649d3bc91SRichard Lowe     *returned_abbrev = ret_abbrev;
25749d3bc91SRichard Lowe     *abbr_count = labbr_count;
258*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
25949d3bc91SRichard Lowe }
26049d3bc91SRichard Lowe 
26149d3bc91SRichard Lowe int
dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,Dwarf_Unsigned * returned_code,Dwarf_Error * error)26249d3bc91SRichard Lowe dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
26307dc1947SRichard Lowe     Dwarf_Unsigned * returned_code,
26407dc1947SRichard Lowe     Dwarf_Error * error)
26549d3bc91SRichard Lowe {
26649d3bc91SRichard Lowe     if (abbrev == NULL) {
26707dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
268*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
26949d3bc91SRichard Lowe     }
27049d3bc91SRichard Lowe 
271*4d9fdb46SRobert Mustacchi     *returned_code = abbrev->dab_code;
272*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
27349d3bc91SRichard Lowe }
27449d3bc91SRichard Lowe 
275*4d9fdb46SRobert Mustacchi /*  DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
276*4d9fdb46SRobert Mustacchi     over 16 bits.  */
27749d3bc91SRichard Lowe int
dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,Dwarf_Half * returned_tag,Dwarf_Error * error)27849d3bc91SRichard Lowe dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
27907dc1947SRichard Lowe     Dwarf_Half * returned_tag, Dwarf_Error * error)
28049d3bc91SRichard Lowe {
28149d3bc91SRichard Lowe     if (abbrev == NULL) {
28207dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
28307dc1947SRichard Lowe         return (DW_DLV_ERROR);
28449d3bc91SRichard Lowe     }
28549d3bc91SRichard Lowe 
286*4d9fdb46SRobert Mustacchi     *returned_tag = abbrev->dab_tag;
28749d3bc91SRichard Lowe     return (DW_DLV_OK);
28849d3bc91SRichard Lowe }
28949d3bc91SRichard Lowe 
29049d3bc91SRichard Lowe 
29149d3bc91SRichard Lowe int
dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,Dwarf_Signed * returned_flag,Dwarf_Error * error)29249d3bc91SRichard Lowe dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
29307dc1947SRichard Lowe     Dwarf_Signed * returned_flag,
29407dc1947SRichard Lowe     Dwarf_Error * error)
29549d3bc91SRichard Lowe {
29649d3bc91SRichard Lowe     if (abbrev == NULL) {
29707dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
29807dc1947SRichard Lowe         return (DW_DLV_ERROR);
29949d3bc91SRichard Lowe     }
30049d3bc91SRichard Lowe 
301*4d9fdb46SRobert Mustacchi     *returned_flag = abbrev->dab_has_child;
30249d3bc91SRichard Lowe     return (DW_DLV_OK);
30349d3bc91SRichard Lowe }
30449d3bc91SRichard Lowe 
30549d3bc91SRichard Lowe 
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 
31349d3bc91SRichard Lowe 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)31449d3bc91SRichard Lowe dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
315*4d9fdb46SRobert Mustacchi     Dwarf_Signed indx,
316*4d9fdb46SRobert 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)
37249d3bc91SRichard Lowe {
37307dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_ptr = 0;
37407dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_end = 0;
37507dc1947SRichard Lowe     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;
38149d3bc91SRichard Lowe 
38249d3bc91SRichard Lowe     if (abbrev == NULL) {
38307dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
38407dc1947SRichard Lowe         return (DW_DLV_ERROR);
38549d3bc91SRichard Lowe     }
386*4d9fdb46SRobert Mustacchi     if (abbrev->dab_code == 0) {
38707dc1947SRichard Lowe         return (DW_DLV_NO_ENTRY);
38849d3bc91SRichard Lowe     }
38949d3bc91SRichard Lowe 
390*4d9fdb46SRobert Mustacchi     if (abbrev->dab_dbg == NULL) {
39107dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
39207dc1947SRichard Lowe         return (DW_DLV_ERROR);
39349d3bc91SRichard Lowe     }
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     }
40449d3bc91SRichard Lowe 
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--) {
40907dc1947SRichard Lowe 
41007dc1947SRichard Lowe         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         }
43149d3bc91SRichard Lowe     }
43249d3bc91SRichard Lowe 
43349d3bc91SRichard Lowe     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;
43949d3bc91SRichard Lowe     }
44049d3bc91SRichard Lowe 
441*4d9fdb46SRobert Mustacchi     if (local_indx >= 0) {
442*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
44349d3bc91SRichard Lowe     }
44449d3bc91SRichard Lowe 
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 ;
46149d3bc91SRichard Lowe     return DW_DLV_OK;
46249d3bc91SRichard Lowe }
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