2009-09-11 Doug Evans * 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 structd 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, case DW_OP_fbreg): Call dwarf_expr_push ourselves, mark value as in stack memory. (execute_stack_op, case DW_OP_call_frame_cfa): 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. Index: dwarf2-frame.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v retrieving revision 1.98 diff -u -p -r1.98 dwarf2-frame.c --- dwarf2-frame.c 11 Sep 2009 18:38:39 -0000 1.98 +++ dwarf2-frame.c 11 Sep 2009 22:56:06 -0000 @@ -357,7 +357,8 @@ register %s (#%d) at %s"), static CORE_ADDR execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size, - struct frame_info *this_frame, CORE_ADDR initial) + struct frame_info *this_frame, CORE_ADDR initial, + int initial_in_stack_memory) { struct dwarf_expr_context *ctx; CORE_ADDR result; @@ -375,7 +376,7 @@ execute_stack_op (gdb_byte *exp, ULONGES ctx->get_frame_cfa = no_get_frame_cfa; ctx->get_tls_address = no_get_tls_address; - dwarf_expr_push (ctx, initial); + dwarf_expr_push (ctx, initial, initial_in_stack_memory); dwarf_expr_eval (ctx, exp, len); result = dwarf_expr_fetch (ctx, 0); @@ -975,7 +976,7 @@ dwarf2_frame_cache (struct frame_info *t case CFA_EXP: cache->cfa = execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len, - cache->addr_size, this_frame, 0); + cache->addr_size, this_frame, 0, 0); break; default: @@ -1131,7 +1132,7 @@ dwarf2_frame_prev_register (struct frame case DWARF2_FRAME_REG_SAVED_EXP: addr = execute_stack_op (cache->reg[regnum].loc.exp, cache->reg[regnum].exp_len, - cache->addr_size, this_frame, cache->cfa); + cache->addr_size, this_frame, cache->cfa, 1); return frame_unwind_got_memory (this_frame, regnum, addr); case DWARF2_FRAME_REG_SAVED_VAL_OFFSET: @@ -1141,7 +1142,7 @@ dwarf2_frame_prev_register (struct frame case DWARF2_FRAME_REG_SAVED_VAL_EXP: addr = execute_stack_op (cache->reg[regnum].loc.exp, cache->reg[regnum].exp_len, - cache->addr_size, this_frame, cache->cfa); + cache->addr_size, this_frame, cache->cfa, 1); return frame_unwind_got_constant (this_frame, regnum, addr); case DWARF2_FRAME_REG_UNSPECIFIED: Index: dwarf2expr.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2expr.c,v retrieving revision 1.36 diff -u -p -r1.36 dwarf2expr.c --- dwarf2expr.c 11 Sep 2009 18:38:39 -0000 1.36 +++ dwarf2expr.c 11 Sep 2009 22:56:06 -0000 @@ -87,7 +87,7 @@ dwarf_expr_grow_stack (struct dwarf_expr { 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 /* 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_cont 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 *ct 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 @@ -559,8 +579,10 @@ execute_stack_op (struct dwarf_expr_cont result = result + offset; ctx->stack_len = before_stack_len; ctx->location = DWARF_VALUE_MEMORY; + dwarf_expr_push (ctx, result, 1); } - break; + goto no_push; /* already pushed */ + case DW_OP_dup: result = dwarf_expr_fetch (ctx, 0); break; @@ -576,7 +598,7 @@ execute_stack_op (struct dwarf_expr_cont 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."), @@ -594,7 +616,7 @@ execute_stack_op (struct dwarf_expr_cont 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,7 +782,8 @@ execute_stack_op (struct dwarf_expr_cont case DW_OP_call_frame_cfa: result = (ctx->get_frame_cfa) (ctx->baton); - break; + dwarf_expr_push (ctx, result, 1); + goto no_push; /* already pushed */ case DW_OP_GNU_push_tls_address: /* Variable is at a constant offset in the thread-local @@ -820,8 +844,9 @@ execute_stack_op (struct dwarf_expr_cont error (_("Unhandled dwarf expression opcode 0x%x"), op); } - /* Most things push a result value. */ - dwarf_expr_push (ctx, result); + /* Most things push a result value (that doesn't live on the + program's stack). */ + dwarf_expr_push (ctx, result, 0); no_push:; } Index: dwarf2expr.h =================================================================== RCS file: /cvs/src/src/gdb/dwarf2expr.h,v retrieving revision 1.18 diff -u -p -r1.18 dwarf2expr.h --- dwarf2expr.h 11 Sep 2009 18:38:39 -0000 1.18 +++ dwarf2expr.h 11 Sep 2009 22:56:06 -0000 @@ -26,22 +26,38 @@ /* The location of a value. */ enum dwarf_value_location { - /* The piece is in memory. */ + /* The piece is in memory. + The value on the dwarf stack is its address. */ DWARF_VALUE_MEMORY, - /* The piece is in a register. */ + + /* The piece is in a register. + The value on the dwarf stack is the register number. */ DWARF_VALUE_REGISTER, - /* The piece is on the stack. */ + + /* The piece is on the dwarf stack. */ DWARF_VALUE_STACK, + /* The piece is a literal. */ DWARF_VALUE_LITERAL }; +/* The dwarf expression stack. */ + +struct dwarf_stack_value +{ + CORE_ADDR value; + + /* Non-zero if the piece is in memory and is known to be + on the program's stack. */ + int in_stack_memory; +}; + /* The expression evaluator works with a dwarf_expr_context, describing its current state and its callbacks. */ struct dwarf_expr_context { /* The stack of values, allocated with xmalloc. */ - CORE_ADDR *stack; + struct dwarf_stack_value *stack; /* The number of values currently pushed on the stack, and the number of elements allocated to the stack. */ @@ -111,7 +127,7 @@ struct dwarf_expr_context Each time DW_OP_piece is executed, we add a new element to the end of this array, recording the current top of the stack, the current location, and the size given as the operand to - DW_OP_piece. We then pop the top value from the stack, rest the + DW_OP_piece. We then pop the top value from the stack, reset the location, and resume evaluation. The Dwarf spec doesn't say whether DW_OP_piece pops the top value @@ -140,8 +156,14 @@ struct dwarf_expr_piece union { - /* This piece's address or register number. */ - CORE_ADDR value; + struct + { + /* This piece's address or register number. */ + CORE_ADDR value; + /* Non-zero if the piece is known to be in memory and on + the program's stack. */ + int in_stack_memory; + } expr; struct { @@ -162,11 +184,13 @@ void free_dwarf_expr_context (struct dwa struct cleanup * make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx); -void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value); +void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value, + int in_stack_memory); void dwarf_expr_pop (struct dwarf_expr_context *ctx); void dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr, size_t len); CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n); +int dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n); gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r); Index: dwarf2loc.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2loc.c,v retrieving revision 1.67 diff -u -p -r1.67 dwarf2loc.c --- dwarf2loc.c 11 Sep 2009 18:38:39 -0000 1.67 +++ dwarf2loc.c 11 Sep 2009 22:56:06 -0000 @@ -265,14 +265,17 @@ read_pieced_value (struct value *v) struct gdbarch *arch = get_frame_arch (frame); bfd_byte regval[MAX_REGISTER_SIZE]; int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, - p->v.value); + p->v.expr.value); get_frame_register (frame, gdb_regnum, regval); memcpy (contents + offset, regval, p->size); } break; case DWARF_VALUE_MEMORY: - read_memory (p->v.value, contents + offset, p->size); + if (p->v.expr.in_stack_memory) + read_stack (p->v.expr.value, contents + offset, p->size); + else + read_memory (p->v.expr.value, contents + offset, p->size); break; case DWARF_VALUE_STACK: @@ -282,7 +285,7 @@ read_pieced_value (struct value *v) int addr_size = gdbarch_addr_bit (c->arch) / 8; store_unsigned_integer (bytes, addr_size, gdbarch_byte_order (c->arch), - p->v.value); + p->v.expr.value); n = p->size; if (n > addr_size) n = addr_size; @@ -330,12 +333,12 @@ write_pieced_value (struct value *to, st case DWARF_VALUE_REGISTER: { struct gdbarch *arch = get_frame_arch (frame); - int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value); + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value); put_frame_register (frame, gdb_regnum, contents + offset); } break; case DWARF_VALUE_MEMORY: - write_memory (p->v.value, contents + offset, p->size); + write_memory (p->v.expr.value, contents + offset, p->size); break; default: set_value_optimized_out (to, 1); @@ -434,11 +437,13 @@ dwarf2_evaluate_loc_desc (struct symbol case DWARF_VALUE_MEMORY: { CORE_ADDR address = dwarf_expr_fetch (ctx, 0); + int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); retval = allocate_value (SYMBOL_TYPE (var)); VALUE_LVAL (retval) = lval_memory; set_value_lazy (retval, 1); - set_value_stack (retval, 1); + if (in_stack_memory) + set_value_stack (retval, 1); set_value_address (retval, address); } break; @@ -485,10 +490,6 @@ dwarf2_evaluate_loc_desc (struct symbol return retval; } - - - - /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */