xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_form.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi   Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
3bc1f688bSRobert Mustacchi   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2008-2018 David Anderson. All rights reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved.
6bc1f688bSRobert Mustacchi 
7bc1f688bSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
8bc1f688bSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
9bc1f688bSRobert Mustacchi   as published by the Free Software Foundation.
10bc1f688bSRobert Mustacchi 
11bc1f688bSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
12bc1f688bSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
13bc1f688bSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14bc1f688bSRobert Mustacchi 
15bc1f688bSRobert Mustacchi   Further, this software is distributed without any warranty that it is
16bc1f688bSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
17bc1f688bSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
18bc1f688bSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
19bc1f688bSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
20bc1f688bSRobert Mustacchi   other software, or any other product whatsoever.
21bc1f688bSRobert Mustacchi 
22bc1f688bSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
23bc1f688bSRobert Mustacchi   License along with this program; if not, write the Free Software
24bc1f688bSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25bc1f688bSRobert Mustacchi   USA.
26bc1f688bSRobert Mustacchi 
27bc1f688bSRobert Mustacchi */
28bc1f688bSRobert Mustacchi 
29bc1f688bSRobert Mustacchi #include "config.h"
30*4d9fdb46SRobert Mustacchi #include <stdio.h>
31bc1f688bSRobert Mustacchi #include "dwarf_incl.h"
32*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
33*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
34*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
35*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
36bc1f688bSRobert Mustacchi #include "dwarf_die_deliv.h"
37*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
38*4d9fdb46SRobert Mustacchi 
39*4d9fdb46SRobert Mustacchi #define TRUE 1
40*4d9fdb46SRobert Mustacchi #define FALSE 0
41*4d9fdb46SRobert Mustacchi 
42*4d9fdb46SRobert Mustacchi /*  It is necessary at times to cause errors of this sort
43*4d9fdb46SRobert Mustacchi     in determining what we really have.  So best to avoid
44*4d9fdb46SRobert Mustacchi     too much malloc and free, hence the static constructor
45*4d9fdb46SRobert Mustacchi     dwarfstring will use malloc if we guess too-small
46*4d9fdb46SRobert Mustacchi     for the size of mbuf. */
47*4d9fdb46SRobert Mustacchi static void
generate_form_error(Dwarf_Debug dbg,Dwarf_Error * error,unsigned form,int err_code,const char * errname,const char * funcname)48*4d9fdb46SRobert Mustacchi generate_form_error(Dwarf_Debug dbg,
49*4d9fdb46SRobert Mustacchi     Dwarf_Error *error,
50*4d9fdb46SRobert Mustacchi     unsigned form,
51*4d9fdb46SRobert Mustacchi     int err_code,
52*4d9fdb46SRobert Mustacchi     const char *errname,
53*4d9fdb46SRobert Mustacchi     const char *funcname)
54*4d9fdb46SRobert Mustacchi {
55*4d9fdb46SRobert Mustacchi     dwarfstring m;
56*4d9fdb46SRobert Mustacchi     char mbuf[DWARFSTRING_ALLOC_SIZE];
57*4d9fdb46SRobert Mustacchi     const char * defaultname = "<unknown form>";
58*4d9fdb46SRobert Mustacchi 
59*4d9fdb46SRobert Mustacchi     dwarfstring_constructor_static(&m,mbuf,
60*4d9fdb46SRobert Mustacchi         sizeof(mbuf));
61*4d9fdb46SRobert Mustacchi     dwarfstring_append(&m,(char *)errname);
62*4d9fdb46SRobert Mustacchi     dwarfstring_append(&m,": In function ");
63*4d9fdb46SRobert Mustacchi     dwarfstring_append(&m,(char *)funcname);
64*4d9fdb46SRobert Mustacchi     dwarfstring_append_printf_u(&m,
65*4d9fdb46SRobert Mustacchi         " on seeing form  0x%x ",form);
66*4d9fdb46SRobert Mustacchi     dwarf_get_FORM_name(form,&defaultname);
67*4d9fdb46SRobert Mustacchi     dwarfstring_append_printf_s(&m,
68*4d9fdb46SRobert Mustacchi         " (%s)",(char *)defaultname);
69*4d9fdb46SRobert Mustacchi     _dwarf_error_string(dbg,error,err_code,
70*4d9fdb46SRobert Mustacchi         dwarfstring_string(&m));
71*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&m);
72*4d9fdb46SRobert Mustacchi }
73*4d9fdb46SRobert Mustacchi 
74*4d9fdb46SRobert Mustacchi /* This code was repeated many times, now it
75*4d9fdb46SRobert Mustacchi    is all in one place. */
76*4d9fdb46SRobert Mustacchi static int
get_attr_dbg(Dwarf_Debug * dbg,Dwarf_CU_Context * cu_context,Dwarf_Attribute attr,Dwarf_Error * error)77*4d9fdb46SRobert Mustacchi get_attr_dbg(Dwarf_Debug *dbg,
78*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context * cu_context,
79*4d9fdb46SRobert Mustacchi     Dwarf_Attribute attr,
80*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
81*4d9fdb46SRobert Mustacchi {
82*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cup;
83*4d9fdb46SRobert Mustacchi     if (attr == NULL) {
84*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
85*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
86*4d9fdb46SRobert Mustacchi     }
87*4d9fdb46SRobert Mustacchi 
88*4d9fdb46SRobert Mustacchi     cup = attr->ar_cu_context;
89*4d9fdb46SRobert Mustacchi     if (cup == NULL) {
90*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
91*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
92*4d9fdb46SRobert Mustacchi     }
93*4d9fdb46SRobert Mustacchi 
94*4d9fdb46SRobert Mustacchi     if (cup->cc_dbg == NULL) {
95*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
96*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
97*4d9fdb46SRobert Mustacchi     }
98*4d9fdb46SRobert Mustacchi     *cu_context = cup;
99*4d9fdb46SRobert Mustacchi     *dbg = cup->cc_dbg;
100*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
101*4d9fdb46SRobert Mustacchi 
102*4d9fdb46SRobert Mustacchi }
103bc1f688bSRobert Mustacchi 
104bc1f688bSRobert Mustacchi int
dwarf_hasform(Dwarf_Attribute attr,Dwarf_Half form,Dwarf_Bool * return_bool,Dwarf_Error * error)105bc1f688bSRobert Mustacchi dwarf_hasform(Dwarf_Attribute attr,
106bc1f688bSRobert Mustacchi     Dwarf_Half form,
107bc1f688bSRobert Mustacchi     Dwarf_Bool * return_bool, Dwarf_Error * error)
108bc1f688bSRobert Mustacchi {
109*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
110bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
111bc1f688bSRobert Mustacchi 
112*4d9fdb46SRobert Mustacchi     int res  =get_attr_dbg(&dbg,&cu_context, attr,error);
113*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
114*4d9fdb46SRobert Mustacchi         return res;
115bc1f688bSRobert Mustacchi     }
116bc1f688bSRobert Mustacchi     *return_bool = (attr->ar_attribute_form == form);
117bc1f688bSRobert Mustacchi     return DW_DLV_OK;
118bc1f688bSRobert Mustacchi }
119bc1f688bSRobert Mustacchi 
120bc1f688bSRobert Mustacchi /* Not often called, we do not worry about efficiency here.
121bc1f688bSRobert Mustacchi    The dwarf_whatform() call does the sanity checks for us.
122bc1f688bSRobert Mustacchi */
123bc1f688bSRobert Mustacchi int
dwarf_whatform_direct(Dwarf_Attribute attr,Dwarf_Half * return_form,Dwarf_Error * error)124bc1f688bSRobert Mustacchi dwarf_whatform_direct(Dwarf_Attribute attr,
125bc1f688bSRobert Mustacchi     Dwarf_Half * return_form, Dwarf_Error * error)
126bc1f688bSRobert Mustacchi {
127bc1f688bSRobert Mustacchi     int res = dwarf_whatform(attr, return_form, error);
128bc1f688bSRobert Mustacchi 
129bc1f688bSRobert Mustacchi     if (res != DW_DLV_OK) {
130bc1f688bSRobert Mustacchi         return res;
131bc1f688bSRobert Mustacchi     }
132bc1f688bSRobert Mustacchi 
133bc1f688bSRobert Mustacchi     *return_form = attr->ar_attribute_form_direct;
134bc1f688bSRobert Mustacchi     return (DW_DLV_OK);
135bc1f688bSRobert Mustacchi }
136*4d9fdb46SRobert Mustacchi 
137*4d9fdb46SRobert Mustacchi /*  Pass in the content of a block and the length of that
138*4d9fdb46SRobert Mustacchi     content. On success return DW_DLV_OK and set *value_count
139*4d9fdb46SRobert Mustacchi     to the size of the array returned through value_array. */
140*4d9fdb46SRobert Mustacchi int
dwarf_uncompress_integer_block_a(Dwarf_Debug dbg,Dwarf_Unsigned input_length_in_bytes,void * input_block,Dwarf_Unsigned * value_count,Dwarf_Signed ** value_array,Dwarf_Error * error)141*4d9fdb46SRobert Mustacchi dwarf_uncompress_integer_block_a(Dwarf_Debug dbg,
142*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned     input_length_in_bytes,
143*4d9fdb46SRobert Mustacchi     void             * input_block,
144*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned   * value_count,
145*4d9fdb46SRobert Mustacchi     Dwarf_Signed    ** value_array,
146*4d9fdb46SRobert Mustacchi     Dwarf_Error      * error)
147*4d9fdb46SRobert Mustacchi {
148*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned output_length_in_units = 0;
149*4d9fdb46SRobert Mustacchi     Dwarf_Signed * output_block = 0;
150*4d9fdb46SRobert Mustacchi     unsigned i = 0;
151*4d9fdb46SRobert Mustacchi     char * ptr = 0;
152*4d9fdb46SRobert Mustacchi     int remain = 0;
153*4d9fdb46SRobert Mustacchi     Dwarf_Signed * array = 0;
154*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+
155*4d9fdb46SRobert Mustacchi         input_length_in_bytes;
156*4d9fdb46SRobert Mustacchi 
157*4d9fdb46SRobert Mustacchi     output_length_in_units = 0;
158*4d9fdb46SRobert Mustacchi     remain = input_length_in_bytes;
159*4d9fdb46SRobert Mustacchi     ptr = input_block;
160*4d9fdb46SRobert Mustacchi     while (remain > 0) {
161*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned len = 0;
162*4d9fdb46SRobert Mustacchi         Dwarf_Signed value = 0;
163*4d9fdb46SRobert Mustacchi         int rres = 0;
164*4d9fdb46SRobert Mustacchi 
165*4d9fdb46SRobert Mustacchi         rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr,
166*4d9fdb46SRobert Mustacchi             &len, &value,endptr);
167*4d9fdb46SRobert Mustacchi         if (rres != DW_DLV_OK) {
168*4d9fdb46SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER);
169*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
170*4d9fdb46SRobert Mustacchi         }
171*4d9fdb46SRobert Mustacchi         ptr += len;
172*4d9fdb46SRobert Mustacchi         remain -= len;
173*4d9fdb46SRobert Mustacchi         output_length_in_units++;
174*4d9fdb46SRobert Mustacchi     }
175*4d9fdb46SRobert Mustacchi     if (remain != 0) {
176*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
177*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
178*4d9fdb46SRobert Mustacchi     }
179*4d9fdb46SRobert Mustacchi 
180*4d9fdb46SRobert Mustacchi     output_block = (Dwarf_Signed*)
181*4d9fdb46SRobert Mustacchi         _dwarf_get_alloc(dbg,
182*4d9fdb46SRobert Mustacchi             DW_DLA_STRING,
183*4d9fdb46SRobert Mustacchi             output_length_in_units * sizeof(Dwarf_Signed));
184*4d9fdb46SRobert Mustacchi     if (!output_block) {
185*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
186*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
187*4d9fdb46SRobert Mustacchi     }
188*4d9fdb46SRobert Mustacchi     array = output_block;
189*4d9fdb46SRobert Mustacchi     remain = input_length_in_bytes;
190*4d9fdb46SRobert Mustacchi     ptr = input_block;
191*4d9fdb46SRobert Mustacchi     for (i=0; i<output_length_in_units && remain>0; i++) {
192*4d9fdb46SRobert Mustacchi         Dwarf_Signed num;
193*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned len;
194*4d9fdb46SRobert Mustacchi         int sres = 0;
195*4d9fdb46SRobert Mustacchi 
196*4d9fdb46SRobert Mustacchi         sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr,
197*4d9fdb46SRobert Mustacchi             &len, &num,endptr);
198*4d9fdb46SRobert Mustacchi         if (sres != DW_DLV_OK) {
199*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,output_block,DW_DLA_STRING);
200*4d9fdb46SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER);
201*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
202*4d9fdb46SRobert Mustacchi         }
203*4d9fdb46SRobert Mustacchi         ptr += len;
204*4d9fdb46SRobert Mustacchi         remain -= len;
205*4d9fdb46SRobert Mustacchi         array[i] = num;
206*4d9fdb46SRobert Mustacchi     }
207*4d9fdb46SRobert Mustacchi 
208*4d9fdb46SRobert Mustacchi     if (remain != 0) {
209*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg, (unsigned char *)output_block,
210*4d9fdb46SRobert Mustacchi             DW_DLA_STRING);
211*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
212*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
213*4d9fdb46SRobert Mustacchi     }
214*4d9fdb46SRobert Mustacchi 
215*4d9fdb46SRobert Mustacchi     *value_count = output_length_in_units;
216*4d9fdb46SRobert Mustacchi     *value_array = output_block;
217*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
218*4d9fdb46SRobert Mustacchi }
219*4d9fdb46SRobert Mustacchi 
220*4d9fdb46SRobert Mustacchi /*  This code was contributed around 2007
221*4d9fdb46SRobert Mustacchi     and the return value is in the wrong form.
222*4d9fdb46SRobert Mustacchi     See dwarf_uncompress_integer_block_a() above.
223*4d9fdb46SRobert Mustacchi 
224*4d9fdb46SRobert Mustacchi     As of 2019 it is not clear that Sun Sparc
225*4d9fdb46SRobert Mustacchi     compilers are in current use, nor whether
226*4d9fdb46SRobert Mustacchi     there is a reason to make reads of
227*4d9fdb46SRobert Mustacchi     this data format safe from corrupted object files.
228*4d9fdb46SRobert Mustacchi */
229bc1f688bSRobert 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)230bc1f688bSRobert Mustacchi dwarf_uncompress_integer_block(
231bc1f688bSRobert Mustacchi     Dwarf_Debug      dbg,
232bc1f688bSRobert Mustacchi     Dwarf_Bool       unit_is_signed,
233bc1f688bSRobert Mustacchi     Dwarf_Small      unit_length_in_bits,
234bc1f688bSRobert Mustacchi     void*            input_block,
235bc1f688bSRobert Mustacchi     Dwarf_Unsigned   input_length_in_bytes,
236bc1f688bSRobert Mustacchi     Dwarf_Unsigned*  output_length_in_units_ptr,
237bc1f688bSRobert Mustacchi     Dwarf_Error*     error
238bc1f688bSRobert Mustacchi )
239bc1f688bSRobert Mustacchi {
240bc1f688bSRobert Mustacchi     Dwarf_Unsigned output_length_in_units = 0;
241bc1f688bSRobert Mustacchi     void * output_block = 0;
242*4d9fdb46SRobert Mustacchi     unsigned i = 0;
243bc1f688bSRobert Mustacchi     char * ptr = 0;
244bc1f688bSRobert Mustacchi     int remain = 0;
245*4d9fdb46SRobert Mustacchi     /*  This only applies to Sun and there an unsigned
246*4d9fdb46SRobert Mustacchi         is 4 bytes so this works.  As with
247*4d9fdb46SRobert Mustacchi         most linux. */
248*4d9fdb46SRobert Mustacchi     unsigned * array = 0;
249*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+
250*4d9fdb46SRobert Mustacchi         input_length_in_bytes;
251bc1f688bSRobert Mustacchi 
252bc1f688bSRobert Mustacchi     if (dbg == NULL) {
253bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
254bc1f688bSRobert Mustacchi         return((void *)DW_DLV_BADADDR);
255bc1f688bSRobert Mustacchi     }
256bc1f688bSRobert Mustacchi 
257*4d9fdb46SRobert Mustacchi 
258bc1f688bSRobert Mustacchi     if (unit_is_signed == false ||
259bc1f688bSRobert Mustacchi         unit_length_in_bits != 32 ||
260bc1f688bSRobert Mustacchi         input_block == NULL ||
261bc1f688bSRobert Mustacchi         input_length_in_bytes == 0 ||
262bc1f688bSRobert Mustacchi         output_length_in_units_ptr == NULL) {
263bc1f688bSRobert Mustacchi 
264bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_BADBITC);
265bc1f688bSRobert Mustacchi         return ((void *) DW_DLV_BADADDR);
266bc1f688bSRobert Mustacchi     }
267bc1f688bSRobert Mustacchi 
268bc1f688bSRobert Mustacchi     /* At this point we assume the format is: signed 32 bit */
269bc1f688bSRobert Mustacchi 
270bc1f688bSRobert Mustacchi     /* first uncompress everything to find the total size. */
271bc1f688bSRobert Mustacchi 
272bc1f688bSRobert Mustacchi     output_length_in_units = 0;
273bc1f688bSRobert Mustacchi     remain = input_length_in_bytes;
274bc1f688bSRobert Mustacchi     ptr = input_block;
275bc1f688bSRobert Mustacchi     while (remain > 0) {
276*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned len = 0;
277*4d9fdb46SRobert Mustacchi         Dwarf_Signed value = 0;
278*4d9fdb46SRobert Mustacchi         int rres = 0;
279*4d9fdb46SRobert Mustacchi 
280*4d9fdb46SRobert Mustacchi         rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr,
281*4d9fdb46SRobert Mustacchi             &len, &value,endptr);
282*4d9fdb46SRobert Mustacchi         if (rres != DW_DLV_OK) {
283*4d9fdb46SRobert Mustacchi             return ((void *)DW_DLV_BADADDR);
284*4d9fdb46SRobert Mustacchi         }
285bc1f688bSRobert Mustacchi         ptr += len;
286bc1f688bSRobert Mustacchi         remain -= len;
287bc1f688bSRobert Mustacchi         output_length_in_units++;
288bc1f688bSRobert Mustacchi     }
289bc1f688bSRobert Mustacchi 
290bc1f688bSRobert Mustacchi     if (remain != 0) {
291bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
292bc1f688bSRobert Mustacchi         return((void *)DW_DLV_BADADDR);
293bc1f688bSRobert Mustacchi     }
294bc1f688bSRobert Mustacchi 
295bc1f688bSRobert Mustacchi     /* then alloc */
296bc1f688bSRobert Mustacchi 
297bc1f688bSRobert Mustacchi     output_block = (void *)
298bc1f688bSRobert Mustacchi         _dwarf_get_alloc(dbg,
299bc1f688bSRobert Mustacchi             DW_DLA_STRING,
300bc1f688bSRobert Mustacchi             output_length_in_units * (unit_length_in_bits / 8));
301bc1f688bSRobert Mustacchi     if (output_block == NULL) {
302bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
303bc1f688bSRobert Mustacchi         return((void*)DW_DLV_BADADDR);
304bc1f688bSRobert Mustacchi     }
305bc1f688bSRobert Mustacchi 
306bc1f688bSRobert Mustacchi     /* then uncompress again and copy into new buffer */
307bc1f688bSRobert Mustacchi 
308*4d9fdb46SRobert Mustacchi     array = (unsigned *) output_block;
309bc1f688bSRobert Mustacchi     remain = input_length_in_bytes;
310bc1f688bSRobert Mustacchi     ptr = input_block;
311bc1f688bSRobert Mustacchi     for (i=0; i<output_length_in_units && remain>0; i++) {
312bc1f688bSRobert Mustacchi         Dwarf_Signed num;
313*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned len;
314*4d9fdb46SRobert Mustacchi         int sres = 0;
315*4d9fdb46SRobert Mustacchi 
316*4d9fdb46SRobert Mustacchi         sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr,
317*4d9fdb46SRobert Mustacchi             &len, &num,endptr);
318*4d9fdb46SRobert Mustacchi         if (sres != DW_DLV_OK) {
319*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,output_block,DW_DLA_STRING);
320*4d9fdb46SRobert Mustacchi             return ((void *) DW_DLV_BADADDR);
321*4d9fdb46SRobert Mustacchi         }
322bc1f688bSRobert Mustacchi         ptr += len;
323bc1f688bSRobert Mustacchi         remain -= len;
324bc1f688bSRobert Mustacchi         array[i] = num;
325bc1f688bSRobert Mustacchi     }
326bc1f688bSRobert Mustacchi 
327bc1f688bSRobert Mustacchi     if (remain != 0) {
328bc1f688bSRobert Mustacchi         dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING);
329bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
330bc1f688bSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
331bc1f688bSRobert Mustacchi     }
332bc1f688bSRobert Mustacchi 
333bc1f688bSRobert Mustacchi     *output_length_in_units_ptr = output_length_in_units;
334bc1f688bSRobert Mustacchi     return output_block;
335bc1f688bSRobert Mustacchi }
336bc1f688bSRobert Mustacchi 
337bc1f688bSRobert Mustacchi void
dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg,void * space)338bc1f688bSRobert Mustacchi dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space)
339bc1f688bSRobert Mustacchi {
340bc1f688bSRobert Mustacchi     dwarf_dealloc(dbg, space, DW_DLA_STRING);
341bc1f688bSRobert Mustacchi }
342bc1f688bSRobert Mustacchi 
343bc1f688bSRobert Mustacchi 
344bc1f688bSRobert Mustacchi int
dwarf_whatform(Dwarf_Attribute attr,Dwarf_Half * return_form,Dwarf_Error * error)345bc1f688bSRobert Mustacchi dwarf_whatform(Dwarf_Attribute attr,
346bc1f688bSRobert Mustacchi     Dwarf_Half * return_form, Dwarf_Error * error)
347bc1f688bSRobert Mustacchi {
348bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
349*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
350bc1f688bSRobert Mustacchi 
351*4d9fdb46SRobert Mustacchi     int res  =get_attr_dbg(&dbg,&cu_context, attr,error);
352*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
353*4d9fdb46SRobert Mustacchi         return res;
354bc1f688bSRobert Mustacchi     }
355bc1f688bSRobert Mustacchi     *return_form = attr->ar_attribute_form;
356bc1f688bSRobert Mustacchi     return (DW_DLV_OK);
357bc1f688bSRobert Mustacchi }
358bc1f688bSRobert Mustacchi 
359bc1f688bSRobert Mustacchi 
360bc1f688bSRobert Mustacchi /*
361bc1f688bSRobert Mustacchi     This function is analogous to dwarf_whatform.
362bc1f688bSRobert Mustacchi     It returns the attribute in attr instead of
363bc1f688bSRobert Mustacchi     the form.
364bc1f688bSRobert Mustacchi */
365bc1f688bSRobert Mustacchi int
dwarf_whatattr(Dwarf_Attribute attr,Dwarf_Half * return_attr,Dwarf_Error * error)366bc1f688bSRobert Mustacchi dwarf_whatattr(Dwarf_Attribute attr,
367bc1f688bSRobert Mustacchi     Dwarf_Half * return_attr, Dwarf_Error * error)
368bc1f688bSRobert Mustacchi {
369bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
370*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
371bc1f688bSRobert Mustacchi 
372*4d9fdb46SRobert Mustacchi     int res  =get_attr_dbg(&dbg,&cu_context, attr,error);
373*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
374*4d9fdb46SRobert Mustacchi         return res;
375bc1f688bSRobert Mustacchi     }
376bc1f688bSRobert Mustacchi     *return_attr = (attr->ar_attribute);
377bc1f688bSRobert Mustacchi     return DW_DLV_OK;
378bc1f688bSRobert Mustacchi }
379bc1f688bSRobert Mustacchi 
380bc1f688bSRobert Mustacchi 
381*4d9fdb46SRobert Mustacchi /*  Convert an offset within the local CU into a section-relative
382*4d9fdb46SRobert Mustacchi     debug_info (or debug_types) offset.
383*4d9fdb46SRobert Mustacchi     See dwarf_global_formref() and dwarf_formref()
384*4d9fdb46SRobert Mustacchi     for additional information on conversion rules.
385*4d9fdb46SRobert Mustacchi */
386*4d9fdb46SRobert Mustacchi int
dwarf_convert_to_global_offset(Dwarf_Attribute attr,Dwarf_Off offset,Dwarf_Off * ret_offset,Dwarf_Error * error)387*4d9fdb46SRobert Mustacchi dwarf_convert_to_global_offset(Dwarf_Attribute attr,
388*4d9fdb46SRobert Mustacchi     Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error)
389*4d9fdb46SRobert Mustacchi {
390*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
391*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
392*4d9fdb46SRobert Mustacchi     int res = 0;
393*4d9fdb46SRobert Mustacchi 
394*4d9fdb46SRobert Mustacchi     res  = get_attr_dbg(&dbg,&cu_context,attr,error);
395*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
396*4d9fdb46SRobert Mustacchi         return res;
397*4d9fdb46SRobert Mustacchi     }
398*4d9fdb46SRobert Mustacchi     switch (attr->ar_attribute_form) {
399*4d9fdb46SRobert Mustacchi     case DW_FORM_ref1:
400*4d9fdb46SRobert Mustacchi     case DW_FORM_ref2:
401*4d9fdb46SRobert Mustacchi     case DW_FORM_ref4:
402*4d9fdb46SRobert Mustacchi     case DW_FORM_ref8:
403*4d9fdb46SRobert Mustacchi     case DW_FORM_ref_udata:
404*4d9fdb46SRobert Mustacchi         /*  It is a cu-local offset. Convert to section-global. */
405*4d9fdb46SRobert Mustacchi         /*  It would be nice to put some code to check
406*4d9fdb46SRobert Mustacchi             legality of the offset */
407*4d9fdb46SRobert Mustacchi         /*  cc_debug_offset always has any DWP Package File
408*4d9fdb46SRobert Mustacchi             offset included (when the cu_context created)
409*4d9fdb46SRobert Mustacchi             so there is no extra work for DWP.
410*4d9fdb46SRobert Mustacchi             Globalize the offset */
411*4d9fdb46SRobert Mustacchi         offset += cu_context->cc_debug_offset;
412*4d9fdb46SRobert Mustacchi 
413*4d9fdb46SRobert Mustacchi         break;
414*4d9fdb46SRobert Mustacchi 
415*4d9fdb46SRobert Mustacchi     case DW_FORM_ref_addr:
416*4d9fdb46SRobert Mustacchi         /*  This offset is defined to be debug_info global already, so
417*4d9fdb46SRobert Mustacchi             use this value unaltered.
418*4d9fdb46SRobert Mustacchi 
419*4d9fdb46SRobert Mustacchi             Since a DWP package file is not relocated there
420*4d9fdb46SRobert Mustacchi             is no way that this reference offset to an address in
421*4d9fdb46SRobert Mustacchi             any other CU can be correct for a DWP Package File offset
422*4d9fdb46SRobert Mustacchi             */
423*4d9fdb46SRobert Mustacchi         break;
424*4d9fdb46SRobert Mustacchi     default: {
425*4d9fdb46SRobert Mustacchi         dwarfstring m;
426*4d9fdb46SRobert Mustacchi 
427*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
428*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
429*4d9fdb46SRobert Mustacchi             "DW_DLE_BAD_REF_FORM. The form "
430*4d9fdb46SRobert Mustacchi             "code is 0x%x which cannot be converted to a global "
431*4d9fdb46SRobert Mustacchi             " offset by "
432*4d9fdb46SRobert Mustacchi             "dwarf_convert_to_global_offset()",
433*4d9fdb46SRobert Mustacchi             attr->ar_attribute_form);
434*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM,
435*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
436*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
437*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
438*4d9fdb46SRobert Mustacchi         }
439*4d9fdb46SRobert Mustacchi     }
440*4d9fdb46SRobert Mustacchi 
441*4d9fdb46SRobert Mustacchi     *ret_offset = (offset);
442*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
443*4d9fdb46SRobert Mustacchi }
444*4d9fdb46SRobert Mustacchi 
445*4d9fdb46SRobert Mustacchi 
446*4d9fdb46SRobert Mustacchi /*  A global offset cannot be returned by this interface:
447bc1f688bSRobert Mustacchi     see dwarf_global_formref().
448bc1f688bSRobert Mustacchi 
449bc1f688bSRobert Mustacchi     DW_FORM_ref_addr is considered an incorrect form
450bc1f688bSRobert Mustacchi     for this call because DW_FORM_ref_addr is a global-offset into
451bc1f688bSRobert Mustacchi     the debug_info section.
452bc1f688bSRobert Mustacchi 
453bc1f688bSRobert Mustacchi     For the same reason DW_FORM_data4/data8 are not returned
454bc1f688bSRobert Mustacchi     from this function.
455bc1f688bSRobert Mustacchi 
456bc1f688bSRobert Mustacchi     For the same reason DW_FORM_sec_offset is not returned
457bc1f688bSRobert Mustacchi     from this function, DW_FORM_sec_offset is a global offset
458bc1f688bSRobert Mustacchi     (to various sections, not a CU relative offset.
459bc1f688bSRobert Mustacchi 
460bc1f688bSRobert Mustacchi     DW_FORM_ref_addr has a value which was documented in
461bc1f688bSRobert Mustacchi     DWARF2 as address-size but which was always an offset
462bc1f688bSRobert Mustacchi     so should have always been offset size (wording
463bc1f688bSRobert Mustacchi     corrected in DWARF3).
464*4d9fdb46SRobert Mustacchi     The dwarfstd.org FAQ "How big is a DW_FORM_ref_addr?"
465*4d9fdb46SRobert Mustacchi     suggested all should use offset-size, but that suggestion
466*4d9fdb46SRobert Mustacchi     seems to have been ignored in favor of doing what the
467*4d9fdb46SRobert Mustacchi     DWARF2 and 3 standards actually say.
468*4d9fdb46SRobert Mustacchi 
469*4d9fdb46SRobert Mustacchi     November, 2010: *ret_offset is always set now.
470*4d9fdb46SRobert Mustacchi     Even in case of error.
471*4d9fdb46SRobert Mustacchi     Set to zero for most errors, but for
472*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_OFFSET_BAD
473*4d9fdb46SRobert Mustacchi     *ret_offset is set to the bad offset.
474*4d9fdb46SRobert Mustacchi 
475*4d9fdb46SRobert Mustacchi     DW_FORM_addrx
476*4d9fdb46SRobert Mustacchi     DW_FORM_strx
477*4d9fdb46SRobert Mustacchi     DW_FORM_rnglistx
478*4d9fdb46SRobert Mustacchi     DW_FORM_GNU_addr_index
479*4d9fdb46SRobert Mustacchi     DW_FORM_GNU_str_index
480*4d9fdb46SRobert Mustacchi     are not references to .debug_info/.debug_types,
481*4d9fdb46SRobert Mustacchi     so they are not allowed here. */
482bc1f688bSRobert Mustacchi 
483bc1f688bSRobert Mustacchi 
484bc1f688bSRobert Mustacchi int
dwarf_formref(Dwarf_Attribute attr,Dwarf_Off * ret_offset,Dwarf_Error * error)485bc1f688bSRobert Mustacchi dwarf_formref(Dwarf_Attribute attr,
486*4d9fdb46SRobert Mustacchi    Dwarf_Off * ret_offset,
487*4d9fdb46SRobert Mustacchi    Dwarf_Error * error)
488bc1f688bSRobert Mustacchi {
489bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
490bc1f688bSRobert Mustacchi     Dwarf_Unsigned offset = 0;
491bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
492*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned maximumoffset = 0;
493*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
494*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end = 0;
495bc1f688bSRobert Mustacchi 
496*4d9fdb46SRobert Mustacchi     *ret_offset = 0;
497*4d9fdb46SRobert Mustacchi     res  = get_attr_dbg(&dbg,&cu_context,attr,error);
498*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
499*4d9fdb46SRobert Mustacchi         return res;
500bc1f688bSRobert Mustacchi     }
501*4d9fdb46SRobert Mustacchi     section_end =
502*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
503bc1f688bSRobert Mustacchi 
504bc1f688bSRobert Mustacchi     switch (attr->ar_attribute_form) {
505bc1f688bSRobert Mustacchi 
506bc1f688bSRobert Mustacchi     case DW_FORM_ref1:
507*4d9fdb46SRobert Mustacchi         offset = *(Dwarf_Small *) attr->ar_debug_ptr;
508bc1f688bSRobert Mustacchi         break;
509bc1f688bSRobert Mustacchi 
510bc1f688bSRobert Mustacchi     case DW_FORM_ref2:
511*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
512*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_HALF_SIZE,
513*4d9fdb46SRobert Mustacchi             error,section_end);
514bc1f688bSRobert Mustacchi         break;
515bc1f688bSRobert Mustacchi 
516bc1f688bSRobert Mustacchi     case DW_FORM_ref4:
517*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
518*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_32BIT_SIZE,
519*4d9fdb46SRobert Mustacchi             error,section_end);
520bc1f688bSRobert Mustacchi         break;
521bc1f688bSRobert Mustacchi 
522bc1f688bSRobert Mustacchi     case DW_FORM_ref8:
523*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
524*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_64BIT_SIZE,
525*4d9fdb46SRobert Mustacchi             error,section_end);
526bc1f688bSRobert Mustacchi         break;
527bc1f688bSRobert Mustacchi 
528*4d9fdb46SRobert Mustacchi     case DW_FORM_ref_udata: {
529*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr;
530*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned localoffset = 0;
531bc1f688bSRobert Mustacchi 
532*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(ptr,localoffset,
533*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
534*4d9fdb46SRobert Mustacchi         offset = localoffset;
535*4d9fdb46SRobert Mustacchi         break;
536*4d9fdb46SRobert Mustacchi     }
537*4d9fdb46SRobert Mustacchi     case DW_FORM_ref_sig8:
538*4d9fdb46SRobert Mustacchi         /*  We cannot handle this here.
539*4d9fdb46SRobert Mustacchi             The reference is to .debug_types
540*4d9fdb46SRobert Mustacchi             not a .debug_info CU local offset. */
541*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_REF_SIG8_NOT_HANDLED);
542bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
543*4d9fdb46SRobert Mustacchi     default: {
544*4d9fdb46SRobert Mustacchi         dwarfstring m;
545*4d9fdb46SRobert Mustacchi 
546*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
547*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
548*4d9fdb46SRobert Mustacchi             "DW_DLE_BAD_REF_FORM. The form "
549*4d9fdb46SRobert Mustacchi             "code is 0x%x which does not have an offset "
550*4d9fdb46SRobert Mustacchi             " for "
551*4d9fdb46SRobert Mustacchi             "dwarf_formref() to return.",
552*4d9fdb46SRobert Mustacchi             attr->ar_attribute_form);
553*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM,
554*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
555*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
556*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
557*4d9fdb46SRobert Mustacchi         }
558bc1f688bSRobert Mustacchi     }
559bc1f688bSRobert Mustacchi 
560*4d9fdb46SRobert Mustacchi     /*  Check that offset is within current
561*4d9fdb46SRobert Mustacchi         cu portion of .debug_info. */
562*4d9fdb46SRobert Mustacchi 
563*4d9fdb46SRobert Mustacchi     maximumoffset = cu_context->cc_length +
564*4d9fdb46SRobert Mustacchi         cu_context->cc_length_size +
565*4d9fdb46SRobert Mustacchi         cu_context->cc_extension_size;
566*4d9fdb46SRobert Mustacchi     if (offset >= maximumoffset) {
567*4d9fdb46SRobert Mustacchi         /*  For the DW_TAG_compile_unit is legal to have the
568*4d9fdb46SRobert Mustacchi             DW_AT_sibling attribute outside the current cu portion of
569*4d9fdb46SRobert Mustacchi             .debug_info.
570*4d9fdb46SRobert Mustacchi             In other words, sibling points to the end of the CU.
571*4d9fdb46SRobert Mustacchi             It is used for precompiled headers.
572*4d9fdb46SRobert Mustacchi             The valid condition will be: 'offset == maximumoffset'. */
573*4d9fdb46SRobert Mustacchi         Dwarf_Half tag = 0;
574*4d9fdb46SRobert Mustacchi         int tres = dwarf_tag(attr->ar_die,&tag,error);
575*4d9fdb46SRobert Mustacchi         if (tres != DW_DLV_OK) {
576*4d9fdb46SRobert Mustacchi             if (tres == DW_DLV_NO_ENTRY) {
577*4d9fdb46SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_NO_TAG_FOR_DIE);
578*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
579*4d9fdb46SRobert Mustacchi             }
580*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
581*4d9fdb46SRobert Mustacchi         }
582*4d9fdb46SRobert Mustacchi 
583*4d9fdb46SRobert Mustacchi         if (DW_TAG_compile_unit != tag &&
584*4d9fdb46SRobert Mustacchi             DW_AT_sibling != attr->ar_attribute &&
585*4d9fdb46SRobert Mustacchi             offset > maximumoffset) {
586*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
587*4d9fdb46SRobert Mustacchi             /* Return the incorrect offset for better error reporting */
588*4d9fdb46SRobert Mustacchi             *ret_offset = (offset);
589*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
590*4d9fdb46SRobert Mustacchi         }
591*4d9fdb46SRobert Mustacchi     }
592*4d9fdb46SRobert Mustacchi     *ret_offset = (offset);
593*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
594*4d9fdb46SRobert Mustacchi }
595*4d9fdb46SRobert Mustacchi 
596*4d9fdb46SRobert Mustacchi static int
_dwarf_formsig8_internal(Dwarf_Attribute attr,int formexpected,int formerrnum,Dwarf_Sig8 * returned_sig_bytes,Dwarf_Error * error)597*4d9fdb46SRobert Mustacchi _dwarf_formsig8_internal(Dwarf_Attribute attr,
598*4d9fdb46SRobert Mustacchi     int formexpected,
599*4d9fdb46SRobert Mustacchi     int formerrnum,
600*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 * returned_sig_bytes,
601*4d9fdb46SRobert Mustacchi     Dwarf_Error*     error)
602*4d9fdb46SRobert Mustacchi {
603*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
604*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
605*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr  field_end = 0;
606*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr  section_end = 0;
607*4d9fdb46SRobert Mustacchi 
608*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
609*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
610*4d9fdb46SRobert Mustacchi         return res;
611*4d9fdb46SRobert Mustacchi     }
612*4d9fdb46SRobert Mustacchi 
613*4d9fdb46SRobert Mustacchi     if (attr->ar_attribute_form != formexpected ) {
614*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, formerrnum);
615*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
616*4d9fdb46SRobert Mustacchi     }
617*4d9fdb46SRobert Mustacchi     section_end =
618*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
619*4d9fdb46SRobert Mustacchi     field_end = attr->ar_debug_ptr + sizeof(Dwarf_Sig8);
620*4d9fdb46SRobert Mustacchi     if (field_end > section_end) {
621bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
622bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
623bc1f688bSRobert Mustacchi     }
624bc1f688bSRobert Mustacchi 
625*4d9fdb46SRobert Mustacchi     memcpy(returned_sig_bytes, attr->ar_debug_ptr,
626*4d9fdb46SRobert Mustacchi         sizeof(Dwarf_Sig8));
627bc1f688bSRobert Mustacchi     return DW_DLV_OK;
628bc1f688bSRobert Mustacchi }
629bc1f688bSRobert Mustacchi 
630*4d9fdb46SRobert Mustacchi int
dwarf_formsig8_const(Dwarf_Attribute attr,Dwarf_Sig8 * returned_sig_bytes,Dwarf_Error * error)631*4d9fdb46SRobert Mustacchi dwarf_formsig8_const(Dwarf_Attribute attr,
632*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 * returned_sig_bytes,
633*4d9fdb46SRobert Mustacchi     Dwarf_Error* error)
634*4d9fdb46SRobert Mustacchi {
635*4d9fdb46SRobert Mustacchi     int res  =_dwarf_formsig8_internal(attr, DW_FORM_data8,
636*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_NOT_DATA8,
637*4d9fdb46SRobert Mustacchi         returned_sig_bytes,error);
638*4d9fdb46SRobert Mustacchi     return res;
639*4d9fdb46SRobert Mustacchi }
640*4d9fdb46SRobert Mustacchi 
641bc1f688bSRobert Mustacchi /*  dwarf_formsig8 returns in the caller-provided 8 byte area
642bc1f688bSRobert Mustacchi     the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes
643bc1f688bSRobert Mustacchi     directly to the caller).  Not a string, an 8 byte
644bc1f688bSRobert Mustacchi     MD5 hash.  This function is new in DWARF4 libdwarf.
645bc1f688bSRobert Mustacchi */
646*4d9fdb46SRobert Mustacchi int
dwarf_formsig8(Dwarf_Attribute attr,Dwarf_Sig8 * returned_sig_bytes,Dwarf_Error * error)647*4d9fdb46SRobert Mustacchi dwarf_formsig8(Dwarf_Attribute attr,
648bc1f688bSRobert Mustacchi     Dwarf_Sig8 * returned_sig_bytes,
649bc1f688bSRobert Mustacchi     Dwarf_Error* error)
650bc1f688bSRobert Mustacchi {
651*4d9fdb46SRobert Mustacchi     int res  = _dwarf_formsig8_internal(attr, DW_FORM_ref_sig8,
652*4d9fdb46SRobert Mustacchi         DW_DLE_BAD_REF_SIG8_FORM,
653*4d9fdb46SRobert Mustacchi         returned_sig_bytes,error);
654*4d9fdb46SRobert Mustacchi     return res;
655bc1f688bSRobert Mustacchi }
656bc1f688bSRobert Mustacchi 
657bc1f688bSRobert Mustacchi 
658*4d9fdb46SRobert Mustacchi 
659*4d9fdb46SRobert Mustacchi 
660*4d9fdb46SRobert Mustacchi /*  Since this returns section-relative debug_info offsets,
661bc1f688bSRobert Mustacchi     this can represent all REFERENCE forms correctly
662bc1f688bSRobert Mustacchi     and allows all applicable forms.
663bc1f688bSRobert Mustacchi 
664bc1f688bSRobert Mustacchi     DW_FORM_ref_addr has a value which was documented in
665bc1f688bSRobert Mustacchi     DWARF2 as address-size but which was always an offset
666bc1f688bSRobert Mustacchi     so should have always been offset size (wording
667bc1f688bSRobert Mustacchi     corrected in DWARF3).
668*4d9fdb46SRobert Mustacchi     gcc and Go and libdwarf producer code
669*4d9fdb46SRobert Mustacchi     define the length of the value of DW_FORM_ref_addr
670*4d9fdb46SRobert Mustacchi     per the version. So for V2 it is address-size and V3 and later
671*4d9fdb46SRobert Mustacchi     it is offset-size.
672bc1f688bSRobert Mustacchi 
673bc1f688bSRobert Mustacchi     See the DWARF4 document for the 3 cases fitting
674bc1f688bSRobert Mustacchi     reference forms.  The caller must determine which section the
675bc1f688bSRobert Mustacchi     reference 'points' to.  The function added in November 2009,
676bc1f688bSRobert Mustacchi     dwarf_get_form_class(), helps in this regard.
677bc1f688bSRobert Mustacchi 
678*4d9fdb46SRobert Mustacchi     unlike dwarf_formref(), this allows references to
679*4d9fdb46SRobert Mustacchi     sections other than just .debug_info/.debug_types.
680*4d9fdb46SRobert Mustacchi     See case DW_FORM_sec_offset:
681*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_ref_alt:   2013 GNU extension
682*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_strp_alt:  2013 GNU extension
683*4d9fdb46SRobert Mustacchi     case DW_FORM_strp_sup:      DWARF5, sup string section
684*4d9fdb46SRobert Mustacchi     case DW_FORM_line_strp:     DWARF5, .debug_line_str section
685bc1f688bSRobert Mustacchi */
686*4d9fdb46SRobert Mustacchi 
687bc1f688bSRobert Mustacchi int
dwarf_global_formref(Dwarf_Attribute attr,Dwarf_Off * ret_offset,Dwarf_Error * error)688bc1f688bSRobert Mustacchi dwarf_global_formref(Dwarf_Attribute attr,
689bc1f688bSRobert Mustacchi     Dwarf_Off * ret_offset, Dwarf_Error * error)
690bc1f688bSRobert Mustacchi {
691bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
692bc1f688bSRobert Mustacchi     Dwarf_Unsigned offset = 0;
693bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
694bc1f688bSRobert Mustacchi     Dwarf_Half context_version = 0;
695*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end = 0;
696bc1f688bSRobert Mustacchi 
697*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
698*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
699*4d9fdb46SRobert Mustacchi         return res;
700bc1f688bSRobert Mustacchi     }
701*4d9fdb46SRobert Mustacchi     section_end =
702*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
703bc1f688bSRobert Mustacchi     context_version = cu_context->cc_version_stamp;
704bc1f688bSRobert Mustacchi     switch (attr->ar_attribute_form) {
705bc1f688bSRobert Mustacchi 
706bc1f688bSRobert Mustacchi     case DW_FORM_ref1:
707*4d9fdb46SRobert Mustacchi         offset = *(Dwarf_Small *) attr->ar_debug_ptr;
708bc1f688bSRobert Mustacchi         goto fixoffset;
709bc1f688bSRobert Mustacchi 
710bc1f688bSRobert Mustacchi     case DW_FORM_ref2:
711*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
712*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_HALF_SIZE,
713*4d9fdb46SRobert Mustacchi             error,section_end);
714bc1f688bSRobert Mustacchi         goto fixoffset;
715bc1f688bSRobert Mustacchi 
716bc1f688bSRobert Mustacchi     case DW_FORM_ref4:
717*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
718*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_32BIT_SIZE,
719*4d9fdb46SRobert Mustacchi             error,section_end);
720bc1f688bSRobert Mustacchi         goto fixoffset;
721bc1f688bSRobert Mustacchi 
722bc1f688bSRobert Mustacchi     case DW_FORM_ref8:
723*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
724*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_64BIT_SIZE,
725*4d9fdb46SRobert Mustacchi             error,section_end);
726bc1f688bSRobert Mustacchi         goto fixoffset;
727bc1f688bSRobert Mustacchi 
728bc1f688bSRobert Mustacchi     case DW_FORM_ref_udata:
729*4d9fdb46SRobert Mustacchi         {
730*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr;
731*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned localoffset = 0;
732bc1f688bSRobert Mustacchi 
733*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(ptr,localoffset,
734*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
735*4d9fdb46SRobert Mustacchi         offset = localoffset;
736*4d9fdb46SRobert Mustacchi 
737*4d9fdb46SRobert Mustacchi         fixoffset: /* we have a local offset, make it global */
738bc1f688bSRobert Mustacchi 
739bc1f688bSRobert Mustacchi         /* check legality of offset */
740bc1f688bSRobert Mustacchi         if (offset >= cu_context->cc_length +
741bc1f688bSRobert Mustacchi             cu_context->cc_length_size +
742bc1f688bSRobert Mustacchi             cu_context->cc_extension_size) {
743bc1f688bSRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
744bc1f688bSRobert Mustacchi             return (DW_DLV_ERROR);
745bc1f688bSRobert Mustacchi         }
746bc1f688bSRobert Mustacchi 
747bc1f688bSRobert Mustacchi         /* globalize the offset */
748*4d9fdb46SRobert Mustacchi         offset += cu_context->cc_debug_offset;
749*4d9fdb46SRobert Mustacchi         }
750bc1f688bSRobert Mustacchi         break;
751*4d9fdb46SRobert Mustacchi 
752bc1f688bSRobert Mustacchi     /*  The DWARF2 document did not make clear that
753bc1f688bSRobert Mustacchi         DW_FORM_data4( and 8) were references with
754bc1f688bSRobert Mustacchi         global offsets to some section.
755bc1f688bSRobert Mustacchi         That was first clearly documented in DWARF3.
756bc1f688bSRobert Mustacchi         In DWARF4 these two forms are no longer references. */
757bc1f688bSRobert Mustacchi     case DW_FORM_data4:
758*4d9fdb46SRobert Mustacchi         if (context_version >= DW_CU_VERSION4) {
759bc1f688bSRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
760bc1f688bSRobert Mustacchi             return (DW_DLV_ERROR);
761bc1f688bSRobert Mustacchi         }
762*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
763*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_32BIT_SIZE,
764*4d9fdb46SRobert Mustacchi             error, section_end);
765bc1f688bSRobert Mustacchi         /* The offset is global. */
766bc1f688bSRobert Mustacchi         break;
767bc1f688bSRobert Mustacchi     case DW_FORM_data8:
768*4d9fdb46SRobert Mustacchi         if (context_version >= DW_CU_VERSION4) {
769bc1f688bSRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
770bc1f688bSRobert Mustacchi             return (DW_DLV_ERROR);
771bc1f688bSRobert Mustacchi         }
772*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
773*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_64BIT_SIZE,
774*4d9fdb46SRobert Mustacchi             error,section_end);
775bc1f688bSRobert Mustacchi         /* The offset is global. */
776bc1f688bSRobert Mustacchi         break;
777bc1f688bSRobert Mustacchi     case DW_FORM_ref_addr:
778bc1f688bSRobert Mustacchi         {
779*4d9fdb46SRobert Mustacchi             /*  In Dwarf V2 DW_FORM_ref_addr was defined
780*4d9fdb46SRobert Mustacchi                 as address-size even though it is a .debug_info
781*4d9fdb46SRobert Mustacchi                 offset.  Fixed in Dwarf V3 to be offset-size.
782*4d9fdb46SRobert Mustacchi                 */
783*4d9fdb46SRobert Mustacchi             unsigned length_size = 0;
784*4d9fdb46SRobert Mustacchi             if (context_version == 2) {
785*4d9fdb46SRobert Mustacchi                 length_size = cu_context->cc_address_size;
786*4d9fdb46SRobert Mustacchi             } else {
787*4d9fdb46SRobert Mustacchi                 length_size = cu_context->cc_length_size;
788*4d9fdb46SRobert Mustacchi             }
789bc1f688bSRobert Mustacchi             if (length_size == 4) {
790*4d9fdb46SRobert Mustacchi                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
791*4d9fdb46SRobert Mustacchi                     attr->ar_debug_ptr, DWARF_32BIT_SIZE,
792*4d9fdb46SRobert Mustacchi                     error,section_end);
793bc1f688bSRobert Mustacchi             } else if (length_size == 8) {
794*4d9fdb46SRobert Mustacchi                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
795*4d9fdb46SRobert Mustacchi                     attr->ar_debug_ptr, DWARF_64BIT_SIZE,
796*4d9fdb46SRobert Mustacchi                     error,section_end);
797bc1f688bSRobert Mustacchi             } else {
798bc1f688bSRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD);
799bc1f688bSRobert Mustacchi                 return (DW_DLV_ERROR);
800bc1f688bSRobert Mustacchi             }
801bc1f688bSRobert Mustacchi         }
802bc1f688bSRobert Mustacchi         break;
803*4d9fdb46SRobert Mustacchi     /*  Index into .debug_rnglist section.
804*4d9fdb46SRobert Mustacchi         Return the index itself. */
805*4d9fdb46SRobert Mustacchi     case DW_FORM_rnglistx: {
806*4d9fdb46SRobert Mustacchi         unsigned length_size = cu_context->cc_length_size;
807*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
808*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, length_size,
809*4d9fdb46SRobert Mustacchi             error,section_end);
810*4d9fdb46SRobert Mustacchi         }
811*4d9fdb46SRobert Mustacchi         break;
812*4d9fdb46SRobert Mustacchi     case DW_FORM_sec_offset:
813*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_ref_alt:  /* 2013 GNU extension */
814*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_strp_alt: /* 2013 GNU extension */
815*4d9fdb46SRobert Mustacchi     case DW_FORM_strp_sup:     /* DWARF5, sup string section */
816*4d9fdb46SRobert Mustacchi     case DW_FORM_line_strp:    /* DWARF5, .debug_line_str section */
817*4d9fdb46SRobert Mustacchi         {
818*4d9fdb46SRobert Mustacchi             /*  DW_FORM_sec_offset first exists in DWARF4.*/
819*4d9fdb46SRobert Mustacchi             /*  It is up to the caller to know what the offset
820*4d9fdb46SRobert Mustacchi                 of DW_FORM_sec_offset, DW_FORM_strp_sup
821*4d9fdb46SRobert Mustacchi                 or DW_FORM_GNU_strp_alt etc refer to,
822*4d9fdb46SRobert Mustacchi                 the offset is not going to refer to .debug_info! */
823*4d9fdb46SRobert Mustacchi             unsigned length_size = cu_context->cc_length_size;
824*4d9fdb46SRobert Mustacchi             if (length_size == 4) {
825*4d9fdb46SRobert Mustacchi                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
826*4d9fdb46SRobert Mustacchi                     attr->ar_debug_ptr, DWARF_32BIT_SIZE,
827*4d9fdb46SRobert Mustacchi                     error,section_end);
828*4d9fdb46SRobert Mustacchi             } else if (length_size == 8) {
829*4d9fdb46SRobert Mustacchi                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
830*4d9fdb46SRobert Mustacchi                     attr->ar_debug_ptr, DWARF_64BIT_SIZE,
831*4d9fdb46SRobert Mustacchi                     error,section_end);
832*4d9fdb46SRobert Mustacchi             } else {
833*4d9fdb46SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD);
834bc1f688bSRobert Mustacchi                 return (DW_DLV_ERROR);
835bc1f688bSRobert Mustacchi             }
836*4d9fdb46SRobert Mustacchi         }
837*4d9fdb46SRobert Mustacchi         break;
838*4d9fdb46SRobert Mustacchi     case DW_FORM_ref_sig8: /* FIXME */
839*4d9fdb46SRobert Mustacchi         /*  We cannot handle this yet.
840*4d9fdb46SRobert Mustacchi             The reference is to .debug_types, and
841*4d9fdb46SRobert Mustacchi             this function only returns an offset in
842*4d9fdb46SRobert Mustacchi             .debug_info at this point. */
843*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_REF_SIG8_NOT_HANDLED);
844*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
845*4d9fdb46SRobert Mustacchi     default: {
846*4d9fdb46SRobert Mustacchi         dwarfstring m;
847*4d9fdb46SRobert Mustacchi         int formcode = attr->ar_attribute_form;
848*4d9fdb46SRobert Mustacchi         int fcres = 0;
849*4d9fdb46SRobert Mustacchi         const char *name = 0;
850*4d9fdb46SRobert Mustacchi 
851*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
852*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
853*4d9fdb46SRobert Mustacchi             "DW_DLE_BAD_REF_FORM: The form code is 0x%x ",
854*4d9fdb46SRobert Mustacchi             formcode);
855*4d9fdb46SRobert Mustacchi         fcres  = dwarf_get_FORM_name (formcode,&name);
856*4d9fdb46SRobert Mustacchi         if (fcres != DW_DLV_OK) {
857*4d9fdb46SRobert Mustacchi             name="<UnknownFormCode>";
858*4d9fdb46SRobert Mustacchi         }
859*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
860*4d9fdb46SRobert Mustacchi             " %s.",(char *)name);
861*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM,
862*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
863*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
864*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
865*4d9fdb46SRobert Mustacchi         }
866*4d9fdb46SRobert Mustacchi     }
867bc1f688bSRobert Mustacchi 
868bc1f688bSRobert Mustacchi     /*  We do not know what section the offset refers to, so
869bc1f688bSRobert Mustacchi         we have no way to check it for correctness. */
870bc1f688bSRobert Mustacchi     *ret_offset = offset;
871bc1f688bSRobert Mustacchi     return DW_DLV_OK;
872bc1f688bSRobert Mustacchi }
873bc1f688bSRobert Mustacchi 
874*4d9fdb46SRobert Mustacchi /*  Part of DebugFission.  So a consumer can get the index when
875*4d9fdb46SRobert Mustacchi     the object with the actual debug_addr  is
876*4d9fdb46SRobert Mustacchi     elsewhere.  New May 2014*/
877*4d9fdb46SRobert Mustacchi 
878*4d9fdb46SRobert Mustacchi int
_dwarf_get_addr_index_itself(int theform,Dwarf_Small * info_ptr,Dwarf_Debug dbg,Dwarf_CU_Context cu_context,Dwarf_Unsigned * val_out,Dwarf_Error * error)879*4d9fdb46SRobert Mustacchi _dwarf_get_addr_index_itself(int theform,
880*4d9fdb46SRobert Mustacchi     Dwarf_Small *info_ptr,
881*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg,
882*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context,
883*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *val_out,
884*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
885*4d9fdb46SRobert Mustacchi {
886*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index = 0;
887*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end = 0;
888*4d9fdb46SRobert Mustacchi 
889*4d9fdb46SRobert Mustacchi     section_end =
890*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
891*4d9fdb46SRobert Mustacchi     switch(theform){
892*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_addr_index:
893*4d9fdb46SRobert Mustacchi     case DW_FORM_addrx:
894*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(info_ptr,index,
895*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
896*4d9fdb46SRobert Mustacchi         break;
897*4d9fdb46SRobert Mustacchi     case DW_FORM_addrx1:
898*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
899*4d9fdb46SRobert Mustacchi             info_ptr, 1,
900*4d9fdb46SRobert Mustacchi             error,section_end);
901*4d9fdb46SRobert Mustacchi         break;
902*4d9fdb46SRobert Mustacchi     case DW_FORM_addrx2:
903*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
904*4d9fdb46SRobert Mustacchi             info_ptr, 2,
905*4d9fdb46SRobert Mustacchi             error,section_end);
906*4d9fdb46SRobert Mustacchi         break;
907*4d9fdb46SRobert Mustacchi     case DW_FORM_addrx3:
908*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
909*4d9fdb46SRobert Mustacchi             info_ptr, 3,
910*4d9fdb46SRobert Mustacchi             error,section_end);
911*4d9fdb46SRobert Mustacchi         break;
912*4d9fdb46SRobert Mustacchi     case DW_FORM_addrx4:
913*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
914*4d9fdb46SRobert Mustacchi             info_ptr, 4,
915*4d9fdb46SRobert Mustacchi             error,section_end);
916*4d9fdb46SRobert Mustacchi         break;
917*4d9fdb46SRobert Mustacchi     default:
918*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX);
919*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
920*4d9fdb46SRobert Mustacchi     }
921*4d9fdb46SRobert Mustacchi     *val_out = index;
922*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
923*4d9fdb46SRobert Mustacchi }
924*4d9fdb46SRobert Mustacchi 
925*4d9fdb46SRobert Mustacchi int
dwarf_get_debug_addr_index(Dwarf_Attribute attr,Dwarf_Unsigned * return_index,Dwarf_Error * error)926*4d9fdb46SRobert Mustacchi dwarf_get_debug_addr_index(Dwarf_Attribute attr,
927*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * return_index,
928*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
929*4d9fdb46SRobert Mustacchi {
930*4d9fdb46SRobert Mustacchi     int theform = 0;
931*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
932*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
933*4d9fdb46SRobert Mustacchi 
934*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
935*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
936*4d9fdb46SRobert Mustacchi         return res;
937*4d9fdb46SRobert Mustacchi     }
938*4d9fdb46SRobert Mustacchi     theform = attr->ar_attribute_form;
939*4d9fdb46SRobert Mustacchi     if (dwarf_addr_form_is_indexed(theform)) {
940*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned index = 0;
941*4d9fdb46SRobert Mustacchi 
942*4d9fdb46SRobert Mustacchi         res = _dwarf_get_addr_index_itself(theform,
943*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr,dbg,cu_context,&index,error);
944*4d9fdb46SRobert Mustacchi         *return_index = index;
945*4d9fdb46SRobert Mustacchi         return res;
946*4d9fdb46SRobert Mustacchi     }
947*4d9fdb46SRobert Mustacchi 
948*4d9fdb46SRobert Mustacchi     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX);
949*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
950*4d9fdb46SRobert Mustacchi }
951*4d9fdb46SRobert Mustacchi 
952*4d9fdb46SRobert Mustacchi static int
dw_read_index_val_itself(Dwarf_Debug dbg,unsigned theform,Dwarf_Small * info_ptr,Dwarf_Small * section_end,Dwarf_Unsigned * return_index,Dwarf_Error * error)953*4d9fdb46SRobert Mustacchi dw_read_index_val_itself(Dwarf_Debug dbg,
954*4d9fdb46SRobert Mustacchi    unsigned theform,
955*4d9fdb46SRobert Mustacchi    Dwarf_Small *info_ptr,
956*4d9fdb46SRobert Mustacchi    Dwarf_Small *section_end,
957*4d9fdb46SRobert Mustacchi    Dwarf_Unsigned *return_index,
958*4d9fdb46SRobert Mustacchi    Dwarf_Error *error)
959*4d9fdb46SRobert Mustacchi {
960*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index = 0;
961*4d9fdb46SRobert Mustacchi 
962*4d9fdb46SRobert Mustacchi     switch(theform) {
963*4d9fdb46SRobert Mustacchi     case DW_FORM_strx:
964*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_str_index:
965*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(info_ptr,index,
966*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
967*4d9fdb46SRobert Mustacchi         break;
968*4d9fdb46SRobert Mustacchi     case DW_FORM_strx1:
969*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
970*4d9fdb46SRobert Mustacchi             info_ptr, 1,
971*4d9fdb46SRobert Mustacchi             error,section_end);
972*4d9fdb46SRobert Mustacchi         break;
973*4d9fdb46SRobert Mustacchi     case DW_FORM_strx2:
974*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
975*4d9fdb46SRobert Mustacchi             info_ptr, 2,
976*4d9fdb46SRobert Mustacchi             error,section_end);
977*4d9fdb46SRobert Mustacchi         break;
978*4d9fdb46SRobert Mustacchi     case DW_FORM_strx3:
979*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
980*4d9fdb46SRobert Mustacchi             info_ptr, 3,
981*4d9fdb46SRobert Mustacchi             error,section_end);
982*4d9fdb46SRobert Mustacchi         break;
983*4d9fdb46SRobert Mustacchi     case DW_FORM_strx4:
984*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned,
985*4d9fdb46SRobert Mustacchi             info_ptr, 4,
986*4d9fdb46SRobert Mustacchi             error,section_end);
987*4d9fdb46SRobert Mustacchi         break;
988*4d9fdb46SRobert Mustacchi     default:
989*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_STR_INDEX);
990*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
991*4d9fdb46SRobert Mustacchi     }
992*4d9fdb46SRobert Mustacchi     *return_index = index;
993*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
994*4d9fdb46SRobert Mustacchi }
995*4d9fdb46SRobert Mustacchi 
996*4d9fdb46SRobert Mustacchi /*  Part of DebugFission.  So a dwarf dumper application
997*4d9fdb46SRobert Mustacchi     can get the index and print it for the user.
998*4d9fdb46SRobert Mustacchi     A convenience function.  New May 2014
999*4d9fdb46SRobert Mustacchi     Also used with DWARF5 forms.  */
1000*4d9fdb46SRobert Mustacchi int
dwarf_get_debug_str_index(Dwarf_Attribute attr,Dwarf_Unsigned * return_index,Dwarf_Error * error)1001*4d9fdb46SRobert Mustacchi dwarf_get_debug_str_index(Dwarf_Attribute attr,
1002*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *return_index,
1003*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
1004*4d9fdb46SRobert Mustacchi {
1005*4d9fdb46SRobert Mustacchi     int theform = attr->ar_attribute_form;
1006*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1007*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
1008*4d9fdb46SRobert Mustacchi     int res  = 0;
1009*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end =  0;
1010*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index = 0;
1011*4d9fdb46SRobert Mustacchi     Dwarf_Small *info_ptr = 0;
1012*4d9fdb46SRobert Mustacchi     int indxres = 0;
1013*4d9fdb46SRobert Mustacchi 
1014*4d9fdb46SRobert Mustacchi     res = get_attr_dbg(&dbg,&cu_context,attr,error);
1015*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1016*4d9fdb46SRobert Mustacchi         return res;
1017*4d9fdb46SRobert Mustacchi     }
1018*4d9fdb46SRobert Mustacchi     section_end =
1019*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
1020*4d9fdb46SRobert Mustacchi     info_ptr = attr->ar_debug_ptr;
1021*4d9fdb46SRobert Mustacchi 
1022*4d9fdb46SRobert Mustacchi     indxres = dw_read_index_val_itself(dbg, theform, info_ptr,
1023*4d9fdb46SRobert Mustacchi         section_end, &index,error);
1024*4d9fdb46SRobert Mustacchi     if (indxres == DW_DLV_OK) {
1025*4d9fdb46SRobert Mustacchi         *return_index = index;
1026*4d9fdb46SRobert Mustacchi         return indxres;
1027*4d9fdb46SRobert Mustacchi     }
1028*4d9fdb46SRobert Mustacchi     return indxres;
1029*4d9fdb46SRobert Mustacchi }
1030*4d9fdb46SRobert Mustacchi 
1031*4d9fdb46SRobert Mustacchi 
1032*4d9fdb46SRobert Mustacchi int
_dwarf_extract_data16(Dwarf_Debug dbg,Dwarf_Small * data,Dwarf_Small * section_start,Dwarf_Small * section_end,Dwarf_Form_Data16 * returned_val,Dwarf_Error * error)1033*4d9fdb46SRobert Mustacchi _dwarf_extract_data16(Dwarf_Debug dbg,
1034*4d9fdb46SRobert Mustacchi     Dwarf_Small *data,
1035*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_start,
1036*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end,
1037*4d9fdb46SRobert Mustacchi     Dwarf_Form_Data16  * returned_val,
1038*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
1039*4d9fdb46SRobert Mustacchi {
1040*4d9fdb46SRobert Mustacchi     Dwarf_Small *data16end = 0;
1041*4d9fdb46SRobert Mustacchi 
1042*4d9fdb46SRobert Mustacchi     data16end = data + sizeof(Dwarf_Form_Data16);
1043*4d9fdb46SRobert Mustacchi     if (data  < section_start ||
1044*4d9fdb46SRobert Mustacchi         section_end < data16end) {
1045*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error,DW_DLE_DATA16_OUTSIDE_SECTION);
1046*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1047*4d9fdb46SRobert Mustacchi     }
1048*4d9fdb46SRobert Mustacchi     memcpy(returned_val, data, sizeof(Dwarf_Form_Data16));
1049*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1050*4d9fdb46SRobert Mustacchi 
1051*4d9fdb46SRobert Mustacchi }
1052*4d9fdb46SRobert Mustacchi 
1053*4d9fdb46SRobert Mustacchi int
dwarf_formdata16(Dwarf_Attribute attr,Dwarf_Form_Data16 * returned_val,Dwarf_Error * error)1054*4d9fdb46SRobert Mustacchi dwarf_formdata16(Dwarf_Attribute attr,
1055*4d9fdb46SRobert Mustacchi     Dwarf_Form_Data16  * returned_val,
1056*4d9fdb46SRobert Mustacchi     Dwarf_Error*     error)
1057*4d9fdb46SRobert Mustacchi {
1058*4d9fdb46SRobert Mustacchi     Dwarf_Half attrform = 0;
1059*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1060*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
1061*4d9fdb46SRobert Mustacchi     int res  = 0;
1062*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end = 0;
1063*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_length = 0;
1064*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_start = 0;
1065*4d9fdb46SRobert Mustacchi 
1066*4d9fdb46SRobert Mustacchi     if (attr == NULL) {
1067*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
1068*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1069*4d9fdb46SRobert Mustacchi     }
1070*4d9fdb46SRobert Mustacchi     if (returned_val == NULL) {
1071*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
1072*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1073*4d9fdb46SRobert Mustacchi     }
1074*4d9fdb46SRobert Mustacchi     attrform = attr->ar_attribute_form;
1075*4d9fdb46SRobert Mustacchi     if (attrform != DW_FORM_data16) {
1076*4d9fdb46SRobert Mustacchi         generate_form_error(dbg,error,attrform,
1077*4d9fdb46SRobert Mustacchi             DW_DLE_ATTR_FORM_BAD,
1078*4d9fdb46SRobert Mustacchi             "DW_DLE_ATTR_FORM_BAD",
1079*4d9fdb46SRobert Mustacchi             "dwarf_formdata16");
1080*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1081*4d9fdb46SRobert Mustacchi     }
1082*4d9fdb46SRobert Mustacchi     res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1083*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1084*4d9fdb46SRobert Mustacchi         return res;
1085*4d9fdb46SRobert Mustacchi     }
1086*4d9fdb46SRobert Mustacchi     section_start = _dwarf_calculate_info_section_start_ptr(
1087*4d9fdb46SRobert Mustacchi         cu_context,&section_length);
1088*4d9fdb46SRobert Mustacchi     section_end = section_start + section_length;
1089*4d9fdb46SRobert Mustacchi 
1090*4d9fdb46SRobert Mustacchi     res = _dwarf_extract_data16(dbg, attr->ar_debug_ptr,
1091*4d9fdb46SRobert Mustacchi         section_start, section_end,
1092*4d9fdb46SRobert Mustacchi         returned_val,  error);
1093*4d9fdb46SRobert Mustacchi     return res;
1094*4d9fdb46SRobert Mustacchi }
1095*4d9fdb46SRobert Mustacchi 
1096*4d9fdb46SRobert Mustacchi /*  The *addrx are DWARF5 standard.
1097*4d9fdb46SRobert Mustacchi     The GNU form was non-standard gcc DWARF4 */
1098*4d9fdb46SRobert Mustacchi Dwarf_Bool
dwarf_addr_form_is_indexed(int form)1099*4d9fdb46SRobert Mustacchi dwarf_addr_form_is_indexed(int form)
1100*4d9fdb46SRobert Mustacchi {
1101*4d9fdb46SRobert Mustacchi     if (form == DW_FORM_addrx ||
1102*4d9fdb46SRobert Mustacchi         form == DW_FORM_addrx1 ||
1103*4d9fdb46SRobert Mustacchi         form == DW_FORM_addrx2 ||
1104*4d9fdb46SRobert Mustacchi         form == DW_FORM_addrx3 ||
1105*4d9fdb46SRobert Mustacchi         form == DW_FORM_addrx4 ||
1106*4d9fdb46SRobert Mustacchi         form == DW_FORM_GNU_addr_index) {
1107*4d9fdb46SRobert Mustacchi         return TRUE;
1108*4d9fdb46SRobert Mustacchi     }
1109*4d9fdb46SRobert Mustacchi     return FALSE;
1110*4d9fdb46SRobert Mustacchi }
1111bc1f688bSRobert Mustacchi 
1112bc1f688bSRobert Mustacchi int
dwarf_formaddr(Dwarf_Attribute attr,Dwarf_Addr * return_addr,Dwarf_Error * error)1113bc1f688bSRobert Mustacchi dwarf_formaddr(Dwarf_Attribute attr,
1114bc1f688bSRobert Mustacchi     Dwarf_Addr * return_addr, Dwarf_Error * error)
1115bc1f688bSRobert Mustacchi {
1116bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
1117bc1f688bSRobert Mustacchi     Dwarf_Addr ret_addr = 0;
1118bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1119*4d9fdb46SRobert Mustacchi     Dwarf_Half attrform = 0;
1120bc1f688bSRobert Mustacchi 
1121*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1122*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1123*4d9fdb46SRobert Mustacchi         return res;
1124bc1f688bSRobert Mustacchi     }
1125*4d9fdb46SRobert Mustacchi     attrform = attr->ar_attribute_form;
1126*4d9fdb46SRobert Mustacchi     if (dwarf_addr_form_is_indexed(attrform)) {
1127*4d9fdb46SRobert Mustacchi         res = _dwarf_look_in_local_and_tied(
1128*4d9fdb46SRobert Mustacchi             attrform,
1129*4d9fdb46SRobert Mustacchi             cu_context,
1130*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr,
1131*4d9fdb46SRobert Mustacchi             return_addr,
1132*4d9fdb46SRobert Mustacchi             error);
1133*4d9fdb46SRobert Mustacchi         return res;
1134bc1f688bSRobert Mustacchi     }
1135*4d9fdb46SRobert Mustacchi     if (attrform == DW_FORM_addr
1136*4d9fdb46SRobert Mustacchi         /*  || attrform == DW_FORM_ref_addr Allowance of
1137bc1f688bSRobert Mustacchi             DW_FORM_ref_addr was a mistake. The value returned in that
1138bc1f688bSRobert Mustacchi             case is NOT an address it is a global debug_info offset (ie,
1139bc1f688bSRobert Mustacchi             not CU-relative offset within the CU in debug_info). The
1140*4d9fdb46SRobert Mustacchi             DWARF2 document refers to it as an address (misleadingly) in
1141bc1f688bSRobert Mustacchi             sec 6.5.4 where it describes the reference form. It is
1142bc1f688bSRobert Mustacchi             address-sized so that the linker can easily update it, but
1143bc1f688bSRobert Mustacchi             it is a reference inside the debug_info section. No longer
1144bc1f688bSRobert Mustacchi             allowed. */
1145bc1f688bSRobert Mustacchi         ) {
1146*4d9fdb46SRobert Mustacchi         Dwarf_Small *section_end =
1147*4d9fdb46SRobert Mustacchi             _dwarf_calculate_info_section_end_ptr(cu_context);
1148bc1f688bSRobert Mustacchi 
1149*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr,
1150*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr,
1151*4d9fdb46SRobert Mustacchi             cu_context->cc_address_size,
1152*4d9fdb46SRobert Mustacchi             error,section_end);
1153bc1f688bSRobert Mustacchi         *return_addr = ret_addr;
1154bc1f688bSRobert Mustacchi         return (DW_DLV_OK);
1155bc1f688bSRobert Mustacchi     }
1156*4d9fdb46SRobert Mustacchi     generate_form_error(dbg,error,attrform,
1157*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_BAD,
1158*4d9fdb46SRobert Mustacchi         "DW_DLE_ATTR_FORM_BAD",
1159*4d9fdb46SRobert Mustacchi         "dwarf_formaddr");
1160*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
1161bc1f688bSRobert Mustacchi }
1162bc1f688bSRobert Mustacchi 
1163bc1f688bSRobert Mustacchi 
1164bc1f688bSRobert Mustacchi int
dwarf_formflag(Dwarf_Attribute attr,Dwarf_Bool * ret_bool,Dwarf_Error * error)1165bc1f688bSRobert Mustacchi dwarf_formflag(Dwarf_Attribute attr,
1166bc1f688bSRobert Mustacchi     Dwarf_Bool * ret_bool, Dwarf_Error * error)
1167bc1f688bSRobert Mustacchi {
1168bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1169*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
1170bc1f688bSRobert Mustacchi 
1171bc1f688bSRobert Mustacchi     if (attr == NULL) {
1172bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
1173bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
1174bc1f688bSRobert Mustacchi     }
1175bc1f688bSRobert Mustacchi 
1176bc1f688bSRobert Mustacchi     cu_context = attr->ar_cu_context;
1177bc1f688bSRobert Mustacchi     if (cu_context == NULL) {
1178bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
1179bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
1180bc1f688bSRobert Mustacchi     }
1181*4d9fdb46SRobert Mustacchi     dbg = cu_context->cc_dbg;
1182bc1f688bSRobert Mustacchi 
1183*4d9fdb46SRobert Mustacchi     if (dbg == NULL) {
1184bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
1185bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
1186bc1f688bSRobert Mustacchi     }
1187bc1f688bSRobert Mustacchi     if (attr->ar_attribute_form == DW_FORM_flag_present) {
1188bc1f688bSRobert Mustacchi         /*  Implicit means we don't read any data at all. Just
1189bc1f688bSRobert Mustacchi             the existence of the Form does it. DWARF4. */
1190bc1f688bSRobert Mustacchi         *ret_bool = 1;
1191bc1f688bSRobert Mustacchi         return (DW_DLV_OK);
1192bc1f688bSRobert Mustacchi     }
1193bc1f688bSRobert Mustacchi 
1194bc1f688bSRobert Mustacchi     if (attr->ar_attribute_form == DW_FORM_flag) {
1195*4d9fdb46SRobert Mustacchi         *ret_bool = *(Dwarf_Small *)(attr->ar_debug_ptr);
1196bc1f688bSRobert Mustacchi         return (DW_DLV_OK);
1197bc1f688bSRobert Mustacchi     }
1198*4d9fdb46SRobert Mustacchi     generate_form_error(dbg,error,attr->ar_attribute_form,
1199*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_BAD,
1200*4d9fdb46SRobert Mustacchi         "DW_DLE_ATTR_FORM_BAD",
1201*4d9fdb46SRobert Mustacchi         "dwarf_formflat");
1202bc1f688bSRobert Mustacchi     return (DW_DLV_ERROR);
1203bc1f688bSRobert Mustacchi }
1204bc1f688bSRobert Mustacchi 
1205*4d9fdb46SRobert Mustacchi Dwarf_Bool
_dwarf_allow_formudata(unsigned form)1206*4d9fdb46SRobert Mustacchi _dwarf_allow_formudata(unsigned form)
1207*4d9fdb46SRobert Mustacchi {
1208*4d9fdb46SRobert Mustacchi     switch(form) {
1209*4d9fdb46SRobert Mustacchi     case DW_FORM_data1:
1210*4d9fdb46SRobert Mustacchi     case DW_FORM_data2:
1211*4d9fdb46SRobert Mustacchi     case DW_FORM_data4:
1212*4d9fdb46SRobert Mustacchi     case DW_FORM_data8:
1213*4d9fdb46SRobert Mustacchi     case DW_FORM_udata:
1214*4d9fdb46SRobert Mustacchi     case DW_FORM_loclistx:
1215*4d9fdb46SRobert Mustacchi     case DW_FORM_rnglistx:
1216*4d9fdb46SRobert Mustacchi     return TRUE;
1217*4d9fdb46SRobert Mustacchi     }
1218*4d9fdb46SRobert Mustacchi     return FALSE;
1219*4d9fdb46SRobert Mustacchi }
1220*4d9fdb46SRobert Mustacchi /*  If the form is DW_FORM_constx and the .debug_addr section
1221*4d9fdb46SRobert Mustacchi     is missing, this returns DW_DLV_ERROR and the error number
1222*4d9fdb46SRobert Mustacchi     in the Dwarf_Error is  DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION.
1223*4d9fdb46SRobert Mustacchi     When that arises, a consumer should call
1224*4d9fdb46SRobert Mustacchi     dwarf_get_debug_addr_index() and use that on the appropriate
1225*4d9fdb46SRobert Mustacchi     .debug_addr section in the executable or another object. */
1226bc1f688bSRobert Mustacchi 
1227bc1f688bSRobert Mustacchi int
_dwarf_formudata_internal(Dwarf_Debug dbg,unsigned form,Dwarf_Byte_Ptr data,Dwarf_Byte_Ptr section_end,Dwarf_Unsigned * return_uval,Dwarf_Unsigned * bytes_read,Dwarf_Error * error)1228*4d9fdb46SRobert Mustacchi _dwarf_formudata_internal(Dwarf_Debug dbg,
1229*4d9fdb46SRobert Mustacchi     unsigned form,
1230*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr data,
1231*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end,
1232*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *return_uval,
1233*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *bytes_read,
1234*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
1235bc1f688bSRobert Mustacchi {
1236bc1f688bSRobert Mustacchi     Dwarf_Unsigned ret_value = 0;
1237bc1f688bSRobert Mustacchi 
1238*4d9fdb46SRobert Mustacchi     switch (form) {
1239bc1f688bSRobert Mustacchi     case DW_FORM_data1:
1240*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1241*4d9fdb46SRobert Mustacchi             data, sizeof(Dwarf_Small),
1242*4d9fdb46SRobert Mustacchi             error,section_end);
1243bc1f688bSRobert Mustacchi         *return_uval = ret_value;
1244*4d9fdb46SRobert Mustacchi         *bytes_read = 1;
1245bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1246bc1f688bSRobert Mustacchi 
1247bc1f688bSRobert Mustacchi     /*  READ_UNALIGNED does the right thing as it reads
1248bc1f688bSRobert Mustacchi         the right number bits and generates host order.
1249bc1f688bSRobert Mustacchi         So we can just assign to *return_uval. */
1250bc1f688bSRobert Mustacchi     case DW_FORM_data2:{
1251*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1252*4d9fdb46SRobert Mustacchi             data, DWARF_HALF_SIZE,
1253*4d9fdb46SRobert Mustacchi             error,section_end);
1254bc1f688bSRobert Mustacchi         *return_uval = ret_value;
1255*4d9fdb46SRobert Mustacchi         *bytes_read = 2;
1256bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1257bc1f688bSRobert Mustacchi         }
1258bc1f688bSRobert Mustacchi 
1259bc1f688bSRobert Mustacchi     case DW_FORM_data4:{
1260*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1261*4d9fdb46SRobert Mustacchi             data,
1262*4d9fdb46SRobert Mustacchi             DWARF_32BIT_SIZE,
1263*4d9fdb46SRobert Mustacchi             error,section_end);
1264bc1f688bSRobert Mustacchi         *return_uval = ret_value;
1265*4d9fdb46SRobert Mustacchi         *bytes_read = DWARF_32BIT_SIZE;;
1266bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1267bc1f688bSRobert Mustacchi         }
1268bc1f688bSRobert Mustacchi 
1269bc1f688bSRobert Mustacchi     case DW_FORM_data8:{
1270*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1271*4d9fdb46SRobert Mustacchi             data,
1272*4d9fdb46SRobert Mustacchi             DWARF_64BIT_SIZE,
1273*4d9fdb46SRobert Mustacchi             error,section_end);
1274bc1f688bSRobert Mustacchi         *return_uval = ret_value;
1275*4d9fdb46SRobert Mustacchi         *bytes_read = DWARF_64BIT_SIZE;
1276bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1277bc1f688bSRobert Mustacchi         }
1278bc1f688bSRobert Mustacchi         break;
1279*4d9fdb46SRobert Mustacchi     /* real udata */
1280*4d9fdb46SRobert Mustacchi     case DW_FORM_loclistx:
1281*4d9fdb46SRobert Mustacchi     case DW_FORM_rnglistx:
1282*4d9fdb46SRobert Mustacchi     case DW_FORM_udata: {
1283*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned leblen = 0;
1284*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(data, ret_value,leblen,
1285*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
1286bc1f688bSRobert Mustacchi         *return_uval = ret_value;
1287*4d9fdb46SRobert Mustacchi         *bytes_read = leblen;
1288bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1289*4d9fdb46SRobert Mustacchi     }
1290*4d9fdb46SRobert Mustacchi         /*  IRIX bug 583450. We do not allow reading
1291*4d9fdb46SRobert Mustacchi             sdata from a udata
1292bc1f688bSRobert Mustacchi             value. Caller can retry, calling sdata */
1293bc1f688bSRobert Mustacchi     default:
1294bc1f688bSRobert Mustacchi         break;
1295bc1f688bSRobert Mustacchi     }
1296*4d9fdb46SRobert Mustacchi     generate_form_error(dbg,error,form,
1297*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_BAD,
1298*4d9fdb46SRobert Mustacchi         "DW_DLE_ATTR_FORM_BAD",
1299*4d9fdb46SRobert Mustacchi         "formudata (internal function)");
1300bc1f688bSRobert Mustacchi     return (DW_DLV_ERROR);
1301bc1f688bSRobert Mustacchi }
1302bc1f688bSRobert Mustacchi 
1303*4d9fdb46SRobert Mustacchi int
dwarf_formudata(Dwarf_Attribute attr,Dwarf_Unsigned * return_uval,Dwarf_Error * error)1304*4d9fdb46SRobert Mustacchi dwarf_formudata(Dwarf_Attribute attr,
1305*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * return_uval, Dwarf_Error * error)
1306*4d9fdb46SRobert Mustacchi {
1307*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
1308*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1309*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end = 0;
1310*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned bytes_read = 0;
1311*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr data =  attr->ar_debug_ptr;
1312*4d9fdb46SRobert Mustacchi     unsigned form = 0;
1313*4d9fdb46SRobert Mustacchi 
1314*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1315*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1316*4d9fdb46SRobert Mustacchi         return res;
1317*4d9fdb46SRobert Mustacchi     }
1318*4d9fdb46SRobert Mustacchi     section_end =
1319*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
1320*4d9fdb46SRobert Mustacchi     form = attr->ar_attribute_form;
1321*4d9fdb46SRobert Mustacchi 
1322*4d9fdb46SRobert Mustacchi     res = _dwarf_formudata_internal(dbg,
1323*4d9fdb46SRobert Mustacchi         form, data, section_end, return_uval,
1324*4d9fdb46SRobert Mustacchi         &bytes_read, error);
1325*4d9fdb46SRobert Mustacchi     return res;
1326*4d9fdb46SRobert Mustacchi }
1327*4d9fdb46SRobert Mustacchi 
1328bc1f688bSRobert Mustacchi 
1329bc1f688bSRobert Mustacchi int
dwarf_formsdata(Dwarf_Attribute attr,Dwarf_Signed * return_sval,Dwarf_Error * error)1330bc1f688bSRobert Mustacchi dwarf_formsdata(Dwarf_Attribute attr,
1331bc1f688bSRobert Mustacchi     Dwarf_Signed * return_sval, Dwarf_Error * error)
1332bc1f688bSRobert Mustacchi {
1333bc1f688bSRobert Mustacchi     Dwarf_Signed ret_value = 0;
1334bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
1335bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1336*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr section_end = 0;
1337bc1f688bSRobert Mustacchi 
1338*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1339*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1340*4d9fdb46SRobert Mustacchi         return res;
1341bc1f688bSRobert Mustacchi     }
1342*4d9fdb46SRobert Mustacchi     section_end =
1343*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
1344bc1f688bSRobert Mustacchi     switch (attr->ar_attribute_form) {
1345bc1f688bSRobert Mustacchi 
1346bc1f688bSRobert Mustacchi     case DW_FORM_data1:
1347*4d9fdb46SRobert Mustacchi         if ( attr->ar_debug_ptr >= section_end) {
1348*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
1349*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1350*4d9fdb46SRobert Mustacchi         }
1351*4d9fdb46SRobert Mustacchi         *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_ptr);
1352bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1353bc1f688bSRobert Mustacchi 
1354bc1f688bSRobert Mustacchi     /*  READ_UNALIGNED does not sign extend.
1355bc1f688bSRobert Mustacchi         So we have to use a cast to get the
1356bc1f688bSRobert Mustacchi         value sign extended in the right way for each case. */
1357bc1f688bSRobert Mustacchi     case DW_FORM_data2:{
1358*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed,
1359*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr,
1360*4d9fdb46SRobert Mustacchi             DWARF_HALF_SIZE,
1361*4d9fdb46SRobert Mustacchi             error,section_end);
1362bc1f688bSRobert Mustacchi         *return_sval = (Dwarf_Shalf) ret_value;
1363bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1364bc1f688bSRobert Mustacchi 
1365bc1f688bSRobert Mustacchi         }
1366bc1f688bSRobert Mustacchi 
1367bc1f688bSRobert Mustacchi     case DW_FORM_data4:{
1368*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed,
1369*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr,
1370*4d9fdb46SRobert Mustacchi             DWARF_32BIT_SIZE,
1371*4d9fdb46SRobert Mustacchi             error,section_end);
1372*4d9fdb46SRobert Mustacchi         SIGN_EXTEND(ret_value,DWARF_32BIT_SIZE);
1373bc1f688bSRobert Mustacchi         *return_sval = (Dwarf_Signed) ret_value;
1374bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1375bc1f688bSRobert Mustacchi         }
1376bc1f688bSRobert Mustacchi 
1377*4d9fdb46SRobert Mustacchi     case DW_FORM_data8:{
1378*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed,
1379*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr,
1380*4d9fdb46SRobert Mustacchi             DWARF_64BIT_SIZE,
1381*4d9fdb46SRobert Mustacchi             error,section_end);
1382*4d9fdb46SRobert Mustacchi         /* No SIGN_EXTEND needed, we are filling all bytes already.*/
1383*4d9fdb46SRobert Mustacchi         *return_sval = (Dwarf_Signed) ret_value;
1384*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1385*4d9fdb46SRobert Mustacchi         }
1386*4d9fdb46SRobert Mustacchi 
1387*4d9fdb46SRobert Mustacchi     /*  DW_FORM_implicit_const  is a value in the
1388*4d9fdb46SRobert Mustacchi         abbreviations, not in the DIEs. */
1389*4d9fdb46SRobert Mustacchi     case DW_FORM_implicit_const:
1390*4d9fdb46SRobert Mustacchi         *return_sval = attr->ar_implicit_const;
1391*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1392*4d9fdb46SRobert Mustacchi 
1393*4d9fdb46SRobert Mustacchi     case DW_FORM_sdata: {
1394*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr;
1395*4d9fdb46SRobert Mustacchi 
1396*4d9fdb46SRobert Mustacchi         DECODE_LEB128_SWORD_CK(tmp, ret_value,
1397*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
1398bc1f688bSRobert Mustacchi         *return_sval = ret_value;
1399bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1400bc1f688bSRobert Mustacchi 
1401*4d9fdb46SRobert Mustacchi     }
1402bc1f688bSRobert Mustacchi 
1403*4d9fdb46SRobert Mustacchi         /* IRIX bug 583450. We do not allow reading sdata from a udata
1404*4d9fdb46SRobert Mustacchi             value. Caller can retry, calling udata */
1405bc1f688bSRobert Mustacchi 
1406bc1f688bSRobert Mustacchi     default:
1407bc1f688bSRobert Mustacchi         break;
1408bc1f688bSRobert Mustacchi     }
1409*4d9fdb46SRobert Mustacchi     generate_form_error(dbg,error,attr->ar_attribute_form,
1410*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_BAD,
1411*4d9fdb46SRobert Mustacchi         "DW_DLE_ATTR_FORM_BAD",
1412*4d9fdb46SRobert Mustacchi         "dwarf_formsdata");
1413*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
1414bc1f688bSRobert Mustacchi }
1415bc1f688bSRobert Mustacchi 
1416*4d9fdb46SRobert Mustacchi int
_dwarf_formblock_internal(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_CU_Context cu_context,Dwarf_Block * return_block,Dwarf_Error * error)1417*4d9fdb46SRobert Mustacchi _dwarf_formblock_internal(Dwarf_Debug dbg,
1418*4d9fdb46SRobert Mustacchi     Dwarf_Attribute attr,
1419*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context,
1420*4d9fdb46SRobert Mustacchi     Dwarf_Block * return_block,
1421*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
1422*4d9fdb46SRobert Mustacchi {
1423*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_start = 0;
1424*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end = 0;
1425*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_length = 0;
1426*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned length = 0;
1427*4d9fdb46SRobert Mustacchi     Dwarf_Small *data = 0;
1428*4d9fdb46SRobert Mustacchi 
1429*4d9fdb46SRobert Mustacchi     section_end =
1430*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(cu_context);
1431*4d9fdb46SRobert Mustacchi     section_start =
1432*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_start_ptr(cu_context,
1433*4d9fdb46SRobert Mustacchi         &section_length);
1434*4d9fdb46SRobert Mustacchi 
1435*4d9fdb46SRobert Mustacchi     switch (attr->ar_attribute_form) {
1436*4d9fdb46SRobert Mustacchi 
1437*4d9fdb46SRobert Mustacchi     case DW_FORM_block1:
1438*4d9fdb46SRobert Mustacchi         length = *(Dwarf_Small *) attr->ar_debug_ptr;
1439*4d9fdb46SRobert Mustacchi         data = attr->ar_debug_ptr + sizeof(Dwarf_Small);
1440*4d9fdb46SRobert Mustacchi         break;
1441*4d9fdb46SRobert Mustacchi 
1442*4d9fdb46SRobert Mustacchi     case DW_FORM_block2:
1443*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned,
1444*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_HALF_SIZE,
1445*4d9fdb46SRobert Mustacchi             error,section_end);
1446*4d9fdb46SRobert Mustacchi         data = attr->ar_debug_ptr + DWARF_HALF_SIZE;
1447*4d9fdb46SRobert Mustacchi         break;
1448*4d9fdb46SRobert Mustacchi 
1449*4d9fdb46SRobert Mustacchi     case DW_FORM_block4:
1450*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned,
1451*4d9fdb46SRobert Mustacchi             attr->ar_debug_ptr, DWARF_32BIT_SIZE,
1452*4d9fdb46SRobert Mustacchi             error,section_end);
1453*4d9fdb46SRobert Mustacchi         data = attr->ar_debug_ptr + DWARF_32BIT_SIZE;
1454*4d9fdb46SRobert Mustacchi         break;
1455*4d9fdb46SRobert Mustacchi 
1456*4d9fdb46SRobert Mustacchi     case DW_FORM_block: {
1457*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr;
1458*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned leblen = 0;
1459*4d9fdb46SRobert Mustacchi 
1460*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(tmp, length, leblen,
1461*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
1462*4d9fdb46SRobert Mustacchi         data = attr->ar_debug_ptr + leblen;
1463*4d9fdb46SRobert Mustacchi         break;
1464*4d9fdb46SRobert Mustacchi         }
1465*4d9fdb46SRobert Mustacchi     default:
1466*4d9fdb46SRobert Mustacchi         generate_form_error(dbg,error,attr->ar_attribute_form,
1467*4d9fdb46SRobert Mustacchi             DW_DLE_ATTR_FORM_BAD,
1468*4d9fdb46SRobert Mustacchi             "DW_DLE_ATTR_FORM_BAD",
1469*4d9fdb46SRobert Mustacchi             "dwarf_formblock");
1470*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1471*4d9fdb46SRobert Mustacchi     }
1472*4d9fdb46SRobert Mustacchi     /*  We have the data. Check for errors. */
1473*4d9fdb46SRobert Mustacchi     if (length >= section_length) {
1474*4d9fdb46SRobert Mustacchi         /*  Sanity test looking for wraparound:
1475*4d9fdb46SRobert Mustacchi             when length actually added in
1476*4d9fdb46SRobert Mustacchi             it would not be caught.
1477*4d9fdb46SRobert Mustacchi             Test could be just >, but >= ok here too.*/
1478*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
1479*4d9fdb46SRobert Mustacchi             DW_DLE_FORM_BLOCK_LENGTH_ERROR,
1480*4d9fdb46SRobert Mustacchi             "DW_DLE_FORM_BLOCK_LENGTH_ERROR: "
1481*4d9fdb46SRobert Mustacchi             "The length of the block is greater "
1482*4d9fdb46SRobert Mustacchi             "than the section length! Corrupt Dwarf.");
1483*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1484*4d9fdb46SRobert Mustacchi     }
1485*4d9fdb46SRobert Mustacchi     if ((attr->ar_debug_ptr + length) > section_end) {
1486*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
1487*4d9fdb46SRobert Mustacchi             DW_DLE_FORM_BLOCK_LENGTH_ERROR,
1488*4d9fdb46SRobert Mustacchi             "DW_DLE_FORM_BLOCK_LENGTH_ERROR: "
1489*4d9fdb46SRobert Mustacchi             "The block length means the block "
1490*4d9fdb46SRobert Mustacchi             "runs off the end of the section length!"
1491*4d9fdb46SRobert Mustacchi             " Corrupt Dwarf.");
1492*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1493*4d9fdb46SRobert Mustacchi     }
1494*4d9fdb46SRobert Mustacchi     if (data > section_end) {
1495*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
1496*4d9fdb46SRobert Mustacchi             DW_DLE_FORM_BLOCK_LENGTH_ERROR,
1497*4d9fdb46SRobert Mustacchi             "DW_DLE_FORM_BLOCK_LENGTH_ERROR: "
1498*4d9fdb46SRobert Mustacchi             "The block content is "
1499*4d9fdb46SRobert Mustacchi             "past the end of the section!"
1500*4d9fdb46SRobert Mustacchi             " Corrupt Dwarf.");
1501*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR);
1502*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1503*4d9fdb46SRobert Mustacchi     }
1504*4d9fdb46SRobert Mustacchi     if ((data + length) > section_end) {
1505*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
1506*4d9fdb46SRobert Mustacchi             DW_DLE_FORM_BLOCK_LENGTH_ERROR,
1507*4d9fdb46SRobert Mustacchi             "DW_DLE_FORM_BLOCK_LENGTH_ERROR: "
1508*4d9fdb46SRobert Mustacchi             "The end of the block content is "
1509*4d9fdb46SRobert Mustacchi             "past the end of the section!"
1510*4d9fdb46SRobert Mustacchi             " Corrupt Dwarf.");
1511*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1512*4d9fdb46SRobert Mustacchi     }
1513*4d9fdb46SRobert Mustacchi     return_block->bl_len = length;
1514*4d9fdb46SRobert Mustacchi     return_block->bl_data = data;
1515*4d9fdb46SRobert Mustacchi     /*  This struct is public so use the old name instead
1516*4d9fdb46SRobert Mustacchi         of what we now would call it:  bl_kind  */
1517*4d9fdb46SRobert Mustacchi     return_block->bl_from_loclist =  DW_LKIND_expression;
1518*4d9fdb46SRobert Mustacchi     return_block->bl_section_offset =  data - section_start;
1519*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1520*4d9fdb46SRobert Mustacchi }
1521bc1f688bSRobert Mustacchi 
1522bc1f688bSRobert Mustacchi int
dwarf_formblock(Dwarf_Attribute attr,Dwarf_Block ** return_block,Dwarf_Error * error)1523bc1f688bSRobert Mustacchi dwarf_formblock(Dwarf_Attribute attr,
1524bc1f688bSRobert Mustacchi     Dwarf_Block ** return_block, Dwarf_Error * error)
1525bc1f688bSRobert Mustacchi {
1526bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1527bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
1528*4d9fdb46SRobert Mustacchi     Dwarf_Block local_block;
1529*4d9fdb46SRobert Mustacchi     Dwarf_Block *out_block = 0;
1530*4d9fdb46SRobert Mustacchi     int res = 0;
1531bc1f688bSRobert Mustacchi 
1532*4d9fdb46SRobert Mustacchi     memset(&local_block,0,sizeof(local_block));
1533*4d9fdb46SRobert Mustacchi     res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1534*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1535*4d9fdb46SRobert Mustacchi         return res;
1536*4d9fdb46SRobert Mustacchi     }
1537*4d9fdb46SRobert Mustacchi     res = _dwarf_formblock_internal(dbg,attr,
1538*4d9fdb46SRobert Mustacchi         cu_context, &local_block, error);
1539*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1540*4d9fdb46SRobert Mustacchi         return res;
1541*4d9fdb46SRobert Mustacchi     }
1542*4d9fdb46SRobert Mustacchi     out_block = (Dwarf_Block *)
1543*4d9fdb46SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
1544*4d9fdb46SRobert Mustacchi     if (out_block == NULL) {
1545*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1546*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1547*4d9fdb46SRobert Mustacchi     }
1548*4d9fdb46SRobert Mustacchi     *out_block = local_block;
1549*4d9fdb46SRobert Mustacchi     *return_block = out_block;
1550*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1551bc1f688bSRobert Mustacchi }
1552bc1f688bSRobert Mustacchi 
1553*4d9fdb46SRobert Mustacchi int
_dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg,Dwarf_Small * data_ptr,Dwarf_Small * end_data_ptr,UNUSEDARG Dwarf_Half attrnum,Dwarf_Half attrform,Dwarf_CU_Context cu_context,Dwarf_Unsigned * str_sect_offset_out,Dwarf_Error * error)1554*4d9fdb46SRobert Mustacchi _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg,
1555*4d9fdb46SRobert Mustacchi     Dwarf_Small *data_ptr,
1556*4d9fdb46SRobert Mustacchi     Dwarf_Small *end_data_ptr,
1557*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Half   attrnum,
1558*4d9fdb46SRobert Mustacchi     Dwarf_Half   attrform,
1559*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cu_context,
1560*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *str_sect_offset_out,
1561*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
1562*4d9fdb46SRobert Mustacchi {
1563*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset_base = 0;
1564*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index_to_offset_entry = 0;
1565*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offsetintable = 0;
1566*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned end_offsetintable = 0;
1567*4d9fdb46SRobert Mustacchi     int res = 0;
1568*4d9fdb46SRobert Mustacchi     int idxres = 0;
1569*4d9fdb46SRobert Mustacchi 
1570*4d9fdb46SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error);
1571*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1572*4d9fdb46SRobert Mustacchi         return res;
1573*4d9fdb46SRobert Mustacchi     }
1574*4d9fdb46SRobert Mustacchi     idxres = dw_read_index_val_itself(dbg,
1575*4d9fdb46SRobert Mustacchi         attrform,data_ptr,end_data_ptr,&index_to_offset_entry,error);
1576*4d9fdb46SRobert Mustacchi     if ( idxres != DW_DLV_OK) {
1577*4d9fdb46SRobert Mustacchi         return idxres;
1578bc1f688bSRobert Mustacchi     }
1579bc1f688bSRobert Mustacchi 
1580*4d9fdb46SRobert Mustacchi     /*  DW_FORM_GNU_str_index has no 'base' value.
1581*4d9fdb46SRobert Mustacchi         DW_FORM_strx* has a base value
1582*4d9fdb46SRobert Mustacchi         for the offset table */
1583*4d9fdb46SRobert Mustacchi     if( attrform != DW_FORM_GNU_str_index) {
1584*4d9fdb46SRobert Mustacchi         res = _dwarf_get_string_base_attr_value(dbg,cu_context,
1585*4d9fdb46SRobert Mustacchi             &offset_base,error);
1586*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1587*4d9fdb46SRobert Mustacchi             /*  DW_DLV_NO_ENTRY could be acceptable when
1588*4d9fdb46SRobert Mustacchi                 a producer knows that the base offset will be zero.
1589*4d9fdb46SRobert Mustacchi                 Hence DW_AT_str_offsets_base missing.
1590*4d9fdb46SRobert Mustacchi                 DWARF5 draft as of September 2015 allows the attribute
1591*4d9fdb46SRobert Mustacchi                 to be missing (it's up to the compilation tools to
1592*4d9fdb46SRobert Mustacchi                 make sure that has the correct effect).
1593*4d9fdb46SRobert Mustacchi             */
1594*4d9fdb46SRobert Mustacchi             return res;
1595bc1f688bSRobert Mustacchi         }
1596bc1f688bSRobert Mustacchi     }
1597bc1f688bSRobert Mustacchi 
1598*4d9fdb46SRobert Mustacchi     offsetintable = (index_to_offset_entry*cu_context->cc_length_size )
1599*4d9fdb46SRobert Mustacchi         + offset_base;
1600*4d9fdb46SRobert Mustacchi     {
1601*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned fissoff = 0;
1602*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned size = 0;
1603*4d9fdb46SRobert Mustacchi         fissoff = _dwarf_get_dwp_extra_offset(&cu_context->cc_dwp_offsets,
1604*4d9fdb46SRobert Mustacchi             DW_SECT_STR_OFFSETS, &size);
1605*4d9fdb46SRobert Mustacchi         offsetintable += fissoff;
1606*4d9fdb46SRobert Mustacchi     }
1607*4d9fdb46SRobert Mustacchi     end_offsetintable = offsetintable + cu_context->cc_length_size;
1608*4d9fdb46SRobert Mustacchi     /*  The offsets table is a series of offset-size entries.
1609*4d9fdb46SRobert Mustacchi         The == case in the test applies when we are at the last table
1610*4d9fdb46SRobert Mustacchi         entry, so == is not an error, hence only test >
1611*4d9fdb46SRobert Mustacchi     */
1612*4d9fdb46SRobert Mustacchi     if (end_offsetintable > dbg->de_debug_str_offsets.dss_size ) {
1613bc1f688bSRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
1614bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
1615bc1f688bSRobert Mustacchi     }
1616bc1f688bSRobert Mustacchi 
1617*4d9fdb46SRobert Mustacchi     {
1618*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned offsettostr = 0;
1619*4d9fdb46SRobert Mustacchi         Dwarf_Small *offsets_start = dbg->de_debug_str_offsets.dss_data;
1620*4d9fdb46SRobert Mustacchi         Dwarf_Small *offsets_end   = offsets_start +
1621*4d9fdb46SRobert Mustacchi             dbg->de_debug_str_offsets.dss_size;
1622*4d9fdb46SRobert Mustacchi         /* Now read the string offset from the offset table. */
1623*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,offsettostr,Dwarf_Unsigned,
1624*4d9fdb46SRobert Mustacchi             offsets_start+ offsetintable,
1625*4d9fdb46SRobert Mustacchi             cu_context->cc_length_size,error,offsets_end);
1626*4d9fdb46SRobert Mustacchi         *str_sect_offset_out = offsettostr;
1627*4d9fdb46SRobert Mustacchi     }
1628*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1629*4d9fdb46SRobert Mustacchi }
1630*4d9fdb46SRobert Mustacchi 
1631*4d9fdb46SRobert Mustacchi int
_dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg,unsigned attrform,Dwarf_Unsigned offset,char ** return_str,Dwarf_Error * error)1632*4d9fdb46SRobert Mustacchi _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg,
1633*4d9fdb46SRobert Mustacchi     unsigned attrform,
1634*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
1635*4d9fdb46SRobert Mustacchi     char ** return_str,
1636*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
1637*4d9fdb46SRobert Mustacchi {
1638*4d9fdb46SRobert Mustacchi     if (attrform == DW_FORM_strp ||
1639*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_line_strp ||
1640*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_GNU_str_index ||
1641*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_strx1 ||
1642*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_strx2 ||
1643*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_strx3 ||
1644*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_strx4 ||
1645*4d9fdb46SRobert Mustacchi         attrform == DW_FORM_strx) {
1646*4d9fdb46SRobert Mustacchi         /*  The 'offset' into .debug_str or .debug_line_str is given,
1647*4d9fdb46SRobert Mustacchi             here we turn that into a pointer. */
1648*4d9fdb46SRobert Mustacchi         Dwarf_Small   *secend = 0;
1649*4d9fdb46SRobert Mustacchi         Dwarf_Small   *secbegin = 0;
1650*4d9fdb46SRobert Mustacchi         Dwarf_Small   *strbegin = 0;
1651*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned secsize = 0;
1652*4d9fdb46SRobert Mustacchi         int errcode = 0;
1653*4d9fdb46SRobert Mustacchi         int res = 0;
1654*4d9fdb46SRobert Mustacchi 
1655*4d9fdb46SRobert Mustacchi         if(attrform == DW_FORM_line_strp) {
1656*4d9fdb46SRobert Mustacchi             res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error);
1657*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
1658*4d9fdb46SRobert Mustacchi                 return res;
1659*4d9fdb46SRobert Mustacchi             }
1660*4d9fdb46SRobert Mustacchi             errcode = DW_DLE_STRP_OFFSET_BAD;
1661*4d9fdb46SRobert Mustacchi             secsize = dbg->de_debug_line_str.dss_size;
1662*4d9fdb46SRobert Mustacchi             secbegin = dbg->de_debug_line_str.dss_data;
1663*4d9fdb46SRobert Mustacchi             strbegin= dbg->de_debug_line_str.dss_data + offset;
1664*4d9fdb46SRobert Mustacchi         } else {
1665*4d9fdb46SRobert Mustacchi             /* DW_FORM_strp  etc */
1666*4d9fdb46SRobert Mustacchi             res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
1667*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
1668*4d9fdb46SRobert Mustacchi                 return res;
1669*4d9fdb46SRobert Mustacchi             }
1670*4d9fdb46SRobert Mustacchi             errcode = DW_DLE_STRING_OFFSET_BAD;
1671*4d9fdb46SRobert Mustacchi             secsize = dbg->de_debug_str.dss_size;
1672*4d9fdb46SRobert Mustacchi             secbegin = dbg->de_debug_str.dss_data;
1673*4d9fdb46SRobert Mustacchi             strbegin= dbg->de_debug_str.dss_data + offset;
1674*4d9fdb46SRobert Mustacchi             secend = dbg->de_debug_str.dss_data + secsize;
1675*4d9fdb46SRobert Mustacchi         }
1676*4d9fdb46SRobert Mustacchi         if (offset >= secsize) {
1677*4d9fdb46SRobert Mustacchi             /*  Badly damaged DWARF here. */
1678*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, errcode);
1679*4d9fdb46SRobert Mustacchi             return (DW_DLV_ERROR);
1680*4d9fdb46SRobert Mustacchi         }
1681*4d9fdb46SRobert Mustacchi         res= _dwarf_check_string_valid(dbg,secbegin,strbegin, secend,
1682*4d9fdb46SRobert Mustacchi             errcode,error);
1683*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1684*4d9fdb46SRobert Mustacchi             return res;
1685*4d9fdb46SRobert Mustacchi         }
1686*4d9fdb46SRobert Mustacchi 
1687*4d9fdb46SRobert Mustacchi         *return_str = (char *)strbegin;
1688*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1689*4d9fdb46SRobert Mustacchi     }
1690*4d9fdb46SRobert Mustacchi     generate_form_error(dbg,error,attrform,
1691*4d9fdb46SRobert Mustacchi         DW_DLE_ATTR_FORM_BAD,
1692*4d9fdb46SRobert Mustacchi         "DW_DLE_ATTR_FORM_BAD",
1693*4d9fdb46SRobert Mustacchi         "extract debug_str string");
1694bc1f688bSRobert Mustacchi     return (DW_DLV_ERROR);
1695bc1f688bSRobert Mustacchi }
1696bc1f688bSRobert Mustacchi 
1697*4d9fdb46SRobert Mustacchi /* Contrary to pre-2005 documentation,
1698bc1f688bSRobert Mustacchi    The string pointer returned thru return_str must
1699bc1f688bSRobert Mustacchi    never have dwarf_dealloc() applied to it.
1700bc1f688bSRobert Mustacchi    Documentation fixed July 2005.
1701bc1f688bSRobert Mustacchi */
1702bc1f688bSRobert Mustacchi int
dwarf_formstring(Dwarf_Attribute attr,char ** return_str,Dwarf_Error * error)1703bc1f688bSRobert Mustacchi dwarf_formstring(Dwarf_Attribute attr,
1704bc1f688bSRobert Mustacchi     char **return_str, Dwarf_Error * error)
1705bc1f688bSRobert Mustacchi {
1706bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1707bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
1708bc1f688bSRobert Mustacchi     Dwarf_Unsigned offset = 0;
1709bc1f688bSRobert Mustacchi     int res = DW_DLV_ERROR;
1710*4d9fdb46SRobert Mustacchi     Dwarf_Small *secdataptr = 0;
1711*4d9fdb46SRobert Mustacchi     Dwarf_Small *secend = 0;
1712*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secdatalen = 0;
1713*4d9fdb46SRobert Mustacchi     Dwarf_Small *infoptr = attr->ar_debug_ptr;
1714*4d9fdb46SRobert Mustacchi     Dwarf_Small *contextend = 0;
1715bc1f688bSRobert Mustacchi 
1716*4d9fdb46SRobert Mustacchi     res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1717*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1718*4d9fdb46SRobert Mustacchi         return res;
1719bc1f688bSRobert Mustacchi     }
1720*4d9fdb46SRobert Mustacchi     if (cu_context->cc_is_info) {
1721*4d9fdb46SRobert Mustacchi         secdataptr = (Dwarf_Small *)dbg->de_debug_info.dss_data;
1722*4d9fdb46SRobert Mustacchi         secdatalen = dbg->de_debug_info.dss_size;
1723*4d9fdb46SRobert Mustacchi     } else {
1724*4d9fdb46SRobert Mustacchi         secdataptr = (Dwarf_Small *)dbg->de_debug_types.dss_data;
1725*4d9fdb46SRobert Mustacchi         secdatalen = dbg->de_debug_types.dss_size;
1726bc1f688bSRobert Mustacchi     }
1727*4d9fdb46SRobert Mustacchi     contextend = secdataptr +
1728*4d9fdb46SRobert Mustacchi         cu_context->cc_debug_offset +
1729*4d9fdb46SRobert Mustacchi         cu_context->cc_length +
1730*4d9fdb46SRobert Mustacchi         cu_context->cc_length_size +
1731bc1f688bSRobert Mustacchi         cu_context->cc_extension_size;
1732*4d9fdb46SRobert Mustacchi     secend = secdataptr + secdatalen;
1733*4d9fdb46SRobert Mustacchi     if (contextend < secend) {
1734*4d9fdb46SRobert Mustacchi         secend = contextend;
1735bc1f688bSRobert Mustacchi     }
1736*4d9fdb46SRobert Mustacchi     switch(attr->ar_attribute_form) {
1737*4d9fdb46SRobert Mustacchi     case DW_FORM_string: {
1738*4d9fdb46SRobert Mustacchi         Dwarf_Small *begin = attr->ar_debug_ptr;
1739*4d9fdb46SRobert Mustacchi 
1740*4d9fdb46SRobert Mustacchi         res= _dwarf_check_string_valid(dbg,secdataptr,begin, secend,
1741*4d9fdb46SRobert Mustacchi             DW_DLE_FORM_STRING_BAD_STRING,error);
1742*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1743*4d9fdb46SRobert Mustacchi             return res;
1744bc1f688bSRobert Mustacchi         }
1745bc1f688bSRobert Mustacchi         *return_str = (char *) (begin);
1746bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1747bc1f688bSRobert Mustacchi     }
1748*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_strp_alt:
1749*4d9fdb46SRobert Mustacchi     case DW_FORM_strp_sup:  {
1750*4d9fdb46SRobert Mustacchi         Dwarf_Error alterr = 0;
1751*4d9fdb46SRobert Mustacchi         /*  See dwarfstd.org issue 120604.1
1752*4d9fdb46SRobert Mustacchi             This is the offset in the .debug_str section
1753*4d9fdb46SRobert Mustacchi             of another object file.
1754*4d9fdb46SRobert Mustacchi             The 'tied' file notion should apply.
1755*4d9fdb46SRobert Mustacchi             It is not clear whether both a supplementary
1756*4d9fdb46SRobert Mustacchi             and a split object might be needed at the same time
1757*4d9fdb46SRobert Mustacchi             (hence two 'tied' files simultaneously). */
1758*4d9fdb46SRobert Mustacchi         Dwarf_Off soffset = 0;
1759bc1f688bSRobert Mustacchi 
1760*4d9fdb46SRobert Mustacchi         res = dwarf_global_formref(attr, &soffset,error);
1761bc1f688bSRobert Mustacchi         if (res != DW_DLV_OK) {
1762bc1f688bSRobert Mustacchi             return res;
1763bc1f688bSRobert Mustacchi         }
1764*4d9fdb46SRobert Mustacchi         res = _dwarf_get_string_from_tied(dbg, soffset,
1765*4d9fdb46SRobert Mustacchi             return_str, &alterr);
1766*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
1767*4d9fdb46SRobert Mustacchi             if (dwarf_errno(alterr) == DW_DLE_NO_TIED_FILE_AVAILABLE) {
1768*4d9fdb46SRobert Mustacchi                 dwarf_dealloc(dbg,alterr,DW_DLA_ERROR);
1769*4d9fdb46SRobert Mustacchi                 if( attr->ar_attribute_form == DW_FORM_GNU_strp_alt) {
1770*4d9fdb46SRobert Mustacchi                     *return_str =
1771*4d9fdb46SRobert Mustacchi                         (char *)"<DW_FORM_GNU_strp_alt-no-tied-file>";
1772*4d9fdb46SRobert Mustacchi                 } else {
1773*4d9fdb46SRobert Mustacchi                     *return_str =
1774*4d9fdb46SRobert Mustacchi                         (char *)"<DW_FORM_strp_sup-no-tied-file>";
1775*4d9fdb46SRobert Mustacchi                 }
1776*4d9fdb46SRobert Mustacchi                 return DW_DLV_OK;
1777*4d9fdb46SRobert Mustacchi             }
1778*4d9fdb46SRobert Mustacchi             if (error) {
1779*4d9fdb46SRobert Mustacchi                 *error = alterr;
1780*4d9fdb46SRobert Mustacchi             }
1781*4d9fdb46SRobert Mustacchi             return res;
1782*4d9fdb46SRobert Mustacchi         }
1783*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
1784*4d9fdb46SRobert Mustacchi             if( attr->ar_attribute_form == DW_FORM_GNU_strp_alt) {
1785*4d9fdb46SRobert Mustacchi                 *return_str =
1786*4d9fdb46SRobert Mustacchi                     (char *)"<DW_FORM_GNU_strp_alt-no-tied-file>";
1787*4d9fdb46SRobert Mustacchi             }else {
1788*4d9fdb46SRobert Mustacchi                 *return_str =
1789*4d9fdb46SRobert Mustacchi                     (char *)"<DW_FORM_strp_sup-no-tied-file>";
1790*4d9fdb46SRobert Mustacchi             }
1791*4d9fdb46SRobert Mustacchi         }
1792*4d9fdb46SRobert Mustacchi         return res;
1793*4d9fdb46SRobert Mustacchi     }
1794*4d9fdb46SRobert Mustacchi     case DW_FORM_GNU_str_index:
1795*4d9fdb46SRobert Mustacchi     case DW_FORM_strx:
1796*4d9fdb46SRobert Mustacchi     case DW_FORM_strx1:
1797*4d9fdb46SRobert Mustacchi     case DW_FORM_strx2:
1798*4d9fdb46SRobert Mustacchi     case DW_FORM_strx3:
1799*4d9fdb46SRobert Mustacchi     case DW_FORM_strx4: {
1800*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned offsettostr= 0;
1801*4d9fdb46SRobert Mustacchi         res = _dwarf_extract_string_offset_via_str_offsets(dbg,
1802*4d9fdb46SRobert Mustacchi             infoptr,
1803*4d9fdb46SRobert Mustacchi             secend,
1804*4d9fdb46SRobert Mustacchi             attr->ar_attribute,
1805*4d9fdb46SRobert Mustacchi             attr->ar_attribute_form,
1806*4d9fdb46SRobert Mustacchi             cu_context,
1807*4d9fdb46SRobert Mustacchi             &offsettostr,
1808*4d9fdb46SRobert Mustacchi             error);
1809*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1810*4d9fdb46SRobert Mustacchi             return res;
1811*4d9fdb46SRobert Mustacchi         }
1812*4d9fdb46SRobert Mustacchi         offset = offsettostr;
1813*4d9fdb46SRobert Mustacchi         break;
1814*4d9fdb46SRobert Mustacchi     }
1815*4d9fdb46SRobert Mustacchi     case DW_FORM_strp:
1816*4d9fdb46SRobert Mustacchi     case DW_FORM_line_strp:{
1817*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
1818*4d9fdb46SRobert Mustacchi             infoptr,
1819*4d9fdb46SRobert Mustacchi             cu_context->cc_length_size,error,secend);
1820*4d9fdb46SRobert Mustacchi         break;
1821*4d9fdb46SRobert Mustacchi     }
1822*4d9fdb46SRobert Mustacchi     default:
1823*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_STRING_FORM_IMPROPER);
1824*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1825*4d9fdb46SRobert Mustacchi     }
1826*4d9fdb46SRobert Mustacchi     /*  Now we have offset so read the string from
1827*4d9fdb46SRobert Mustacchi         debug_str or debug_line_str. */
1828*4d9fdb46SRobert Mustacchi     res = _dwarf_extract_local_debug_str_string_given_offset(dbg,
1829*4d9fdb46SRobert Mustacchi         attr->ar_attribute_form,
1830*4d9fdb46SRobert Mustacchi         offset,
1831*4d9fdb46SRobert Mustacchi         return_str,
1832*4d9fdb46SRobert Mustacchi         error);
1833*4d9fdb46SRobert Mustacchi     return res;
1834*4d9fdb46SRobert Mustacchi }
1835*4d9fdb46SRobert Mustacchi 
1836*4d9fdb46SRobert Mustacchi 
1837*4d9fdb46SRobert Mustacchi int
_dwarf_get_string_from_tied(Dwarf_Debug dbg,Dwarf_Unsigned offset,char ** return_str,Dwarf_Error * error)1838*4d9fdb46SRobert Mustacchi _dwarf_get_string_from_tied(Dwarf_Debug dbg,
1839*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
1840*4d9fdb46SRobert Mustacchi     char **return_str,
1841*4d9fdb46SRobert Mustacchi     Dwarf_Error*error)
1842*4d9fdb46SRobert Mustacchi {
1843*4d9fdb46SRobert Mustacchi     Dwarf_Debug tieddbg = 0;
1844*4d9fdb46SRobert Mustacchi     Dwarf_Small *secend = 0;
1845*4d9fdb46SRobert Mustacchi     Dwarf_Small *secbegin = 0;
1846*4d9fdb46SRobert Mustacchi     Dwarf_Small *strbegin = 0;
1847*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
1848*4d9fdb46SRobert Mustacchi     Dwarf_Error localerror = 0;
1849*4d9fdb46SRobert Mustacchi 
1850*4d9fdb46SRobert Mustacchi     /* Attach errors to dbg, not tieddbg. */
1851*4d9fdb46SRobert Mustacchi     tieddbg = dbg->de_tied_data.td_tied_object;
1852*4d9fdb46SRobert Mustacchi     if (!tieddbg) {
1853*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE);
1854*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1855*4d9fdb46SRobert Mustacchi     }
1856*4d9fdb46SRobert Mustacchi     /* The 'offset' into .debug_str is set. */
1857*4d9fdb46SRobert Mustacchi     res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str,&localerror);
1858*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1859*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lerrno = dwarf_errno(localerror);
1860*4d9fdb46SRobert Mustacchi         dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR);
1861*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,lerrno);
1862*4d9fdb46SRobert Mustacchi         return res;
1863*4d9fdb46SRobert Mustacchi     } else if (res == DW_DLV_NO_ENTRY) {
1864*4d9fdb46SRobert Mustacchi         return res;
1865*4d9fdb46SRobert Mustacchi     }
1866*4d9fdb46SRobert Mustacchi     if (offset >= tieddbg->de_debug_str.dss_size) {
1867*4d9fdb46SRobert Mustacchi         /*  Badly damaged DWARF here. */
1868*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error,  DW_DLE_NO_TIED_STRING_AVAILABLE);
1869bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
1870bc1f688bSRobert Mustacchi     }
1871*4d9fdb46SRobert Mustacchi     secbegin = tieddbg->de_debug_str.dss_data;
1872*4d9fdb46SRobert Mustacchi     strbegin= tieddbg->de_debug_str.dss_data + offset;
1873*4d9fdb46SRobert Mustacchi     secend = tieddbg->de_debug_str.dss_data +
1874*4d9fdb46SRobert Mustacchi         tieddbg->de_debug_str.dss_size;
1875*4d9fdb46SRobert Mustacchi 
1876*4d9fdb46SRobert Mustacchi     /*  Ensure the offset lies within the .debug_str */
1877*4d9fdb46SRobert Mustacchi     if (offset >= tieddbg->de_debug_str.dss_size) {
1878*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error,  DW_DLE_NO_TIED_STRING_AVAILABLE);
1879*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
1880bc1f688bSRobert Mustacchi     }
1881*4d9fdb46SRobert Mustacchi     res= _dwarf_check_string_valid(tieddbg,secbegin,strbegin, secend,
1882*4d9fdb46SRobert Mustacchi         DW_DLE_NO_TIED_STRING_AVAILABLE,
1883*4d9fdb46SRobert Mustacchi         &localerror);
1884*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1885*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lerrno = dwarf_errno(localerror);
1886*4d9fdb46SRobert Mustacchi         dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR);
1887*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,lerrno);
1888*4d9fdb46SRobert Mustacchi         return res;
1889*4d9fdb46SRobert Mustacchi     } else if (res == DW_DLV_NO_ENTRY) {
1890*4d9fdb46SRobert Mustacchi         return res;
1891*4d9fdb46SRobert Mustacchi     }
1892*4d9fdb46SRobert Mustacchi     *return_str = (char *) (tieddbg->de_debug_str.dss_data + offset);
1893bc1f688bSRobert Mustacchi     return DW_DLV_OK;
1894bc1f688bSRobert Mustacchi }
1895bc1f688bSRobert Mustacchi 
1896*4d9fdb46SRobert Mustacchi 
1897*4d9fdb46SRobert Mustacchi 
1898bc1f688bSRobert Mustacchi 
1899bc1f688bSRobert Mustacchi int
dwarf_formexprloc(Dwarf_Attribute attr,Dwarf_Unsigned * return_exprlen,Dwarf_Ptr * block_ptr,Dwarf_Error * error)1900bc1f688bSRobert Mustacchi dwarf_formexprloc(Dwarf_Attribute attr,
1901bc1f688bSRobert Mustacchi     Dwarf_Unsigned * return_exprlen,
1902bc1f688bSRobert Mustacchi     Dwarf_Ptr  * block_ptr,
1903bc1f688bSRobert Mustacchi     Dwarf_Error * error)
1904bc1f688bSRobert Mustacchi {
1905bc1f688bSRobert Mustacchi     Dwarf_Debug dbg = 0;
1906bc1f688bSRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
1907bc1f688bSRobert Mustacchi 
1908*4d9fdb46SRobert Mustacchi     int res  = get_attr_dbg(&dbg,&cu_context,attr,error);
1909*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1910*4d9fdb46SRobert Mustacchi         return res;
1911bc1f688bSRobert Mustacchi     }
1912bc1f688bSRobert Mustacchi     if (dbg == NULL) {
1913bc1f688bSRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
1914bc1f688bSRobert Mustacchi         return (DW_DLV_ERROR);
1915bc1f688bSRobert Mustacchi     }
1916bc1f688bSRobert Mustacchi     if (attr->ar_attribute_form == DW_FORM_exprloc ) {
1917*4d9fdb46SRobert Mustacchi         Dwarf_Die die = 0;
1918*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned leb_len = 0;
1919*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr section_start = 0;
1920*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned section_len = 0;
1921*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr section_end = 0;
1922*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr info_ptr = 0;
1923*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned exprlen = 0;
1924*4d9fdb46SRobert Mustacchi         Dwarf_Small * addr = attr->ar_debug_ptr;
1925*4d9fdb46SRobert Mustacchi 
1926*4d9fdb46SRobert Mustacchi         info_ptr = addr;
1927*4d9fdb46SRobert Mustacchi         section_start =
1928*4d9fdb46SRobert Mustacchi             _dwarf_calculate_info_section_start_ptr(cu_context,
1929*4d9fdb46SRobert Mustacchi             &section_len);
1930*4d9fdb46SRobert Mustacchi         section_end = section_start + section_len;
1931*4d9fdb46SRobert Mustacchi 
1932*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_LEN_CK(info_ptr, exprlen, leb_len,
1933*4d9fdb46SRobert Mustacchi             dbg,error,section_end);
1934*4d9fdb46SRobert Mustacchi         if (exprlen > section_len) {
1935*4d9fdb46SRobert Mustacchi             /* Corrupted dwarf!  */
1936*4d9fdb46SRobert Mustacchi             dwarfstring m;
1937*4d9fdb46SRobert Mustacchi 
1938*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
1939*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
1940*4d9fdb46SRobert Mustacchi                 "DW_DLE_ATTR_OUTSIDE_SECTION: "
1941*4d9fdb46SRobert Mustacchi                 "The expression length is %u,",exprlen);
1942*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
1943*4d9fdb46SRobert Mustacchi                 " but the section length is just %u. "
1944*4d9fdb46SRobert Mustacchi                 "Corrupt Dwarf.",section_len);
1945*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error,
1946*4d9fdb46SRobert Mustacchi                 DW_DLE_ATTR_OUTSIDE_SECTION,
1947*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
1948*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
1949*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1950*4d9fdb46SRobert Mustacchi         }
1951*4d9fdb46SRobert Mustacchi         die = attr->ar_die;
1952*4d9fdb46SRobert Mustacchi         /*  Is the block entirely in the section, or is
1953*4d9fdb46SRobert Mustacchi             there bug somewhere?
1954*4d9fdb46SRobert Mustacchi             Here the final addr may be 1 past end of section. */
1955*4d9fdb46SRobert Mustacchi         if (_dwarf_reference_outside_section(die,
1956*4d9fdb46SRobert Mustacchi             (Dwarf_Small *)addr,
1957*4d9fdb46SRobert Mustacchi             ((Dwarf_Small *)addr)+exprlen +leb_len)) {
1958*4d9fdb46SRobert Mustacchi             dwarfstring m;
1959*4d9fdb46SRobert Mustacchi 
1960*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
1961*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
1962*4d9fdb46SRobert Mustacchi                 "DW_DLE_ATTR_OUTSIDE_SECTION: "
1963*4d9fdb46SRobert Mustacchi                 "The expression length %u,",exprlen);
1964*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
1965*4d9fdb46SRobert Mustacchi                 " plus the leb value length of "
1966*4d9fdb46SRobert Mustacchi                 "%u ",leb_len);
1967*4d9fdb46SRobert Mustacchi             dwarfstring_append(&m,
1968*4d9fdb46SRobert Mustacchi                 " runs past the end of the section. "
1969*4d9fdb46SRobert Mustacchi                 "Corrupt Dwarf.");
1970*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error,
1971*4d9fdb46SRobert Mustacchi                 DW_DLE_ATTR_OUTSIDE_SECTION,
1972*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
1973*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
1974*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1975*4d9fdb46SRobert Mustacchi         }
1976bc1f688bSRobert Mustacchi         *return_exprlen = exprlen;
1977*4d9fdb46SRobert Mustacchi         *block_ptr = addr + leb_len;
1978bc1f688bSRobert Mustacchi         return DW_DLV_OK;
1979bc1f688bSRobert Mustacchi 
1980bc1f688bSRobert Mustacchi     }
1981*4d9fdb46SRobert Mustacchi     {
1982*4d9fdb46SRobert Mustacchi         dwarfstring m;
1983*4d9fdb46SRobert Mustacchi         const char *name = "<name not known>";
1984*4d9fdb46SRobert Mustacchi         unsigned  mform = attr->ar_attribute_form;
1985*4d9fdb46SRobert Mustacchi 
1986*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
1987*4d9fdb46SRobert Mustacchi 
1988*4d9fdb46SRobert Mustacchi         dwarf_get_FORM_name (mform,&name);
1989*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
1990*4d9fdb46SRobert Mustacchi             "DW_DLE_ATTR_EXPRLOC_FORM_BAD: "
1991*4d9fdb46SRobert Mustacchi             "The form is 0x%x ", mform);
1992*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
1993*4d9fdb46SRobert Mustacchi             "(%s) but should be DW_FORM_exprloc. "
1994*4d9fdb46SRobert Mustacchi             "Corrupt Dwarf.",(char *)name);
1995*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD,
1996*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
1997*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
1998*4d9fdb46SRobert Mustacchi     }
1999*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
2000bc1f688bSRobert Mustacchi }
2001