1 /* Dwarf2 Expression Evaluator
2 Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin (dan@dberlin.org)
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 #include "elf/dwarf2.h"
28 #include "dwarf2expr.h"
30 /* Local prototypes. */
32 static void execute_stack_op (struct dwarf_expr_context
*,
33 unsigned char *, unsigned char *);
35 /* Create a new context for the expression evaluator. */
37 struct dwarf_expr_context
*
38 new_dwarf_expr_context ()
40 struct dwarf_expr_context
*retval
;
41 retval
= xcalloc (1, sizeof (struct dwarf_expr_context
));
42 retval
->stack_len
= 10;
43 retval
->stack
= xmalloc (10 * sizeof (CORE_ADDR
));
47 /* Release the memory allocated to CTX. */
50 free_dwarf_expr_context (struct dwarf_expr_context
*ctx
)
56 /* Expand the memory allocated to CTX's stack to contain at least
57 NEED more elements than are currently used. */
60 dwarf_expr_grow_stack (struct dwarf_expr_context
*ctx
, size_t need
)
62 if (ctx
->stack_len
+ need
> ctx
->stack_allocated
)
64 size_t templen
= ctx
->stack_len
* 2;
65 while (templen
< (ctx
->stack_len
+ need
))
67 ctx
->stack
= xrealloc (ctx
->stack
,
68 templen
* sizeof (CORE_ADDR
));
69 ctx
->stack_allocated
= templen
;
73 /* Push VALUE onto CTX's stack. */
76 dwarf_expr_push (struct dwarf_expr_context
*ctx
, CORE_ADDR value
)
78 dwarf_expr_grow_stack (ctx
, 1);
79 ctx
->stack
[ctx
->stack_len
++] = value
;
82 /* Pop the top item off of CTX's stack. */
85 dwarf_expr_pop (struct dwarf_expr_context
*ctx
)
87 if (ctx
->stack_len
<= 0)
88 error ("dwarf expression stack underflow");
92 /* Retrieve the N'th item on CTX's stack. */
95 dwarf_expr_fetch (struct dwarf_expr_context
*ctx
, int n
)
97 if (ctx
->stack_len
< n
)
98 error ("Asked for position %d of stack, stack only has %d elements on it\n",
100 return ctx
->stack
[ctx
->stack_len
- (1 + n
)];
104 /* Evaluate the expression at ADDR (LEN bytes long) using the context
108 dwarf_expr_eval (struct dwarf_expr_context
*ctx
, unsigned char *addr
,
111 execute_stack_op (ctx
, addr
, addr
+ len
);
114 /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
115 by R, and return the new value of BUF. Verify that it doesn't extend
118 static unsigned char *
119 read_uleb128 (unsigned char *buf
, unsigned char *buf_end
, ULONGEST
* r
)
128 error ("read_uleb128: Corrupted DWARF expression.");
131 result
|= (byte
& 0x7f) << shift
;
132 if ((byte
& 0x80) == 0)
140 /* Decode the signed LEB128 constant at BUF into the variable pointed to
141 by R, and return the new value of BUF. Verify that it doesn't extend
144 static unsigned char *
145 read_sleb128 (unsigned char *buf
, unsigned char *buf_end
, LONGEST
* r
)
154 error ("read_sleb128: Corrupted DWARF expression.");
157 result
|= (byte
& 0x7f) << shift
;
159 if ((byte
& 0x80) == 0)
162 if (shift
< (sizeof (*r
) * 8) && (byte
& 0x40) != 0)
163 result
|= -(1 << shift
);
169 /* Read an address from BUF, and verify that it doesn't extend past
170 BUF_END. The address is returned, and *BYTES_READ is set to the
171 number of bytes read from BUF. */
174 read_address (unsigned char *buf
, unsigned char *buf_end
, int *bytes_read
)
178 if (buf_end
- buf
< TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
)
179 error ("read_address: Corrupted DWARF expression.");
181 *bytes_read
= TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
;
182 result
= extract_address (buf
, TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
186 /* Return the type of an address, for unsigned arithmetic. */
189 unsigned_address_type (void)
191 switch (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
)
194 return builtin_type_uint16
;
196 return builtin_type_uint32
;
198 return builtin_type_uint64
;
200 internal_error (__FILE__
, __LINE__
,
201 "Unsupported address size.\n");
205 /* Return the type of an address, for signed arithmetic. */
208 signed_address_type (void)
210 switch (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
)
213 return builtin_type_int16
;
215 return builtin_type_int32
;
217 return builtin_type_int64
;
219 internal_error (__FILE__
, __LINE__
,
220 "Unsupported address size.\n");
224 /* The engine for the expression evaluator. Using the context in CTX,
225 evaluate the expression between OP_PTR and OP_END. */
228 execute_stack_op (struct dwarf_expr_context
*ctx
, unsigned char *op_ptr
,
229 unsigned char *op_end
)
231 while (op_ptr
< op_end
)
233 enum dwarf_location_atom op
= *op_ptr
++;
234 CORE_ADDR result
, memaddr
;
235 ULONGEST uoffset
, reg
;
238 enum lval_type expr_lval
;
276 result
= op
- DW_OP_lit0
;
280 result
= read_address (op_ptr
, op_end
, &bytes_read
);
281 op_ptr
+= bytes_read
;
285 result
= extract_unsigned_integer (op_ptr
, 1);
289 result
= extract_signed_integer (op_ptr
, 1);
293 result
= extract_unsigned_integer (op_ptr
, 2);
297 result
= extract_signed_integer (op_ptr
, 2);
301 result
= extract_unsigned_integer (op_ptr
, 4);
305 result
= extract_signed_integer (op_ptr
, 4);
309 result
= extract_unsigned_integer (op_ptr
, 8);
313 result
= extract_signed_integer (op_ptr
, 8);
317 op_ptr
= read_uleb128 (op_ptr
, op_end
, &uoffset
);
321 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
325 /* The DW_OP_reg operations are required to occur alone in
326 location expressions. */
359 /* NOTE: in the presence of DW_OP_piece this check is incorrect. */
360 if (op_ptr
!= op_end
)
361 error ("DWARF-2 expression error: DW_OP_reg operations must be "
364 /* FIXME drow/2003-02-21: This call to read_reg could be pushed
365 into the evaluator's caller by changing the semantics for in_reg.
366 Then we wouldn't need to return an lval_type and a memaddr. */
367 result
= (ctx
->read_reg
) (ctx
->baton
, op
- DW_OP_reg0
, &expr_lval
,
370 if (expr_lval
== lval_register
)
372 ctx
->regnum
= op
- DW_OP_reg0
;
381 op_ptr
= read_uleb128 (op_ptr
, op_end
, ®
);
382 if (op_ptr
!= op_end
)
383 error ("DWARF-2 expression error: DW_OP_reg operations must be "
386 result
= (ctx
->read_reg
) (ctx
->baton
, reg
, &expr_lval
, &memaddr
);
388 if (expr_lval
== lval_register
)
431 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
432 result
= (ctx
->read_reg
) (ctx
->baton
, op
- DW_OP_breg0
,
433 &expr_lval
, &memaddr
);
439 op_ptr
= read_uleb128 (op_ptr
, op_end
, ®
);
440 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
441 result
= (ctx
->read_reg
) (ctx
->baton
, reg
, &expr_lval
, &memaddr
);
447 unsigned char *datastart
;
449 unsigned int before_stack_len
;
451 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
452 /* Rather than create a whole new context, we simply
453 record the stack length before execution, then reset it
454 afterwards, effectively erasing whatever the recursive
456 before_stack_len
= ctx
->stack_len
;
457 (ctx
->get_frame_base
) (ctx
->baton
, &datastart
, &datalen
);
458 dwarf_expr_eval (ctx
, datastart
, datalen
);
459 result
= dwarf_expr_fetch (ctx
, 0);
462 char *buf
= alloca (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
465 (ctx
->read_mem
) (ctx
->baton
, buf
, result
,
466 TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
467 result
= read_address (buf
,
468 buf
+ TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
,
471 result
= result
+ offset
;
472 ctx
->stack_len
= before_stack_len
;
477 result
= dwarf_expr_fetch (ctx
, 0);
481 dwarf_expr_pop (ctx
);
486 result
= dwarf_expr_fetch (ctx
, offset
);
490 result
= dwarf_expr_fetch (ctx
, 1);
495 CORE_ADDR t1
, t2
, t3
;
497 if (ctx
->stack_len
< 3)
498 error ("Not enough elements for DW_OP_rot. Need 3, have %d\n",
500 t1
= ctx
->stack
[ctx
->stack_len
- 1];
501 t2
= ctx
->stack
[ctx
->stack_len
- 2];
502 t3
= ctx
->stack
[ctx
->stack_len
- 3];
503 ctx
->stack
[ctx
->stack_len
- 1] = t2
;
504 ctx
->stack
[ctx
->stack_len
- 2] = t3
;
505 ctx
->stack
[ctx
->stack_len
- 3] = t1
;
510 case DW_OP_deref_size
:
514 case DW_OP_plus_uconst
:
515 /* Unary operations. */
516 result
= dwarf_expr_fetch (ctx
, 0);
517 dwarf_expr_pop (ctx
);
523 char *buf
= alloca (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
526 (ctx
->read_mem
) (ctx
->baton
, buf
, result
,
527 TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
528 result
= read_address (buf
,
529 buf
+ TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
,
534 case DW_OP_deref_size
:
536 char *buf
= alloca (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
539 (ctx
->read_mem
) (ctx
->baton
, buf
, result
, *op_ptr
++);
540 result
= read_address (buf
,
541 buf
+ TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
,
547 if ((signed int) result
< 0)
556 case DW_OP_plus_uconst
:
557 op_ptr
= read_uleb128 (op_ptr
, op_end
, ®
);
581 /* Binary operations. Use the value engine to do computations in
583 CORE_ADDR first
, second
;
584 enum exp_opcode binop
;
585 struct value
*val1
, *val2
;
587 second
= dwarf_expr_fetch (ctx
, 0);
588 dwarf_expr_pop (ctx
);
590 first
= dwarf_expr_fetch (ctx
, 1);
591 dwarf_expr_pop (ctx
);
593 val1
= value_from_longest (unsigned_address_type (), first
);
594 val2
= value_from_longest (unsigned_address_type (), second
);
599 binop
= BINOP_BITWISE_AND
;
613 binop
= BINOP_BITWISE_IOR
;
625 val1
= value_from_longest (signed_address_type (), first
);
628 binop
= BINOP_BITWISE_XOR
;
646 binop
= BINOP_NOTEQUAL
;
649 internal_error (__FILE__
, __LINE__
,
650 "Can't be reached.");
652 result
= value_as_long (value_binop (val1
, val2
, binop
));
656 case DW_OP_GNU_push_tls_address
:
657 result
= dwarf_expr_fetch (ctx
, 0);
658 dwarf_expr_pop (ctx
);
659 result
= (ctx
->get_tls_address
) (ctx
->baton
, result
);
663 offset
= extract_signed_integer (op_ptr
, 2);
669 offset
= extract_signed_integer (op_ptr
, 2);
671 if (dwarf_expr_fetch (ctx
, 0) != 0)
673 dwarf_expr_pop (ctx
);
680 error ("Unhandled dwarf expression opcode");
683 /* Most things push a result value. */
684 dwarf_expr_push (ctx
, result
);