/* Local prototypes. */
static void execute_stack_op (struct dwarf_expr_context *,
- gdb_byte *, gdb_byte *);
+ const gdb_byte *, const gdb_byte *);
static struct type *unsigned_address_type (struct gdbarch *, int);
/* Create a new context for the expression evaluator. */
new_dwarf_expr_context (void)
{
struct dwarf_expr_context *retval;
+
retval = xcalloc (1, sizeof (struct dwarf_expr_context));
retval->stack_len = 0;
retval->stack_allocated = 10;
if (ctx->stack_len + need > ctx->stack_allocated)
{
size_t newlen = ctx->stack_len + need + 10;
+
ctx->stack = xrealloc (ctx->stack,
newlen * sizeof (struct dwarf_stack_value));
ctx->stack_allocated = newlen;
}
+/* Return true if the expression stack is empty. */
+
+static int
+dwarf_expr_stack_empty_p (struct dwarf_expr_context *ctx)
+{
+ return ctx->stack_len == 0;
+}
+
/* Add a new piece to CTX's piece list. */
static void
-add_piece (struct dwarf_expr_context *ctx, ULONGEST size)
+add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset)
{
struct dwarf_expr_piece *p;
ctx->num_pieces++;
- if (ctx->pieces)
- ctx->pieces = xrealloc (ctx->pieces,
- (ctx->num_pieces
- * sizeof (struct dwarf_expr_piece)));
- else
- ctx->pieces = xmalloc (ctx->num_pieces
- * sizeof (struct dwarf_expr_piece));
+ ctx->pieces = xrealloc (ctx->pieces,
+ (ctx->num_pieces
+ * sizeof (struct dwarf_expr_piece)));
p = &ctx->pieces[ctx->num_pieces - 1];
p->location = ctx->location;
p->size = size;
+ p->offset = offset;
+
if (p->location == DWARF_VALUE_LITERAL)
{
p->v.literal.data = ctx->data;
p->v.literal.length = ctx->len;
}
+ else if (dwarf_expr_stack_empty_p (ctx))
+ {
+ p->location = DWARF_VALUE_OPTIMIZED_OUT;
+ /* Also reset the context's location, for our callers. This is
+ a somewhat strange approach, but this lets us avoid setting
+ the location to DWARF_VALUE_MEMORY in all the individual
+ cases in the evaluator. */
+ ctx->location = DWARF_VALUE_OPTIMIZED_OUT;
+ }
else
{
p->v.expr.value = dwarf_expr_fetch (ctx, 0);
CTX. */
void
-dwarf_expr_eval (struct dwarf_expr_context *ctx, gdb_byte *addr, size_t len)
+dwarf_expr_eval (struct dwarf_expr_context *ctx, const gdb_byte *addr,
+ size_t len)
{
int old_recursion_depth = ctx->recursion_depth;
by R, and return the new value of BUF. Verify that it doesn't extend
past BUF_END. */
-gdb_byte *
-read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r)
+const gdb_byte *
+read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end, ULONGEST * r)
{
unsigned shift = 0;
ULONGEST result = 0;
by R, and return the new value of BUF. Verify that it doesn't extend
past BUF_END. */
-gdb_byte *
-read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r)
+const gdb_byte *
+read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end, LONGEST * r)
{
unsigned shift = 0;
LONGEST result = 0;
doesn't extend past BUF_END. */
CORE_ADDR
-dwarf2_read_address (struct gdbarch *gdbarch, gdb_byte *buf,
- gdb_byte *buf_end, int addr_size)
+dwarf2_read_address (struct gdbarch *gdbarch, const gdb_byte *buf,
+ const gdb_byte *buf_end, int addr_size)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR result;
if (buf_end - buf < addr_size)
error (_("dwarf2_read_address: Corrupted DWARF expression."));
expression, or that it is followed by a composition operator. */
static void
-require_composition (gdb_byte *op_ptr, gdb_byte *op_end, const char *op_name)
+require_composition (const gdb_byte *op_ptr, const gdb_byte *op_end,
+ const char *op_name)
{
/* It seems like DW_OP_GNU_uninit should be handled here. However,
it doesn't seem to make sense for DW_OP_*_value, and it was not
static void
execute_stack_op (struct dwarf_expr_context *ctx,
- gdb_byte *op_ptr, gdb_byte *op_end)
+ const gdb_byte *op_ptr, const gdb_byte *op_end)
{
enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
+
ctx->location = DWARF_VALUE_MEMORY;
ctx->initialized = 1; /* Default is initialized. */
case DW_OP_reg31:
if (op_ptr != op_end
&& *op_ptr != DW_OP_piece
+ && *op_ptr != DW_OP_bit_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."));
+ "used either alone or in conjuction with DW_OP_piece "
+ "or DW_OP_bit_piece."));
result = op - DW_OP_reg0;
ctx->location = DWARF_VALUE_REGISTER;
case DW_OP_implicit_value:
{
ULONGEST len;
+
op_ptr = read_uleb128 (op_ptr, op_end, &len);
if (op_ptr + len > op_end)
error (_("DW_OP_implicit_value: too few bytes available."));
break;
case DW_OP_fbreg:
{
- gdb_byte *datastart;
+ const gdb_byte *datastart;
size_t datalen;
unsigned int before_stack_len;
case DW_OP_deref:
{
gdb_byte *buf = alloca (ctx->addr_size);
+
(ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size);
result = dwarf2_read_address (ctx->gdbarch,
buf, buf + ctx->addr_size,
{
int addr_size = *op_ptr++;
gdb_byte *buf = alloca (addr_size);
+
(ctx->read_mem) (ctx->baton, buf, result, addr_size);
result = dwarf2_read_address (ctx->gdbarch,
buf, buf + addr_size,
/* Record the piece. */
op_ptr = read_uleb128 (op_ptr, op_end, &size);
- add_piece (ctx, size);
+ add_piece (ctx, 8 * size, 0);
/* Pop off the address/regnum, and reset the location
type. */
- if (ctx->location != DWARF_VALUE_LITERAL)
+ if (ctx->location != DWARF_VALUE_LITERAL
+ && ctx->location != DWARF_VALUE_OPTIMIZED_OUT)
dwarf_expr_pop (ctx);
ctx->location = DWARF_VALUE_MEMORY;
}
goto no_push;
+ case DW_OP_bit_piece:
+ {
+ ULONGEST size, offset;
+
+ /* Record the piece. */
+ op_ptr = read_uleb128 (op_ptr, op_end, &size);
+ op_ptr = read_uleb128 (op_ptr, op_end, &offset);
+ add_piece (ctx, size, offset);
+
+ /* Pop off the address/regnum, and reset the location
+ type. */
+ if (ctx->location != DWARF_VALUE_LITERAL
+ && ctx->location != DWARF_VALUE_OPTIMIZED_OUT)
+ dwarf_expr_pop (ctx);
+ ctx->location = DWARF_VALUE_MEMORY;
+ }
+ goto no_push;
+
case DW_OP_GNU_uninit:
if (op_ptr != op_end)
error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always "