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