import less(1)
[unleashed/tickless.git] / usr / src / lib / libdwarf / common / dwarf_abbrev.c
blobc2ae361f33f7617bb8d35d34960a26d161f5b89e
1 /*
3 Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
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.
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.
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.
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.
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
29 http://www.sgi.com
31 For further information regarding this notice, see:
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
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.
45 #include "config.h"
46 #include "dwarf_incl.h"
47 #include <stdio.h>
48 #include "dwarf_abbrev.h"
50 int
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)
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;
66 if (dbg == NULL) {
67 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
68 return (DW_DLV_ERROR);
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);
75 if (res != DW_DLV_OK) {
76 return res;
80 if (offset >= dbg->de_debug_abbrev.dss_size) {
81 return (DW_DLV_NO_ENTRY);
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);
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);
98 *abbr_count = 0;
99 if (length != NULL)
100 *length = 1;
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;
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;
114 return (DW_DLV_OK);
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;
122 do {
123 Dwarf_Unsigned utmp2;
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;
130 if (attr != 0)
131 (labbr_count)++;
133 } while (abbrev_ptr < abbrev_section_end &&
134 (attr != 0 || attr_form != 0));
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);
142 if (length != NULL)
143 *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
145 *returned_abbrev = ret_abbrev;
146 *abbr_count = labbr_count;
147 return (DW_DLV_OK);
151 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
152 Dwarf_Unsigned * returned_code,
153 Dwarf_Error * error)
155 if (abbrev == NULL) {
156 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
157 return (DW_DLV_ERROR);
160 *returned_code = abbrev->ab_code;
161 return (DW_DLV_OK);
164 /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
165 over 16 bits. */
167 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
168 Dwarf_Half * returned_tag, Dwarf_Error * error)
170 if (abbrev == NULL) {
171 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
172 return (DW_DLV_ERROR);
175 *returned_tag = abbrev->ab_tag;
176 return (DW_DLV_OK);
181 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
182 Dwarf_Signed * returned_flag,
183 Dwarf_Error * error)
185 if (abbrev == NULL) {
186 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
187 return (DW_DLV_ERROR);
190 *returned_flag = abbrev->ab_has_child;
191 return (DW_DLV_OK);
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)
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;
208 if (index < 0)
209 return (DW_DLV_NO_ENTRY);
211 if (abbrev == NULL) {
212 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
213 return (DW_DLV_ERROR);
216 if (abbrev->ab_code == 0) {
217 return (DW_DLV_NO_ENTRY);
220 if (abbrev->ab_dbg == NULL) {
221 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
222 return (DW_DLV_ERROR);
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;
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;
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;
243 if (abbrev_ptr >= abbrev_end) {
244 _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
245 return (DW_DLV_ERROR);
248 if (index >= 0) {
249 return (DW_DLV_NO_ENTRY);
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;
257 *returned_attr_num = (attr);
258 return DW_DLV_OK;