/* DWARF 2 Expression Evaluator.
- Copyright 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
Contributed by Daniel Berlin (dan@dberlin.org)
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "symtab.h"
static void execute_stack_op (struct dwarf_expr_context *,
gdb_byte *, gdb_byte *);
+static struct type *unsigned_address_type (void);
/* Create a new context for the expression evaluator. */
CORE_ADDR
dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
{
- if (ctx->stack_len < n)
+ if (ctx->stack_len <= n)
error (_("Asked for position %d of stack, stack only has %d elements on it."),
n, ctx->stack_len);
return ctx->stack[ctx->stack_len - (1 + n)];
{
CORE_ADDR result;
- if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+ if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
error (_("dwarf2_read_address: Corrupted DWARF expression."));
- *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
- /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
- address is always unsigned. That may or may not be true. */
- result = extract_unsigned_integer (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+ *bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+
+ /* For most architectures, calling extract_unsigned_integer() alone
+ is sufficient for extracting an address. However, some
+ architectures (e.g. MIPS) use signed addresses and using
+ extract_unsigned_integer() will not produce a correct
+ result. Turning the unsigned integer into a value and then
+ decomposing that value as an address will cause
+ gdbarch_integer_to_address() to be invoked for those
+ architectures which require it. Thus, using value_as_address()
+ will produce the correct result for both types of architectures.
+
+ One concern regarding the use of values for this purpose is
+ efficiency. Obviously, these extra calls will take more time to
+ execute and creating a value takes more space, space which will
+ have to be garbage collected at a later time. If constructing
+ and then decomposing a value for this purpose proves to be too
+ inefficient, then gdbarch_integer_to_address() can be called
+ directly.
+
+ The use of `unsigned_address_type' in the code below refers to
+ the type of buf and has no bearing on the signedness of the
+ address being returned. */
+
+ result = value_as_address (value_from_longest
+ (unsigned_address_type (),
+ extract_unsigned_integer
+ (buf,
+ gdbarch_addr_bit (current_gdbarch)
+ / TARGET_CHAR_BIT)));
+
return result;
}
static struct type *
unsigned_address_type (void)
{
- switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+ switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
{
case 2:
return builtin_type_uint16;
static struct type *
signed_address_type (void)
{
- switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+ switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
{
case 2:
return builtin_type_int16;
gdb_byte *op_ptr, gdb_byte *op_end)
{
ctx->in_reg = 0;
+ ctx->initialized = 1; /* Default is initialized. */
while (op_ptr < op_end)
{
case DW_OP_reg29:
case DW_OP_reg30:
case DW_OP_reg31:
- if (op_ptr != op_end && *op_ptr != DW_OP_piece)
+ if (op_ptr != op_end
+ && *op_ptr != DW_OP_piece
+ && *op_ptr != DW_OP_GNU_uninit)
error (_("DWARF-2 expression error: DW_OP_reg operations must be "
"used either alone or in conjuction with DW_OP_piece."));
{
case DW_OP_deref:
{
- gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+ gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch)
+ / TARGET_CHAR_BIT);
int bytes_read;
(ctx->read_mem) (ctx->baton, buf, result,
- TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+ gdbarch_addr_bit (current_gdbarch)
+ / TARGET_CHAR_BIT);
result = dwarf2_read_address (buf,
- buf + (TARGET_ADDR_BIT
+ buf + (gdbarch_addr_bit
+ (current_gdbarch)
/ TARGET_CHAR_BIT),
&bytes_read);
}
case DW_OP_deref_size:
{
- gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+ gdb_byte *buf
+ = alloca (gdbarch_addr_bit (current_gdbarch)
+ / TARGET_CHAR_BIT);
int bytes_read;
(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
result = dwarf2_read_address (buf,
- buf + (TARGET_ADDR_BIT
+ buf + (gdbarch_addr_bit
+ (current_gdbarch)
/ TARGET_CHAR_BIT),
&bytes_read);
}
}
goto no_push;
+ case DW_OP_GNU_uninit:
+ if (op_ptr != op_end)
+ error (_("DWARF-2 expression error: DW_OP_GNU_unint must always "
+ "be the very last op."));
+
+ ctx->initialized = 0;
+ goto no_push;
+
default:
error (_("Unhandled dwarf expression opcode 0x%x"), op);
}