xref: /titanic_52/usr/src/lib/libdwarf/common/dwarf_loc.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi 
3*7fd79137SRobert Mustacchi   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
4*7fd79137SRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5*7fd79137SRobert Mustacchi 
6*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
9*7fd79137SRobert Mustacchi 
10*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*7fd79137SRobert Mustacchi 
14*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
20*7fd79137SRobert Mustacchi 
21*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
23*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*7fd79137SRobert Mustacchi   USA.
25*7fd79137SRobert Mustacchi 
26*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
28*7fd79137SRobert Mustacchi 
29*7fd79137SRobert Mustacchi   http://www.sgi.com
30*7fd79137SRobert Mustacchi 
31*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
32*7fd79137SRobert Mustacchi 
33*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*7fd79137SRobert Mustacchi 
35*7fd79137SRobert Mustacchi */
36*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
37*7fd79137SRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*7fd79137SRobert Mustacchi    Boston, MA 02110-1301, USA.
39*7fd79137SRobert Mustacchi    SGI has moved from the Crittenden Lane address.
40*7fd79137SRobert Mustacchi */
41*7fd79137SRobert Mustacchi 
42*7fd79137SRobert Mustacchi 
43*7fd79137SRobert Mustacchi 
44*7fd79137SRobert Mustacchi 
45*7fd79137SRobert Mustacchi #include "config.h"
46*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
47*7fd79137SRobert Mustacchi #include "dwarf_loc.h"
48*7fd79137SRobert Mustacchi #include <stdio.h> /* for debugging only. */
49*7fd79137SRobert Mustacchi #include <sys/types.h>
50*7fd79137SRobert Mustacchi 
51*7fd79137SRobert Mustacchi /*
52*7fd79137SRobert Mustacchi     Given a Dwarf_Block that represents a location expression,
53*7fd79137SRobert Mustacchi     this function returns a pointer to a Dwarf_Locdesc struct
54*7fd79137SRobert Mustacchi     that has its ld_cents field set to the number of location
55*7fd79137SRobert Mustacchi     operators in the block, and its ld_s field pointing to a
56*7fd79137SRobert Mustacchi     contiguous block of Dwarf_Loc structs.  However, the
57*7fd79137SRobert Mustacchi     ld_lopc and ld_hipc values are uninitialized.  Returns
58*7fd79137SRobert Mustacchi     NULL on error.  This function assumes that the length of
59*7fd79137SRobert Mustacchi     the block is greater than 0.  Zero length location expressions
60*7fd79137SRobert Mustacchi     to represent variables that have been optimized away are
61*7fd79137SRobert Mustacchi     handled in the calling function.
62*7fd79137SRobert Mustacchi */
63*7fd79137SRobert Mustacchi static Dwarf_Locdesc *
64*7fd79137SRobert Mustacchi _dwarf_get_locdesc(Dwarf_Debug dbg,
65*7fd79137SRobert Mustacchi     Dwarf_Block * loc_block,
66*7fd79137SRobert Mustacchi     Dwarf_Half address_size,
67*7fd79137SRobert Mustacchi     Dwarf_Addr lowpc,
68*7fd79137SRobert Mustacchi     Dwarf_Addr highpc,
69*7fd79137SRobert Mustacchi     Dwarf_Error * error)
70*7fd79137SRobert Mustacchi {
71*7fd79137SRobert Mustacchi     /* Size of the block containing the location expression. */
72*7fd79137SRobert Mustacchi     Dwarf_Unsigned loc_len = 0;
73*7fd79137SRobert Mustacchi 
74*7fd79137SRobert Mustacchi     /* Sweeps the block containing the location expression. */
75*7fd79137SRobert Mustacchi     Dwarf_Small *loc_ptr = 0;
76*7fd79137SRobert Mustacchi 
77*7fd79137SRobert Mustacchi     /* Current location operator. */
78*7fd79137SRobert Mustacchi     Dwarf_Small atom = 0;
79*7fd79137SRobert Mustacchi 
80*7fd79137SRobert Mustacchi     /* Offset of current operator from start of block. */
81*7fd79137SRobert Mustacchi     Dwarf_Unsigned offset = 0;
82*7fd79137SRobert Mustacchi 
83*7fd79137SRobert Mustacchi     /* Operands of current location operator. */
84*7fd79137SRobert Mustacchi     Dwarf_Unsigned operand1, operand2;
85*7fd79137SRobert Mustacchi 
86*7fd79137SRobert Mustacchi     /* Used to chain the Dwarf_Loc_Chain_s structs. */
87*7fd79137SRobert Mustacchi     Dwarf_Loc_Chain curr_loc = NULL;
88*7fd79137SRobert Mustacchi     Dwarf_Loc_Chain prev_loc = NULL;
89*7fd79137SRobert Mustacchi     Dwarf_Loc_Chain head_loc = NULL;
90*7fd79137SRobert Mustacchi 
91*7fd79137SRobert Mustacchi     /* Count of the number of location operators. */
92*7fd79137SRobert Mustacchi     Dwarf_Unsigned op_count = 0;
93*7fd79137SRobert Mustacchi 
94*7fd79137SRobert Mustacchi     /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
95*7fd79137SRobert Mustacchi     Dwarf_Loc *block_loc = 0;
96*7fd79137SRobert Mustacchi 
97*7fd79137SRobert Mustacchi     /* Dwarf_Locdesc pointer to be returned. */
98*7fd79137SRobert Mustacchi     Dwarf_Locdesc *locdesc = 0;
99*7fd79137SRobert Mustacchi 
100*7fd79137SRobert Mustacchi     Dwarf_Word leb128_length = 0;
101*7fd79137SRobert Mustacchi     Dwarf_Unsigned i = 0;
102*7fd79137SRobert Mustacchi 
103*7fd79137SRobert Mustacchi     /* ***** BEGIN CODE ***** */
104*7fd79137SRobert Mustacchi 
105*7fd79137SRobert Mustacchi     loc_len = loc_block->bl_len;
106*7fd79137SRobert Mustacchi     loc_ptr = loc_block->bl_data;
107*7fd79137SRobert Mustacchi 
108*7fd79137SRobert Mustacchi     offset = 0;
109*7fd79137SRobert Mustacchi     op_count = 0;
110*7fd79137SRobert Mustacchi     while (offset < loc_len) {
111*7fd79137SRobert Mustacchi 
112*7fd79137SRobert Mustacchi         operand1 = 0;
113*7fd79137SRobert Mustacchi         operand2 = 0;
114*7fd79137SRobert Mustacchi         op_count++;
115*7fd79137SRobert Mustacchi 
116*7fd79137SRobert Mustacchi         atom = *(Dwarf_Small *) loc_ptr;
117*7fd79137SRobert Mustacchi         loc_ptr++;
118*7fd79137SRobert Mustacchi         offset++;
119*7fd79137SRobert Mustacchi 
120*7fd79137SRobert Mustacchi         curr_loc =
121*7fd79137SRobert Mustacchi             (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
122*7fd79137SRobert Mustacchi                                                1);
123*7fd79137SRobert Mustacchi         if (curr_loc == NULL) {
124*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
125*7fd79137SRobert Mustacchi             return (NULL);
126*7fd79137SRobert Mustacchi         }
127*7fd79137SRobert Mustacchi         curr_loc->lc_offset = offset;
128*7fd79137SRobert Mustacchi         curr_loc->lc_atom = atom;
129*7fd79137SRobert Mustacchi         switch (atom) {
130*7fd79137SRobert Mustacchi 
131*7fd79137SRobert Mustacchi         case DW_OP_reg0:
132*7fd79137SRobert Mustacchi         case DW_OP_reg1:
133*7fd79137SRobert Mustacchi         case DW_OP_reg2:
134*7fd79137SRobert Mustacchi         case DW_OP_reg3:
135*7fd79137SRobert Mustacchi         case DW_OP_reg4:
136*7fd79137SRobert Mustacchi         case DW_OP_reg5:
137*7fd79137SRobert Mustacchi         case DW_OP_reg6:
138*7fd79137SRobert Mustacchi         case DW_OP_reg7:
139*7fd79137SRobert Mustacchi         case DW_OP_reg8:
140*7fd79137SRobert Mustacchi         case DW_OP_reg9:
141*7fd79137SRobert Mustacchi         case DW_OP_reg10:
142*7fd79137SRobert Mustacchi         case DW_OP_reg11:
143*7fd79137SRobert Mustacchi         case DW_OP_reg12:
144*7fd79137SRobert Mustacchi         case DW_OP_reg13:
145*7fd79137SRobert Mustacchi         case DW_OP_reg14:
146*7fd79137SRobert Mustacchi         case DW_OP_reg15:
147*7fd79137SRobert Mustacchi         case DW_OP_reg16:
148*7fd79137SRobert Mustacchi         case DW_OP_reg17:
149*7fd79137SRobert Mustacchi         case DW_OP_reg18:
150*7fd79137SRobert Mustacchi         case DW_OP_reg19:
151*7fd79137SRobert Mustacchi         case DW_OP_reg20:
152*7fd79137SRobert Mustacchi         case DW_OP_reg21:
153*7fd79137SRobert Mustacchi         case DW_OP_reg22:
154*7fd79137SRobert Mustacchi         case DW_OP_reg23:
155*7fd79137SRobert Mustacchi         case DW_OP_reg24:
156*7fd79137SRobert Mustacchi         case DW_OP_reg25:
157*7fd79137SRobert Mustacchi         case DW_OP_reg26:
158*7fd79137SRobert Mustacchi         case DW_OP_reg27:
159*7fd79137SRobert Mustacchi         case DW_OP_reg28:
160*7fd79137SRobert Mustacchi         case DW_OP_reg29:
161*7fd79137SRobert Mustacchi         case DW_OP_reg30:
162*7fd79137SRobert Mustacchi         case DW_OP_reg31:
163*7fd79137SRobert Mustacchi             break;
164*7fd79137SRobert Mustacchi 
165*7fd79137SRobert Mustacchi         case DW_OP_regx:
166*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
167*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
168*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
169*7fd79137SRobert Mustacchi             break;
170*7fd79137SRobert Mustacchi 
171*7fd79137SRobert Mustacchi         case DW_OP_lit0:
172*7fd79137SRobert Mustacchi         case DW_OP_lit1:
173*7fd79137SRobert Mustacchi         case DW_OP_lit2:
174*7fd79137SRobert Mustacchi         case DW_OP_lit3:
175*7fd79137SRobert Mustacchi         case DW_OP_lit4:
176*7fd79137SRobert Mustacchi         case DW_OP_lit5:
177*7fd79137SRobert Mustacchi         case DW_OP_lit6:
178*7fd79137SRobert Mustacchi         case DW_OP_lit7:
179*7fd79137SRobert Mustacchi         case DW_OP_lit8:
180*7fd79137SRobert Mustacchi         case DW_OP_lit9:
181*7fd79137SRobert Mustacchi         case DW_OP_lit10:
182*7fd79137SRobert Mustacchi         case DW_OP_lit11:
183*7fd79137SRobert Mustacchi         case DW_OP_lit12:
184*7fd79137SRobert Mustacchi         case DW_OP_lit13:
185*7fd79137SRobert Mustacchi         case DW_OP_lit14:
186*7fd79137SRobert Mustacchi         case DW_OP_lit15:
187*7fd79137SRobert Mustacchi         case DW_OP_lit16:
188*7fd79137SRobert Mustacchi         case DW_OP_lit17:
189*7fd79137SRobert Mustacchi         case DW_OP_lit18:
190*7fd79137SRobert Mustacchi         case DW_OP_lit19:
191*7fd79137SRobert Mustacchi         case DW_OP_lit20:
192*7fd79137SRobert Mustacchi         case DW_OP_lit21:
193*7fd79137SRobert Mustacchi         case DW_OP_lit22:
194*7fd79137SRobert Mustacchi         case DW_OP_lit23:
195*7fd79137SRobert Mustacchi         case DW_OP_lit24:
196*7fd79137SRobert Mustacchi         case DW_OP_lit25:
197*7fd79137SRobert Mustacchi         case DW_OP_lit26:
198*7fd79137SRobert Mustacchi         case DW_OP_lit27:
199*7fd79137SRobert Mustacchi         case DW_OP_lit28:
200*7fd79137SRobert Mustacchi         case DW_OP_lit29:
201*7fd79137SRobert Mustacchi         case DW_OP_lit30:
202*7fd79137SRobert Mustacchi         case DW_OP_lit31:
203*7fd79137SRobert Mustacchi             operand1 = atom - DW_OP_lit0;
204*7fd79137SRobert Mustacchi             break;
205*7fd79137SRobert Mustacchi 
206*7fd79137SRobert Mustacchi         case DW_OP_addr:
207*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
208*7fd79137SRobert Mustacchi                            loc_ptr, address_size);
209*7fd79137SRobert Mustacchi             loc_ptr += address_size;
210*7fd79137SRobert Mustacchi             offset += address_size;
211*7fd79137SRobert Mustacchi             break;
212*7fd79137SRobert Mustacchi 
213*7fd79137SRobert Mustacchi         case DW_OP_const1u:
214*7fd79137SRobert Mustacchi             operand1 = *(Dwarf_Small *) loc_ptr;
215*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 1;
216*7fd79137SRobert Mustacchi             offset = offset + 1;
217*7fd79137SRobert Mustacchi             break;
218*7fd79137SRobert Mustacchi 
219*7fd79137SRobert Mustacchi         case DW_OP_const1s:
220*7fd79137SRobert Mustacchi             operand1 = *(Dwarf_Sbyte *) loc_ptr;
221*7fd79137SRobert Mustacchi             SIGN_EXTEND(operand1,1);
222*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 1;
223*7fd79137SRobert Mustacchi             offset = offset + 1;
224*7fd79137SRobert Mustacchi             break;
225*7fd79137SRobert Mustacchi 
226*7fd79137SRobert Mustacchi         case DW_OP_const2u:
227*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
228*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 2;
229*7fd79137SRobert Mustacchi             offset = offset + 2;
230*7fd79137SRobert Mustacchi             break;
231*7fd79137SRobert Mustacchi 
232*7fd79137SRobert Mustacchi         case DW_OP_const2s:
233*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
234*7fd79137SRobert Mustacchi             SIGN_EXTEND(operand1,2);
235*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 2;
236*7fd79137SRobert Mustacchi             offset = offset + 2;
237*7fd79137SRobert Mustacchi             break;
238*7fd79137SRobert Mustacchi 
239*7fd79137SRobert Mustacchi         case DW_OP_const4u:
240*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
241*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 4;
242*7fd79137SRobert Mustacchi             offset = offset + 4;
243*7fd79137SRobert Mustacchi             break;
244*7fd79137SRobert Mustacchi 
245*7fd79137SRobert Mustacchi         case DW_OP_const4s:
246*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
247*7fd79137SRobert Mustacchi             SIGN_EXTEND(operand1,4);
248*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 4;
249*7fd79137SRobert Mustacchi             offset = offset + 4;
250*7fd79137SRobert Mustacchi             break;
251*7fd79137SRobert Mustacchi 
252*7fd79137SRobert Mustacchi         case DW_OP_const8u:
253*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
254*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 8;
255*7fd79137SRobert Mustacchi             offset = offset + 8;
256*7fd79137SRobert Mustacchi             break;
257*7fd79137SRobert Mustacchi 
258*7fd79137SRobert Mustacchi         case DW_OP_const8s:
259*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
260*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 8;
261*7fd79137SRobert Mustacchi             offset = offset + 8;
262*7fd79137SRobert Mustacchi             break;
263*7fd79137SRobert Mustacchi 
264*7fd79137SRobert Mustacchi         case DW_OP_constu:
265*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
266*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
267*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
268*7fd79137SRobert Mustacchi             break;
269*7fd79137SRobert Mustacchi 
270*7fd79137SRobert Mustacchi         case DW_OP_consts:
271*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
272*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
273*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
274*7fd79137SRobert Mustacchi             break;
275*7fd79137SRobert Mustacchi 
276*7fd79137SRobert Mustacchi         case DW_OP_fbreg:
277*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
278*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
279*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
280*7fd79137SRobert Mustacchi             break;
281*7fd79137SRobert Mustacchi 
282*7fd79137SRobert Mustacchi         case DW_OP_breg0:
283*7fd79137SRobert Mustacchi         case DW_OP_breg1:
284*7fd79137SRobert Mustacchi         case DW_OP_breg2:
285*7fd79137SRobert Mustacchi         case DW_OP_breg3:
286*7fd79137SRobert Mustacchi         case DW_OP_breg4:
287*7fd79137SRobert Mustacchi         case DW_OP_breg5:
288*7fd79137SRobert Mustacchi         case DW_OP_breg6:
289*7fd79137SRobert Mustacchi         case DW_OP_breg7:
290*7fd79137SRobert Mustacchi         case DW_OP_breg8:
291*7fd79137SRobert Mustacchi         case DW_OP_breg9:
292*7fd79137SRobert Mustacchi         case DW_OP_breg10:
293*7fd79137SRobert Mustacchi         case DW_OP_breg11:
294*7fd79137SRobert Mustacchi         case DW_OP_breg12:
295*7fd79137SRobert Mustacchi         case DW_OP_breg13:
296*7fd79137SRobert Mustacchi         case DW_OP_breg14:
297*7fd79137SRobert Mustacchi         case DW_OP_breg15:
298*7fd79137SRobert Mustacchi         case DW_OP_breg16:
299*7fd79137SRobert Mustacchi         case DW_OP_breg17:
300*7fd79137SRobert Mustacchi         case DW_OP_breg18:
301*7fd79137SRobert Mustacchi         case DW_OP_breg19:
302*7fd79137SRobert Mustacchi         case DW_OP_breg20:
303*7fd79137SRobert Mustacchi         case DW_OP_breg21:
304*7fd79137SRobert Mustacchi         case DW_OP_breg22:
305*7fd79137SRobert Mustacchi         case DW_OP_breg23:
306*7fd79137SRobert Mustacchi         case DW_OP_breg24:
307*7fd79137SRobert Mustacchi         case DW_OP_breg25:
308*7fd79137SRobert Mustacchi         case DW_OP_breg26:
309*7fd79137SRobert Mustacchi         case DW_OP_breg27:
310*7fd79137SRobert Mustacchi         case DW_OP_breg28:
311*7fd79137SRobert Mustacchi         case DW_OP_breg29:
312*7fd79137SRobert Mustacchi         case DW_OP_breg30:
313*7fd79137SRobert Mustacchi         case DW_OP_breg31:
314*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
315*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
316*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
317*7fd79137SRobert Mustacchi             break;
318*7fd79137SRobert Mustacchi 
319*7fd79137SRobert Mustacchi         case DW_OP_bregx:
320*7fd79137SRobert Mustacchi             /* uleb reg num followed by sleb offset */
321*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
322*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
323*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
324*7fd79137SRobert Mustacchi 
325*7fd79137SRobert Mustacchi             operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
326*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
327*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
328*7fd79137SRobert Mustacchi             break;
329*7fd79137SRobert Mustacchi 
330*7fd79137SRobert Mustacchi         case DW_OP_dup:
331*7fd79137SRobert Mustacchi         case DW_OP_drop:
332*7fd79137SRobert Mustacchi             break;
333*7fd79137SRobert Mustacchi 
334*7fd79137SRobert Mustacchi         case DW_OP_pick:
335*7fd79137SRobert Mustacchi             operand1 = *(Dwarf_Small *) loc_ptr;
336*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 1;
337*7fd79137SRobert Mustacchi             offset = offset + 1;
338*7fd79137SRobert Mustacchi             break;
339*7fd79137SRobert Mustacchi 
340*7fd79137SRobert Mustacchi         case DW_OP_over:
341*7fd79137SRobert Mustacchi         case DW_OP_swap:
342*7fd79137SRobert Mustacchi         case DW_OP_rot:
343*7fd79137SRobert Mustacchi         case DW_OP_deref:
344*7fd79137SRobert Mustacchi             break;
345*7fd79137SRobert Mustacchi 
346*7fd79137SRobert Mustacchi         case DW_OP_deref_size:
347*7fd79137SRobert Mustacchi             operand1 = *(Dwarf_Small *) loc_ptr;
348*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 1;
349*7fd79137SRobert Mustacchi             offset = offset + 1;
350*7fd79137SRobert Mustacchi             break;
351*7fd79137SRobert Mustacchi 
352*7fd79137SRobert Mustacchi         case DW_OP_xderef:
353*7fd79137SRobert Mustacchi             break;
354*7fd79137SRobert Mustacchi 
355*7fd79137SRobert Mustacchi         case DW_OP_xderef_size:
356*7fd79137SRobert Mustacchi             operand1 = *(Dwarf_Small *) loc_ptr;
357*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 1;
358*7fd79137SRobert Mustacchi             offset = offset + 1;
359*7fd79137SRobert Mustacchi             break;
360*7fd79137SRobert Mustacchi 
361*7fd79137SRobert Mustacchi         case DW_OP_abs:
362*7fd79137SRobert Mustacchi         case DW_OP_and:
363*7fd79137SRobert Mustacchi         case DW_OP_div:
364*7fd79137SRobert Mustacchi         case DW_OP_minus:
365*7fd79137SRobert Mustacchi         case DW_OP_mod:
366*7fd79137SRobert Mustacchi         case DW_OP_mul:
367*7fd79137SRobert Mustacchi         case DW_OP_neg:
368*7fd79137SRobert Mustacchi         case DW_OP_not:
369*7fd79137SRobert Mustacchi         case DW_OP_or:
370*7fd79137SRobert Mustacchi         case DW_OP_plus:
371*7fd79137SRobert Mustacchi             break;
372*7fd79137SRobert Mustacchi 
373*7fd79137SRobert Mustacchi         case DW_OP_plus_uconst:
374*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
375*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
376*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
377*7fd79137SRobert Mustacchi             break;
378*7fd79137SRobert Mustacchi 
379*7fd79137SRobert Mustacchi         case DW_OP_shl:
380*7fd79137SRobert Mustacchi         case DW_OP_shr:
381*7fd79137SRobert Mustacchi         case DW_OP_shra:
382*7fd79137SRobert Mustacchi         case DW_OP_xor:
383*7fd79137SRobert Mustacchi             break;
384*7fd79137SRobert Mustacchi 
385*7fd79137SRobert Mustacchi         case DW_OP_le:
386*7fd79137SRobert Mustacchi         case DW_OP_ge:
387*7fd79137SRobert Mustacchi         case DW_OP_eq:
388*7fd79137SRobert Mustacchi         case DW_OP_lt:
389*7fd79137SRobert Mustacchi         case DW_OP_gt:
390*7fd79137SRobert Mustacchi         case DW_OP_ne:
391*7fd79137SRobert Mustacchi             break;
392*7fd79137SRobert Mustacchi 
393*7fd79137SRobert Mustacchi         case DW_OP_skip:
394*7fd79137SRobert Mustacchi         case DW_OP_bra:
395*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
396*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 2;
397*7fd79137SRobert Mustacchi             offset = offset + 2;
398*7fd79137SRobert Mustacchi             break;
399*7fd79137SRobert Mustacchi 
400*7fd79137SRobert Mustacchi         case DW_OP_piece:
401*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
402*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
403*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
404*7fd79137SRobert Mustacchi             break;
405*7fd79137SRobert Mustacchi 
406*7fd79137SRobert Mustacchi         case DW_OP_nop:
407*7fd79137SRobert Mustacchi             break;
408*7fd79137SRobert Mustacchi         case DW_OP_push_object_address: /* DWARF3 */
409*7fd79137SRobert Mustacchi             break;
410*7fd79137SRobert Mustacchi         case DW_OP_call2:       /* DWARF3 */
411*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
412*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 2;
413*7fd79137SRobert Mustacchi             offset = offset + 2;
414*7fd79137SRobert Mustacchi             break;
415*7fd79137SRobert Mustacchi 
416*7fd79137SRobert Mustacchi         case DW_OP_call4:       /* DWARF3 */
417*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
418*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + 4;
419*7fd79137SRobert Mustacchi             offset = offset + 4;
420*7fd79137SRobert Mustacchi             break;
421*7fd79137SRobert Mustacchi         case DW_OP_call_ref:    /* DWARF3 */
422*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr,
423*7fd79137SRobert Mustacchi                            dbg->de_length_size);
424*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + dbg->de_length_size;
425*7fd79137SRobert Mustacchi             offset = offset + dbg->de_length_size;
426*7fd79137SRobert Mustacchi             break;
427*7fd79137SRobert Mustacchi 
428*7fd79137SRobert Mustacchi         case DW_OP_form_tls_address:    /* DWARF3f */
429*7fd79137SRobert Mustacchi             break;
430*7fd79137SRobert Mustacchi         case DW_OP_call_frame_cfa:      /* DWARF3f */
431*7fd79137SRobert Mustacchi             break;
432*7fd79137SRobert Mustacchi         case DW_OP_bit_piece:   /* DWARF3f */
433*7fd79137SRobert Mustacchi             /* uleb size in bits followed by uleb offset in bits */
434*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
435*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
436*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
437*7fd79137SRobert Mustacchi 
438*7fd79137SRobert Mustacchi             operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
439*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
440*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
441*7fd79137SRobert Mustacchi             break;
442*7fd79137SRobert Mustacchi         case DW_OP_implicit_value: /* DWARF4 */
443*7fd79137SRobert Mustacchi             /* uleb length of value bytes followed by that
444*7fd79137SRobert Mustacchi                number of bytes of the value. */
445*7fd79137SRobert Mustacchi             operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
446*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + leb128_length;
447*7fd79137SRobert Mustacchi             offset = offset + leb128_length;
448*7fd79137SRobert Mustacchi 
449*7fd79137SRobert Mustacchi             /* Second operand is block of 'operand1' bytes of stuff. */
450*7fd79137SRobert Mustacchi             /* This using the second operand as a pointer
451*7fd79137SRobert Mustacchi                is quite ugly. */
452*7fd79137SRobert Mustacchi             /* This gets an ugly compiler warning. Sorry. */
453*7fd79137SRobert Mustacchi             operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr;
454*7fd79137SRobert Mustacchi             offset = offset + operand1;
455*7fd79137SRobert Mustacchi             loc_ptr = loc_ptr + operand1;
456*7fd79137SRobert Mustacchi             break;
457*7fd79137SRobert Mustacchi         case DW_OP_stack_value:  /* DWARF4 */
458*7fd79137SRobert Mustacchi             break;
459*7fd79137SRobert Mustacchi 
460*7fd79137SRobert Mustacchi 
461*7fd79137SRobert Mustacchi         default:
462*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
463*7fd79137SRobert Mustacchi             return (NULL);
464*7fd79137SRobert Mustacchi         }
465*7fd79137SRobert Mustacchi 
466*7fd79137SRobert Mustacchi 
467*7fd79137SRobert Mustacchi         curr_loc->lc_number = operand1;
468*7fd79137SRobert Mustacchi         curr_loc->lc_number2 = operand2;
469*7fd79137SRobert Mustacchi 
470*7fd79137SRobert Mustacchi         if (head_loc == NULL)
471*7fd79137SRobert Mustacchi             head_loc = prev_loc = curr_loc;
472*7fd79137SRobert Mustacchi         else {
473*7fd79137SRobert Mustacchi             prev_loc->lc_next = curr_loc;
474*7fd79137SRobert Mustacchi             prev_loc = curr_loc;
475*7fd79137SRobert Mustacchi         }
476*7fd79137SRobert Mustacchi     }
477*7fd79137SRobert Mustacchi 
478*7fd79137SRobert Mustacchi     block_loc =
479*7fd79137SRobert Mustacchi         (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
480*7fd79137SRobert Mustacchi     if (block_loc == NULL) {
481*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
482*7fd79137SRobert Mustacchi         return (NULL);
483*7fd79137SRobert Mustacchi     }
484*7fd79137SRobert Mustacchi 
485*7fd79137SRobert Mustacchi     curr_loc = head_loc;
486*7fd79137SRobert Mustacchi     for (i = 0; i < op_count; i++) {
487*7fd79137SRobert Mustacchi         (block_loc + i)->lr_atom = curr_loc->lc_atom;
488*7fd79137SRobert Mustacchi         (block_loc + i)->lr_number = curr_loc->lc_number;
489*7fd79137SRobert Mustacchi         (block_loc + i)->lr_number2 = curr_loc->lc_number2;
490*7fd79137SRobert Mustacchi         (block_loc + i)->lr_offset = curr_loc->lc_offset;
491*7fd79137SRobert Mustacchi 
492*7fd79137SRobert Mustacchi         prev_loc = curr_loc;
493*7fd79137SRobert Mustacchi         curr_loc = curr_loc->lc_next;
494*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
495*7fd79137SRobert Mustacchi     }
496*7fd79137SRobert Mustacchi 
497*7fd79137SRobert Mustacchi     locdesc =
498*7fd79137SRobert Mustacchi         (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
499*7fd79137SRobert Mustacchi     if (locdesc == NULL) {
500*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
501*7fd79137SRobert Mustacchi         return (NULL);
502*7fd79137SRobert Mustacchi     }
503*7fd79137SRobert Mustacchi 
504*7fd79137SRobert Mustacchi     locdesc->ld_cents = op_count;
505*7fd79137SRobert Mustacchi     locdesc->ld_s = block_loc;
506*7fd79137SRobert Mustacchi     locdesc->ld_from_loclist = loc_block->bl_from_loclist;
507*7fd79137SRobert Mustacchi     locdesc->ld_section_offset = loc_block->bl_section_offset;
508*7fd79137SRobert Mustacchi     locdesc->ld_lopc = lowpc;
509*7fd79137SRobert Mustacchi     locdesc->ld_hipc = highpc;
510*7fd79137SRobert Mustacchi 
511*7fd79137SRobert Mustacchi     return (locdesc);
512*7fd79137SRobert Mustacchi }
513*7fd79137SRobert Mustacchi 
514*7fd79137SRobert Mustacchi /* Using a loclist offset to get the in-memory
515*7fd79137SRobert Mustacchi    address of .debug_loc data to read, returns the loclist
516*7fd79137SRobert Mustacchi    'header' info in return_block.
517*7fd79137SRobert Mustacchi */
518*7fd79137SRobert Mustacchi 
519*7fd79137SRobert Mustacchi #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
520*7fd79137SRobert Mustacchi 
521*7fd79137SRobert Mustacchi static int
522*7fd79137SRobert Mustacchi _dwarf_read_loc_section(Dwarf_Debug dbg,
523*7fd79137SRobert Mustacchi                         Dwarf_Block * return_block,
524*7fd79137SRobert Mustacchi                         Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
525*7fd79137SRobert Mustacchi                         Dwarf_Off sec_offset,
526*7fd79137SRobert Mustacchi                         Dwarf_Half address_size,
527*7fd79137SRobert Mustacchi                         Dwarf_Error * error)
528*7fd79137SRobert Mustacchi {
529*7fd79137SRobert Mustacchi     Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
530*7fd79137SRobert Mustacchi 
531*7fd79137SRobert Mustacchi     Dwarf_Addr start_addr = 0;
532*7fd79137SRobert Mustacchi     Dwarf_Addr end_addr = 0;
533*7fd79137SRobert Mustacchi     Dwarf_Half exprblock_size = 0;
534*7fd79137SRobert Mustacchi     Dwarf_Unsigned exprblock_off =
535*7fd79137SRobert Mustacchi         2 * address_size + sizeof(Dwarf_Half);
536*7fd79137SRobert Mustacchi 
537*7fd79137SRobert Mustacchi     if (sec_offset >= dbg->de_debug_loc.dss_size) {
538*7fd79137SRobert Mustacchi         /* We're at the end. No more present. */
539*7fd79137SRobert Mustacchi         return DW_DLV_NO_ENTRY;
540*7fd79137SRobert Mustacchi     }
541*7fd79137SRobert Mustacchi 
542*7fd79137SRobert Mustacchi     /* If it goes past end, error */
543*7fd79137SRobert Mustacchi     if (exprblock_off > dbg->de_debug_loc.dss_size) {
544*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
545*7fd79137SRobert Mustacchi         return DW_DLV_ERROR;
546*7fd79137SRobert Mustacchi     }
547*7fd79137SRobert Mustacchi 
548*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
549*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
550*7fd79137SRobert Mustacchi                    beg + address_size, address_size);
551*7fd79137SRobert Mustacchi     if (start_addr == 0 && end_addr == 0) {
552*7fd79137SRobert Mustacchi         /* If start_addr and end_addr are 0, it's the end and no
553*7fd79137SRobert Mustacchi            exprblock_size field follows. */
554*7fd79137SRobert Mustacchi         exprblock_size = 0;
555*7fd79137SRobert Mustacchi         exprblock_off -= sizeof(Dwarf_Half);
556*7fd79137SRobert Mustacchi     } else if (start_addr == MAX_ADDR) {
557*7fd79137SRobert Mustacchi         /* end address is a base address, no exprblock_size field here
558*7fd79137SRobert Mustacchi            either */
559*7fd79137SRobert Mustacchi         exprblock_size = 0;
560*7fd79137SRobert Mustacchi         exprblock_off -= sizeof(Dwarf_Half);
561*7fd79137SRobert Mustacchi     } else {
562*7fd79137SRobert Mustacchi 
563*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
564*7fd79137SRobert Mustacchi                        beg + 2 * address_size, sizeof(Dwarf_Half));
565*7fd79137SRobert Mustacchi         /* exprblock_size can be zero, means no expression */
566*7fd79137SRobert Mustacchi         if ((exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) {
567*7fd79137SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
568*7fd79137SRobert Mustacchi             return DW_DLV_ERROR;
569*7fd79137SRobert Mustacchi         }
570*7fd79137SRobert Mustacchi     }
571*7fd79137SRobert Mustacchi #undef MAX_ADDR
572*7fd79137SRobert Mustacchi     *lowpc = start_addr;
573*7fd79137SRobert Mustacchi     *hipc = end_addr;
574*7fd79137SRobert Mustacchi 
575*7fd79137SRobert Mustacchi     return_block->bl_len = exprblock_size;
576*7fd79137SRobert Mustacchi     return_block->bl_from_loclist = 1;
577*7fd79137SRobert Mustacchi     return_block->bl_data = beg + exprblock_off;
578*7fd79137SRobert Mustacchi     return_block->bl_section_offset =
579*7fd79137SRobert Mustacchi         ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc.dss_data;
580*7fd79137SRobert Mustacchi 
581*7fd79137SRobert Mustacchi     return DW_DLV_OK;
582*7fd79137SRobert Mustacchi 
583*7fd79137SRobert Mustacchi }
584*7fd79137SRobert Mustacchi static int
585*7fd79137SRobert Mustacchi _dwarf_get_loclist_count(Dwarf_Debug dbg,
586*7fd79137SRobert Mustacchi                          Dwarf_Off loclist_offset,
587*7fd79137SRobert Mustacchi                          Dwarf_Half address_size,
588*7fd79137SRobert Mustacchi                          int *loclist_count, Dwarf_Error * error)
589*7fd79137SRobert Mustacchi {
590*7fd79137SRobert Mustacchi     int count = 0;
591*7fd79137SRobert Mustacchi     Dwarf_Off offset = loclist_offset;
592*7fd79137SRobert Mustacchi 
593*7fd79137SRobert Mustacchi 
594*7fd79137SRobert Mustacchi     for (;;) {
595*7fd79137SRobert Mustacchi         Dwarf_Block b;
596*7fd79137SRobert Mustacchi         Dwarf_Addr lowpc;
597*7fd79137SRobert Mustacchi         Dwarf_Addr highpc;
598*7fd79137SRobert Mustacchi         int res = _dwarf_read_loc_section(dbg, &b,
599*7fd79137SRobert Mustacchi                   &lowpc, &highpc,
600*7fd79137SRobert Mustacchi                   offset, address_size,error);
601*7fd79137SRobert Mustacchi 
602*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
603*7fd79137SRobert Mustacchi             return res;
604*7fd79137SRobert Mustacchi         }
605*7fd79137SRobert Mustacchi         offset = b.bl_len + b.bl_section_offset;
606*7fd79137SRobert Mustacchi         if (lowpc == 0 && highpc == 0) {
607*7fd79137SRobert Mustacchi             break;
608*7fd79137SRobert Mustacchi         }
609*7fd79137SRobert Mustacchi         count++;
610*7fd79137SRobert Mustacchi     }
611*7fd79137SRobert Mustacchi     *loclist_count = count;
612*7fd79137SRobert Mustacchi     return DW_DLV_OK;
613*7fd79137SRobert Mustacchi }
614*7fd79137SRobert Mustacchi 
615*7fd79137SRobert Mustacchi /* Helper routine to avoid code duplication.
616*7fd79137SRobert Mustacchi */
617*7fd79137SRobert Mustacchi static int
618*7fd79137SRobert Mustacchi _dwarf_setup_loc(Dwarf_Attribute attr,
619*7fd79137SRobert Mustacchi                  Dwarf_Debug * dbg_ret,
620*7fd79137SRobert Mustacchi                  Dwarf_CU_Context *cucontext_ret,
621*7fd79137SRobert Mustacchi                  Dwarf_Half * form_ret, Dwarf_Error * error)
622*7fd79137SRobert Mustacchi {
623*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
624*7fd79137SRobert Mustacchi     Dwarf_Half form = 0;
625*7fd79137SRobert Mustacchi     int blkres = DW_DLV_ERROR;
626*7fd79137SRobert Mustacchi 
627*7fd79137SRobert Mustacchi     if (attr == NULL) {
628*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
629*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
630*7fd79137SRobert Mustacchi     }
631*7fd79137SRobert Mustacchi     if (attr->ar_cu_context == NULL) {
632*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
633*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
634*7fd79137SRobert Mustacchi     }
635*7fd79137SRobert Mustacchi     *cucontext_ret = attr->ar_cu_context;
636*7fd79137SRobert Mustacchi 
637*7fd79137SRobert Mustacchi     dbg = attr->ar_cu_context->cc_dbg;
638*7fd79137SRobert Mustacchi     if (dbg == NULL) {
639*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
640*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
641*7fd79137SRobert Mustacchi     }
642*7fd79137SRobert Mustacchi     *dbg_ret = dbg;
643*7fd79137SRobert Mustacchi     blkres = dwarf_whatform(attr, &form, error);
644*7fd79137SRobert Mustacchi     if (blkres != DW_DLV_OK) {
645*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
646*7fd79137SRobert Mustacchi         return blkres;
647*7fd79137SRobert Mustacchi     }
648*7fd79137SRobert Mustacchi     *form_ret = form;
649*7fd79137SRobert Mustacchi     return DW_DLV_OK;
650*7fd79137SRobert Mustacchi }
651*7fd79137SRobert Mustacchi 
652*7fd79137SRobert Mustacchi /* Helper routine  to avoid code duplication.
653*7fd79137SRobert Mustacchi */
654*7fd79137SRobert Mustacchi static int
655*7fd79137SRobert Mustacchi _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
656*7fd79137SRobert Mustacchi                                 Dwarf_Attribute attr,
657*7fd79137SRobert Mustacchi                                 Dwarf_Unsigned * loclist_offset,
658*7fd79137SRobert Mustacchi                                 Dwarf_Error * error)
659*7fd79137SRobert Mustacchi {
660*7fd79137SRobert Mustacchi     int blkres = dwarf_formudata(attr, loclist_offset, error);
661*7fd79137SRobert Mustacchi     if (blkres != DW_DLV_OK) {
662*7fd79137SRobert Mustacchi         return (blkres);
663*7fd79137SRobert Mustacchi     }
664*7fd79137SRobert Mustacchi 
665*7fd79137SRobert Mustacchi     if (!dbg->de_debug_loc.dss_data) {
666*7fd79137SRobert Mustacchi         int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
667*7fd79137SRobert Mustacchi         if (secload != DW_DLV_OK) {
668*7fd79137SRobert Mustacchi             return secload;
669*7fd79137SRobert Mustacchi         }
670*7fd79137SRobert Mustacchi     }
671*7fd79137SRobert Mustacchi     return DW_DLV_OK;
672*7fd79137SRobert Mustacchi }
673*7fd79137SRobert Mustacchi 
674*7fd79137SRobert Mustacchi /* When llbuf (see dwarf_loclist_n) is partially set up
675*7fd79137SRobert Mustacchi    and an error is encountered, tear it down as it
676*7fd79137SRobert Mustacchi    won't be used.
677*7fd79137SRobert Mustacchi */
678*7fd79137SRobert Mustacchi static void
679*7fd79137SRobert Mustacchi _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
680*7fd79137SRobert Mustacchi {
681*7fd79137SRobert Mustacchi     int i;
682*7fd79137SRobert Mustacchi     for (i = 0; i < count; ++i) {
683*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
684*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
685*7fd79137SRobert Mustacchi     }
686*7fd79137SRobert Mustacchi     dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
687*7fd79137SRobert Mustacchi }
688*7fd79137SRobert Mustacchi 
689*7fd79137SRobert Mustacchi /*
690*7fd79137SRobert Mustacchi         Handles simple location entries and loclists.
691*7fd79137SRobert Mustacchi         Returns all the Locdesc's thru llbuf.
692*7fd79137SRobert Mustacchi 
693*7fd79137SRobert Mustacchi */
694*7fd79137SRobert Mustacchi int
695*7fd79137SRobert Mustacchi dwarf_loclist_n(Dwarf_Attribute attr,
696*7fd79137SRobert Mustacchi                 Dwarf_Locdesc *** llbuf_out,
697*7fd79137SRobert Mustacchi                 Dwarf_Signed * listlen_out, Dwarf_Error * error)
698*7fd79137SRobert Mustacchi {
699*7fd79137SRobert Mustacchi     Dwarf_Debug dbg;
700*7fd79137SRobert Mustacchi 
701*7fd79137SRobert Mustacchi     /*
702*7fd79137SRobert Mustacchi        Dwarf_Attribute that describes the DW_AT_location in die, if
703*7fd79137SRobert Mustacchi        present. */
704*7fd79137SRobert Mustacchi     Dwarf_Attribute loc_attr = attr;
705*7fd79137SRobert Mustacchi 
706*7fd79137SRobert Mustacchi     /* Dwarf_Block that describes a single location expression. */
707*7fd79137SRobert Mustacchi     Dwarf_Block loc_block;
708*7fd79137SRobert Mustacchi 
709*7fd79137SRobert Mustacchi     /* A pointer to the current Dwarf_Locdesc read. */
710*7fd79137SRobert Mustacchi     Dwarf_Locdesc *locdesc = 0;
711*7fd79137SRobert Mustacchi 
712*7fd79137SRobert Mustacchi     Dwarf_Half form = 0;
713*7fd79137SRobert Mustacchi     Dwarf_Addr lowpc = 0;
714*7fd79137SRobert Mustacchi     Dwarf_Addr highpc = 0;
715*7fd79137SRobert Mustacchi     Dwarf_Signed listlen = 0;
716*7fd79137SRobert Mustacchi     Dwarf_Locdesc **llbuf = 0;
717*7fd79137SRobert Mustacchi     Dwarf_CU_Context cucontext = 0;
718*7fd79137SRobert Mustacchi     unsigned address_size = 0;
719*7fd79137SRobert Mustacchi 
720*7fd79137SRobert Mustacchi     int blkres = DW_DLV_ERROR;
721*7fd79137SRobert Mustacchi     int setup_res = DW_DLV_ERROR;
722*7fd79137SRobert Mustacchi 
723*7fd79137SRobert Mustacchi     /* ***** BEGIN CODE ***** */
724*7fd79137SRobert Mustacchi     setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
725*7fd79137SRobert Mustacchi     if (setup_res != DW_DLV_OK) {
726*7fd79137SRobert Mustacchi         return setup_res;
727*7fd79137SRobert Mustacchi     }
728*7fd79137SRobert Mustacchi     address_size = cucontext->cc_address_size;
729*7fd79137SRobert Mustacchi     /* If this is a form_block then it's a location expression. If it's
730*7fd79137SRobert Mustacchi        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
731*7fd79137SRobert Mustacchi     if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
732*7fd79137SRobert Mustacchi           cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
733*7fd79137SRobert Mustacchi           (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
734*7fd79137SRobert Mustacchi          (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
735*7fd79137SRobert Mustacchi             form == DW_FORM_sec_offset))
736*7fd79137SRobert Mustacchi         {
737*7fd79137SRobert Mustacchi 
738*7fd79137SRobert Mustacchi 
739*7fd79137SRobert Mustacchi         /* A reference to .debug_loc, with an offset in .debug_loc of a
740*7fd79137SRobert Mustacchi            loclist */
741*7fd79137SRobert Mustacchi         Dwarf_Unsigned loclist_offset = 0;
742*7fd79137SRobert Mustacchi         int off_res  = DW_DLV_ERROR;
743*7fd79137SRobert Mustacchi         int count_res = DW_DLV_ERROR;
744*7fd79137SRobert Mustacchi         int loclist_count;
745*7fd79137SRobert Mustacchi         int lli;
746*7fd79137SRobert Mustacchi 
747*7fd79137SRobert Mustacchi         off_res = _dwarf_get_loclist_header_start(dbg,
748*7fd79137SRobert Mustacchi                                                   attr, &loclist_offset,
749*7fd79137SRobert Mustacchi                                                   error);
750*7fd79137SRobert Mustacchi         if (off_res != DW_DLV_OK) {
751*7fd79137SRobert Mustacchi             return off_res;
752*7fd79137SRobert Mustacchi         }
753*7fd79137SRobert Mustacchi         count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
754*7fd79137SRobert Mustacchi                                              address_size,
755*7fd79137SRobert Mustacchi                                              &loclist_count, error);
756*7fd79137SRobert Mustacchi         listlen = loclist_count;
757*7fd79137SRobert Mustacchi         if (count_res != DW_DLV_OK) {
758*7fd79137SRobert Mustacchi             return count_res;
759*7fd79137SRobert Mustacchi         }
760*7fd79137SRobert Mustacchi         if (loclist_count == 0) {
761*7fd79137SRobert Mustacchi             return DW_DLV_NO_ENTRY;
762*7fd79137SRobert Mustacchi         }
763*7fd79137SRobert Mustacchi 
764*7fd79137SRobert Mustacchi         llbuf = (Dwarf_Locdesc **)
765*7fd79137SRobert Mustacchi             _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
766*7fd79137SRobert Mustacchi         if (!llbuf) {
767*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
768*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
769*7fd79137SRobert Mustacchi         }
770*7fd79137SRobert Mustacchi 
771*7fd79137SRobert Mustacchi         for (lli = 0; lli < loclist_count; ++lli) {
772*7fd79137SRobert Mustacchi             blkres = _dwarf_read_loc_section(dbg, &loc_block,
773*7fd79137SRobert Mustacchi                 &lowpc,
774*7fd79137SRobert Mustacchi                 &highpc,
775*7fd79137SRobert Mustacchi                 loclist_offset,
776*7fd79137SRobert Mustacchi                 address_size,
777*7fd79137SRobert Mustacchi                 error);
778*7fd79137SRobert Mustacchi             if (blkres != DW_DLV_OK) {
779*7fd79137SRobert Mustacchi                 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
780*7fd79137SRobert Mustacchi                 return (blkres);
781*7fd79137SRobert Mustacchi             }
782*7fd79137SRobert Mustacchi             locdesc = _dwarf_get_locdesc(dbg, &loc_block,
783*7fd79137SRobert Mustacchi                 address_size,
784*7fd79137SRobert Mustacchi                 lowpc, highpc, error);
785*7fd79137SRobert Mustacchi             if (locdesc == NULL) {
786*7fd79137SRobert Mustacchi                 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
787*7fd79137SRobert Mustacchi                 /* low level error already set: let it be passed back */
788*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
789*7fd79137SRobert Mustacchi             }
790*7fd79137SRobert Mustacchi             llbuf[lli] = locdesc;
791*7fd79137SRobert Mustacchi 
792*7fd79137SRobert Mustacchi             /* Now get to next loclist entry offset. */
793*7fd79137SRobert Mustacchi             loclist_offset = loc_block.bl_section_offset +
794*7fd79137SRobert Mustacchi                 loc_block.bl_len;
795*7fd79137SRobert Mustacchi         }
796*7fd79137SRobert Mustacchi 
797*7fd79137SRobert Mustacchi 
798*7fd79137SRobert Mustacchi     } else {
799*7fd79137SRobert Mustacchi         Dwarf_Block *tblock = 0;
800*7fd79137SRobert Mustacchi 
801*7fd79137SRobert Mustacchi         blkres = dwarf_formblock(loc_attr, &tblock, error);
802*7fd79137SRobert Mustacchi         if (blkres != DW_DLV_OK) {
803*7fd79137SRobert Mustacchi             return (blkres);
804*7fd79137SRobert Mustacchi         }
805*7fd79137SRobert Mustacchi         loc_block = *tblock;
806*7fd79137SRobert Mustacchi         /* We copied tblock contents to the stack var, so can dealloc
807*7fd79137SRobert Mustacchi            tblock now.  Avoids leaks. */
808*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
809*7fd79137SRobert Mustacchi         listlen = 1; /* One by definition of a location entry. */
810*7fd79137SRobert Mustacchi         lowpc = 0;   /* HACK */
811*7fd79137SRobert Mustacchi         highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
812*7fd79137SRobert Mustacchi 
813*7fd79137SRobert Mustacchi         /* An empty location description (block length 0) means the
814*7fd79137SRobert Mustacchi            code generator emitted no variable, the variable was not
815*7fd79137SRobert Mustacchi            generated, it was unused or perhaps never tested after being
816*7fd79137SRobert Mustacchi            set. Dwarf2, section 2.4.1 In other words, it is not an
817*7fd79137SRobert Mustacchi            error, and we don't test for block length 0 specially here. */
818*7fd79137SRobert Mustacchi         locdesc = _dwarf_get_locdesc(dbg, &loc_block,
819*7fd79137SRobert Mustacchi             address_size,
820*7fd79137SRobert Mustacchi             lowpc, highpc, error);
821*7fd79137SRobert Mustacchi         if (locdesc == NULL) {
822*7fd79137SRobert Mustacchi             /* low level error already set: let it be passed back */
823*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
824*7fd79137SRobert Mustacchi         }
825*7fd79137SRobert Mustacchi         llbuf = (Dwarf_Locdesc **)
826*7fd79137SRobert Mustacchi             _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
827*7fd79137SRobert Mustacchi         if (!llbuf) {
828*7fd79137SRobert Mustacchi             /* Free the locdesc we allocated but won't use. */
829*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
830*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
831*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
832*7fd79137SRobert Mustacchi         }
833*7fd79137SRobert Mustacchi         llbuf[0] = locdesc;
834*7fd79137SRobert Mustacchi     }
835*7fd79137SRobert Mustacchi 
836*7fd79137SRobert Mustacchi     *llbuf_out = llbuf;
837*7fd79137SRobert Mustacchi     *listlen_out = listlen;
838*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
839*7fd79137SRobert Mustacchi }
840*7fd79137SRobert Mustacchi 
841*7fd79137SRobert Mustacchi 
842*7fd79137SRobert Mustacchi /*
843*7fd79137SRobert Mustacchi         Handles only a location expression.
844*7fd79137SRobert Mustacchi         If called on a loclist, just returns one of those.
845*7fd79137SRobert Mustacchi         Cannot not handle a real loclist.
846*7fd79137SRobert Mustacchi         It returns the location expression as a loclist with
847*7fd79137SRobert Mustacchi         a single entry.
848*7fd79137SRobert Mustacchi         See dwarf_loclist_n() which handles any number
849*7fd79137SRobert Mustacchi         of location list entries.
850*7fd79137SRobert Mustacchi 
851*7fd79137SRobert Mustacchi         This is the original definition, and it simply
852*7fd79137SRobert Mustacchi         does not work for loclists. Kept for compatibility.
853*7fd79137SRobert Mustacchi */
854*7fd79137SRobert Mustacchi int
855*7fd79137SRobert Mustacchi dwarf_loclist(Dwarf_Attribute attr,
856*7fd79137SRobert Mustacchi     Dwarf_Locdesc ** llbuf,
857*7fd79137SRobert Mustacchi     Dwarf_Signed * listlen, Dwarf_Error * error)
858*7fd79137SRobert Mustacchi {
859*7fd79137SRobert Mustacchi     Dwarf_Debug dbg;
860*7fd79137SRobert Mustacchi 
861*7fd79137SRobert Mustacchi     /* Dwarf_Attribute that describes the DW_AT_location in die, if
862*7fd79137SRobert Mustacchi        present. */
863*7fd79137SRobert Mustacchi     Dwarf_Attribute loc_attr = attr;
864*7fd79137SRobert Mustacchi 
865*7fd79137SRobert Mustacchi     /* Dwarf_Block that describes a single location expression. */
866*7fd79137SRobert Mustacchi     Dwarf_Block loc_block;
867*7fd79137SRobert Mustacchi 
868*7fd79137SRobert Mustacchi     /* A pointer to the current Dwarf_Locdesc read. */
869*7fd79137SRobert Mustacchi     Dwarf_Locdesc *locdesc = 0;
870*7fd79137SRobert Mustacchi 
871*7fd79137SRobert Mustacchi     Dwarf_Half form = 0;
872*7fd79137SRobert Mustacchi     Dwarf_Addr lowpc = 0;
873*7fd79137SRobert Mustacchi     Dwarf_Addr highpc = 0;
874*7fd79137SRobert Mustacchi     Dwarf_CU_Context cucontext = 0;
875*7fd79137SRobert Mustacchi     unsigned address_size = 0;
876*7fd79137SRobert Mustacchi 
877*7fd79137SRobert Mustacchi     int blkres = DW_DLV_ERROR;
878*7fd79137SRobert Mustacchi     int setup_res = DW_DLV_ERROR;
879*7fd79137SRobert Mustacchi 
880*7fd79137SRobert Mustacchi     /* ***** BEGIN CODE ***** */
881*7fd79137SRobert Mustacchi     setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error);
882*7fd79137SRobert Mustacchi     if (setup_res != DW_DLV_OK) {
883*7fd79137SRobert Mustacchi         return setup_res;
884*7fd79137SRobert Mustacchi     }
885*7fd79137SRobert Mustacchi     address_size = cucontext->cc_address_size;
886*7fd79137SRobert Mustacchi     /* If this is a form_block then it's a location expression. If it's
887*7fd79137SRobert Mustacchi        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
888*7fd79137SRobert Mustacchi     if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
889*7fd79137SRobert Mustacchi           cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
890*7fd79137SRobert Mustacchi           (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
891*7fd79137SRobert Mustacchi          (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
892*7fd79137SRobert Mustacchi             form == DW_FORM_sec_offset))
893*7fd79137SRobert Mustacchi         {
894*7fd79137SRobert Mustacchi 
895*7fd79137SRobert Mustacchi         /* A reference to .debug_loc, with an offset in .debug_loc of a
896*7fd79137SRobert Mustacchi            loclist */
897*7fd79137SRobert Mustacchi         Dwarf_Unsigned loclist_offset = 0;
898*7fd79137SRobert Mustacchi         int off_res = DW_DLV_ERROR;
899*7fd79137SRobert Mustacchi 
900*7fd79137SRobert Mustacchi         off_res = _dwarf_get_loclist_header_start(dbg,
901*7fd79137SRobert Mustacchi             attr, &loclist_offset,
902*7fd79137SRobert Mustacchi             error);
903*7fd79137SRobert Mustacchi         if (off_res != DW_DLV_OK) {
904*7fd79137SRobert Mustacchi             return off_res;
905*7fd79137SRobert Mustacchi         }
906*7fd79137SRobert Mustacchi 
907*7fd79137SRobert Mustacchi         /* With dwarf_loclist, just read a single entry */
908*7fd79137SRobert Mustacchi         blkres = _dwarf_read_loc_section(dbg, &loc_block,
909*7fd79137SRobert Mustacchi             &lowpc,
910*7fd79137SRobert Mustacchi             &highpc,
911*7fd79137SRobert Mustacchi             loclist_offset,
912*7fd79137SRobert Mustacchi             address_size,
913*7fd79137SRobert Mustacchi             error);
914*7fd79137SRobert Mustacchi         if (blkres != DW_DLV_OK) {
915*7fd79137SRobert Mustacchi             return (blkres);
916*7fd79137SRobert Mustacchi         }
917*7fd79137SRobert Mustacchi     } else {
918*7fd79137SRobert Mustacchi         Dwarf_Block *tblock = 0;
919*7fd79137SRobert Mustacchi 
920*7fd79137SRobert Mustacchi         blkres = dwarf_formblock(loc_attr, &tblock, error);
921*7fd79137SRobert Mustacchi         if (blkres != DW_DLV_OK) {
922*7fd79137SRobert Mustacchi             return (blkres);
923*7fd79137SRobert Mustacchi         }
924*7fd79137SRobert Mustacchi         loc_block = *tblock;
925*7fd79137SRobert Mustacchi         /* We copied tblock contents to the stack var, so can dealloc
926*7fd79137SRobert Mustacchi            tblock now.  Avoids leaks. */
927*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
928*7fd79137SRobert Mustacchi         lowpc = 0;              /* HACK */
929*7fd79137SRobert Mustacchi         highpc = (Dwarf_Unsigned) (-1LL);       /* HACK */
930*7fd79137SRobert Mustacchi     }
931*7fd79137SRobert Mustacchi 
932*7fd79137SRobert Mustacchi     /* An empty location description (block length 0) means the code
933*7fd79137SRobert Mustacchi        generator emitted no variable, the variable was not generated,
934*7fd79137SRobert Mustacchi        it was unused or perhaps never tested after being set. Dwarf2,
935*7fd79137SRobert Mustacchi        section 2.4.1 In other words, it is not an error, and we don't
936*7fd79137SRobert Mustacchi        test for block length 0 specially here.
937*7fd79137SRobert Mustacchi        See *dwarf_loclist_n() which handles the general case, this case
938*7fd79137SRobert Mustacchi        handles only a single location expression.  */
939*7fd79137SRobert Mustacchi     locdesc = _dwarf_get_locdesc(dbg, &loc_block,
940*7fd79137SRobert Mustacchi         address_size,
941*7fd79137SRobert Mustacchi         lowpc, highpc, error);
942*7fd79137SRobert Mustacchi     if (locdesc == NULL) {
943*7fd79137SRobert Mustacchi         /* low level error already set: let it be passed back */
944*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
945*7fd79137SRobert Mustacchi     }
946*7fd79137SRobert Mustacchi 
947*7fd79137SRobert Mustacchi     *llbuf = locdesc;
948*7fd79137SRobert Mustacchi     *listlen = 1;
949*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
950*7fd79137SRobert Mustacchi }
951*7fd79137SRobert Mustacchi 
952*7fd79137SRobert Mustacchi 
953*7fd79137SRobert Mustacchi 
954*7fd79137SRobert Mustacchi /*
955*7fd79137SRobert Mustacchi         Handles only a location expression.
956*7fd79137SRobert Mustacchi         It returns the location expression as a loclist with
957*7fd79137SRobert Mustacchi         a single entry.
958*7fd79137SRobert Mustacchi 
959*7fd79137SRobert Mustacchi         Usable to access dwarf expressions from any source, but
960*7fd79137SRobert Mustacchi         specifically from
961*7fd79137SRobert Mustacchi             DW_CFA_def_cfa_expression
962*7fd79137SRobert Mustacchi             DW_CFA_expression
963*7fd79137SRobert Mustacchi             DW_CFA_val_expression
964*7fd79137SRobert Mustacchi 
965*7fd79137SRobert Mustacchi         expression_in must point to a valid dwarf expression
966*7fd79137SRobert Mustacchi         set of bytes of length expression_length. Not
967*7fd79137SRobert Mustacchi         a DW_FORM_block*, just the expression bytes.
968*7fd79137SRobert Mustacchi 
969*7fd79137SRobert Mustacchi         If the address_size != de_pointer_size this will not work
970*7fd79137SRobert Mustacchi         right. FIXME.
971*7fd79137SRobert Mustacchi */
972*7fd79137SRobert Mustacchi int
973*7fd79137SRobert Mustacchi dwarf_loclist_from_expr(Dwarf_Debug dbg,
974*7fd79137SRobert Mustacchi     Dwarf_Ptr expression_in,
975*7fd79137SRobert Mustacchi     Dwarf_Unsigned expression_length,
976*7fd79137SRobert Mustacchi     Dwarf_Locdesc ** llbuf,
977*7fd79137SRobert Mustacchi     Dwarf_Signed * listlen, Dwarf_Error * error)
978*7fd79137SRobert Mustacchi {
979*7fd79137SRobert Mustacchi     int res = 0;
980*7fd79137SRobert Mustacchi     Dwarf_Half addr_size =  dbg->de_pointer_size;
981*7fd79137SRobert Mustacchi     res = dwarf_loclist_from_expr_a(dbg,expression_in,
982*7fd79137SRobert Mustacchi         expression_length, addr_size,llbuf,listlen,error);
983*7fd79137SRobert Mustacchi     return res;
984*7fd79137SRobert Mustacchi }
985*7fd79137SRobert Mustacchi /* New April 27 2009. Adding addr_size argument for the rare
986*7fd79137SRobert Mustacchi  * cases where an object has CUs with a different address_size. */
987*7fd79137SRobert Mustacchi int
988*7fd79137SRobert Mustacchi dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
989*7fd79137SRobert Mustacchi     Dwarf_Ptr expression_in,
990*7fd79137SRobert Mustacchi     Dwarf_Unsigned expression_length,
991*7fd79137SRobert Mustacchi     Dwarf_Half addr_size,
992*7fd79137SRobert Mustacchi     Dwarf_Locdesc ** llbuf,
993*7fd79137SRobert Mustacchi     Dwarf_Signed * listlen, Dwarf_Error * error)
994*7fd79137SRobert Mustacchi {
995*7fd79137SRobert Mustacchi     /* Dwarf_Block that describes a single location expression. */
996*7fd79137SRobert Mustacchi     Dwarf_Block loc_block;
997*7fd79137SRobert Mustacchi 
998*7fd79137SRobert Mustacchi     /* A pointer to the current Dwarf_Locdesc read. */
999*7fd79137SRobert Mustacchi     Dwarf_Locdesc *locdesc = 0;
1000*7fd79137SRobert Mustacchi     Dwarf_Addr lowpc = 0;
1001*7fd79137SRobert Mustacchi     Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
1002*7fd79137SRobert Mustacchi 
1003*7fd79137SRobert Mustacchi     memset(&loc_block,0,sizeof(loc_block));
1004*7fd79137SRobert Mustacchi     loc_block.bl_len = expression_length;
1005*7fd79137SRobert Mustacchi     loc_block.bl_data = expression_in;
1006*7fd79137SRobert Mustacchi     loc_block.bl_from_loclist = 0; /* Not from loclist. */
1007*7fd79137SRobert Mustacchi     loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
1008*7fd79137SRobert Mustacchi 
1009*7fd79137SRobert Mustacchi     /* An empty location description (block length 0) means the code
1010*7fd79137SRobert Mustacchi     generator emitted no variable, the variable was not generated,
1011*7fd79137SRobert Mustacchi     it was unused or perhaps never tested after being set. Dwarf2,
1012*7fd79137SRobert Mustacchi     section 2.4.1 In other words, it is not an error, and we don't
1013*7fd79137SRobert Mustacchi     test for block length 0 specially here.  */
1014*7fd79137SRobert Mustacchi     locdesc = _dwarf_get_locdesc(dbg, &loc_block,
1015*7fd79137SRobert Mustacchi         addr_size,lowpc, highpc, error);
1016*7fd79137SRobert Mustacchi     if (locdesc == NULL) {
1017*7fd79137SRobert Mustacchi         /* low level error already set: let it be passed back */
1018*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1019*7fd79137SRobert Mustacchi     }
1020*7fd79137SRobert Mustacchi 
1021*7fd79137SRobert Mustacchi     *llbuf = locdesc;
1022*7fd79137SRobert Mustacchi     *listlen = 1;
1023*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
1024*7fd79137SRobert Mustacchi }
1025*7fd79137SRobert Mustacchi 
1026*7fd79137SRobert Mustacchi /* Usable to read a single loclist or to read a block of them
1027*7fd79137SRobert Mustacchi    or to read an entire section's loclists.
1028*7fd79137SRobert Mustacchi 
1029*7fd79137SRobert Mustacchi    It's broken because it's not safe to read a loclist entry
1030*7fd79137SRobert Mustacchi    when we do not know the address size (in any object where
1031*7fd79137SRobert Mustacchi    address size can vary by compilation unit).
1032*7fd79137SRobert Mustacchi */
1033*7fd79137SRobert Mustacchi 
1034*7fd79137SRobert Mustacchi  /*ARGSUSED*/ int
1035*7fd79137SRobert Mustacchi dwarf_get_loclist_entry(Dwarf_Debug dbg,
1036*7fd79137SRobert Mustacchi     Dwarf_Unsigned offset,
1037*7fd79137SRobert Mustacchi     Dwarf_Addr * hipc_offset,
1038*7fd79137SRobert Mustacchi     Dwarf_Addr * lopc_offset,
1039*7fd79137SRobert Mustacchi     Dwarf_Ptr * data,
1040*7fd79137SRobert Mustacchi     Dwarf_Unsigned * entry_len,
1041*7fd79137SRobert Mustacchi     Dwarf_Unsigned * next_entry,
1042*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1043*7fd79137SRobert Mustacchi {
1044*7fd79137SRobert Mustacchi     Dwarf_Block b;
1045*7fd79137SRobert Mustacchi     Dwarf_Addr lowpc = 0;
1046*7fd79137SRobert Mustacchi     Dwarf_Addr highpc = 0;
1047*7fd79137SRobert Mustacchi     Dwarf_Half address_size = 0;
1048*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
1049*7fd79137SRobert Mustacchi 
1050*7fd79137SRobert Mustacchi     if (!dbg->de_debug_loc.dss_data) {
1051*7fd79137SRobert Mustacchi         int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
1052*7fd79137SRobert Mustacchi         if (secload != DW_DLV_OK) {
1053*7fd79137SRobert Mustacchi             return secload;
1054*7fd79137SRobert Mustacchi         }
1055*7fd79137SRobert Mustacchi     }
1056*7fd79137SRobert Mustacchi 
1057*7fd79137SRobert Mustacchi     /* FIXME: address_size is not necessarily the same in every frame. */
1058*7fd79137SRobert Mustacchi     address_size = dbg->de_pointer_size;
1059*7fd79137SRobert Mustacchi     res = _dwarf_read_loc_section(dbg,
1060*7fd79137SRobert Mustacchi          &b, &lowpc, &highpc, offset,
1061*7fd79137SRobert Mustacchi          address_size,error);
1062*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1063*7fd79137SRobert Mustacchi         return res;
1064*7fd79137SRobert Mustacchi     }
1065*7fd79137SRobert Mustacchi     *hipc_offset = highpc;
1066*7fd79137SRobert Mustacchi     *lopc_offset = lowpc;
1067*7fd79137SRobert Mustacchi     *entry_len = b.bl_len;
1068*7fd79137SRobert Mustacchi     *data = b.bl_data;
1069*7fd79137SRobert Mustacchi     *next_entry = b.bl_len + b.bl_section_offset;
1070*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1071*7fd79137SRobert Mustacchi }
1072*7fd79137SRobert Mustacchi 
1073*7fd79137SRobert Mustacchi 
1074