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