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 *
_dwarf_get_locdesc(Dwarf_Debug dbg,Dwarf_Block * loc_block,Dwarf_Half address_size,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Error * error)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
_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*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
_dwarf_get_loclist_count(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,int * loclist_count,Dwarf_Error * error)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
_dwarf_setup_loc(Dwarf_Attribute attr,Dwarf_Debug * dbg_ret,Dwarf_CU_Context * cucontext_ret,Dwarf_Half * form_ret,Dwarf_Error * error)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
_dwarf_get_loclist_header_start(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_Unsigned * loclist_offset,Dwarf_Error * error)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
_dwarf_cleanup_llbuf(Dwarf_Debug dbg,Dwarf_Locdesc ** llbuf,int count)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
dwarf_loclist_n(Dwarf_Attribute attr,Dwarf_Locdesc *** llbuf_out,Dwarf_Signed * listlen_out,Dwarf_Error * error)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
dwarf_loclist(Dwarf_Attribute attr,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)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
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*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
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*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
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*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