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