4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/lib/libdwarf/dwarf_loc.c,v 1.2.2.1 2009/08/03 08:13:06 kensmith Exp $
32 #include "_libdwarf.h"
35 dwarf_decode_sleb128(uint8_t **dp
)
46 ret
|= ((b
& 0x7f) << shift
);
49 } while ((b
& 0x80) != 0);
51 if (shift
< 32 && (b
& 0x40) != 0)
60 dwarf_decode_uleb128(uint8_t **dp
)
71 ret
|= ((b
& 0x7f) << shift
);
74 } while ((b
& 0x80) != 0);
82 * Given an array of bytes of length 'len' representing a
83 * DWARF expression, compute the number of operations based
84 * on there being one byte describing the operation and
85 * zero or more bytes of operands as defined in the standard
86 * for each operation type.
89 dwarf_op_num(uint8_t pointer_size
, uint8_t *p
, int len
)
94 uint8_t *last
= p
+ len
;
97 * Process each byte. If an error occurs, then the
98 * count will be set to -1.
100 while (p
< last
&& count
>= 0) {
104 /* Operations with no operands. */
207 /* Operations with 1-byte operands. */
211 case DW_OP_deref_size
:
212 case DW_OP_xderef_size
:
216 /* Operations with 2-byte operands. */
224 /* Operations with 4-byte operands. */
230 /* Operations with 8-byte operands. */
236 /* Operations with an unsigned LEB128 operand. */
238 case DW_OP_plus_uconst
:
241 uval
= dwarf_decode_uleb128(&p
);
244 /* Operations with a signed LEB128 operand. */
279 sval
= dwarf_decode_sleb128(&p
);
283 * Operations with an unsigned LEB128 operand
284 * followed by a signed LEB128 operand.
287 uval
= dwarf_decode_uleb128(&p
);
288 sval
= dwarf_decode_sleb128(&p
);
291 /* Target address size operand. */
296 /* All other operations cause an error. */
307 dwarf_loc_fill(Dwarf_Locdesc
*lbuf
, uint8_t pointer_size
, uint8_t *p
, int len
)
310 int ret
= DWARF_E_NONE
;
313 uint8_t *last
= p
+ len
;
316 * Process each byte. If an error occurs, then the
317 * count will be set to -1.
319 while (p
< last
&& ret
== DWARF_E_NONE
) {
323 lbuf
->ld_s
[count
].lr_atom
= *p
;
326 /* Operations with no operands. */
429 /* Operations with 1-byte operands. */
433 case DW_OP_deref_size
:
434 case DW_OP_xderef_size
:
438 /* Operations with 2-byte operands. */
446 /* Operations with 4-byte operands. */
452 /* Operations with 8-byte operands. */
458 /* Operations with an unsigned LEB128 operand. */
460 case DW_OP_plus_uconst
:
463 operand1
= dwarf_decode_uleb128(&p
);
466 /* Operations with a signed LEB128 operand. */
501 operand1
= dwarf_decode_sleb128(&p
);
505 * Operations with an unsigned LEB128 operand
506 * followed by a signed LEB128 operand.
509 operand1
= dwarf_decode_uleb128(&p
);
510 operand2
= dwarf_decode_sleb128(&p
);
513 /* Target address size operand. */
518 /* All other operations cause an error. */
523 lbuf
->ld_s
[count
].lr_number
= operand1
;
524 lbuf
->ld_s
[count
].lr_number2
= operand2
;
533 dwarf_locdesc(Dwarf_Die die
, uint64_t attr
, Dwarf_Locdesc
**llbuf
, Dwarf_Signed
*lenp
, Dwarf_Error
*err
)
538 int ret
= DWARF_E_NONE
;
541 return DWARF_E_ERROR
;
543 if (die
== NULL
|| llbuf
== NULL
|| lenp
== NULL
) {
544 DWARF_SET_ERROR(err
, DWARF_E_ARGUMENT
);
545 return DWARF_E_ARGUMENT
;
548 if ((av
= dwarf_attrval_find(die
, attr
)) == NULL
) {
549 DWARF_SET_ERROR(err
, DWARF_E_NO_ENTRY
);
550 ret
= DWARF_E_NO_ENTRY
;
551 } else if ((lbuf
= calloc(sizeof(Dwarf_Locdesc
), 1)) == NULL
) {
552 DWARF_SET_ERROR(err
, DWARF_E_MEMORY
);
553 ret
= DWARF_E_MEMORY
;
556 switch (av
->av_form
) {
561 /* Compute the number of locations: */
562 if ((num
= dwarf_op_num(die
->die_cu
->cu_pointer_size
,
563 av
->u
[1].u8p
, av
->u
[0].u64
)) < 0) {
564 DWARF_SET_ERROR(err
, DWARF_E_INVALID_EXPR
);
565 ret
= DWARF_E_INVALID_EXPR
;
567 /* Allocate an array of location structures. */
568 } else if ((lbuf
->ld_s
=
569 calloc(sizeof(Dwarf_Loc
), num
)) == NULL
) {
570 DWARF_SET_ERROR(err
, DWARF_E_MEMORY
);
571 ret
= DWARF_E_MEMORY
;
573 /* Fill the array of location structures. */
574 } else if ((ret
= dwarf_loc_fill(lbuf
,
575 die
->die_cu
->cu_pointer_size
,
576 av
->u
[1].u8p
, av
->u
[0].u64
)) != DWARF_E_NONE
) {
579 /* Only one descriptor is returned. */
583 printf("%s(%d): form %s not handled\n",__func__
,
584 __LINE__
,get_form_desc(av
->av_form
));
585 DWARF_SET_ERROR(err
, DWARF_E_NOT_IMPLEMENTED
);
589 if (ret
== DWARF_E_NONE
) {
599 dwarf_locdesc_free(Dwarf_Locdesc
*lbuf
, Dwarf_Error
*err
)
602 return DWARF_E_ERROR
;
605 DWARF_SET_ERROR(err
, DWARF_E_ARGUMENT
);
606 return DWARF_E_ARGUMENT
;
609 if (lbuf
->ld_s
!= NULL
)