xref: /titanic_51/usr/src/lib/libdwarf/common/dwarf_form.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
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
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
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 *
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
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
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
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
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 */
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
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
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
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
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
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
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
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
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