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