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 (void)
40 struct dwarf_expr_context
*retval
;
41 retval
= xcalloc (1, sizeof (struct dwarf_expr_context
));
42 retval
->stack_len
= 0;
43 retval
->stack_allocated
= 10;
44 retval
->stack
= xmalloc (retval
->stack_allocated
* sizeof (CORE_ADDR
));
48 /* Release the memory allocated to CTX. */
51 free_dwarf_expr_context (struct dwarf_expr_context
*ctx
)
57 /* Expand the memory allocated to CTX's stack to contain at least
58 NEED more elements than are currently used. */
61 dwarf_expr_grow_stack (struct dwarf_expr_context
*ctx
, size_t need
)
63 if (ctx
->stack_len
+ need
> ctx
->stack_allocated
)
65 size_t newlen
= ctx
->stack_len
+ need
+ 10;
66 ctx
->stack
= xrealloc (ctx
->stack
,
67 newlen
* sizeof (CORE_ADDR
));
68 ctx
->stack_allocated
= newlen
;
72 /* Push VALUE onto CTX's stack. */
75 dwarf_expr_push (struct dwarf_expr_context
*ctx
, CORE_ADDR value
)
77 dwarf_expr_grow_stack (ctx
, 1);
78 ctx
->stack
[ctx
->stack_len
++] = value
;
81 /* Pop the top item off of CTX's stack. */
84 dwarf_expr_pop (struct dwarf_expr_context
*ctx
)
86 if (ctx
->stack_len
<= 0)
87 error ("dwarf expression stack underflow");
91 /* Retrieve the N'th item on CTX's stack. */
94 dwarf_expr_fetch (struct dwarf_expr_context
*ctx
, int n
)
96 if (ctx
->stack_len
< n
)
97 error ("Asked for position %d of stack, stack only has %d elements on it\n",
99 return ctx
->stack
[ctx
->stack_len
- (1 + n
)];
103 /* Evaluate the expression at ADDR (LEN bytes long) using the context
107 dwarf_expr_eval (struct dwarf_expr_context
*ctx
, unsigned char *addr
,
110 execute_stack_op (ctx
, addr
, addr
+ len
);
113 /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
114 by R, and return the new value of BUF. Verify that it doesn't extend
118 read_uleb128 (unsigned char *buf
, unsigned char *buf_end
, ULONGEST
* r
)
127 error ("read_uleb128: Corrupted DWARF expression.");
130 result
|= (byte
& 0x7f) << shift
;
131 if ((byte
& 0x80) == 0)
139 /* Decode the signed LEB128 constant at BUF into the variable pointed to
140 by R, and return the new value of BUF. Verify that it doesn't extend
144 read_sleb128 (unsigned char *buf
, unsigned char *buf_end
, LONGEST
* r
)
153 error ("read_sleb128: Corrupted DWARF expression.");
156 result
|= (byte
& 0x7f) << shift
;
158 if ((byte
& 0x80) == 0)
161 if (shift
< (sizeof (*r
) * 8) && (byte
& 0x40) != 0)
162 result
|= -(1 << shift
);
168 /* Read an address from BUF, and verify that it doesn't extend past
169 BUF_END. The address is returned, and *BYTES_READ is set to the
170 number of bytes read from BUF. */
173 dwarf2_read_address (unsigned char *buf
, unsigned char *buf_end
, int *bytes_read
)
177 if (buf_end
- buf
< TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
)
178 error ("dwarf2_read_address: Corrupted DWARF expression.");
180 *bytes_read
= TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
;
181 /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
182 address is always unsigned. That may or may not be true. */
183 result
= extract_unsigned_integer (buf
, TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
187 /* Return the type of an address, for unsigned arithmetic. */
190 unsigned_address_type (void)
192 switch (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
)
195 return builtin_type_uint16
;
197 return builtin_type_uint32
;
199 return builtin_type_uint64
;
201 internal_error (__FILE__
, __LINE__
,
202 "Unsupported address size.\n");
206 /* Return the type of an address, for signed arithmetic. */
209 signed_address_type (void)
211 switch (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
)
214 return builtin_type_int16
;
216 return builtin_type_int32
;
218 return builtin_type_int64
;
220 internal_error (__FILE__
, __LINE__
,
221 "Unsupported address size.\n");
225 /* The engine for the expression evaluator. Using the context in CTX,
226 evaluate the expression between OP_PTR and OP_END. */
229 execute_stack_op (struct dwarf_expr_context
*ctx
, unsigned char *op_ptr
,
230 unsigned char *op_end
)
234 while (op_ptr
< op_end
)
236 enum dwarf_location_atom op
= *op_ptr
++;
238 ULONGEST uoffset
, reg
;
276 result
= op
- DW_OP_lit0
;
280 result
= dwarf2_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 if (op_ptr
!= op_end
&& *op_ptr
!= DW_OP_piece
)
360 error ("DWARF-2 expression error: DW_OP_reg operations must be "
361 "used either alone or in conjuction with DW_OP_piece.");
363 result
= op
- DW_OP_reg0
;
369 op_ptr
= read_uleb128 (op_ptr
, op_end
, ®
);
370 if (op_ptr
!= op_end
&& *op_ptr
!= DW_OP_piece
)
371 error ("DWARF-2 expression error: DW_OP_reg operations must be "
372 "used either alone or in conjuction with DW_OP_piece.");
411 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
412 result
= (ctx
->read_reg
) (ctx
->baton
, op
- DW_OP_breg0
);
418 op_ptr
= read_uleb128 (op_ptr
, op_end
, ®
);
419 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
420 result
= (ctx
->read_reg
) (ctx
->baton
, reg
);
426 unsigned char *datastart
;
428 unsigned int before_stack_len
;
430 op_ptr
= read_sleb128 (op_ptr
, op_end
, &offset
);
431 /* Rather than create a whole new context, we simply
432 record the stack length before execution, then reset it
433 afterwards, effectively erasing whatever the recursive
435 before_stack_len
= ctx
->stack_len
;
436 /* FIXME: cagney/2003-03-26: This code should be using
437 get_frame_base_address(), and then implement a dwarf2
438 specific this_base method. */
439 (ctx
->get_frame_base
) (ctx
->baton
, &datastart
, &datalen
);
440 dwarf_expr_eval (ctx
, datastart
, datalen
);
441 result
= dwarf_expr_fetch (ctx
, 0);
443 result
= (ctx
->read_reg
) (ctx
->baton
, result
);
444 result
= result
+ offset
;
445 ctx
->stack_len
= before_stack_len
;
450 result
= dwarf_expr_fetch (ctx
, 0);
454 dwarf_expr_pop (ctx
);
459 result
= dwarf_expr_fetch (ctx
, offset
);
463 result
= dwarf_expr_fetch (ctx
, 1);
468 CORE_ADDR t1
, t2
, t3
;
470 if (ctx
->stack_len
< 3)
471 error ("Not enough elements for DW_OP_rot. Need 3, have %d\n",
473 t1
= ctx
->stack
[ctx
->stack_len
- 1];
474 t2
= ctx
->stack
[ctx
->stack_len
- 2];
475 t3
= ctx
->stack
[ctx
->stack_len
- 3];
476 ctx
->stack
[ctx
->stack_len
- 1] = t2
;
477 ctx
->stack
[ctx
->stack_len
- 2] = t3
;
478 ctx
->stack
[ctx
->stack_len
- 3] = t1
;
483 case DW_OP_deref_size
:
487 case DW_OP_plus_uconst
:
488 /* Unary operations. */
489 result
= dwarf_expr_fetch (ctx
, 0);
490 dwarf_expr_pop (ctx
);
496 char *buf
= alloca (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
499 (ctx
->read_mem
) (ctx
->baton
, buf
, result
,
500 TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
501 result
= dwarf2_read_address (buf
,
502 buf
+ (TARGET_ADDR_BIT
508 case DW_OP_deref_size
:
510 char *buf
= alloca (TARGET_ADDR_BIT
/ TARGET_CHAR_BIT
);
513 (ctx
->read_mem
) (ctx
->baton
, buf
, result
, *op_ptr
++);
514 result
= dwarf2_read_address (buf
,
515 buf
+ (TARGET_ADDR_BIT
522 if ((signed int) result
< 0)
531 case DW_OP_plus_uconst
:
532 op_ptr
= read_uleb128 (op_ptr
, op_end
, ®
);
556 /* Binary operations. Use the value engine to do computations in
558 CORE_ADDR first
, second
;
559 enum exp_opcode binop
;
560 struct value
*val1
, *val2
;
562 second
= dwarf_expr_fetch (ctx
, 0);
563 dwarf_expr_pop (ctx
);
565 first
= dwarf_expr_fetch (ctx
, 0);
566 dwarf_expr_pop (ctx
);
568 val1
= value_from_longest (unsigned_address_type (), first
);
569 val2
= value_from_longest (unsigned_address_type (), second
);
574 binop
= BINOP_BITWISE_AND
;
588 binop
= BINOP_BITWISE_IOR
;
600 val1
= value_from_longest (signed_address_type (), first
);
603 binop
= BINOP_BITWISE_XOR
;
621 binop
= BINOP_NOTEQUAL
;
624 internal_error (__FILE__
, __LINE__
,
625 "Can't be reached.");
627 result
= value_as_long (value_binop (val1
, val2
, binop
));
631 case DW_OP_GNU_push_tls_address
:
632 /* Variable is at a constant offset in the thread-local
633 storage block into the objfile for the current thread and
634 the dynamic linker module containing this expression. Here
635 we return returns the offset from that base. The top of the
636 stack has the offset from the beginning of the thread
637 control block at which the variable is located. Nothing
638 should follow this operator, so the top of stack would be
640 result
= dwarf_expr_fetch (ctx
, 0);
641 dwarf_expr_pop (ctx
);
642 result
= (ctx
->get_tls_address
) (ctx
->baton
, result
);
646 offset
= extract_signed_integer (op_ptr
, 2);
652 offset
= extract_signed_integer (op_ptr
, 2);
654 if (dwarf_expr_fetch (ctx
, 0) != 0)
656 dwarf_expr_pop (ctx
);
663 error ("Unhandled dwarf expression opcode 0x%x", op
);
666 /* Most things push a result value. */
667 dwarf_expr_push (ctx
, result
);