/* DWARF 2 Expression Evaluator.
- Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008
+ Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Daniel Berlin (dan@dberlin.org)
doesn't extend past BUF_END. */
CORE_ADDR
-dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size)
+dwarf2_read_address (struct gdbarch *gdbarch, gdb_byte *buf,
+ gdb_byte *buf_end, int addr_size)
{
CORE_ADDR result;
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.
+ result. Make sure we invoke gdbarch_integer_to_address()
+ for those architectures which require it.
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 (addr_size),
- extract_unsigned_integer (buf, addr_size)));
- return result;
+ if (gdbarch_integer_to_address_p (gdbarch))
+ return gdbarch_integer_to_address
+ (gdbarch, unsigned_address_type (addr_size), buf);
+
+ return extract_unsigned_integer (buf, addr_size);
}
/* Return the type of an address of size ADDR_SIZE,
break;
case DW_OP_addr:
- result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size);
+ result = dwarf2_read_address (ctx->gdbarch,
+ op_ptr, op_end, ctx->addr_size);
op_ptr += ctx->addr_size;
break;
offset = *op_ptr++;
result = dwarf_expr_fetch (ctx, offset);
break;
+
+ case DW_OP_swap:
+ {
+ CORE_ADDR t1, t2;
+
+ if (ctx->stack_len < 2)
+ error (_("Not enough elements for DW_OP_swap. Need 2, have %d."),
+ ctx->stack_len);
+ t1 = ctx->stack[ctx->stack_len - 1];
+ t2 = ctx->stack[ctx->stack_len - 2];
+ ctx->stack[ctx->stack_len - 1] = t2;
+ ctx->stack[ctx->stack_len - 2] = t1;
+ goto no_push;
+ }
case DW_OP_over:
result = dwarf_expr_fetch (ctx, 1);
{
gdb_byte *buf = alloca (ctx->addr_size);
(ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size);
- result = dwarf2_read_address (buf, buf + ctx->addr_size,
+ result = dwarf2_read_address (ctx->gdbarch,
+ buf, buf + ctx->addr_size,
ctx->addr_size);
}
break;
int addr_size = *op_ptr++;
gdb_byte *buf = alloca (addr_size);
(ctx->read_mem) (ctx->baton, buf, result, addr_size);
- result = dwarf2_read_address (buf, buf + addr_size,
+ result = dwarf2_read_address (ctx->gdbarch,
+ buf, buf + addr_size,
addr_size);
}
break;
case DW_OP_GNU_uninit:
if (op_ptr != op_end)
- error (_("DWARF-2 expression error: DW_OP_GNU_unint must always "
+ error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always "
"be the very last op."));
ctx->initialized = 0;