1179187Sjb/*-
2179187Sjb * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3179187Sjb * All rights reserved.
4179187Sjb *
5179187Sjb * Redistribution and use in source and binary forms, with or without
6179187Sjb * modification, are permitted provided that the following conditions
7179187Sjb * are met:
8179187Sjb * 1. Redistributions of source code must retain the above copyright
9179187Sjb *    notice, this list of conditions and the following disclaimer.
10179187Sjb * 2. Redistributions in binary form must reproduce the above copyright
11179187Sjb *    notice, this list of conditions and the following disclaimer in the
12179187Sjb *    documentation and/or other materials provided with the distribution.
13179187Sjb *
14179187Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15179187Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16179187Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17179187Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18179187Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19179187Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20179187Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21179187Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22179187Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23179187Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24179187Sjb * SUCH DAMAGE.
25179187Sjb *
26179187Sjb * $FreeBSD$
27179187Sjb */
28179187Sjb
29179187Sjb#include <stdlib.h>
30179187Sjb#include "_libdwarf.h"
31179187Sjb
32179187Sjbstatic int64_t
33179187Sjbdwarf_decode_sleb128(uint8_t **dp)
34179187Sjb{
35179187Sjb	int64_t ret = 0;
36179187Sjb	uint8_t b;
37179187Sjb	int shift = 0;
38179187Sjb
39179187Sjb	uint8_t *src = *dp;
40179187Sjb
41179187Sjb	do {
42179187Sjb		b = *src++;
43179187Sjb
44179187Sjb		ret |= ((b & 0x7f) << shift);
45179187Sjb
46179187Sjb		shift += 7;
47179187Sjb	} while ((b & 0x80) != 0);
48179187Sjb
49179187Sjb	if (shift < 32 && (b & 0x40) != 0)
50179187Sjb		ret |= (-1 << shift);
51179187Sjb
52179187Sjb	*dp = src;
53179187Sjb
54179187Sjb	return ret;
55179187Sjb}
56179187Sjb
57179187Sjbstatic uint64_t
58179187Sjbdwarf_decode_uleb128(uint8_t **dp)
59179187Sjb{
60179187Sjb	uint64_t ret = 0;
61179187Sjb	uint8_t b;
62179187Sjb	int shift = 0;
63179187Sjb
64179187Sjb	uint8_t *src = *dp;
65179187Sjb
66179187Sjb	do {
67179187Sjb		b = *src++;
68179187Sjb
69179187Sjb		ret |= ((b & 0x7f) << shift);
70179187Sjb
71179187Sjb		shift += 7;
72179187Sjb	} while ((b & 0x80) != 0);
73179187Sjb
74179187Sjb	*dp = src;
75179187Sjb
76179187Sjb	return ret;
77179187Sjb}
78179187Sjb
79179187Sjb/*
80179187Sjb * Given an array of bytes of length 'len' representing a
81179187Sjb * DWARF expression, compute the number of operations based
82179187Sjb * on there being one byte describing the operation and
83179187Sjb * zero or more bytes of operands as defined in the standard
84179187Sjb * for each operation type.
85179187Sjb */
86179187Sjbint
87179187Sjbdwarf_op_num(uint8_t pointer_size, uint8_t *p, int len)
88179187Sjb{
89179187Sjb	int count = 0;
90179187Sjb	int64_t sval;
91179187Sjb	uint64_t uval;
92179187Sjb	uint8_t *last = p + len;
93179187Sjb
94179187Sjb	/*
95179187Sjb	 * Process each byte. If an error occurs, then the
96179187Sjb	 * count will be set to -1.
97179187Sjb	 */
98179187Sjb	while (p < last && count >= 0) {
99179187Sjb		count++;
100179187Sjb
101179187Sjb		switch (*p++) {
102179187Sjb		/* Operations with no operands. */
103179187Sjb		case DW_OP_deref:
104179187Sjb		case DW_OP_reg0:
105179187Sjb		case DW_OP_reg1:
106179187Sjb		case DW_OP_reg2:
107179187Sjb		case DW_OP_reg3:
108179187Sjb		case DW_OP_reg4:
109179187Sjb		case DW_OP_reg5:
110179187Sjb		case DW_OP_reg6:
111179187Sjb		case DW_OP_reg7:
112179187Sjb		case DW_OP_reg8:
113179187Sjb		case DW_OP_reg9:
114179187Sjb		case DW_OP_reg10:
115179187Sjb		case DW_OP_reg11:
116179187Sjb		case DW_OP_reg12:
117179187Sjb		case DW_OP_reg13:
118179187Sjb		case DW_OP_reg14:
119179187Sjb		case DW_OP_reg15:
120179187Sjb		case DW_OP_reg16:
121179187Sjb		case DW_OP_reg17:
122179187Sjb		case DW_OP_reg18:
123179187Sjb		case DW_OP_reg19:
124179187Sjb		case DW_OP_reg20:
125179187Sjb		case DW_OP_reg21:
126179187Sjb		case DW_OP_reg22:
127179187Sjb		case DW_OP_reg23:
128179187Sjb		case DW_OP_reg24:
129179187Sjb		case DW_OP_reg25:
130179187Sjb		case DW_OP_reg26:
131179187Sjb		case DW_OP_reg27:
132179187Sjb		case DW_OP_reg28:
133179187Sjb		case DW_OP_reg29:
134179187Sjb		case DW_OP_reg30:
135179187Sjb		case DW_OP_reg31:
136179187Sjb
137179187Sjb		case DW_OP_lit0:
138179187Sjb		case DW_OP_lit1:
139179187Sjb		case DW_OP_lit2:
140179187Sjb		case DW_OP_lit3:
141179187Sjb		case DW_OP_lit4:
142179187Sjb		case DW_OP_lit5:
143179187Sjb		case DW_OP_lit6:
144179187Sjb		case DW_OP_lit7:
145179187Sjb		case DW_OP_lit8:
146179187Sjb		case DW_OP_lit9:
147179187Sjb		case DW_OP_lit10:
148179187Sjb		case DW_OP_lit11:
149179187Sjb		case DW_OP_lit12:
150179187Sjb		case DW_OP_lit13:
151179187Sjb		case DW_OP_lit14:
152179187Sjb		case DW_OP_lit15:
153179187Sjb		case DW_OP_lit16:
154179187Sjb		case DW_OP_lit17:
155179187Sjb		case DW_OP_lit18:
156179187Sjb		case DW_OP_lit19:
157179187Sjb		case DW_OP_lit20:
158179187Sjb		case DW_OP_lit21:
159179187Sjb		case DW_OP_lit22:
160179187Sjb		case DW_OP_lit23:
161179187Sjb		case DW_OP_lit24:
162179187Sjb		case DW_OP_lit25:
163179187Sjb		case DW_OP_lit26:
164179187Sjb		case DW_OP_lit27:
165179187Sjb		case DW_OP_lit28:
166179187Sjb		case DW_OP_lit29:
167179187Sjb		case DW_OP_lit30:
168179187Sjb		case DW_OP_lit31:
169179187Sjb
170179187Sjb		case DW_OP_dup:
171179187Sjb		case DW_OP_drop:
172179187Sjb
173179187Sjb		case DW_OP_over:
174179187Sjb
175179187Sjb		case DW_OP_swap:
176179187Sjb		case DW_OP_rot:
177179187Sjb		case DW_OP_xderef:
178179187Sjb
179179187Sjb		case DW_OP_abs:
180179187Sjb		case DW_OP_and:
181179187Sjb		case DW_OP_div:
182179187Sjb		case DW_OP_minus:
183179187Sjb		case DW_OP_mod:
184179187Sjb		case DW_OP_mul:
185179187Sjb		case DW_OP_neg:
186179187Sjb		case DW_OP_not:
187179187Sjb		case DW_OP_or:
188179187Sjb		case DW_OP_plus:
189179187Sjb
190179187Sjb		case DW_OP_shl:
191179187Sjb		case DW_OP_shr:
192179187Sjb		case DW_OP_shra:
193179187Sjb		case DW_OP_xor:
194179187Sjb
195179187Sjb		case DW_OP_eq:
196179187Sjb		case DW_OP_ge:
197179187Sjb		case DW_OP_gt:
198179187Sjb		case DW_OP_le:
199179187Sjb		case DW_OP_lt:
200179187Sjb		case DW_OP_ne:
201179187Sjb
202179187Sjb		case DW_OP_nop:
203179187Sjb			break;
204179187Sjb
205179187Sjb		/* Operations with 1-byte operands. */
206179187Sjb		case DW_OP_const1u:
207179187Sjb		case DW_OP_const1s:
208179187Sjb		case DW_OP_pick:
209179187Sjb		case DW_OP_deref_size:
210179187Sjb		case DW_OP_xderef_size:
211179187Sjb			p++;
212179187Sjb			break;
213179187Sjb
214179187Sjb		/* Operations with 2-byte operands. */
215179187Sjb		case DW_OP_const2u:
216179187Sjb		case DW_OP_const2s:
217179187Sjb		case DW_OP_bra:
218179187Sjb		case DW_OP_skip:
219179187Sjb			p += 2;
220179187Sjb			break;
221179187Sjb
222179187Sjb		/* Operations with 4-byte operands. */
223179187Sjb		case DW_OP_const4u:
224179187Sjb		case DW_OP_const4s:
225179187Sjb			p += 4;
226179187Sjb			break;
227179187Sjb
228179187Sjb		/* Operations with 8-byte operands. */
229179187Sjb		case DW_OP_const8u:
230179187Sjb		case DW_OP_const8s:
231179187Sjb			p += 8;
232179187Sjb			break;
233179187Sjb
234179187Sjb		/* Operations with an unsigned LEB128 operand. */
235179187Sjb		case DW_OP_constu:
236179187Sjb		case DW_OP_plus_uconst:
237179187Sjb		case DW_OP_regx:
238179187Sjb		case DW_OP_piece:
239195747Snp			uval = dwarf_decode_uleb128(&p);
240179187Sjb			break;
241179187Sjb
242179187Sjb		/* Operations with a signed LEB128 operand. */
243179187Sjb		case DW_OP_consts:
244179187Sjb		case DW_OP_breg0:
245179187Sjb		case DW_OP_breg1:
246179187Sjb		case DW_OP_breg2:
247179187Sjb		case DW_OP_breg3:
248179187Sjb		case DW_OP_breg4:
249179187Sjb		case DW_OP_breg5:
250179187Sjb		case DW_OP_breg6:
251179187Sjb		case DW_OP_breg7:
252179187Sjb		case DW_OP_breg8:
253179187Sjb		case DW_OP_breg9:
254179187Sjb		case DW_OP_breg10:
255179187Sjb		case DW_OP_breg11:
256179187Sjb		case DW_OP_breg12:
257179187Sjb		case DW_OP_breg13:
258179187Sjb		case DW_OP_breg14:
259179187Sjb		case DW_OP_breg15:
260179187Sjb		case DW_OP_breg16:
261179187Sjb		case DW_OP_breg17:
262179187Sjb		case DW_OP_breg18:
263179187Sjb		case DW_OP_breg19:
264179187Sjb		case DW_OP_breg20:
265179187Sjb		case DW_OP_breg21:
266179187Sjb		case DW_OP_breg22:
267179187Sjb		case DW_OP_breg23:
268179187Sjb		case DW_OP_breg24:
269179187Sjb		case DW_OP_breg25:
270179187Sjb		case DW_OP_breg26:
271179187Sjb		case DW_OP_breg27:
272179187Sjb		case DW_OP_breg28:
273179187Sjb		case DW_OP_breg29:
274179187Sjb		case DW_OP_breg30:
275179187Sjb		case DW_OP_breg31:
276179187Sjb		case DW_OP_fbreg:
277179187Sjb			sval = dwarf_decode_sleb128(&p);
278179187Sjb			break;
279179187Sjb
280179187Sjb		/*
281179187Sjb		 * Operations with an unsigned LEB128 operand
282179187Sjb		 * followed by a signed LEB128 operand.
283179187Sjb		 */
284179187Sjb		case DW_OP_bregx:
285179187Sjb			uval = dwarf_decode_uleb128(&p);
286179187Sjb			sval = dwarf_decode_sleb128(&p);
287179187Sjb			break;
288179187Sjb
289179187Sjb		/* Target address size operand. */
290179187Sjb		case DW_OP_addr:
291179187Sjb			p += pointer_size;
292179187Sjb			break;
293179187Sjb
294179187Sjb		/* All other operations cause an error. */
295179187Sjb		default:
296179187Sjb			count = -1;
297179187Sjb			break;
298179187Sjb		}
299179187Sjb	}
300179187Sjb
301179187Sjb	return count;
302179187Sjb}
303179187Sjb
304179187Sjbstatic int
305179187Sjbdwarf_loc_fill(Dwarf_Locdesc *lbuf, uint8_t pointer_size, uint8_t *p, int len)
306179187Sjb{
307179187Sjb	int count = 0;
308179187Sjb	int ret = DWARF_E_NONE;
309179187Sjb	uint64_t operand1;
310179187Sjb	uint64_t operand2;
311179187Sjb	uint8_t *last = p + len;
312179187Sjb
313179187Sjb	/*
314179187Sjb	 * Process each byte. If an error occurs, then the
315179187Sjb	 * count will be set to -1.
316179187Sjb	 */
317179187Sjb	while (p < last && ret == DWARF_E_NONE) {
318179187Sjb		operand1 = 0;
319179187Sjb		operand2 = 0;
320179187Sjb
321179187Sjb		lbuf->ld_s[count].lr_atom = *p;
322179187Sjb
323179187Sjb		switch (*p++) {
324179187Sjb		/* Operations with no operands. */
325179187Sjb		case DW_OP_deref:
326179187Sjb		case DW_OP_reg0:
327179187Sjb		case DW_OP_reg1:
328179187Sjb		case DW_OP_reg2:
329179187Sjb		case DW_OP_reg3:
330179187Sjb		case DW_OP_reg4:
331179187Sjb		case DW_OP_reg5:
332179187Sjb		case DW_OP_reg6:
333179187Sjb		case DW_OP_reg7:
334179187Sjb		case DW_OP_reg8:
335179187Sjb		case DW_OP_reg9:
336179187Sjb		case DW_OP_reg10:
337179187Sjb		case DW_OP_reg11:
338179187Sjb		case DW_OP_reg12:
339179187Sjb		case DW_OP_reg13:
340179187Sjb		case DW_OP_reg14:
341179187Sjb		case DW_OP_reg15:
342179187Sjb		case DW_OP_reg16:
343179187Sjb		case DW_OP_reg17:
344179187Sjb		case DW_OP_reg18:
345179187Sjb		case DW_OP_reg19:
346179187Sjb		case DW_OP_reg20:
347179187Sjb		case DW_OP_reg21:
348179187Sjb		case DW_OP_reg22:
349179187Sjb		case DW_OP_reg23:
350179187Sjb		case DW_OP_reg24:
351179187Sjb		case DW_OP_reg25:
352179187Sjb		case DW_OP_reg26:
353179187Sjb		case DW_OP_reg27:
354179187Sjb		case DW_OP_reg28:
355179187Sjb		case DW_OP_reg29:
356179187Sjb		case DW_OP_reg30:
357179187Sjb		case DW_OP_reg31:
358179187Sjb
359179187Sjb		case DW_OP_lit0:
360179187Sjb		case DW_OP_lit1:
361179187Sjb		case DW_OP_lit2:
362179187Sjb		case DW_OP_lit3:
363179187Sjb		case DW_OP_lit4:
364179187Sjb		case DW_OP_lit5:
365179187Sjb		case DW_OP_lit6:
366179187Sjb		case DW_OP_lit7:
367179187Sjb		case DW_OP_lit8:
368179187Sjb		case DW_OP_lit9:
369179187Sjb		case DW_OP_lit10:
370179187Sjb		case DW_OP_lit11:
371179187Sjb		case DW_OP_lit12:
372179187Sjb		case DW_OP_lit13:
373179187Sjb		case DW_OP_lit14:
374179187Sjb		case DW_OP_lit15:
375179187Sjb		case DW_OP_lit16:
376179187Sjb		case DW_OP_lit17:
377179187Sjb		case DW_OP_lit18:
378179187Sjb		case DW_OP_lit19:
379179187Sjb		case DW_OP_lit20:
380179187Sjb		case DW_OP_lit21:
381179187Sjb		case DW_OP_lit22:
382179187Sjb		case DW_OP_lit23:
383179187Sjb		case DW_OP_lit24:
384179187Sjb		case DW_OP_lit25:
385179187Sjb		case DW_OP_lit26:
386179187Sjb		case DW_OP_lit27:
387179187Sjb		case DW_OP_lit28:
388179187Sjb		case DW_OP_lit29:
389179187Sjb		case DW_OP_lit30:
390179187Sjb		case DW_OP_lit31:
391179187Sjb
392179187Sjb		case DW_OP_dup:
393179187Sjb		case DW_OP_drop:
394179187Sjb
395179187Sjb		case DW_OP_over:
396179187Sjb
397179187Sjb		case DW_OP_swap:
398179187Sjb		case DW_OP_rot:
399179187Sjb		case DW_OP_xderef:
400179187Sjb
401179187Sjb		case DW_OP_abs:
402179187Sjb		case DW_OP_and:
403179187Sjb		case DW_OP_div:
404179187Sjb		case DW_OP_minus:
405179187Sjb		case DW_OP_mod:
406179187Sjb		case DW_OP_mul:
407179187Sjb		case DW_OP_neg:
408179187Sjb		case DW_OP_not:
409179187Sjb		case DW_OP_or:
410179187Sjb		case DW_OP_plus:
411179187Sjb
412179187Sjb		case DW_OP_shl:
413179187Sjb		case DW_OP_shr:
414179187Sjb		case DW_OP_shra:
415179187Sjb		case DW_OP_xor:
416179187Sjb
417179187Sjb		case DW_OP_eq:
418179187Sjb		case DW_OP_ge:
419179187Sjb		case DW_OP_gt:
420179187Sjb		case DW_OP_le:
421179187Sjb		case DW_OP_lt:
422179187Sjb		case DW_OP_ne:
423179187Sjb
424179187Sjb		case DW_OP_nop:
425179187Sjb			break;
426179187Sjb
427179187Sjb		/* Operations with 1-byte operands. */
428179187Sjb		case DW_OP_const1u:
429179187Sjb		case DW_OP_const1s:
430179187Sjb		case DW_OP_pick:
431179187Sjb		case DW_OP_deref_size:
432179187Sjb		case DW_OP_xderef_size:
433179187Sjb			operand1 = *p++;
434179187Sjb			break;
435179187Sjb
436179187Sjb		/* Operations with 2-byte operands. */
437179187Sjb		case DW_OP_const2u:
438179187Sjb		case DW_OP_const2s:
439179187Sjb		case DW_OP_bra:
440179187Sjb		case DW_OP_skip:
441179187Sjb			p += 2;
442179187Sjb			break;
443179187Sjb
444179187Sjb		/* Operations with 4-byte operands. */
445179187Sjb		case DW_OP_const4u:
446179187Sjb		case DW_OP_const4s:
447179187Sjb			p += 4;
448179187Sjb			break;
449179187Sjb
450179187Sjb		/* Operations with 8-byte operands. */
451179187Sjb		case DW_OP_const8u:
452179187Sjb		case DW_OP_const8s:
453179187Sjb			p += 8;
454179187Sjb			break;
455179187Sjb
456179187Sjb		/* Operations with an unsigned LEB128 operand. */
457179187Sjb		case DW_OP_constu:
458179187Sjb		case DW_OP_plus_uconst:
459179187Sjb		case DW_OP_regx:
460179187Sjb		case DW_OP_piece:
461195747Snp			operand1 = dwarf_decode_uleb128(&p);
462179187Sjb			break;
463179187Sjb
464179187Sjb		/* Operations with a signed LEB128 operand. */
465179187Sjb		case DW_OP_consts:
466179187Sjb		case DW_OP_breg0:
467179187Sjb		case DW_OP_breg1:
468179187Sjb		case DW_OP_breg2:
469179187Sjb		case DW_OP_breg3:
470179187Sjb		case DW_OP_breg4:
471179187Sjb		case DW_OP_breg5:
472179187Sjb		case DW_OP_breg6:
473179187Sjb		case DW_OP_breg7:
474179187Sjb		case DW_OP_breg8:
475179187Sjb		case DW_OP_breg9:
476179187Sjb		case DW_OP_breg10:
477179187Sjb		case DW_OP_breg11:
478179187Sjb		case DW_OP_breg12:
479179187Sjb		case DW_OP_breg13:
480179187Sjb		case DW_OP_breg14:
481179187Sjb		case DW_OP_breg15:
482179187Sjb		case DW_OP_breg16:
483179187Sjb		case DW_OP_breg17:
484179187Sjb		case DW_OP_breg18:
485179187Sjb		case DW_OP_breg19:
486179187Sjb		case DW_OP_breg20:
487179187Sjb		case DW_OP_breg21:
488179187Sjb		case DW_OP_breg22:
489179187Sjb		case DW_OP_breg23:
490179187Sjb		case DW_OP_breg24:
491179187Sjb		case DW_OP_breg25:
492179187Sjb		case DW_OP_breg26:
493179187Sjb		case DW_OP_breg27:
494179187Sjb		case DW_OP_breg28:
495179187Sjb		case DW_OP_breg29:
496179187Sjb		case DW_OP_breg30:
497179187Sjb		case DW_OP_breg31:
498179187Sjb		case DW_OP_fbreg:
499179187Sjb			operand1 = dwarf_decode_sleb128(&p);
500179187Sjb			break;
501179187Sjb
502179187Sjb		/*
503179187Sjb		 * Operations with an unsigned LEB128 operand
504179187Sjb		 * followed by a signed LEB128 operand.
505179187Sjb		 */
506179187Sjb		case DW_OP_bregx:
507179187Sjb			operand1 = dwarf_decode_uleb128(&p);
508179187Sjb			operand2 = dwarf_decode_sleb128(&p);
509179187Sjb			break;
510179187Sjb
511179187Sjb		/* Target address size operand. */
512179187Sjb		case DW_OP_addr:
513179187Sjb			p += pointer_size;
514179187Sjb			break;
515179187Sjb
516179187Sjb		/* All other operations cause an error. */
517179187Sjb		default:
518179187Sjb			break;
519179187Sjb		}
520179187Sjb
521179187Sjb		lbuf->ld_s[count].lr_number = operand1;
522179187Sjb		lbuf->ld_s[count].lr_number2 = operand2;
523179187Sjb
524179187Sjb		count++;
525179187Sjb	}
526179187Sjb
527179187Sjb	return ret;
528179187Sjb}
529179187Sjb
530179187Sjbint
531179187Sjbdwarf_locdesc(Dwarf_Die die, uint64_t attr, Dwarf_Locdesc **llbuf, Dwarf_Signed *lenp, Dwarf_Error *err)
532179187Sjb{
533179187Sjb	Dwarf_AttrValue av;
534179187Sjb	Dwarf_Locdesc *lbuf;
535179187Sjb	int num;
536179187Sjb	int ret = DWARF_E_NONE;
537179187Sjb
538179187Sjb	if (err == NULL)
539179187Sjb		return DWARF_E_ERROR;
540179187Sjb
541179187Sjb	if (die == NULL || llbuf == NULL || lenp == NULL) {
542179187Sjb		DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
543179187Sjb		return DWARF_E_ARGUMENT;
544179187Sjb	}
545179187Sjb
546179187Sjb	if ((av = dwarf_attrval_find(die, attr)) == NULL) {
547179187Sjb		DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
548179187Sjb		ret = DWARF_E_NO_ENTRY;
549179187Sjb	} else if ((lbuf = calloc(sizeof(Dwarf_Locdesc), 1)) == NULL) {
550179187Sjb		DWARF_SET_ERROR(err, DWARF_E_MEMORY);
551179187Sjb		ret = DWARF_E_MEMORY;
552179187Sjb	} else {
553179187Sjb		*lenp = 0;
554179187Sjb		switch (av->av_form) {
555179187Sjb		case DW_FORM_block:
556179187Sjb		case DW_FORM_block1:
557179187Sjb		case DW_FORM_block2:
558179187Sjb		case DW_FORM_block4:
559179187Sjb			/* Compute the number of locations: */
560179187Sjb			if ((num = dwarf_op_num(die->die_cu->cu_pointer_size,
561179187Sjb			    av->u[1].u8p, av->u[0].u64)) < 0) {
562179187Sjb				DWARF_SET_ERROR(err, DWARF_E_INVALID_EXPR);
563179187Sjb				ret = DWARF_E_INVALID_EXPR;
564179187Sjb
565179187Sjb			/* Allocate an array of location structures. */
566179187Sjb			} else if ((lbuf->ld_s =
567179187Sjb			    calloc(sizeof(Dwarf_Loc), num)) == NULL) {
568179187Sjb				DWARF_SET_ERROR(err, DWARF_E_MEMORY);
569179187Sjb				ret = DWARF_E_MEMORY;
570179187Sjb
571179187Sjb			/* Fill the array of location structures. */
572179187Sjb			} else if ((ret = dwarf_loc_fill(lbuf,
573179187Sjb			    die->die_cu->cu_pointer_size,
574179187Sjb			    av->u[1].u8p, av->u[0].u64)) != DWARF_E_NONE) {
575179187Sjb				free(lbuf->ld_s);
576179187Sjb			} else
577179187Sjb				/* Only one descriptor is returned. */
578179187Sjb				*lenp = 1;
579179187Sjb			break;
580179187Sjb		default:
581179187Sjb			printf("%s(%d): form %s not handled\n",__func__,
582179187Sjb			    __LINE__,get_form_desc(av->av_form));
583179187Sjb			DWARF_SET_ERROR(err, DWARF_E_NOT_IMPLEMENTED);
584179187Sjb			ret = DWARF_E_ERROR;
585179187Sjb		}
586179187Sjb
587179187Sjb		if (ret == DWARF_E_NONE) {
588179187Sjb			*llbuf = lbuf;
589179187Sjb		} else
590179187Sjb			free(lbuf);
591179187Sjb	}
592179187Sjb
593179187Sjb	return ret;
594179187Sjb}
595179187Sjb
596179187Sjbint
597179187Sjbdwarf_locdesc_free(Dwarf_Locdesc *lbuf, Dwarf_Error *err)
598179187Sjb{
599179187Sjb	if (err == NULL)
600179187Sjb		return DWARF_E_ERROR;
601179187Sjb
602179187Sjb	if (lbuf == NULL) {
603179187Sjb		DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
604179187Sjb		return DWARF_E_ARGUMENT;
605179187Sjb	}
606179187Sjb
607179187Sjb	if (lbuf->ld_s != NULL)
608179187Sjb		free(lbuf->ld_s);
609179187Sjb
610179187Sjb	free(lbuf);
611179187Sjb
612179187Sjb	return DWARF_E_NONE;
613179187Sjb}
614