aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2expr.c
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2009-09-15 16:20:53 +0000
committerDoug Evans <dje@google.com>2009-09-15 16:20:53 +0000
commit44353522ecb0bfbddc5670741e5e8a3f7ae8d2e6 (patch)
treec313a1ee9d6ba6f9709239eb7aaf324123f19a4d /gdb/dwarf2expr.c
parent7d4f32d36af917e1f2662f204146b808bbbbf8f2 (diff)
downloadgdb-44353522ecb0bfbddc5670741e5e8a3f7ae8d2e6.zip
gdb-44353522ecb0bfbddc5670741e5e8a3f7ae8d2e6.tar.gz
gdb-44353522ecb0bfbddc5670741e5e8a3f7ae8d2e6.tar.bz2
* dwarf2expr.h (dwarf_value_location): Add more comments describing
enum values. (struct dwarf_stack_value): New struct. (struct dwarf_expr_context): Change type of `stack' from CORE_ADDR* to struct dwarf_stack_value*. (struct dwarf_expr_piece): Move `v.value' into its own struct, v.expr, all uses updated. Add v.expr.in_stack_memory. (dwarf_expr_push): Update declaration. (dwarf_expr_fetch_in_stack_memory): Declare. * dwarf2expr.c (dwarf_expr_grow_stack): Update calculation of size of stack value. (dwarf_expr_push): New arg in_stack_memory, all callers updated. (dwarf_expr_fetch_in_stack_memory): New function. (add_piece): Set in_stack_memory for non-literal values. (execute_stack_op): Allow ops to specify whether the value is on the program's stack. (execute_stack_op, case DW_OP_fbreg): Mark value as in stack memory. (execute_stack_op, case DW_OP_call_frame_cfa): Ditto. (execute_stack_op, case DW_OP_dup): Copy in_stack_memory flag. (execute_stack_op, cases DW_OP_pick, DW_OP_over): Ditto. (execute_stack_op, cases DW_OP_swap, DW_OP_rot): Update type of dwarf stack value. * dwarf2loc.c (read_pieced_value): Call read_stack for values known to be on the program's stack. (dwarf2_evaluate_loc_desc, case DWARF_VALUE_MEMORY): Call set_value_stack only for objects known to be in stack memory. * dwarf2-frame.c (execute_stack_op): New arg initial_in_stack_memory, all callers updated.
Diffstat (limited to 'gdb/dwarf2expr.c')
-rw-r--r--gdb/dwarf2expr.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 2b0f585..46bc9d7 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -87,7 +87,7 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
{
size_t newlen = ctx->stack_len + need + 10;
ctx->stack = xrealloc (ctx->stack,
- newlen * sizeof (CORE_ADDR));
+ newlen * sizeof (struct dwarf_stack_value));
ctx->stack_allocated = newlen;
}
}
@@ -95,10 +95,15 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
/* Push VALUE onto CTX's stack. */
void
-dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value)
+dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value,
+ int in_stack_memory)
{
+ struct dwarf_stack_value *v;
+
dwarf_expr_grow_stack (ctx, 1);
- ctx->stack[ctx->stack_len++] = value;
+ v = &ctx->stack[ctx->stack_len++];
+ v->value = value;
+ v->in_stack_memory = in_stack_memory;
}
/* Pop the top item off of CTX's stack. */
@@ -119,7 +124,19 @@ dwarf_expr_fetch (struct dwarf_expr_context *ctx, int 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)];
+ return ctx->stack[ctx->stack_len - (1 + n)].value;
+
+}
+
+/* Retrieve the in_stack_memory flag of the N'th item on CTX's stack. */
+
+int
+dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int 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)].in_stack_memory;
}
@@ -148,7 +165,10 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size)
p->v.literal.length = ctx->len;
}
else
- p->v.value = dwarf_expr_fetch (ctx, 0);
+ {
+ p->v.expr.value = dwarf_expr_fetch (ctx, 0);
+ p->v.expr.in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
+ }
}
/* Evaluate the expression at ADDR (LEN bytes long) using the context
@@ -329,6 +349,13 @@ execute_stack_op (struct dwarf_expr_context *ctx,
{
enum dwarf_location_atom op = *op_ptr++;
CORE_ADDR result;
+ /* Assume the value is not in stack memory.
+ Code that knows otherwise sets this to 1.
+ Some arithmetic on stack addresses can probably be assumed to still
+ be a stack address, but we skip this complication for now.
+ This is just an optimization, so it's always ok to punt
+ and leave this as 0. */
+ int in_stack_memory = 0;
ULONGEST uoffset, reg;
LONGEST offset;
@@ -557,12 +584,15 @@ execute_stack_op (struct dwarf_expr_context *ctx,
if (ctx->location == DWARF_VALUE_REGISTER)
result = (ctx->read_reg) (ctx->baton, result);
result = result + offset;
+ in_stack_memory = 1;
ctx->stack_len = before_stack_len;
ctx->location = DWARF_VALUE_MEMORY;
}
break;
+
case DW_OP_dup:
result = dwarf_expr_fetch (ctx, 0);
+ in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
break;
case DW_OP_drop:
@@ -572,11 +602,12 @@ execute_stack_op (struct dwarf_expr_context *ctx,
case DW_OP_pick:
offset = *op_ptr++;
result = dwarf_expr_fetch (ctx, offset);
+ in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, offset);
break;
case DW_OP_swap:
{
- CORE_ADDR t1, t2;
+ struct dwarf_stack_value t1, t2;
if (ctx->stack_len < 2)
error (_("Not enough elements for DW_OP_swap. Need 2, have %d."),
@@ -590,11 +621,12 @@ execute_stack_op (struct dwarf_expr_context *ctx,
case DW_OP_over:
result = dwarf_expr_fetch (ctx, 1);
+ in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 1);
break;
case DW_OP_rot:
{
- CORE_ADDR t1, t2, t3;
+ struct dwarf_stack_value t1, t2, t3;
if (ctx->stack_len < 3)
error (_("Not enough elements for DW_OP_rot. Need 3, have %d."),
@@ -758,6 +790,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
case DW_OP_call_frame_cfa:
result = (ctx->get_frame_cfa) (ctx->baton);
+ in_stack_memory = 1;
break;
case DW_OP_GNU_push_tls_address:
@@ -820,7 +853,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
}
/* Most things push a result value. */
- dwarf_expr_push (ctx, result);
+ dwarf_expr_push (ctx, result, in_stack_memory);
no_push:;
}