diff options
author | Doug Evans <dje@google.com> | 2009-09-15 16:20:53 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2009-09-15 16:20:53 +0000 |
commit | 44353522ecb0bfbddc5670741e5e8a3f7ae8d2e6 (patch) | |
tree | c313a1ee9d6ba6f9709239eb7aaf324123f19a4d /gdb/dwarf2expr.c | |
parent | 7d4f32d36af917e1f2662f204146b808bbbbf8f2 (diff) | |
download | gdb-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.c | 49 |
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:; } |