1*0a6a1f1dSLionel Sambuc /* $NetBSD: libdwarf_loc.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
2*0a6a1f1dSLionel Sambuc
3*0a6a1f1dSLionel Sambuc /*-
4*0a6a1f1dSLionel Sambuc * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5*0a6a1f1dSLionel Sambuc * All rights reserved.
6*0a6a1f1dSLionel Sambuc *
7*0a6a1f1dSLionel Sambuc * Redistribution and use in source and binary forms, with or without
8*0a6a1f1dSLionel Sambuc * modification, are permitted provided that the following conditions
9*0a6a1f1dSLionel Sambuc * are met:
10*0a6a1f1dSLionel Sambuc * 1. Redistributions of source code must retain the above copyright
11*0a6a1f1dSLionel Sambuc * notice, this list of conditions and the following disclaimer.
12*0a6a1f1dSLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
13*0a6a1f1dSLionel Sambuc * notice, this list of conditions and the following disclaimer in the
14*0a6a1f1dSLionel Sambuc * documentation and/or other materials provided with the distribution.
15*0a6a1f1dSLionel Sambuc *
16*0a6a1f1dSLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*0a6a1f1dSLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*0a6a1f1dSLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*0a6a1f1dSLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*0a6a1f1dSLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*0a6a1f1dSLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*0a6a1f1dSLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*0a6a1f1dSLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*0a6a1f1dSLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*0a6a1f1dSLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*0a6a1f1dSLionel Sambuc * SUCH DAMAGE.
27*0a6a1f1dSLionel Sambuc */
28*0a6a1f1dSLionel Sambuc
29*0a6a1f1dSLionel Sambuc #include "_libdwarf.h"
30*0a6a1f1dSLionel Sambuc
31*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: libdwarf_loc.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32*0a6a1f1dSLionel Sambuc ELFTC_VCSID("Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy ");
33*0a6a1f1dSLionel Sambuc
34*0a6a1f1dSLionel Sambuc /*
35*0a6a1f1dSLionel Sambuc * Given an array of bytes of length 'len' representing a
36*0a6a1f1dSLionel Sambuc * DWARF expression, compute the number of operations based
37*0a6a1f1dSLionel Sambuc * on there being one byte describing the operation and
38*0a6a1f1dSLionel Sambuc * zero or more bytes of operands as defined in the standard
39*0a6a1f1dSLionel Sambuc * for each operation type. Also, if lbuf is non-null, store
40*0a6a1f1dSLionel Sambuc * the opcode and oprand in it.
41*0a6a1f1dSLionel Sambuc */
42*0a6a1f1dSLionel Sambuc static int
_dwarf_loc_fill_loc(Dwarf_Debug dbg,Dwarf_Locdesc * lbuf,uint8_t pointer_size,uint8_t * p,int len)43*0a6a1f1dSLionel Sambuc _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
44*0a6a1f1dSLionel Sambuc uint8_t *p, int len)
45*0a6a1f1dSLionel Sambuc {
46*0a6a1f1dSLionel Sambuc int count;
47*0a6a1f1dSLionel Sambuc uint64_t operand1;
48*0a6a1f1dSLionel Sambuc uint64_t operand2;
49*0a6a1f1dSLionel Sambuc uint8_t *ps, *pe;
50*0a6a1f1dSLionel Sambuc
51*0a6a1f1dSLionel Sambuc count = 0;
52*0a6a1f1dSLionel Sambuc ps = p;
53*0a6a1f1dSLionel Sambuc pe = p + len;
54*0a6a1f1dSLionel Sambuc
55*0a6a1f1dSLionel Sambuc /*
56*0a6a1f1dSLionel Sambuc * Process each byte. If an error occurs, then the
57*0a6a1f1dSLionel Sambuc * count will be set to -1.
58*0a6a1f1dSLionel Sambuc */
59*0a6a1f1dSLionel Sambuc while (p < pe) {
60*0a6a1f1dSLionel Sambuc
61*0a6a1f1dSLionel Sambuc operand1 = 0;
62*0a6a1f1dSLionel Sambuc operand2 = 0;
63*0a6a1f1dSLionel Sambuc
64*0a6a1f1dSLionel Sambuc if (lbuf != NULL) {
65*0a6a1f1dSLionel Sambuc lbuf->ld_s[count].lr_atom = *p;
66*0a6a1f1dSLionel Sambuc lbuf->ld_s[count].lr_offset = p - ps;
67*0a6a1f1dSLionel Sambuc }
68*0a6a1f1dSLionel Sambuc
69*0a6a1f1dSLionel Sambuc switch (*p++) {
70*0a6a1f1dSLionel Sambuc /* Operations with no operands. */
71*0a6a1f1dSLionel Sambuc case DW_OP_deref:
72*0a6a1f1dSLionel Sambuc case DW_OP_reg0:
73*0a6a1f1dSLionel Sambuc case DW_OP_reg1:
74*0a6a1f1dSLionel Sambuc case DW_OP_reg2:
75*0a6a1f1dSLionel Sambuc case DW_OP_reg3:
76*0a6a1f1dSLionel Sambuc case DW_OP_reg4:
77*0a6a1f1dSLionel Sambuc case DW_OP_reg5:
78*0a6a1f1dSLionel Sambuc case DW_OP_reg6:
79*0a6a1f1dSLionel Sambuc case DW_OP_reg7:
80*0a6a1f1dSLionel Sambuc case DW_OP_reg8:
81*0a6a1f1dSLionel Sambuc case DW_OP_reg9:
82*0a6a1f1dSLionel Sambuc case DW_OP_reg10:
83*0a6a1f1dSLionel Sambuc case DW_OP_reg11:
84*0a6a1f1dSLionel Sambuc case DW_OP_reg12:
85*0a6a1f1dSLionel Sambuc case DW_OP_reg13:
86*0a6a1f1dSLionel Sambuc case DW_OP_reg14:
87*0a6a1f1dSLionel Sambuc case DW_OP_reg15:
88*0a6a1f1dSLionel Sambuc case DW_OP_reg16:
89*0a6a1f1dSLionel Sambuc case DW_OP_reg17:
90*0a6a1f1dSLionel Sambuc case DW_OP_reg18:
91*0a6a1f1dSLionel Sambuc case DW_OP_reg19:
92*0a6a1f1dSLionel Sambuc case DW_OP_reg20:
93*0a6a1f1dSLionel Sambuc case DW_OP_reg21:
94*0a6a1f1dSLionel Sambuc case DW_OP_reg22:
95*0a6a1f1dSLionel Sambuc case DW_OP_reg23:
96*0a6a1f1dSLionel Sambuc case DW_OP_reg24:
97*0a6a1f1dSLionel Sambuc case DW_OP_reg25:
98*0a6a1f1dSLionel Sambuc case DW_OP_reg26:
99*0a6a1f1dSLionel Sambuc case DW_OP_reg27:
100*0a6a1f1dSLionel Sambuc case DW_OP_reg28:
101*0a6a1f1dSLionel Sambuc case DW_OP_reg29:
102*0a6a1f1dSLionel Sambuc case DW_OP_reg30:
103*0a6a1f1dSLionel Sambuc case DW_OP_reg31:
104*0a6a1f1dSLionel Sambuc
105*0a6a1f1dSLionel Sambuc case DW_OP_lit0:
106*0a6a1f1dSLionel Sambuc case DW_OP_lit1:
107*0a6a1f1dSLionel Sambuc case DW_OP_lit2:
108*0a6a1f1dSLionel Sambuc case DW_OP_lit3:
109*0a6a1f1dSLionel Sambuc case DW_OP_lit4:
110*0a6a1f1dSLionel Sambuc case DW_OP_lit5:
111*0a6a1f1dSLionel Sambuc case DW_OP_lit6:
112*0a6a1f1dSLionel Sambuc case DW_OP_lit7:
113*0a6a1f1dSLionel Sambuc case DW_OP_lit8:
114*0a6a1f1dSLionel Sambuc case DW_OP_lit9:
115*0a6a1f1dSLionel Sambuc case DW_OP_lit10:
116*0a6a1f1dSLionel Sambuc case DW_OP_lit11:
117*0a6a1f1dSLionel Sambuc case DW_OP_lit12:
118*0a6a1f1dSLionel Sambuc case DW_OP_lit13:
119*0a6a1f1dSLionel Sambuc case DW_OP_lit14:
120*0a6a1f1dSLionel Sambuc case DW_OP_lit15:
121*0a6a1f1dSLionel Sambuc case DW_OP_lit16:
122*0a6a1f1dSLionel Sambuc case DW_OP_lit17:
123*0a6a1f1dSLionel Sambuc case DW_OP_lit18:
124*0a6a1f1dSLionel Sambuc case DW_OP_lit19:
125*0a6a1f1dSLionel Sambuc case DW_OP_lit20:
126*0a6a1f1dSLionel Sambuc case DW_OP_lit21:
127*0a6a1f1dSLionel Sambuc case DW_OP_lit22:
128*0a6a1f1dSLionel Sambuc case DW_OP_lit23:
129*0a6a1f1dSLionel Sambuc case DW_OP_lit24:
130*0a6a1f1dSLionel Sambuc case DW_OP_lit25:
131*0a6a1f1dSLionel Sambuc case DW_OP_lit26:
132*0a6a1f1dSLionel Sambuc case DW_OP_lit27:
133*0a6a1f1dSLionel Sambuc case DW_OP_lit28:
134*0a6a1f1dSLionel Sambuc case DW_OP_lit29:
135*0a6a1f1dSLionel Sambuc case DW_OP_lit30:
136*0a6a1f1dSLionel Sambuc case DW_OP_lit31:
137*0a6a1f1dSLionel Sambuc
138*0a6a1f1dSLionel Sambuc case DW_OP_dup:
139*0a6a1f1dSLionel Sambuc case DW_OP_drop:
140*0a6a1f1dSLionel Sambuc
141*0a6a1f1dSLionel Sambuc case DW_OP_over:
142*0a6a1f1dSLionel Sambuc
143*0a6a1f1dSLionel Sambuc case DW_OP_swap:
144*0a6a1f1dSLionel Sambuc case DW_OP_rot:
145*0a6a1f1dSLionel Sambuc case DW_OP_xderef:
146*0a6a1f1dSLionel Sambuc
147*0a6a1f1dSLionel Sambuc case DW_OP_abs:
148*0a6a1f1dSLionel Sambuc case DW_OP_and:
149*0a6a1f1dSLionel Sambuc case DW_OP_div:
150*0a6a1f1dSLionel Sambuc case DW_OP_minus:
151*0a6a1f1dSLionel Sambuc case DW_OP_mod:
152*0a6a1f1dSLionel Sambuc case DW_OP_mul:
153*0a6a1f1dSLionel Sambuc case DW_OP_neg:
154*0a6a1f1dSLionel Sambuc case DW_OP_not:
155*0a6a1f1dSLionel Sambuc case DW_OP_or:
156*0a6a1f1dSLionel Sambuc case DW_OP_plus:
157*0a6a1f1dSLionel Sambuc
158*0a6a1f1dSLionel Sambuc case DW_OP_shl:
159*0a6a1f1dSLionel Sambuc case DW_OP_shr:
160*0a6a1f1dSLionel Sambuc case DW_OP_shra:
161*0a6a1f1dSLionel Sambuc case DW_OP_xor:
162*0a6a1f1dSLionel Sambuc
163*0a6a1f1dSLionel Sambuc case DW_OP_eq:
164*0a6a1f1dSLionel Sambuc case DW_OP_ge:
165*0a6a1f1dSLionel Sambuc case DW_OP_gt:
166*0a6a1f1dSLionel Sambuc case DW_OP_le:
167*0a6a1f1dSLionel Sambuc case DW_OP_lt:
168*0a6a1f1dSLionel Sambuc case DW_OP_ne:
169*0a6a1f1dSLionel Sambuc
170*0a6a1f1dSLionel Sambuc case DW_OP_nop:
171*0a6a1f1dSLionel Sambuc case DW_OP_form_tls_address:
172*0a6a1f1dSLionel Sambuc case DW_OP_call_frame_cfa:
173*0a6a1f1dSLionel Sambuc case DW_OP_stack_value:
174*0a6a1f1dSLionel Sambuc case DW_OP_GNU_push_tls_address:
175*0a6a1f1dSLionel Sambuc break;
176*0a6a1f1dSLionel Sambuc
177*0a6a1f1dSLionel Sambuc /* Operations with 1-byte operands. */
178*0a6a1f1dSLionel Sambuc case DW_OP_const1u:
179*0a6a1f1dSLionel Sambuc case DW_OP_const1s:
180*0a6a1f1dSLionel Sambuc case DW_OP_pick:
181*0a6a1f1dSLionel Sambuc case DW_OP_deref_size:
182*0a6a1f1dSLionel Sambuc case DW_OP_xderef_size:
183*0a6a1f1dSLionel Sambuc operand1 = *p++;
184*0a6a1f1dSLionel Sambuc break;
185*0a6a1f1dSLionel Sambuc
186*0a6a1f1dSLionel Sambuc /* Operations with 2-byte operands. */
187*0a6a1f1dSLionel Sambuc case DW_OP_call2:
188*0a6a1f1dSLionel Sambuc case DW_OP_const2u:
189*0a6a1f1dSLionel Sambuc case DW_OP_const2s:
190*0a6a1f1dSLionel Sambuc case DW_OP_bra:
191*0a6a1f1dSLionel Sambuc case DW_OP_skip:
192*0a6a1f1dSLionel Sambuc operand1 = dbg->decode(&p, 2);
193*0a6a1f1dSLionel Sambuc break;
194*0a6a1f1dSLionel Sambuc
195*0a6a1f1dSLionel Sambuc /* Operations with 4-byte operands. */
196*0a6a1f1dSLionel Sambuc case DW_OP_call4:
197*0a6a1f1dSLionel Sambuc case DW_OP_const4u:
198*0a6a1f1dSLionel Sambuc case DW_OP_const4s:
199*0a6a1f1dSLionel Sambuc operand1 = dbg->decode(&p, 4);
200*0a6a1f1dSLionel Sambuc break;
201*0a6a1f1dSLionel Sambuc
202*0a6a1f1dSLionel Sambuc /* Operations with 8-byte operands. */
203*0a6a1f1dSLionel Sambuc case DW_OP_const8u:
204*0a6a1f1dSLionel Sambuc case DW_OP_const8s:
205*0a6a1f1dSLionel Sambuc operand1 = dbg->decode(&p, 8);
206*0a6a1f1dSLionel Sambuc break;
207*0a6a1f1dSLionel Sambuc
208*0a6a1f1dSLionel Sambuc /* Operations with an unsigned LEB128 operand. */
209*0a6a1f1dSLionel Sambuc case DW_OP_constu:
210*0a6a1f1dSLionel Sambuc case DW_OP_plus_uconst:
211*0a6a1f1dSLionel Sambuc case DW_OP_regx:
212*0a6a1f1dSLionel Sambuc case DW_OP_piece:
213*0a6a1f1dSLionel Sambuc operand1 = _dwarf_decode_uleb128(&p);
214*0a6a1f1dSLionel Sambuc break;
215*0a6a1f1dSLionel Sambuc
216*0a6a1f1dSLionel Sambuc /* Operations with a signed LEB128 operand. */
217*0a6a1f1dSLionel Sambuc case DW_OP_consts:
218*0a6a1f1dSLionel Sambuc case DW_OP_breg0:
219*0a6a1f1dSLionel Sambuc case DW_OP_breg1:
220*0a6a1f1dSLionel Sambuc case DW_OP_breg2:
221*0a6a1f1dSLionel Sambuc case DW_OP_breg3:
222*0a6a1f1dSLionel Sambuc case DW_OP_breg4:
223*0a6a1f1dSLionel Sambuc case DW_OP_breg5:
224*0a6a1f1dSLionel Sambuc case DW_OP_breg6:
225*0a6a1f1dSLionel Sambuc case DW_OP_breg7:
226*0a6a1f1dSLionel Sambuc case DW_OP_breg8:
227*0a6a1f1dSLionel Sambuc case DW_OP_breg9:
228*0a6a1f1dSLionel Sambuc case DW_OP_breg10:
229*0a6a1f1dSLionel Sambuc case DW_OP_breg11:
230*0a6a1f1dSLionel Sambuc case DW_OP_breg12:
231*0a6a1f1dSLionel Sambuc case DW_OP_breg13:
232*0a6a1f1dSLionel Sambuc case DW_OP_breg14:
233*0a6a1f1dSLionel Sambuc case DW_OP_breg15:
234*0a6a1f1dSLionel Sambuc case DW_OP_breg16:
235*0a6a1f1dSLionel Sambuc case DW_OP_breg17:
236*0a6a1f1dSLionel Sambuc case DW_OP_breg18:
237*0a6a1f1dSLionel Sambuc case DW_OP_breg19:
238*0a6a1f1dSLionel Sambuc case DW_OP_breg20:
239*0a6a1f1dSLionel Sambuc case DW_OP_breg21:
240*0a6a1f1dSLionel Sambuc case DW_OP_breg22:
241*0a6a1f1dSLionel Sambuc case DW_OP_breg23:
242*0a6a1f1dSLionel Sambuc case DW_OP_breg24:
243*0a6a1f1dSLionel Sambuc case DW_OP_breg25:
244*0a6a1f1dSLionel Sambuc case DW_OP_breg26:
245*0a6a1f1dSLionel Sambuc case DW_OP_breg27:
246*0a6a1f1dSLionel Sambuc case DW_OP_breg28:
247*0a6a1f1dSLionel Sambuc case DW_OP_breg29:
248*0a6a1f1dSLionel Sambuc case DW_OP_breg30:
249*0a6a1f1dSLionel Sambuc case DW_OP_breg31:
250*0a6a1f1dSLionel Sambuc case DW_OP_fbreg:
251*0a6a1f1dSLionel Sambuc operand1 = _dwarf_decode_sleb128(&p);
252*0a6a1f1dSLionel Sambuc break;
253*0a6a1f1dSLionel Sambuc
254*0a6a1f1dSLionel Sambuc /*
255*0a6a1f1dSLionel Sambuc * Oeration with two unsigned LEB128 operands.
256*0a6a1f1dSLionel Sambuc */
257*0a6a1f1dSLionel Sambuc case DW_OP_bit_piece:
258*0a6a1f1dSLionel Sambuc operand1 = _dwarf_decode_uleb128(&p);
259*0a6a1f1dSLionel Sambuc operand2 = _dwarf_decode_uleb128(&p);
260*0a6a1f1dSLionel Sambuc break;
261*0a6a1f1dSLionel Sambuc
262*0a6a1f1dSLionel Sambuc /*
263*0a6a1f1dSLionel Sambuc * Operations with an unsigned LEB128 operand
264*0a6a1f1dSLionel Sambuc * followed by a signed LEB128 operand.
265*0a6a1f1dSLionel Sambuc */
266*0a6a1f1dSLionel Sambuc case DW_OP_bregx:
267*0a6a1f1dSLionel Sambuc operand1 = _dwarf_decode_uleb128(&p);
268*0a6a1f1dSLionel Sambuc operand2 = _dwarf_decode_sleb128(&p);
269*0a6a1f1dSLionel Sambuc break;
270*0a6a1f1dSLionel Sambuc
271*0a6a1f1dSLionel Sambuc /*
272*0a6a1f1dSLionel Sambuc * Operation with an unsigned LEB128 operand
273*0a6a1f1dSLionel Sambuc * followed by a block. Store a pointer to the
274*0a6a1f1dSLionel Sambuc * block in the operand2.
275*0a6a1f1dSLionel Sambuc */
276*0a6a1f1dSLionel Sambuc case DW_OP_implicit_value:
277*0a6a1f1dSLionel Sambuc operand1 = _dwarf_decode_uleb128(&p);
278*0a6a1f1dSLionel Sambuc operand2 = (Dwarf_Unsigned) (uintptr_t) p;
279*0a6a1f1dSLionel Sambuc p += operand1;
280*0a6a1f1dSLionel Sambuc break;
281*0a6a1f1dSLionel Sambuc
282*0a6a1f1dSLionel Sambuc /* Target address size operand. */
283*0a6a1f1dSLionel Sambuc case DW_OP_addr:
284*0a6a1f1dSLionel Sambuc operand1 = dbg->decode(&p, pointer_size);
285*0a6a1f1dSLionel Sambuc break;
286*0a6a1f1dSLionel Sambuc
287*0a6a1f1dSLionel Sambuc /*
288*0a6a1f1dSLionel Sambuc * XXX Opcode DW_OP_call_ref has an operand with size
289*0a6a1f1dSLionel Sambuc * "dwarf_size". Here we use dbg->dbg_offset_size
290*0a6a1f1dSLionel Sambuc * as "dwarf_size" to be compatible with SGI libdwarf.
291*0a6a1f1dSLionel Sambuc * However note that dbg->dbg_offset_size is just
292*0a6a1f1dSLionel Sambuc * a "guess" value so the parsing result of
293*0a6a1f1dSLionel Sambuc * DW_OP_call_ref might not be correct at all. XXX
294*0a6a1f1dSLionel Sambuc */
295*0a6a1f1dSLionel Sambuc case DW_OP_call_ref:
296*0a6a1f1dSLionel Sambuc operand1 = dbg->decode(&p, dbg->dbg_offset_size);
297*0a6a1f1dSLionel Sambuc break;
298*0a6a1f1dSLionel Sambuc
299*0a6a1f1dSLionel Sambuc /* All other operations cause an error. */
300*0a6a1f1dSLionel Sambuc default:
301*0a6a1f1dSLionel Sambuc count = -1;
302*0a6a1f1dSLionel Sambuc break;
303*0a6a1f1dSLionel Sambuc }
304*0a6a1f1dSLionel Sambuc
305*0a6a1f1dSLionel Sambuc if (lbuf != NULL) {
306*0a6a1f1dSLionel Sambuc lbuf->ld_s[count].lr_number = operand1;
307*0a6a1f1dSLionel Sambuc lbuf->ld_s[count].lr_number2 = operand2;
308*0a6a1f1dSLionel Sambuc }
309*0a6a1f1dSLionel Sambuc
310*0a6a1f1dSLionel Sambuc count++;
311*0a6a1f1dSLionel Sambuc }
312*0a6a1f1dSLionel Sambuc
313*0a6a1f1dSLionel Sambuc return (count);
314*0a6a1f1dSLionel Sambuc }
315*0a6a1f1dSLionel Sambuc
316*0a6a1f1dSLionel Sambuc int
_dwarf_loc_expr_add_atom(Dwarf_Debug dbg,uint8_t * out,uint8_t * end,Dwarf_Small atom,Dwarf_Unsigned operand1,Dwarf_Unsigned operand2,int * length,Dwarf_Error * error)317*0a6a1f1dSLionel Sambuc _dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end,
318*0a6a1f1dSLionel Sambuc Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2,
319*0a6a1f1dSLionel Sambuc int *length, Dwarf_Error *error)
320*0a6a1f1dSLionel Sambuc {
321*0a6a1f1dSLionel Sambuc uint8_t buf[64];
322*0a6a1f1dSLionel Sambuc uint8_t *p, *pe;
323*0a6a1f1dSLionel Sambuc uint64_t offset;
324*0a6a1f1dSLionel Sambuc int len;
325*0a6a1f1dSLionel Sambuc
326*0a6a1f1dSLionel Sambuc if (out != NULL && end != NULL) {
327*0a6a1f1dSLionel Sambuc p = out;
328*0a6a1f1dSLionel Sambuc pe = end;
329*0a6a1f1dSLionel Sambuc } else {
330*0a6a1f1dSLionel Sambuc p = out = buf;
331*0a6a1f1dSLionel Sambuc pe = &buf[sizeof(buf)];
332*0a6a1f1dSLionel Sambuc }
333*0a6a1f1dSLionel Sambuc
334*0a6a1f1dSLionel Sambuc switch (atom) {
335*0a6a1f1dSLionel Sambuc /* Operations with no operands. */
336*0a6a1f1dSLionel Sambuc case DW_OP_deref:
337*0a6a1f1dSLionel Sambuc case DW_OP_reg0:
338*0a6a1f1dSLionel Sambuc case DW_OP_reg1:
339*0a6a1f1dSLionel Sambuc case DW_OP_reg2:
340*0a6a1f1dSLionel Sambuc case DW_OP_reg3:
341*0a6a1f1dSLionel Sambuc case DW_OP_reg4:
342*0a6a1f1dSLionel Sambuc case DW_OP_reg5:
343*0a6a1f1dSLionel Sambuc case DW_OP_reg6:
344*0a6a1f1dSLionel Sambuc case DW_OP_reg7:
345*0a6a1f1dSLionel Sambuc case DW_OP_reg8:
346*0a6a1f1dSLionel Sambuc case DW_OP_reg9:
347*0a6a1f1dSLionel Sambuc case DW_OP_reg10:
348*0a6a1f1dSLionel Sambuc case DW_OP_reg11:
349*0a6a1f1dSLionel Sambuc case DW_OP_reg12:
350*0a6a1f1dSLionel Sambuc case DW_OP_reg13:
351*0a6a1f1dSLionel Sambuc case DW_OP_reg14:
352*0a6a1f1dSLionel Sambuc case DW_OP_reg15:
353*0a6a1f1dSLionel Sambuc case DW_OP_reg16:
354*0a6a1f1dSLionel Sambuc case DW_OP_reg17:
355*0a6a1f1dSLionel Sambuc case DW_OP_reg18:
356*0a6a1f1dSLionel Sambuc case DW_OP_reg19:
357*0a6a1f1dSLionel Sambuc case DW_OP_reg20:
358*0a6a1f1dSLionel Sambuc case DW_OP_reg21:
359*0a6a1f1dSLionel Sambuc case DW_OP_reg22:
360*0a6a1f1dSLionel Sambuc case DW_OP_reg23:
361*0a6a1f1dSLionel Sambuc case DW_OP_reg24:
362*0a6a1f1dSLionel Sambuc case DW_OP_reg25:
363*0a6a1f1dSLionel Sambuc case DW_OP_reg26:
364*0a6a1f1dSLionel Sambuc case DW_OP_reg27:
365*0a6a1f1dSLionel Sambuc case DW_OP_reg28:
366*0a6a1f1dSLionel Sambuc case DW_OP_reg29:
367*0a6a1f1dSLionel Sambuc case DW_OP_reg30:
368*0a6a1f1dSLionel Sambuc case DW_OP_reg31:
369*0a6a1f1dSLionel Sambuc
370*0a6a1f1dSLionel Sambuc case DW_OP_lit0:
371*0a6a1f1dSLionel Sambuc case DW_OP_lit1:
372*0a6a1f1dSLionel Sambuc case DW_OP_lit2:
373*0a6a1f1dSLionel Sambuc case DW_OP_lit3:
374*0a6a1f1dSLionel Sambuc case DW_OP_lit4:
375*0a6a1f1dSLionel Sambuc case DW_OP_lit5:
376*0a6a1f1dSLionel Sambuc case DW_OP_lit6:
377*0a6a1f1dSLionel Sambuc case DW_OP_lit7:
378*0a6a1f1dSLionel Sambuc case DW_OP_lit8:
379*0a6a1f1dSLionel Sambuc case DW_OP_lit9:
380*0a6a1f1dSLionel Sambuc case DW_OP_lit10:
381*0a6a1f1dSLionel Sambuc case DW_OP_lit11:
382*0a6a1f1dSLionel Sambuc case DW_OP_lit12:
383*0a6a1f1dSLionel Sambuc case DW_OP_lit13:
384*0a6a1f1dSLionel Sambuc case DW_OP_lit14:
385*0a6a1f1dSLionel Sambuc case DW_OP_lit15:
386*0a6a1f1dSLionel Sambuc case DW_OP_lit16:
387*0a6a1f1dSLionel Sambuc case DW_OP_lit17:
388*0a6a1f1dSLionel Sambuc case DW_OP_lit18:
389*0a6a1f1dSLionel Sambuc case DW_OP_lit19:
390*0a6a1f1dSLionel Sambuc case DW_OP_lit20:
391*0a6a1f1dSLionel Sambuc case DW_OP_lit21:
392*0a6a1f1dSLionel Sambuc case DW_OP_lit22:
393*0a6a1f1dSLionel Sambuc case DW_OP_lit23:
394*0a6a1f1dSLionel Sambuc case DW_OP_lit24:
395*0a6a1f1dSLionel Sambuc case DW_OP_lit25:
396*0a6a1f1dSLionel Sambuc case DW_OP_lit26:
397*0a6a1f1dSLionel Sambuc case DW_OP_lit27:
398*0a6a1f1dSLionel Sambuc case DW_OP_lit28:
399*0a6a1f1dSLionel Sambuc case DW_OP_lit29:
400*0a6a1f1dSLionel Sambuc case DW_OP_lit30:
401*0a6a1f1dSLionel Sambuc case DW_OP_lit31:
402*0a6a1f1dSLionel Sambuc
403*0a6a1f1dSLionel Sambuc case DW_OP_dup:
404*0a6a1f1dSLionel Sambuc case DW_OP_drop:
405*0a6a1f1dSLionel Sambuc
406*0a6a1f1dSLionel Sambuc case DW_OP_over:
407*0a6a1f1dSLionel Sambuc
408*0a6a1f1dSLionel Sambuc case DW_OP_swap:
409*0a6a1f1dSLionel Sambuc case DW_OP_rot:
410*0a6a1f1dSLionel Sambuc case DW_OP_xderef:
411*0a6a1f1dSLionel Sambuc
412*0a6a1f1dSLionel Sambuc case DW_OP_abs:
413*0a6a1f1dSLionel Sambuc case DW_OP_and:
414*0a6a1f1dSLionel Sambuc case DW_OP_div:
415*0a6a1f1dSLionel Sambuc case DW_OP_minus:
416*0a6a1f1dSLionel Sambuc case DW_OP_mod:
417*0a6a1f1dSLionel Sambuc case DW_OP_mul:
418*0a6a1f1dSLionel Sambuc case DW_OP_neg:
419*0a6a1f1dSLionel Sambuc case DW_OP_not:
420*0a6a1f1dSLionel Sambuc case DW_OP_or:
421*0a6a1f1dSLionel Sambuc case DW_OP_plus:
422*0a6a1f1dSLionel Sambuc
423*0a6a1f1dSLionel Sambuc case DW_OP_shl:
424*0a6a1f1dSLionel Sambuc case DW_OP_shr:
425*0a6a1f1dSLionel Sambuc case DW_OP_shra:
426*0a6a1f1dSLionel Sambuc case DW_OP_xor:
427*0a6a1f1dSLionel Sambuc
428*0a6a1f1dSLionel Sambuc case DW_OP_eq:
429*0a6a1f1dSLionel Sambuc case DW_OP_ge:
430*0a6a1f1dSLionel Sambuc case DW_OP_gt:
431*0a6a1f1dSLionel Sambuc case DW_OP_le:
432*0a6a1f1dSLionel Sambuc case DW_OP_lt:
433*0a6a1f1dSLionel Sambuc case DW_OP_ne:
434*0a6a1f1dSLionel Sambuc
435*0a6a1f1dSLionel Sambuc case DW_OP_nop:
436*0a6a1f1dSLionel Sambuc case DW_OP_GNU_push_tls_address:
437*0a6a1f1dSLionel Sambuc *p++ = atom;
438*0a6a1f1dSLionel Sambuc break;
439*0a6a1f1dSLionel Sambuc
440*0a6a1f1dSLionel Sambuc /* Operations with 1-byte operands. */
441*0a6a1f1dSLionel Sambuc case DW_OP_const1u:
442*0a6a1f1dSLionel Sambuc case DW_OP_const1s:
443*0a6a1f1dSLionel Sambuc case DW_OP_pick:
444*0a6a1f1dSLionel Sambuc case DW_OP_deref_size:
445*0a6a1f1dSLionel Sambuc case DW_OP_xderef_size:
446*0a6a1f1dSLionel Sambuc *p++ = atom;
447*0a6a1f1dSLionel Sambuc *p++ = (uint8_t) operand1;
448*0a6a1f1dSLionel Sambuc break;
449*0a6a1f1dSLionel Sambuc
450*0a6a1f1dSLionel Sambuc /* Operations with 2-byte operands. */
451*0a6a1f1dSLionel Sambuc case DW_OP_const2u:
452*0a6a1f1dSLionel Sambuc case DW_OP_const2s:
453*0a6a1f1dSLionel Sambuc case DW_OP_bra:
454*0a6a1f1dSLionel Sambuc case DW_OP_skip:
455*0a6a1f1dSLionel Sambuc *p++ = atom;
456*0a6a1f1dSLionel Sambuc offset = 0;
457*0a6a1f1dSLionel Sambuc dbg->write(p, &offset, operand1, 2);
458*0a6a1f1dSLionel Sambuc p += 2;
459*0a6a1f1dSLionel Sambuc break;
460*0a6a1f1dSLionel Sambuc
461*0a6a1f1dSLionel Sambuc /* Operations with 4-byte operands. */
462*0a6a1f1dSLionel Sambuc case DW_OP_const4u:
463*0a6a1f1dSLionel Sambuc case DW_OP_const4s:
464*0a6a1f1dSLionel Sambuc *p++ = atom;
465*0a6a1f1dSLionel Sambuc offset = 0;
466*0a6a1f1dSLionel Sambuc dbg->write(p, &offset, operand1, 4);
467*0a6a1f1dSLionel Sambuc p += 4;
468*0a6a1f1dSLionel Sambuc break;
469*0a6a1f1dSLionel Sambuc
470*0a6a1f1dSLionel Sambuc /* Operations with 8-byte operands. */
471*0a6a1f1dSLionel Sambuc case DW_OP_const8u:
472*0a6a1f1dSLionel Sambuc case DW_OP_const8s:
473*0a6a1f1dSLionel Sambuc *p++ = atom;
474*0a6a1f1dSLionel Sambuc offset = 0;
475*0a6a1f1dSLionel Sambuc dbg->write(p, &offset, operand1, 8);
476*0a6a1f1dSLionel Sambuc p += 8;
477*0a6a1f1dSLionel Sambuc break;
478*0a6a1f1dSLionel Sambuc
479*0a6a1f1dSLionel Sambuc /* Operations with an unsigned LEB128 operand. */
480*0a6a1f1dSLionel Sambuc case DW_OP_constu:
481*0a6a1f1dSLionel Sambuc case DW_OP_plus_uconst:
482*0a6a1f1dSLionel Sambuc case DW_OP_regx:
483*0a6a1f1dSLionel Sambuc case DW_OP_piece:
484*0a6a1f1dSLionel Sambuc *p++ = atom;
485*0a6a1f1dSLionel Sambuc len = _dwarf_write_uleb128(p, pe, operand1);
486*0a6a1f1dSLionel Sambuc assert(len > 0);
487*0a6a1f1dSLionel Sambuc p += len;
488*0a6a1f1dSLionel Sambuc break;
489*0a6a1f1dSLionel Sambuc
490*0a6a1f1dSLionel Sambuc /* Operations with a signed LEB128 operand. */
491*0a6a1f1dSLionel Sambuc case DW_OP_consts:
492*0a6a1f1dSLionel Sambuc case DW_OP_breg0:
493*0a6a1f1dSLionel Sambuc case DW_OP_breg1:
494*0a6a1f1dSLionel Sambuc case DW_OP_breg2:
495*0a6a1f1dSLionel Sambuc case DW_OP_breg3:
496*0a6a1f1dSLionel Sambuc case DW_OP_breg4:
497*0a6a1f1dSLionel Sambuc case DW_OP_breg5:
498*0a6a1f1dSLionel Sambuc case DW_OP_breg6:
499*0a6a1f1dSLionel Sambuc case DW_OP_breg7:
500*0a6a1f1dSLionel Sambuc case DW_OP_breg8:
501*0a6a1f1dSLionel Sambuc case DW_OP_breg9:
502*0a6a1f1dSLionel Sambuc case DW_OP_breg10:
503*0a6a1f1dSLionel Sambuc case DW_OP_breg11:
504*0a6a1f1dSLionel Sambuc case DW_OP_breg12:
505*0a6a1f1dSLionel Sambuc case DW_OP_breg13:
506*0a6a1f1dSLionel Sambuc case DW_OP_breg14:
507*0a6a1f1dSLionel Sambuc case DW_OP_breg15:
508*0a6a1f1dSLionel Sambuc case DW_OP_breg16:
509*0a6a1f1dSLionel Sambuc case DW_OP_breg17:
510*0a6a1f1dSLionel Sambuc case DW_OP_breg18:
511*0a6a1f1dSLionel Sambuc case DW_OP_breg19:
512*0a6a1f1dSLionel Sambuc case DW_OP_breg20:
513*0a6a1f1dSLionel Sambuc case DW_OP_breg21:
514*0a6a1f1dSLionel Sambuc case DW_OP_breg22:
515*0a6a1f1dSLionel Sambuc case DW_OP_breg23:
516*0a6a1f1dSLionel Sambuc case DW_OP_breg24:
517*0a6a1f1dSLionel Sambuc case DW_OP_breg25:
518*0a6a1f1dSLionel Sambuc case DW_OP_breg26:
519*0a6a1f1dSLionel Sambuc case DW_OP_breg27:
520*0a6a1f1dSLionel Sambuc case DW_OP_breg28:
521*0a6a1f1dSLionel Sambuc case DW_OP_breg29:
522*0a6a1f1dSLionel Sambuc case DW_OP_breg30:
523*0a6a1f1dSLionel Sambuc case DW_OP_breg31:
524*0a6a1f1dSLionel Sambuc case DW_OP_fbreg:
525*0a6a1f1dSLionel Sambuc *p++ = atom;
526*0a6a1f1dSLionel Sambuc len = _dwarf_write_sleb128(p, pe, operand1);
527*0a6a1f1dSLionel Sambuc assert(len > 0);
528*0a6a1f1dSLionel Sambuc p += len;
529*0a6a1f1dSLionel Sambuc break;
530*0a6a1f1dSLionel Sambuc
531*0a6a1f1dSLionel Sambuc /*
532*0a6a1f1dSLionel Sambuc * Operations with an unsigned LEB128 operand
533*0a6a1f1dSLionel Sambuc * followed by a signed LEB128 operand.
534*0a6a1f1dSLionel Sambuc */
535*0a6a1f1dSLionel Sambuc case DW_OP_bregx:
536*0a6a1f1dSLionel Sambuc *p++ = atom;
537*0a6a1f1dSLionel Sambuc len = _dwarf_write_uleb128(p, pe, operand1);
538*0a6a1f1dSLionel Sambuc assert(len > 0);
539*0a6a1f1dSLionel Sambuc p += len;
540*0a6a1f1dSLionel Sambuc len = _dwarf_write_sleb128(p, pe, operand2);
541*0a6a1f1dSLionel Sambuc assert(len > 0);
542*0a6a1f1dSLionel Sambuc p += len;
543*0a6a1f1dSLionel Sambuc break;
544*0a6a1f1dSLionel Sambuc
545*0a6a1f1dSLionel Sambuc /* Target address size operand. */
546*0a6a1f1dSLionel Sambuc case DW_OP_addr:
547*0a6a1f1dSLionel Sambuc *p++ = atom;
548*0a6a1f1dSLionel Sambuc offset = 0;
549*0a6a1f1dSLionel Sambuc dbg->write(p, &offset, operand1, dbg->dbg_pointer_size);
550*0a6a1f1dSLionel Sambuc p += dbg->dbg_pointer_size;
551*0a6a1f1dSLionel Sambuc break;
552*0a6a1f1dSLionel Sambuc
553*0a6a1f1dSLionel Sambuc /* All other operations cause an error. */
554*0a6a1f1dSLionel Sambuc default:
555*0a6a1f1dSLionel Sambuc DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD);
556*0a6a1f1dSLionel Sambuc return (DW_DLE_LOC_EXPR_BAD);
557*0a6a1f1dSLionel Sambuc }
558*0a6a1f1dSLionel Sambuc
559*0a6a1f1dSLionel Sambuc if (length)
560*0a6a1f1dSLionel Sambuc *length = p - out;
561*0a6a1f1dSLionel Sambuc
562*0a6a1f1dSLionel Sambuc return (DW_DLE_NONE);
563*0a6a1f1dSLionel Sambuc }
564*0a6a1f1dSLionel Sambuc
565*0a6a1f1dSLionel Sambuc int
_dwarf_loc_fill_locdesc(Dwarf_Debug dbg,Dwarf_Locdesc * llbuf,uint8_t * in,uint64_t in_len,uint8_t pointer_size,Dwarf_Error * error)566*0a6a1f1dSLionel Sambuc _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in,
567*0a6a1f1dSLionel Sambuc uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error)
568*0a6a1f1dSLionel Sambuc {
569*0a6a1f1dSLionel Sambuc int num;
570*0a6a1f1dSLionel Sambuc
571*0a6a1f1dSLionel Sambuc assert(llbuf != NULL);
572*0a6a1f1dSLionel Sambuc assert(in != NULL);
573*0a6a1f1dSLionel Sambuc assert(in_len > 0);
574*0a6a1f1dSLionel Sambuc
575*0a6a1f1dSLionel Sambuc /* Compute the number of locations. */
576*0a6a1f1dSLionel Sambuc if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) <
577*0a6a1f1dSLionel Sambuc 0) {
578*0a6a1f1dSLionel Sambuc DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD);
579*0a6a1f1dSLionel Sambuc return (DW_DLE_LOC_EXPR_BAD);
580*0a6a1f1dSLionel Sambuc }
581*0a6a1f1dSLionel Sambuc
582*0a6a1f1dSLionel Sambuc llbuf->ld_cents = num;
583*0a6a1f1dSLionel Sambuc if (num <= 0)
584*0a6a1f1dSLionel Sambuc return (DW_DLE_NONE);
585*0a6a1f1dSLionel Sambuc
586*0a6a1f1dSLionel Sambuc if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) {
587*0a6a1f1dSLionel Sambuc DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
588*0a6a1f1dSLionel Sambuc return (DW_DLE_MEMORY);
589*0a6a1f1dSLionel Sambuc }
590*0a6a1f1dSLionel Sambuc
591*0a6a1f1dSLionel Sambuc (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len);
592*0a6a1f1dSLionel Sambuc
593*0a6a1f1dSLionel Sambuc return (DW_DLE_NONE);
594*0a6a1f1dSLionel Sambuc }
595*0a6a1f1dSLionel Sambuc
596*0a6a1f1dSLionel Sambuc int
_dwarf_loc_fill_locexpr(Dwarf_Debug dbg,Dwarf_Locdesc ** ret_llbuf,uint8_t * in,uint64_t in_len,uint8_t pointer_size,Dwarf_Error * error)597*0a6a1f1dSLionel Sambuc _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in,
598*0a6a1f1dSLionel Sambuc uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error)
599*0a6a1f1dSLionel Sambuc {
600*0a6a1f1dSLionel Sambuc Dwarf_Locdesc *llbuf;
601*0a6a1f1dSLionel Sambuc int ret;
602*0a6a1f1dSLionel Sambuc
603*0a6a1f1dSLionel Sambuc if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) {
604*0a6a1f1dSLionel Sambuc DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
605*0a6a1f1dSLionel Sambuc return (DW_DLE_MEMORY);
606*0a6a1f1dSLionel Sambuc }
607*0a6a1f1dSLionel Sambuc llbuf->ld_lopc = 0;
608*0a6a1f1dSLionel Sambuc llbuf->ld_hipc = ~0ULL;
609*0a6a1f1dSLionel Sambuc llbuf->ld_s = NULL;
610*0a6a1f1dSLionel Sambuc
611*0a6a1f1dSLionel Sambuc ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size,
612*0a6a1f1dSLionel Sambuc error);
613*0a6a1f1dSLionel Sambuc if (ret != DW_DLE_NONE) {
614*0a6a1f1dSLionel Sambuc free(llbuf);
615*0a6a1f1dSLionel Sambuc return (ret);
616*0a6a1f1dSLionel Sambuc }
617*0a6a1f1dSLionel Sambuc
618*0a6a1f1dSLionel Sambuc *ret_llbuf = llbuf;
619*0a6a1f1dSLionel Sambuc
620*0a6a1f1dSLionel Sambuc return (ret);
621*0a6a1f1dSLionel Sambuc }
622*0a6a1f1dSLionel Sambuc
623*0a6a1f1dSLionel Sambuc int
_dwarf_loc_add(Dwarf_Die die,Dwarf_Attribute at,Dwarf_Error * error)624*0a6a1f1dSLionel Sambuc _dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error)
625*0a6a1f1dSLionel Sambuc {
626*0a6a1f1dSLionel Sambuc Dwarf_Debug dbg;
627*0a6a1f1dSLionel Sambuc Dwarf_CU cu;
628*0a6a1f1dSLionel Sambuc int ret;
629*0a6a1f1dSLionel Sambuc
630*0a6a1f1dSLionel Sambuc assert(at->at_ld == NULL);
631*0a6a1f1dSLionel Sambuc assert(at->u[1].u8p != NULL);
632*0a6a1f1dSLionel Sambuc assert(at->u[0].u64 > 0);
633*0a6a1f1dSLionel Sambuc
634*0a6a1f1dSLionel Sambuc cu = die->die_cu;
635*0a6a1f1dSLionel Sambuc assert(cu != NULL);
636*0a6a1f1dSLionel Sambuc
637*0a6a1f1dSLionel Sambuc dbg = cu->cu_dbg;
638*0a6a1f1dSLionel Sambuc assert(dbg != NULL);
639*0a6a1f1dSLionel Sambuc
640*0a6a1f1dSLionel Sambuc ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p,
641*0a6a1f1dSLionel Sambuc at->u[0].u64, cu->cu_pointer_size, error);
642*0a6a1f1dSLionel Sambuc
643*0a6a1f1dSLionel Sambuc return (ret);
644*0a6a1f1dSLionel Sambuc }
645