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