1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi
3*7fd79137SRobert Mustacchi Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
4*7fd79137SRobert Mustacchi Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
5*7fd79137SRobert Mustacchi Portions Copyright 2008-2010 David Anderson. All rights reserved.
6*7fd79137SRobert Mustacchi
7*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it
8*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
9*7fd79137SRobert Mustacchi as published by the Free Software Foundation.
10*7fd79137SRobert Mustacchi
11*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but
12*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
13*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14*7fd79137SRobert Mustacchi
15*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is
16*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement
17*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or
18*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
19*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with
20*7fd79137SRobert Mustacchi other software, or any other product whatsoever.
21*7fd79137SRobert Mustacchi
22*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
23*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software
24*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25*7fd79137SRobert Mustacchi USA.
26*7fd79137SRobert Mustacchi
27*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
28*7fd79137SRobert Mustacchi Mountain View, CA 94043, or:
29*7fd79137SRobert Mustacchi
30*7fd79137SRobert Mustacchi http://www.sgi.com
31*7fd79137SRobert Mustacchi
32*7fd79137SRobert Mustacchi For further information regarding this notice, see:
33*7fd79137SRobert Mustacchi
34*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan
35*7fd79137SRobert Mustacchi
36*7fd79137SRobert Mustacchi */
37*7fd79137SRobert Mustacchi
38*7fd79137SRobert Mustacchi
39*7fd79137SRobert Mustacchi
40*7fd79137SRobert Mustacchi #include "config.h"
41*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
42*7fd79137SRobert Mustacchi #include "dwarf_die_deliv.h"
43*7fd79137SRobert Mustacchi
44*7fd79137SRobert Mustacchi int
dwarf_hasform(Dwarf_Attribute attr,Dwarf_Half form,Dwarf_Bool * return_bool,Dwarf_Error * error)45*7fd79137SRobert Mustacchi dwarf_hasform(Dwarf_Attribute attr,
46*7fd79137SRobert Mustacchi Dwarf_Half form,
47*7fd79137SRobert Mustacchi Dwarf_Bool * return_bool, Dwarf_Error * error)
48*7fd79137SRobert Mustacchi {
49*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
50*7fd79137SRobert Mustacchi
51*7fd79137SRobert Mustacchi if (attr == NULL) {
52*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
53*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
54*7fd79137SRobert Mustacchi }
55*7fd79137SRobert Mustacchi
56*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
57*7fd79137SRobert Mustacchi if (cu_context == NULL) {
58*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
59*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
60*7fd79137SRobert Mustacchi }
61*7fd79137SRobert Mustacchi
62*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
63*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
64*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
65*7fd79137SRobert Mustacchi }
66*7fd79137SRobert Mustacchi
67*7fd79137SRobert Mustacchi *return_bool = (attr->ar_attribute_form == form);
68*7fd79137SRobert Mustacchi return DW_DLV_OK;
69*7fd79137SRobert Mustacchi }
70*7fd79137SRobert Mustacchi
71*7fd79137SRobert Mustacchi /* Not often called, we do not worry about efficiency here.
72*7fd79137SRobert Mustacchi The dwarf_whatform() call does the sanity checks for us.
73*7fd79137SRobert Mustacchi */
74*7fd79137SRobert Mustacchi int
dwarf_whatform_direct(Dwarf_Attribute attr,Dwarf_Half * return_form,Dwarf_Error * error)75*7fd79137SRobert Mustacchi dwarf_whatform_direct(Dwarf_Attribute attr,
76*7fd79137SRobert Mustacchi Dwarf_Half * return_form, Dwarf_Error * error)
77*7fd79137SRobert Mustacchi {
78*7fd79137SRobert Mustacchi int res = dwarf_whatform(attr, return_form, error);
79*7fd79137SRobert Mustacchi
80*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
81*7fd79137SRobert Mustacchi return res;
82*7fd79137SRobert Mustacchi }
83*7fd79137SRobert Mustacchi
84*7fd79137SRobert Mustacchi *return_form = attr->ar_attribute_form_direct;
85*7fd79137SRobert Mustacchi return (DW_DLV_OK);
86*7fd79137SRobert Mustacchi }
87*7fd79137SRobert Mustacchi void *
dwarf_uncompress_integer_block(Dwarf_Debug dbg,Dwarf_Bool unit_is_signed,Dwarf_Small unit_length_in_bits,void * input_block,Dwarf_Unsigned input_length_in_bytes,Dwarf_Unsigned * output_length_in_units_ptr,Dwarf_Error * error)88*7fd79137SRobert Mustacchi dwarf_uncompress_integer_block(
89*7fd79137SRobert Mustacchi Dwarf_Debug dbg,
90*7fd79137SRobert Mustacchi Dwarf_Bool unit_is_signed,
91*7fd79137SRobert Mustacchi Dwarf_Small unit_length_in_bits,
92*7fd79137SRobert Mustacchi void* input_block,
93*7fd79137SRobert Mustacchi Dwarf_Unsigned input_length_in_bytes,
94*7fd79137SRobert Mustacchi Dwarf_Unsigned* output_length_in_units_ptr,
95*7fd79137SRobert Mustacchi Dwarf_Error* error
96*7fd79137SRobert Mustacchi )
97*7fd79137SRobert Mustacchi {
98*7fd79137SRobert Mustacchi Dwarf_Unsigned output_length_in_units = 0;
99*7fd79137SRobert Mustacchi void * output_block = 0;
100*7fd79137SRobert Mustacchi int i = 0;
101*7fd79137SRobert Mustacchi char * ptr = 0;
102*7fd79137SRobert Mustacchi int remain = 0;
103*7fd79137SRobert Mustacchi Dwarf_sfixed * array = 0;
104*7fd79137SRobert Mustacchi
105*7fd79137SRobert Mustacchi if (dbg == NULL) {
106*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
107*7fd79137SRobert Mustacchi return((void *)DW_DLV_BADADDR);
108*7fd79137SRobert Mustacchi }
109*7fd79137SRobert Mustacchi
110*7fd79137SRobert Mustacchi if (unit_is_signed == false ||
111*7fd79137SRobert Mustacchi unit_length_in_bits != 32 ||
112*7fd79137SRobert Mustacchi input_block == NULL ||
113*7fd79137SRobert Mustacchi input_length_in_bytes == 0 ||
114*7fd79137SRobert Mustacchi output_length_in_units_ptr == NULL) {
115*7fd79137SRobert Mustacchi
116*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_BADBITC);
117*7fd79137SRobert Mustacchi return ((void *) DW_DLV_BADADDR);
118*7fd79137SRobert Mustacchi }
119*7fd79137SRobert Mustacchi
120*7fd79137SRobert Mustacchi /* At this point we assume the format is: signed 32 bit */
121*7fd79137SRobert Mustacchi
122*7fd79137SRobert Mustacchi /* first uncompress everything to find the total size. */
123*7fd79137SRobert Mustacchi
124*7fd79137SRobert Mustacchi output_length_in_units = 0;
125*7fd79137SRobert Mustacchi remain = input_length_in_bytes;
126*7fd79137SRobert Mustacchi ptr = input_block;
127*7fd79137SRobert Mustacchi while (remain > 0) {
128*7fd79137SRobert Mustacchi Dwarf_Signed num;
129*7fd79137SRobert Mustacchi Dwarf_Word len;
130*7fd79137SRobert Mustacchi num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
131*7fd79137SRobert Mustacchi ptr += len;
132*7fd79137SRobert Mustacchi remain -= len;
133*7fd79137SRobert Mustacchi output_length_in_units++;
134*7fd79137SRobert Mustacchi }
135*7fd79137SRobert Mustacchi
136*7fd79137SRobert Mustacchi if (remain != 0) {
137*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
138*7fd79137SRobert Mustacchi return((void *)DW_DLV_BADADDR);
139*7fd79137SRobert Mustacchi }
140*7fd79137SRobert Mustacchi
141*7fd79137SRobert Mustacchi /* then alloc */
142*7fd79137SRobert Mustacchi
143*7fd79137SRobert Mustacchi output_block = (void *)
144*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg,
145*7fd79137SRobert Mustacchi DW_DLA_STRING,
146*7fd79137SRobert Mustacchi output_length_in_units * (unit_length_in_bits / 8));
147*7fd79137SRobert Mustacchi if (output_block == NULL) {
148*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
149*7fd79137SRobert Mustacchi return((void*)DW_DLV_BADADDR);
150*7fd79137SRobert Mustacchi }
151*7fd79137SRobert Mustacchi
152*7fd79137SRobert Mustacchi /* then uncompress again and copy into new buffer */
153*7fd79137SRobert Mustacchi
154*7fd79137SRobert Mustacchi array = (Dwarf_sfixed *) output_block;
155*7fd79137SRobert Mustacchi remain = input_length_in_bytes;
156*7fd79137SRobert Mustacchi ptr = input_block;
157*7fd79137SRobert Mustacchi for (i=0; i<output_length_in_units && remain>0; i++) {
158*7fd79137SRobert Mustacchi Dwarf_Signed num;
159*7fd79137SRobert Mustacchi Dwarf_Word len;
160*7fd79137SRobert Mustacchi num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
161*7fd79137SRobert Mustacchi ptr += len;
162*7fd79137SRobert Mustacchi remain -= len;
163*7fd79137SRobert Mustacchi array[i] = num;
164*7fd79137SRobert Mustacchi }
165*7fd79137SRobert Mustacchi
166*7fd79137SRobert Mustacchi if (remain != 0) {
167*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING);
168*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
169*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR);
170*7fd79137SRobert Mustacchi }
171*7fd79137SRobert Mustacchi
172*7fd79137SRobert Mustacchi *output_length_in_units_ptr = output_length_in_units;
173*7fd79137SRobert Mustacchi return output_block;
174*7fd79137SRobert Mustacchi }
175*7fd79137SRobert Mustacchi
176*7fd79137SRobert Mustacchi void
dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg,void * space)177*7fd79137SRobert Mustacchi dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space)
178*7fd79137SRobert Mustacchi {
179*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, space, DW_DLA_STRING);
180*7fd79137SRobert Mustacchi }
181*7fd79137SRobert Mustacchi
182*7fd79137SRobert Mustacchi
183*7fd79137SRobert Mustacchi int
dwarf_whatform(Dwarf_Attribute attr,Dwarf_Half * return_form,Dwarf_Error * error)184*7fd79137SRobert Mustacchi dwarf_whatform(Dwarf_Attribute attr,
185*7fd79137SRobert Mustacchi Dwarf_Half * return_form, Dwarf_Error * error)
186*7fd79137SRobert Mustacchi {
187*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
188*7fd79137SRobert Mustacchi
189*7fd79137SRobert Mustacchi if (attr == NULL) {
190*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
191*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
192*7fd79137SRobert Mustacchi }
193*7fd79137SRobert Mustacchi
194*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
195*7fd79137SRobert Mustacchi if (cu_context == NULL) {
196*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
197*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
198*7fd79137SRobert Mustacchi }
199*7fd79137SRobert Mustacchi
200*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
201*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
202*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
203*7fd79137SRobert Mustacchi }
204*7fd79137SRobert Mustacchi
205*7fd79137SRobert Mustacchi *return_form = attr->ar_attribute_form;
206*7fd79137SRobert Mustacchi return (DW_DLV_OK);
207*7fd79137SRobert Mustacchi }
208*7fd79137SRobert Mustacchi
209*7fd79137SRobert Mustacchi
210*7fd79137SRobert Mustacchi /*
211*7fd79137SRobert Mustacchi This function is analogous to dwarf_whatform.
212*7fd79137SRobert Mustacchi It returns the attribute in attr instead of
213*7fd79137SRobert Mustacchi the form.
214*7fd79137SRobert Mustacchi */
215*7fd79137SRobert Mustacchi int
dwarf_whatattr(Dwarf_Attribute attr,Dwarf_Half * return_attr,Dwarf_Error * error)216*7fd79137SRobert Mustacchi dwarf_whatattr(Dwarf_Attribute attr,
217*7fd79137SRobert Mustacchi Dwarf_Half * return_attr, Dwarf_Error * error)
218*7fd79137SRobert Mustacchi {
219*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
220*7fd79137SRobert Mustacchi
221*7fd79137SRobert Mustacchi if (attr == NULL) {
222*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
223*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
224*7fd79137SRobert Mustacchi }
225*7fd79137SRobert Mustacchi
226*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
227*7fd79137SRobert Mustacchi if (cu_context == NULL) {
228*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
229*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
230*7fd79137SRobert Mustacchi }
231*7fd79137SRobert Mustacchi
232*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
233*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
234*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
235*7fd79137SRobert Mustacchi }
236*7fd79137SRobert Mustacchi
237*7fd79137SRobert Mustacchi *return_attr = (attr->ar_attribute);
238*7fd79137SRobert Mustacchi return DW_DLV_OK;
239*7fd79137SRobert Mustacchi }
240*7fd79137SRobert Mustacchi
241*7fd79137SRobert Mustacchi
242*7fd79137SRobert Mustacchi /*
243*7fd79137SRobert Mustacchi A global offset cannot be returned by this interface:
244*7fd79137SRobert Mustacchi see dwarf_global_formref().
245*7fd79137SRobert Mustacchi
246*7fd79137SRobert Mustacchi DW_FORM_ref_addr is considered an incorrect form
247*7fd79137SRobert Mustacchi for this call because DW_FORM_ref_addr is a global-offset into
248*7fd79137SRobert Mustacchi the debug_info section.
249*7fd79137SRobert Mustacchi
250*7fd79137SRobert Mustacchi For the same reason DW_FORM_data4/data8 are not returned
251*7fd79137SRobert Mustacchi from this function.
252*7fd79137SRobert Mustacchi
253*7fd79137SRobert Mustacchi For the same reason DW_FORM_sec_offset is not returned
254*7fd79137SRobert Mustacchi from this function, DW_FORM_sec_offset is a global offset
255*7fd79137SRobert Mustacchi (to various sections, not a CU relative offset.
256*7fd79137SRobert Mustacchi
257*7fd79137SRobert Mustacchi DW_FORM_ref_addr has a value which was documented in
258*7fd79137SRobert Mustacchi DWARF2 as address-size but which was always an offset
259*7fd79137SRobert Mustacchi so should have always been offset size (wording
260*7fd79137SRobert Mustacchi corrected in DWARF3).
261*7fd79137SRobert Mustacchi
262*7fd79137SRobert Mustacchi
263*7fd79137SRobert Mustacchi */
264*7fd79137SRobert Mustacchi int
dwarf_formref(Dwarf_Attribute attr,Dwarf_Off * ret_offset,Dwarf_Error * error)265*7fd79137SRobert Mustacchi dwarf_formref(Dwarf_Attribute attr,
266*7fd79137SRobert Mustacchi Dwarf_Off * ret_offset, Dwarf_Error * error)
267*7fd79137SRobert Mustacchi {
268*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
269*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = 0;
270*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
271*7fd79137SRobert Mustacchi
272*7fd79137SRobert Mustacchi
273*7fd79137SRobert Mustacchi if (attr == NULL) {
274*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
275*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
276*7fd79137SRobert Mustacchi }
277*7fd79137SRobert Mustacchi
278*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
279*7fd79137SRobert Mustacchi if (cu_context == NULL) {
280*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
281*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
282*7fd79137SRobert Mustacchi }
283*7fd79137SRobert Mustacchi
284*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
285*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
286*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
287*7fd79137SRobert Mustacchi }
288*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
289*7fd79137SRobert Mustacchi
290*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) {
291*7fd79137SRobert Mustacchi
292*7fd79137SRobert Mustacchi case DW_FORM_ref1:
293*7fd79137SRobert Mustacchi offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
294*7fd79137SRobert Mustacchi break;
295*7fd79137SRobert Mustacchi
296*7fd79137SRobert Mustacchi case DW_FORM_ref2:
297*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
298*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
299*7fd79137SRobert Mustacchi break;
300*7fd79137SRobert Mustacchi
301*7fd79137SRobert Mustacchi case DW_FORM_ref4:
302*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
303*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
304*7fd79137SRobert Mustacchi break;
305*7fd79137SRobert Mustacchi
306*7fd79137SRobert Mustacchi case DW_FORM_ref8:
307*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
308*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
309*7fd79137SRobert Mustacchi break;
310*7fd79137SRobert Mustacchi
311*7fd79137SRobert Mustacchi case DW_FORM_ref_udata:
312*7fd79137SRobert Mustacchi offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
313*7fd79137SRobert Mustacchi break;
314*7fd79137SRobert Mustacchi
315*7fd79137SRobert Mustacchi default:
316*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
317*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
318*7fd79137SRobert Mustacchi }
319*7fd79137SRobert Mustacchi
320*7fd79137SRobert Mustacchi /* Check that offset is within current cu portion of .debug_info. */
321*7fd79137SRobert Mustacchi if (offset >= cu_context->cc_length +
322*7fd79137SRobert Mustacchi cu_context->cc_length_size + cu_context->cc_extension_size) {
323*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
324*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
325*7fd79137SRobert Mustacchi }
326*7fd79137SRobert Mustacchi
327*7fd79137SRobert Mustacchi *ret_offset = (offset);
328*7fd79137SRobert Mustacchi return DW_DLV_OK;
329*7fd79137SRobert Mustacchi }
330*7fd79137SRobert Mustacchi
331*7fd79137SRobert Mustacchi /* dwarf_formsig8 returns in the caller-provided 8 byte area
332*7fd79137SRobert Mustacchi the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes
333*7fd79137SRobert Mustacchi directly to the caller). Not a string, an 8 byte
334*7fd79137SRobert Mustacchi MD5 hash. This function is new in DWARF4 libdwarf.
335*7fd79137SRobert Mustacchi */
dwarf_formsig8(Dwarf_Attribute attr,Dwarf_Sig8 * returned_sig_bytes,Dwarf_Error * error)336*7fd79137SRobert Mustacchi int dwarf_formsig8(Dwarf_Attribute attr,
337*7fd79137SRobert Mustacchi Dwarf_Sig8 * returned_sig_bytes,
338*7fd79137SRobert Mustacchi Dwarf_Error* error)
339*7fd79137SRobert Mustacchi {
340*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
341*7fd79137SRobert Mustacchi Dwarf_Unsigned field_end_offset = 0;
342*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
343*7fd79137SRobert Mustacchi
344*7fd79137SRobert Mustacchi
345*7fd79137SRobert Mustacchi if (attr == NULL) {
346*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
347*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
348*7fd79137SRobert Mustacchi }
349*7fd79137SRobert Mustacchi
350*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
351*7fd79137SRobert Mustacchi if (cu_context == NULL) {
352*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
353*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
354*7fd79137SRobert Mustacchi }
355*7fd79137SRobert Mustacchi
356*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
357*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
358*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
359*7fd79137SRobert Mustacchi }
360*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
361*7fd79137SRobert Mustacchi
362*7fd79137SRobert Mustacchi if(attr->ar_attribute_form != DW_FORM_ref_sig8 ) {
363*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_BAD_REF_SIG8_FORM);
364*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
365*7fd79137SRobert Mustacchi }
366*7fd79137SRobert Mustacchi
367*7fd79137SRobert Mustacchi field_end_offset = attr->ar_debug_info_ptr + sizeof(Dwarf_Sig8) -
368*7fd79137SRobert Mustacchi (dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset);
369*7fd79137SRobert Mustacchi /* Check that offset is within current cu portion of .debug_info. */
370*7fd79137SRobert Mustacchi if (field_end_offset > cu_context->cc_length +
371*7fd79137SRobert Mustacchi cu_context->cc_length_size + cu_context->cc_extension_size) {
372*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
373*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
374*7fd79137SRobert Mustacchi }
375*7fd79137SRobert Mustacchi
376*7fd79137SRobert Mustacchi memcpy(returned_sig_bytes, attr->ar_debug_info_ptr,
377*7fd79137SRobert Mustacchi sizeof(Dwarf_Sig8));
378*7fd79137SRobert Mustacchi return DW_DLV_OK;
379*7fd79137SRobert Mustacchi }
380*7fd79137SRobert Mustacchi
381*7fd79137SRobert Mustacchi
382*7fd79137SRobert Mustacchi /*
383*7fd79137SRobert Mustacchi Since this returns section-relative debug_info offsets,
384*7fd79137SRobert Mustacchi this can represent all REFERENCE forms correctly
385*7fd79137SRobert Mustacchi and allows all applicable forms.
386*7fd79137SRobert Mustacchi
387*7fd79137SRobert Mustacchi DW_FORM_ref_addr has a value which was documented in
388*7fd79137SRobert Mustacchi DWARF2 as address-size but which was always an offset
389*7fd79137SRobert Mustacchi so should have always been offset size (wording
390*7fd79137SRobert Mustacchi corrected in DWARF3).
391*7fd79137SRobert Mustacchi
392*7fd79137SRobert Mustacchi See the DWARF4 document for the 3 cases fitting
393*7fd79137SRobert Mustacchi reference forms. The caller must determine which section the
394*7fd79137SRobert Mustacchi reference 'points' to. The function added in November 2009,
395*7fd79137SRobert Mustacchi dwarf_get_form_class(), helps in this regard.
396*7fd79137SRobert Mustacchi
397*7fd79137SRobert Mustacchi */
398*7fd79137SRobert Mustacchi int
dwarf_global_formref(Dwarf_Attribute attr,Dwarf_Off * ret_offset,Dwarf_Error * error)399*7fd79137SRobert Mustacchi dwarf_global_formref(Dwarf_Attribute attr,
400*7fd79137SRobert Mustacchi Dwarf_Off * ret_offset, Dwarf_Error * error)
401*7fd79137SRobert Mustacchi {
402*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
403*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = 0;
404*7fd79137SRobert Mustacchi Dwarf_Addr ref_addr = 0;
405*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
406*7fd79137SRobert Mustacchi Dwarf_Half context_version = 0;
407*7fd79137SRobert Mustacchi
408*7fd79137SRobert Mustacchi if (attr == NULL) {
409*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
410*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
411*7fd79137SRobert Mustacchi }
412*7fd79137SRobert Mustacchi
413*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
414*7fd79137SRobert Mustacchi if (cu_context == NULL) {
415*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
416*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
417*7fd79137SRobert Mustacchi }
418*7fd79137SRobert Mustacchi context_version = cu_context->cc_version_stamp;
419*7fd79137SRobert Mustacchi
420*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
421*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
422*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
423*7fd79137SRobert Mustacchi }
424*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
425*7fd79137SRobert Mustacchi
426*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) {
427*7fd79137SRobert Mustacchi
428*7fd79137SRobert Mustacchi case DW_FORM_ref1:
429*7fd79137SRobert Mustacchi offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
430*7fd79137SRobert Mustacchi goto fixoffset;
431*7fd79137SRobert Mustacchi
432*7fd79137SRobert Mustacchi case DW_FORM_ref2:
433*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
434*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
435*7fd79137SRobert Mustacchi goto fixoffset;
436*7fd79137SRobert Mustacchi
437*7fd79137SRobert Mustacchi case DW_FORM_ref4:
438*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
439*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
440*7fd79137SRobert Mustacchi goto fixoffset;
441*7fd79137SRobert Mustacchi
442*7fd79137SRobert Mustacchi case DW_FORM_ref8:
443*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
444*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
445*7fd79137SRobert Mustacchi goto fixoffset;
446*7fd79137SRobert Mustacchi
447*7fd79137SRobert Mustacchi case DW_FORM_ref_udata:
448*7fd79137SRobert Mustacchi offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
449*7fd79137SRobert Mustacchi
450*7fd79137SRobert Mustacchi fixoffset: /* we have a local offset, make it
451*7fd79137SRobert Mustacchi global */
452*7fd79137SRobert Mustacchi
453*7fd79137SRobert Mustacchi /* check legality of offset */
454*7fd79137SRobert Mustacchi if (offset >= cu_context->cc_length +
455*7fd79137SRobert Mustacchi cu_context->cc_length_size +
456*7fd79137SRobert Mustacchi cu_context->cc_extension_size) {
457*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
458*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
459*7fd79137SRobert Mustacchi }
460*7fd79137SRobert Mustacchi
461*7fd79137SRobert Mustacchi /* globalize the offset */
462*7fd79137SRobert Mustacchi offset += cu_context->cc_debug_info_offset;
463*7fd79137SRobert Mustacchi break;
464*7fd79137SRobert Mustacchi /* The DWARF2 document did not make clear that
465*7fd79137SRobert Mustacchi DW_FORM_data4( and 8) were references with
466*7fd79137SRobert Mustacchi global offsets to some section.
467*7fd79137SRobert Mustacchi That was first clearly documented in DWARF3.
468*7fd79137SRobert Mustacchi In DWARF4 these two forms are no longer references. */
469*7fd79137SRobert Mustacchi case DW_FORM_data4:
470*7fd79137SRobert Mustacchi if(context_version == DW_CU_VERSION4) {
471*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
472*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
473*7fd79137SRobert Mustacchi }
474*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
475*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
476*7fd79137SRobert Mustacchi /* The offset is global. */
477*7fd79137SRobert Mustacchi break;
478*7fd79137SRobert Mustacchi case DW_FORM_data8:
479*7fd79137SRobert Mustacchi if(context_version == DW_CU_VERSION4) {
480*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
481*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
482*7fd79137SRobert Mustacchi }
483*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
484*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
485*7fd79137SRobert Mustacchi /* The offset is global. */
486*7fd79137SRobert Mustacchi break;
487*7fd79137SRobert Mustacchi case DW_FORM_ref_addr:
488*7fd79137SRobert Mustacchi case DW_FORM_sec_offset:
489*7fd79137SRobert Mustacchi {
490*7fd79137SRobert Mustacchi /* DW_FORM_sec_offset first exists in DWARF4.*/
491*7fd79137SRobert Mustacchi /* It is up to the caller to know what the offset
492*7fd79137SRobert Mustacchi of DW_FORM_sec_offset refers to,
493*7fd79137SRobert Mustacchi the offset is not going to refer to .debug_info! */
494*7fd79137SRobert Mustacchi unsigned length_size = cu_context->cc_length_size;
495*7fd79137SRobert Mustacchi if(length_size == 4) {
496*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
497*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
498*7fd79137SRobert Mustacchi } else if (length_size == 8) {
499*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
500*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
501*7fd79137SRobert Mustacchi } else {
502*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD);
503*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
504*7fd79137SRobert Mustacchi }
505*7fd79137SRobert Mustacchi }
506*7fd79137SRobert Mustacchi break;
507*7fd79137SRobert Mustacchi
508*7fd79137SRobert Mustacchi default:
509*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
510*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
511*7fd79137SRobert Mustacchi }
512*7fd79137SRobert Mustacchi
513*7fd79137SRobert Mustacchi /* We do not know what section the offset refers to, so
514*7fd79137SRobert Mustacchi we have no way to check it for correctness. */
515*7fd79137SRobert Mustacchi *ret_offset = offset;
516*7fd79137SRobert Mustacchi return DW_DLV_OK;
517*7fd79137SRobert Mustacchi }
518*7fd79137SRobert Mustacchi
519*7fd79137SRobert Mustacchi
520*7fd79137SRobert Mustacchi int
dwarf_formaddr(Dwarf_Attribute attr,Dwarf_Addr * return_addr,Dwarf_Error * error)521*7fd79137SRobert Mustacchi dwarf_formaddr(Dwarf_Attribute attr,
522*7fd79137SRobert Mustacchi Dwarf_Addr * return_addr, Dwarf_Error * error)
523*7fd79137SRobert Mustacchi {
524*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
525*7fd79137SRobert Mustacchi Dwarf_Addr ret_addr = 0;
526*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
527*7fd79137SRobert Mustacchi
528*7fd79137SRobert Mustacchi if (attr == NULL) {
529*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
530*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
531*7fd79137SRobert Mustacchi }
532*7fd79137SRobert Mustacchi
533*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
534*7fd79137SRobert Mustacchi if (cu_context == NULL) {
535*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
536*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
537*7fd79137SRobert Mustacchi }
538*7fd79137SRobert Mustacchi
539*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
540*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
541*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
542*7fd79137SRobert Mustacchi }
543*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
544*7fd79137SRobert Mustacchi
545*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_addr
546*7fd79137SRobert Mustacchi /* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
547*7fd79137SRobert Mustacchi DW_FORM_ref_addr was a mistake. The value returned in that
548*7fd79137SRobert Mustacchi case is NOT an address it is a global debug_info offset (ie,
549*7fd79137SRobert Mustacchi not CU-relative offset within the CU in debug_info). The
550*7fd79137SRobert Mustacchi Dwarf document refers to it as an address (misleadingly) in
551*7fd79137SRobert Mustacchi sec 6.5.4 where it describes the reference form. It is
552*7fd79137SRobert Mustacchi address-sized so that the linker can easily update it, but
553*7fd79137SRobert Mustacchi it is a reference inside the debug_info section. No longer
554*7fd79137SRobert Mustacchi allowed. */
555*7fd79137SRobert Mustacchi ) {
556*7fd79137SRobert Mustacchi
557*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
558*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
559*7fd79137SRobert Mustacchi cu_context->cc_address_size);
560*7fd79137SRobert Mustacchi *return_addr = ret_addr;
561*7fd79137SRobert Mustacchi return (DW_DLV_OK);
562*7fd79137SRobert Mustacchi }
563*7fd79137SRobert Mustacchi
564*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
565*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
566*7fd79137SRobert Mustacchi }
567*7fd79137SRobert Mustacchi
568*7fd79137SRobert Mustacchi
569*7fd79137SRobert Mustacchi int
dwarf_formflag(Dwarf_Attribute attr,Dwarf_Bool * ret_bool,Dwarf_Error * error)570*7fd79137SRobert Mustacchi dwarf_formflag(Dwarf_Attribute attr,
571*7fd79137SRobert Mustacchi Dwarf_Bool * ret_bool, Dwarf_Error * error)
572*7fd79137SRobert Mustacchi {
573*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
574*7fd79137SRobert Mustacchi
575*7fd79137SRobert Mustacchi if (attr == NULL) {
576*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
577*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
578*7fd79137SRobert Mustacchi }
579*7fd79137SRobert Mustacchi
580*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
581*7fd79137SRobert Mustacchi if (cu_context == NULL) {
582*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
583*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
584*7fd79137SRobert Mustacchi }
585*7fd79137SRobert Mustacchi
586*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
587*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
588*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
589*7fd79137SRobert Mustacchi }
590*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_flag_present) {
591*7fd79137SRobert Mustacchi /* Implicit means we don't read any data at all. Just
592*7fd79137SRobert Mustacchi the existence of the Form does it. DWARF4. */
593*7fd79137SRobert Mustacchi *ret_bool = 1;
594*7fd79137SRobert Mustacchi return (DW_DLV_OK);
595*7fd79137SRobert Mustacchi }
596*7fd79137SRobert Mustacchi
597*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_flag) {
598*7fd79137SRobert Mustacchi *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
599*7fd79137SRobert Mustacchi return (DW_DLV_OK);
600*7fd79137SRobert Mustacchi }
601*7fd79137SRobert Mustacchi _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
602*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
603*7fd79137SRobert Mustacchi }
604*7fd79137SRobert Mustacchi
605*7fd79137SRobert Mustacchi
606*7fd79137SRobert Mustacchi int
dwarf_formudata(Dwarf_Attribute attr,Dwarf_Unsigned * return_uval,Dwarf_Error * error)607*7fd79137SRobert Mustacchi dwarf_formudata(Dwarf_Attribute attr,
608*7fd79137SRobert Mustacchi Dwarf_Unsigned * return_uval, Dwarf_Error * error)
609*7fd79137SRobert Mustacchi {
610*7fd79137SRobert Mustacchi Dwarf_Unsigned ret_value = 0;
611*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
612*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
613*7fd79137SRobert Mustacchi
614*7fd79137SRobert Mustacchi if (attr == NULL) {
615*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
616*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
617*7fd79137SRobert Mustacchi }
618*7fd79137SRobert Mustacchi
619*7fd79137SRobert Mustacchi
620*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
621*7fd79137SRobert Mustacchi if (cu_context == NULL) {
622*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
623*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
624*7fd79137SRobert Mustacchi }
625*7fd79137SRobert Mustacchi
626*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
627*7fd79137SRobert Mustacchi if (dbg == NULL) {
628*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
629*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
630*7fd79137SRobert Mustacchi }
631*7fd79137SRobert Mustacchi
632*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) {
633*7fd79137SRobert Mustacchi
634*7fd79137SRobert Mustacchi case DW_FORM_data1:
635*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
636*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Small));
637*7fd79137SRobert Mustacchi *return_uval = ret_value;
638*7fd79137SRobert Mustacchi return DW_DLV_OK;
639*7fd79137SRobert Mustacchi
640*7fd79137SRobert Mustacchi /* READ_UNALIGNED does the right thing as it reads
641*7fd79137SRobert Mustacchi the right number bits and generates host order.
642*7fd79137SRobert Mustacchi So we can just assign to *return_uval. */
643*7fd79137SRobert Mustacchi case DW_FORM_data2:{
644*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
645*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
646*7fd79137SRobert Mustacchi *return_uval = ret_value;
647*7fd79137SRobert Mustacchi return DW_DLV_OK;
648*7fd79137SRobert Mustacchi }
649*7fd79137SRobert Mustacchi
650*7fd79137SRobert Mustacchi case DW_FORM_data4:{
651*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
652*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
653*7fd79137SRobert Mustacchi sizeof(Dwarf_ufixed));
654*7fd79137SRobert Mustacchi *return_uval = ret_value;
655*7fd79137SRobert Mustacchi return DW_DLV_OK;
656*7fd79137SRobert Mustacchi }
657*7fd79137SRobert Mustacchi
658*7fd79137SRobert Mustacchi case DW_FORM_data8:{
659*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
660*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
661*7fd79137SRobert Mustacchi sizeof(Dwarf_Unsigned));
662*7fd79137SRobert Mustacchi *return_uval = ret_value;
663*7fd79137SRobert Mustacchi return DW_DLV_OK;
664*7fd79137SRobert Mustacchi }
665*7fd79137SRobert Mustacchi break;
666*7fd79137SRobert Mustacchi case DW_FORM_udata:
667*7fd79137SRobert Mustacchi ret_value =
668*7fd79137SRobert Mustacchi (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
669*7fd79137SRobert Mustacchi *return_uval = ret_value;
670*7fd79137SRobert Mustacchi return DW_DLV_OK;
671*7fd79137SRobert Mustacchi
672*7fd79137SRobert Mustacchi
673*7fd79137SRobert Mustacchi /* see bug 583450. We do not allow reading sdata from a udata
674*7fd79137SRobert Mustacchi value. Caller can retry, calling sdata */
675*7fd79137SRobert Mustacchi
676*7fd79137SRobert Mustacchi
677*7fd79137SRobert Mustacchi default:
678*7fd79137SRobert Mustacchi break;
679*7fd79137SRobert Mustacchi }
680*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
681*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
682*7fd79137SRobert Mustacchi }
683*7fd79137SRobert Mustacchi
684*7fd79137SRobert Mustacchi
685*7fd79137SRobert Mustacchi int
dwarf_formsdata(Dwarf_Attribute attr,Dwarf_Signed * return_sval,Dwarf_Error * error)686*7fd79137SRobert Mustacchi dwarf_formsdata(Dwarf_Attribute attr,
687*7fd79137SRobert Mustacchi Dwarf_Signed * return_sval, Dwarf_Error * error)
688*7fd79137SRobert Mustacchi {
689*7fd79137SRobert Mustacchi Dwarf_Signed ret_value = 0;
690*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
691*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
692*7fd79137SRobert Mustacchi
693*7fd79137SRobert Mustacchi if (attr == NULL) {
694*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
695*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
696*7fd79137SRobert Mustacchi }
697*7fd79137SRobert Mustacchi
698*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
699*7fd79137SRobert Mustacchi if (cu_context == NULL) {
700*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
701*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
702*7fd79137SRobert Mustacchi }
703*7fd79137SRobert Mustacchi
704*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
705*7fd79137SRobert Mustacchi if (dbg == NULL) {
706*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
707*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
708*7fd79137SRobert Mustacchi }
709*7fd79137SRobert Mustacchi
710*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) {
711*7fd79137SRobert Mustacchi
712*7fd79137SRobert Mustacchi case DW_FORM_data1:
713*7fd79137SRobert Mustacchi *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr);
714*7fd79137SRobert Mustacchi return DW_DLV_OK;
715*7fd79137SRobert Mustacchi
716*7fd79137SRobert Mustacchi /* READ_UNALIGNED does not sign extend.
717*7fd79137SRobert Mustacchi So we have to use a cast to get the
718*7fd79137SRobert Mustacchi value sign extended in the right way for each case. */
719*7fd79137SRobert Mustacchi case DW_FORM_data2:{
720*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
721*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
722*7fd79137SRobert Mustacchi sizeof(Dwarf_Shalf));
723*7fd79137SRobert Mustacchi *return_sval = (Dwarf_Shalf) ret_value;
724*7fd79137SRobert Mustacchi return DW_DLV_OK;
725*7fd79137SRobert Mustacchi
726*7fd79137SRobert Mustacchi }
727*7fd79137SRobert Mustacchi
728*7fd79137SRobert Mustacchi case DW_FORM_data4:{
729*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
730*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
731*7fd79137SRobert Mustacchi sizeof(Dwarf_sfixed));
732*7fd79137SRobert Mustacchi *return_sval = (Dwarf_sfixed) ret_value;
733*7fd79137SRobert Mustacchi return DW_DLV_OK;
734*7fd79137SRobert Mustacchi }
735*7fd79137SRobert Mustacchi
736*7fd79137SRobert Mustacchi case DW_FORM_data8:{
737*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
738*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
739*7fd79137SRobert Mustacchi sizeof(Dwarf_Signed));
740*7fd79137SRobert Mustacchi *return_sval = (Dwarf_Signed) ret_value;
741*7fd79137SRobert Mustacchi return DW_DLV_OK;
742*7fd79137SRobert Mustacchi }
743*7fd79137SRobert Mustacchi
744*7fd79137SRobert Mustacchi case DW_FORM_sdata:
745*7fd79137SRobert Mustacchi ret_value =
746*7fd79137SRobert Mustacchi (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL));
747*7fd79137SRobert Mustacchi *return_sval = ret_value;
748*7fd79137SRobert Mustacchi return DW_DLV_OK;
749*7fd79137SRobert Mustacchi
750*7fd79137SRobert Mustacchi
751*7fd79137SRobert Mustacchi /* see bug 583450. We do not allow reading sdata from a udata
752*7fd79137SRobert Mustacchi value. Caller can retry, calling sdata */
753*7fd79137SRobert Mustacchi
754*7fd79137SRobert Mustacchi
755*7fd79137SRobert Mustacchi default:
756*7fd79137SRobert Mustacchi break;
757*7fd79137SRobert Mustacchi }
758*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
759*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
760*7fd79137SRobert Mustacchi }
761*7fd79137SRobert Mustacchi
762*7fd79137SRobert Mustacchi
763*7fd79137SRobert Mustacchi int
dwarf_formblock(Dwarf_Attribute attr,Dwarf_Block ** return_block,Dwarf_Error * error)764*7fd79137SRobert Mustacchi dwarf_formblock(Dwarf_Attribute attr,
765*7fd79137SRobert Mustacchi Dwarf_Block ** return_block, Dwarf_Error * error)
766*7fd79137SRobert Mustacchi {
767*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
768*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
769*7fd79137SRobert Mustacchi Dwarf_Unsigned length = 0;
770*7fd79137SRobert Mustacchi Dwarf_Small *data = 0;
771*7fd79137SRobert Mustacchi Dwarf_Word leb128_length = 0;
772*7fd79137SRobert Mustacchi Dwarf_Block *ret_block = 0;
773*7fd79137SRobert Mustacchi
774*7fd79137SRobert Mustacchi if (attr == NULL) {
775*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
776*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
777*7fd79137SRobert Mustacchi }
778*7fd79137SRobert Mustacchi
779*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
780*7fd79137SRobert Mustacchi if (cu_context == NULL) {
781*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
782*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
783*7fd79137SRobert Mustacchi }
784*7fd79137SRobert Mustacchi
785*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
786*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
787*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
788*7fd79137SRobert Mustacchi }
789*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
790*7fd79137SRobert Mustacchi
791*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) {
792*7fd79137SRobert Mustacchi
793*7fd79137SRobert Mustacchi case DW_FORM_block1:
794*7fd79137SRobert Mustacchi length = *(Dwarf_Small *) attr->ar_debug_info_ptr;
795*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small);
796*7fd79137SRobert Mustacchi break;
797*7fd79137SRobert Mustacchi
798*7fd79137SRobert Mustacchi case DW_FORM_block2:
799*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
800*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
801*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half);
802*7fd79137SRobert Mustacchi break;
803*7fd79137SRobert Mustacchi
804*7fd79137SRobert Mustacchi case DW_FORM_block4:
805*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
806*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
807*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed);
808*7fd79137SRobert Mustacchi break;
809*7fd79137SRobert Mustacchi
810*7fd79137SRobert Mustacchi case DW_FORM_block:
811*7fd79137SRobert Mustacchi length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr,
812*7fd79137SRobert Mustacchi &leb128_length);
813*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + leb128_length;
814*7fd79137SRobert Mustacchi break;
815*7fd79137SRobert Mustacchi
816*7fd79137SRobert Mustacchi default:
817*7fd79137SRobert Mustacchi _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
818*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
819*7fd79137SRobert Mustacchi }
820*7fd79137SRobert Mustacchi
821*7fd79137SRobert Mustacchi /* Check that block lies within current cu in .debug_info. */
822*7fd79137SRobert Mustacchi if (attr->ar_debug_info_ptr + length >=
823*7fd79137SRobert Mustacchi dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset +
824*7fd79137SRobert Mustacchi cu_context->cc_length + cu_context->cc_length_size +
825*7fd79137SRobert Mustacchi cu_context->cc_extension_size) {
826*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
827*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
828*7fd79137SRobert Mustacchi }
829*7fd79137SRobert Mustacchi
830*7fd79137SRobert Mustacchi ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
831*7fd79137SRobert Mustacchi if (ret_block == NULL) {
832*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
833*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
834*7fd79137SRobert Mustacchi }
835*7fd79137SRobert Mustacchi
836*7fd79137SRobert Mustacchi ret_block->bl_len = length;
837*7fd79137SRobert Mustacchi ret_block->bl_data = (Dwarf_Ptr) data;
838*7fd79137SRobert Mustacchi ret_block->bl_from_loclist = 0;
839*7fd79137SRobert Mustacchi ret_block->bl_section_offset = data - dbg->de_debug_info.dss_data;
840*7fd79137SRobert Mustacchi
841*7fd79137SRobert Mustacchi
842*7fd79137SRobert Mustacchi *return_block = ret_block;
843*7fd79137SRobert Mustacchi return (DW_DLV_OK);
844*7fd79137SRobert Mustacchi }
845*7fd79137SRobert Mustacchi
846*7fd79137SRobert Mustacchi
847*7fd79137SRobert Mustacchi /* Contrary to long standing documentation,
848*7fd79137SRobert Mustacchi The string pointer returned thru return_str must
849*7fd79137SRobert Mustacchi never have dwarf_dealloc() applied to it.
850*7fd79137SRobert Mustacchi Documentation fixed July 2005.
851*7fd79137SRobert Mustacchi */
852*7fd79137SRobert Mustacchi int
dwarf_formstring(Dwarf_Attribute attr,char ** return_str,Dwarf_Error * error)853*7fd79137SRobert Mustacchi dwarf_formstring(Dwarf_Attribute attr,
854*7fd79137SRobert Mustacchi char **return_str, Dwarf_Error * error)
855*7fd79137SRobert Mustacchi {
856*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
857*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
858*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = 0;
859*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR;
860*7fd79137SRobert Mustacchi
861*7fd79137SRobert Mustacchi if (attr == NULL) {
862*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
863*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
864*7fd79137SRobert Mustacchi }
865*7fd79137SRobert Mustacchi
866*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
867*7fd79137SRobert Mustacchi if (cu_context == NULL) {
868*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
869*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
870*7fd79137SRobert Mustacchi }
871*7fd79137SRobert Mustacchi
872*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) {
873*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
874*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
875*7fd79137SRobert Mustacchi }
876*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
877*7fd79137SRobert Mustacchi
878*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_string) {
879*7fd79137SRobert Mustacchi
880*7fd79137SRobert Mustacchi void *begin = attr->ar_debug_info_ptr;
881*7fd79137SRobert Mustacchi
882*7fd79137SRobert Mustacchi if (0 == dbg->de_assume_string_in_bounds) {
883*7fd79137SRobert Mustacchi /* Check that string lies within current cu in .debug_info.
884*7fd79137SRobert Mustacchi */
885*7fd79137SRobert Mustacchi void *end = dbg->de_debug_info.dss_data +
886*7fd79137SRobert Mustacchi cu_context->cc_debug_info_offset +
887*7fd79137SRobert Mustacchi cu_context->cc_length + cu_context->cc_length_size +
888*7fd79137SRobert Mustacchi cu_context->cc_extension_size;
889*7fd79137SRobert Mustacchi if (0 == _dwarf_string_valid(begin, end)) {
890*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
891*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
892*7fd79137SRobert Mustacchi }
893*7fd79137SRobert Mustacchi }
894*7fd79137SRobert Mustacchi *return_str = (char *) (begin);
895*7fd79137SRobert Mustacchi return DW_DLV_OK;
896*7fd79137SRobert Mustacchi }
897*7fd79137SRobert Mustacchi
898*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_strp) {
899*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
900*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr,
901*7fd79137SRobert Mustacchi cu_context->cc_length_size);
902*7fd79137SRobert Mustacchi
903*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
904*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
905*7fd79137SRobert Mustacchi return res;
906*7fd79137SRobert Mustacchi }
907*7fd79137SRobert Mustacchi if (0 == dbg->de_assume_string_in_bounds) {
908*7fd79137SRobert Mustacchi /* Check that string lies within current cu in .debug_info.
909*7fd79137SRobert Mustacchi */
910*7fd79137SRobert Mustacchi void *end = dbg->de_debug_str.dss_data +
911*7fd79137SRobert Mustacchi dbg->de_debug_str.dss_size;
912*7fd79137SRobert Mustacchi void*begin = dbg->de_debug_str.dss_data + offset;
913*7fd79137SRobert Mustacchi if (0 == _dwarf_string_valid(begin, end)) {
914*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_STRP_OFFSET_BAD);
915*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
916*7fd79137SRobert Mustacchi }
917*7fd79137SRobert Mustacchi }
918*7fd79137SRobert Mustacchi *return_str = (char *) (dbg->de_debug_str.dss_data + offset);
919*7fd79137SRobert Mustacchi return DW_DLV_OK;
920*7fd79137SRobert Mustacchi }
921*7fd79137SRobert Mustacchi
922*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
923*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
924*7fd79137SRobert Mustacchi }
925*7fd79137SRobert Mustacchi
926*7fd79137SRobert Mustacchi int
dwarf_formexprloc(Dwarf_Attribute attr,Dwarf_Unsigned * return_exprlen,Dwarf_Ptr * block_ptr,Dwarf_Error * error)927*7fd79137SRobert Mustacchi dwarf_formexprloc(Dwarf_Attribute attr,
928*7fd79137SRobert Mustacchi Dwarf_Unsigned * return_exprlen,
929*7fd79137SRobert Mustacchi Dwarf_Ptr * block_ptr,
930*7fd79137SRobert Mustacchi Dwarf_Error * error)
931*7fd79137SRobert Mustacchi {
932*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0;
933*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0;
934*7fd79137SRobert Mustacchi
935*7fd79137SRobert Mustacchi if (attr == NULL) {
936*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
937*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
938*7fd79137SRobert Mustacchi }
939*7fd79137SRobert Mustacchi
940*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context;
941*7fd79137SRobert Mustacchi if (cu_context == NULL) {
942*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
943*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
944*7fd79137SRobert Mustacchi }
945*7fd79137SRobert Mustacchi
946*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg;
947*7fd79137SRobert Mustacchi if (dbg == NULL) {
948*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
949*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
950*7fd79137SRobert Mustacchi }
951*7fd79137SRobert Mustacchi
952*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_exprloc ) {
953*7fd79137SRobert Mustacchi Dwarf_Unsigned exprlen =
954*7fd79137SRobert Mustacchi (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
955*7fd79137SRobert Mustacchi Dwarf_Small * addr = attr->ar_debug_info_ptr;
956*7fd79137SRobert Mustacchi *return_exprlen = exprlen;
957*7fd79137SRobert Mustacchi *block_ptr = addr + exprlen;
958*7fd79137SRobert Mustacchi return DW_DLV_OK;
959*7fd79137SRobert Mustacchi
960*7fd79137SRobert Mustacchi }
961*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD);
962*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
963*7fd79137SRobert Mustacchi }
964