xref: /titanic_50/usr/src/lib/libdwarf/common/dwarf_abbrev.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
1*f3e7f55eSRobert Mustacchi /*
2*f3e7f55eSRobert Mustacchi 
3*f3e7f55eSRobert Mustacchi   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
4*f3e7f55eSRobert Mustacchi   Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
5*f3e7f55eSRobert Mustacchi 
6*f3e7f55eSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*f3e7f55eSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*f3e7f55eSRobert Mustacchi   as published by the Free Software Foundation.
9*f3e7f55eSRobert Mustacchi 
10*f3e7f55eSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*f3e7f55eSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*f3e7f55eSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*f3e7f55eSRobert Mustacchi 
14*f3e7f55eSRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*f3e7f55eSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*f3e7f55eSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*f3e7f55eSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*f3e7f55eSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*f3e7f55eSRobert Mustacchi   other software, or any other product whatsoever.
20*f3e7f55eSRobert Mustacchi 
21*f3e7f55eSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*f3e7f55eSRobert Mustacchi   License along with this program; if not, write the Free Software
23*f3e7f55eSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*f3e7f55eSRobert Mustacchi   USA.
25*f3e7f55eSRobert Mustacchi 
26*f3e7f55eSRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*f3e7f55eSRobert Mustacchi   Mountain View, CA 94043, or:
28*f3e7f55eSRobert Mustacchi 
29*f3e7f55eSRobert Mustacchi   http://www.sgi.com
30*f3e7f55eSRobert Mustacchi 
31*f3e7f55eSRobert Mustacchi   For further information regarding this notice, see:
32*f3e7f55eSRobert Mustacchi 
33*f3e7f55eSRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*f3e7f55eSRobert Mustacchi 
35*f3e7f55eSRobert Mustacchi */
36*f3e7f55eSRobert Mustacchi /* The address of the Free Software Foundation is
37*f3e7f55eSRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*f3e7f55eSRobert Mustacchi    Boston, MA 02110-1301, USA.
39*f3e7f55eSRobert Mustacchi    SGI has moved from the above address.
40*f3e7f55eSRobert Mustacchi */
41*f3e7f55eSRobert Mustacchi 
42*f3e7f55eSRobert Mustacchi 
43*f3e7f55eSRobert Mustacchi 
44*f3e7f55eSRobert Mustacchi 
45*f3e7f55eSRobert Mustacchi #include "config.h"
46*f3e7f55eSRobert Mustacchi #include "dwarf_incl.h"
47*f3e7f55eSRobert Mustacchi #include <stdio.h>
48*f3e7f55eSRobert Mustacchi #include "dwarf_abbrev.h"
49*f3e7f55eSRobert Mustacchi 
50*f3e7f55eSRobert 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)51*f3e7f55eSRobert Mustacchi dwarf_get_abbrev(Dwarf_Debug dbg,
52*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned offset,
53*f3e7f55eSRobert Mustacchi     Dwarf_Abbrev * returned_abbrev,
54*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned * length,
55*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
56*f3e7f55eSRobert Mustacchi {
57*f3e7f55eSRobert Mustacchi     Dwarf_Small *abbrev_ptr = 0;
58*f3e7f55eSRobert Mustacchi     Dwarf_Small *abbrev_section_end = 0;
59*f3e7f55eSRobert Mustacchi     Dwarf_Half attr = 0;
60*f3e7f55eSRobert Mustacchi     Dwarf_Half attr_form = 0;
61*f3e7f55eSRobert Mustacchi     Dwarf_Abbrev ret_abbrev = 0;
62*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned labbr_count = 0;
63*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned utmp = 0;
64*f3e7f55eSRobert Mustacchi 
65*f3e7f55eSRobert Mustacchi 
66*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
67*f3e7f55eSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
68*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
69*f3e7f55eSRobert Mustacchi     }
70*f3e7f55eSRobert Mustacchi     if (dbg->de_debug_abbrev.dss_data == 0) {
71*f3e7f55eSRobert Mustacchi         /* Loads abbrev section (and .debug_info as we do those
72*f3e7f55eSRobert Mustacchi            together). */
73*f3e7f55eSRobert Mustacchi         int res = _dwarf_load_debug_info(dbg, error);
74*f3e7f55eSRobert Mustacchi 
75*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
76*f3e7f55eSRobert Mustacchi             return res;
77*f3e7f55eSRobert Mustacchi         }
78*f3e7f55eSRobert Mustacchi     }
79*f3e7f55eSRobert Mustacchi 
80*f3e7f55eSRobert Mustacchi     if (offset >= dbg->de_debug_abbrev.dss_size) {
81*f3e7f55eSRobert Mustacchi         return (DW_DLV_NO_ENTRY);
82*f3e7f55eSRobert Mustacchi     }
83*f3e7f55eSRobert Mustacchi 
84*f3e7f55eSRobert Mustacchi 
85*f3e7f55eSRobert Mustacchi     ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
86*f3e7f55eSRobert Mustacchi     if (ret_abbrev == NULL) {
87*f3e7f55eSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
88*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
89*f3e7f55eSRobert Mustacchi     }
90*f3e7f55eSRobert Mustacchi     ret_abbrev->ab_dbg = dbg;
91*f3e7f55eSRobert Mustacchi     if (returned_abbrev == 0 || abbr_count == 0) {
92*f3e7f55eSRobert Mustacchi         dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
93*f3e7f55eSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
94*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
95*f3e7f55eSRobert Mustacchi     }
96*f3e7f55eSRobert Mustacchi 
97*f3e7f55eSRobert Mustacchi 
98*f3e7f55eSRobert Mustacchi     *abbr_count = 0;
99*f3e7f55eSRobert Mustacchi     if (length != NULL)
100*f3e7f55eSRobert Mustacchi         *length = 1;
101*f3e7f55eSRobert Mustacchi 
102*f3e7f55eSRobert Mustacchi     abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset;
103*f3e7f55eSRobert Mustacchi     abbrev_section_end =
104*f3e7f55eSRobert Mustacchi         dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size;
105*f3e7f55eSRobert Mustacchi 
106*f3e7f55eSRobert Mustacchi     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
107*f3e7f55eSRobert Mustacchi     ret_abbrev->ab_code = (Dwarf_Word) utmp;
108*f3e7f55eSRobert Mustacchi     if (ret_abbrev->ab_code == 0) {
109*f3e7f55eSRobert Mustacchi         *returned_abbrev = ret_abbrev;
110*f3e7f55eSRobert Mustacchi         *abbr_count = 0;
111*f3e7f55eSRobert Mustacchi         if (length) {
112*f3e7f55eSRobert Mustacchi             *length = 1;
113*f3e7f55eSRobert Mustacchi         }
114*f3e7f55eSRobert Mustacchi         return (DW_DLV_OK);
115*f3e7f55eSRobert Mustacchi     }
116*f3e7f55eSRobert Mustacchi 
117*f3e7f55eSRobert Mustacchi     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
118*f3e7f55eSRobert Mustacchi     ret_abbrev->ab_tag = utmp;
119*f3e7f55eSRobert Mustacchi     ret_abbrev->ab_has_child = *(abbrev_ptr++);
120*f3e7f55eSRobert Mustacchi     ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
121*f3e7f55eSRobert Mustacchi 
122*f3e7f55eSRobert Mustacchi     do {
123*f3e7f55eSRobert Mustacchi         Dwarf_Unsigned utmp2;
124*f3e7f55eSRobert Mustacchi 
125*f3e7f55eSRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
126*f3e7f55eSRobert Mustacchi         attr = (Dwarf_Half) utmp2;
127*f3e7f55eSRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
128*f3e7f55eSRobert Mustacchi         attr_form = (Dwarf_Half) utmp2;
129*f3e7f55eSRobert Mustacchi 
130*f3e7f55eSRobert Mustacchi         if (attr != 0)
131*f3e7f55eSRobert Mustacchi             (labbr_count)++;
132*f3e7f55eSRobert Mustacchi 
133*f3e7f55eSRobert Mustacchi     } while (abbrev_ptr < abbrev_section_end &&
134*f3e7f55eSRobert Mustacchi              (attr != 0 || attr_form != 0));
135*f3e7f55eSRobert Mustacchi 
136*f3e7f55eSRobert Mustacchi     if (abbrev_ptr > abbrev_section_end) {
137*f3e7f55eSRobert Mustacchi         dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
138*f3e7f55eSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
139*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
140*f3e7f55eSRobert Mustacchi     }
141*f3e7f55eSRobert Mustacchi 
142*f3e7f55eSRobert Mustacchi     if (length != NULL)
143*f3e7f55eSRobert Mustacchi         *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
144*f3e7f55eSRobert Mustacchi 
145*f3e7f55eSRobert Mustacchi     *returned_abbrev = ret_abbrev;
146*f3e7f55eSRobert Mustacchi     *abbr_count = labbr_count;
147*f3e7f55eSRobert Mustacchi     return (DW_DLV_OK);
148*f3e7f55eSRobert Mustacchi }
149*f3e7f55eSRobert Mustacchi 
150*f3e7f55eSRobert Mustacchi int
dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,Dwarf_Unsigned * returned_code,Dwarf_Error * error)151*f3e7f55eSRobert Mustacchi dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
152*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned * returned_code,
153*f3e7f55eSRobert Mustacchi     Dwarf_Error * error)
154*f3e7f55eSRobert Mustacchi {
155*f3e7f55eSRobert Mustacchi     if (abbrev == NULL) {
156*f3e7f55eSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
157*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
158*f3e7f55eSRobert Mustacchi     }
159*f3e7f55eSRobert Mustacchi 
160*f3e7f55eSRobert Mustacchi     *returned_code = abbrev->ab_code;
161*f3e7f55eSRobert Mustacchi     return (DW_DLV_OK);
162*f3e7f55eSRobert Mustacchi }
163*f3e7f55eSRobert Mustacchi 
164*f3e7f55eSRobert Mustacchi /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
165*f3e7f55eSRobert Mustacchi    over 16 bits.  */
166*f3e7f55eSRobert Mustacchi int
dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,Dwarf_Half * returned_tag,Dwarf_Error * error)167*f3e7f55eSRobert Mustacchi dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
168*f3e7f55eSRobert Mustacchi     Dwarf_Half * returned_tag, Dwarf_Error * error)
169*f3e7f55eSRobert Mustacchi {
170*f3e7f55eSRobert Mustacchi     if (abbrev == NULL) {
171*f3e7f55eSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
172*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
173*f3e7f55eSRobert Mustacchi     }
174*f3e7f55eSRobert Mustacchi 
175*f3e7f55eSRobert Mustacchi     *returned_tag = abbrev->ab_tag;
176*f3e7f55eSRobert Mustacchi     return (DW_DLV_OK);
177*f3e7f55eSRobert Mustacchi }
178*f3e7f55eSRobert Mustacchi 
179*f3e7f55eSRobert Mustacchi 
180*f3e7f55eSRobert Mustacchi int
dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,Dwarf_Signed * returned_flag,Dwarf_Error * error)181*f3e7f55eSRobert Mustacchi dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
182*f3e7f55eSRobert Mustacchi     Dwarf_Signed * returned_flag,
183*f3e7f55eSRobert Mustacchi     Dwarf_Error * error)
184*f3e7f55eSRobert Mustacchi {
185*f3e7f55eSRobert Mustacchi     if (abbrev == NULL) {
186*f3e7f55eSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
187*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
188*f3e7f55eSRobert Mustacchi     }
189*f3e7f55eSRobert Mustacchi 
190*f3e7f55eSRobert Mustacchi     *returned_flag = abbrev->ab_has_child;
191*f3e7f55eSRobert Mustacchi     return (DW_DLV_OK);
192*f3e7f55eSRobert Mustacchi }
193*f3e7f55eSRobert Mustacchi 
194*f3e7f55eSRobert Mustacchi 
195*f3e7f55eSRobert Mustacchi int
dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,Dwarf_Signed index,Dwarf_Half * returned_attr_num,Dwarf_Signed * form,Dwarf_Off * offset,Dwarf_Error * error)196*f3e7f55eSRobert Mustacchi dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
197*f3e7f55eSRobert Mustacchi     Dwarf_Signed index,
198*f3e7f55eSRobert Mustacchi     Dwarf_Half * returned_attr_num,
199*f3e7f55eSRobert Mustacchi     Dwarf_Signed * form,
200*f3e7f55eSRobert Mustacchi     Dwarf_Off * offset, Dwarf_Error * error)
201*f3e7f55eSRobert Mustacchi {
202*f3e7f55eSRobert Mustacchi     Dwarf_Byte_Ptr abbrev_ptr = 0;
203*f3e7f55eSRobert Mustacchi     Dwarf_Byte_Ptr abbrev_end = 0;
204*f3e7f55eSRobert Mustacchi     Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
205*f3e7f55eSRobert Mustacchi     Dwarf_Half attr = 0;
206*f3e7f55eSRobert Mustacchi     Dwarf_Half attr_form = 0;
207*f3e7f55eSRobert Mustacchi 
208*f3e7f55eSRobert Mustacchi     if (index < 0)
209*f3e7f55eSRobert Mustacchi         return (DW_DLV_NO_ENTRY);
210*f3e7f55eSRobert Mustacchi 
211*f3e7f55eSRobert Mustacchi     if (abbrev == NULL) {
212*f3e7f55eSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
213*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
214*f3e7f55eSRobert Mustacchi     }
215*f3e7f55eSRobert Mustacchi 
216*f3e7f55eSRobert Mustacchi     if (abbrev->ab_code == 0) {
217*f3e7f55eSRobert Mustacchi         return (DW_DLV_NO_ENTRY);
218*f3e7f55eSRobert Mustacchi     }
219*f3e7f55eSRobert Mustacchi 
220*f3e7f55eSRobert Mustacchi     if (abbrev->ab_dbg == NULL) {
221*f3e7f55eSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
222*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
223*f3e7f55eSRobert Mustacchi     }
224*f3e7f55eSRobert Mustacchi 
225*f3e7f55eSRobert Mustacchi     abbrev_ptr = abbrev->ab_abbrev_ptr;
226*f3e7f55eSRobert Mustacchi     abbrev_end =
227*f3e7f55eSRobert Mustacchi         abbrev->ab_dbg->de_debug_abbrev.dss_data +
228*f3e7f55eSRobert Mustacchi         abbrev->ab_dbg->de_debug_abbrev.dss_size;
229*f3e7f55eSRobert Mustacchi 
230*f3e7f55eSRobert Mustacchi     for (attr = 1, attr_form = 1;
231*f3e7f55eSRobert Mustacchi          index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
232*f3e7f55eSRobert Mustacchi              attr_form != 0);
233*f3e7f55eSRobert Mustacchi          index--) {
234*f3e7f55eSRobert Mustacchi         Dwarf_Unsigned utmp4;
235*f3e7f55eSRobert Mustacchi 
236*f3e7f55eSRobert Mustacchi         mark_abbrev_ptr = abbrev_ptr;
237*f3e7f55eSRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
238*f3e7f55eSRobert Mustacchi         attr = (Dwarf_Half) utmp4;
239*f3e7f55eSRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
240*f3e7f55eSRobert Mustacchi         attr_form = (Dwarf_Half) utmp4;
241*f3e7f55eSRobert Mustacchi     }
242*f3e7f55eSRobert Mustacchi 
243*f3e7f55eSRobert Mustacchi     if (abbrev_ptr >= abbrev_end) {
244*f3e7f55eSRobert Mustacchi         _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
245*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
246*f3e7f55eSRobert Mustacchi     }
247*f3e7f55eSRobert Mustacchi 
248*f3e7f55eSRobert Mustacchi     if (index >= 0) {
249*f3e7f55eSRobert Mustacchi         return (DW_DLV_NO_ENTRY);
250*f3e7f55eSRobert Mustacchi     }
251*f3e7f55eSRobert Mustacchi 
252*f3e7f55eSRobert Mustacchi     if (form != NULL)
253*f3e7f55eSRobert Mustacchi         *form = attr_form;
254*f3e7f55eSRobert Mustacchi     if (offset != NULL)
255*f3e7f55eSRobert Mustacchi         *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev.dss_data;
256*f3e7f55eSRobert Mustacchi 
257*f3e7f55eSRobert Mustacchi     *returned_attr_num = (attr);
258*f3e7f55eSRobert Mustacchi     return DW_DLV_OK;
259*f3e7f55eSRobert Mustacchi }
260