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