This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC] better dwarf checking for values on the stack
- From: dje at google dot com (Doug Evans)
- To: gdb-patches at sourceware dot org, tromey at redhat dot com
- Date: Thu, 10 Sep 2009 16:19:11 -0700 (PDT)
- Subject: [RFC] better dwarf checking for values on the stack
This patch builds on the patch here:
http://sourceware.org/ml/gdb-patches/2009-09/msg00106.html
The purpose is to call set_value_stack only for values actually on the stack.
This addresses the issues identified here:
http://sourceware.org/ml/gdb-patches/2009-09/msg00069.html
I'd like to get this in 7.0, otherwise we have to consider
pulling "set stack-cache" out.
2009-09-10 Doug Evans <dje@google.com>
Add better checking for values on stack.
* dwarf2expr.h (dwarf_value_location): Rename DWARF_VALUE_STACK to
DWARF_VALUE_DWARF_STACK, all uses updated.
New enum DWARF_VALUE_MEMORY_STACK.
* dwarf2expr.c (execute_stack_op, case DW_OP_fbreg): Mark location
as DWARF_VALUE_MEMORY_STACK.
(execute_stack_op, case DW_OP_call_frame_cfa): Ditto.
(execute_stack_op, cases DW_OP_deref, DW_OP_deref_size): Mark
location as DWARF_VALUE_MEMORY.
(execute_stack_op, case DW_OP_piece): Remove unused addr_or_regnum.
* dwarf2loc.c (read_pieced_value): Handle DWARF_VALUE_MEMORY_STACK.
(write_pieced_value): Ditto.
(dwarf2_evaluate_loc_desc): Ditto. Only call set_value_stack for
values known to be on the stack.
* dwarf2-frame.c (execute_stack_op): Handle DWARF_VALUE_MEMORY_STACK.
--- ../../../dcache-for-stack2/src/gdb/dwarf2expr.h 2009-09-10 11:23:40.000000000 -0700
+++ ./dwarf2expr.h 2009-09-10 11:50:25.000000000 -0700
@@ -26,12 +26,25 @@
/* 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 memory and known to be on the stack.
+ The value on the dwarf stack is its address.
+ Stack memory is treated specially as it allows optimized access
+ for remote targets.
+ NOTE: This is an optimization. It is always ok to use
+ DWARF_VALUE_MEMORY instead. */
+ DWARF_VALUE_MEMORY_STACK,
+
+ /* 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. */
- DWARF_VALUE_STACK,
+
+ /* The piece is on the dwarf stack. */
+ DWARF_VALUE_DWARF_STACK,
+
/* The piece is a literal. */
DWARF_VALUE_LITERAL
};
@@ -111,7 +124,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
--- ../../../dcache-for-stack2/src/gdb/dwarf2expr.c 2009-09-10 11:23:40.000000000 -0700
+++ ./dwarf2expr.c 2009-09-10 15:37:20.000000000 -0700
@@ -483,7 +483,7 @@ execute_stack_op (struct dwarf_expr_cont
goto no_push;
case DW_OP_stack_value:
- ctx->location = DWARF_VALUE_STACK;
+ ctx->location = DWARF_VALUE_DWARF_STACK;
require_composition (op_ptr, op_end, "DW_OP_stack_value");
goto no_push;
@@ -551,14 +551,14 @@ execute_stack_op (struct dwarf_expr_cont
(ctx->get_frame_base) (ctx->baton, &datastart, &datalen);
dwarf_expr_eval (ctx, datastart, datalen);
if (ctx->location == DWARF_VALUE_LITERAL
- || ctx->location == DWARF_VALUE_STACK)
+ || ctx->location == DWARF_VALUE_DWARF_STACK)
error (_("Not implemented: computing frame base using explicit value operator"));
result = dwarf_expr_fetch (ctx, 0);
if (ctx->location == DWARF_VALUE_REGISTER)
result = (ctx->read_reg) (ctx->baton, result);
result = result + offset;
ctx->stack_len = before_stack_len;
- ctx->location = DWARF_VALUE_MEMORY;
+ ctx->location = DWARF_VALUE_MEMORY_STACK;
}
break;
case DW_OP_dup:
@@ -627,6 +627,7 @@ execute_stack_op (struct dwarf_expr_cont
result = dwarf2_read_address (ctx->gdbarch,
buf, buf + ctx->addr_size,
ctx->addr_size);
+ ctx->location = DWARF_VALUE_MEMORY;
}
break;
@@ -638,6 +639,7 @@ execute_stack_op (struct dwarf_expr_cont
result = dwarf2_read_address (ctx->gdbarch,
buf, buf + addr_size,
addr_size);
+ ctx->location = DWARF_VALUE_MEMORY;
}
break;
@@ -758,6 +760,7 @@ execute_stack_op (struct dwarf_expr_cont
case DW_OP_call_frame_cfa:
result = (ctx->get_frame_cfa) (ctx->baton);
+ ctx->location = DWARF_VALUE_MEMORY_STACK;
break;
case DW_OP_GNU_push_tls_address:
@@ -794,7 +797,6 @@ execute_stack_op (struct dwarf_expr_cont
case DW_OP_piece:
{
ULONGEST size;
- CORE_ADDR addr_or_regnum;
/* Record the piece. */
op_ptr = read_uleb128 (op_ptr, op_end, &size);
--- ../../../dcache-for-stack2/src/gdb/dwarf2loc.c 2009-09-10 11:23:40.000000000 -0700
+++ ./dwarf2loc.c 2009-09-10 11:57:01.000000000 -0700
@@ -220,7 +220,7 @@ struct piece_closure
/* The number of pieces used to describe this variable. */
int n_pieces;
- /* The architecture, used only for DWARF_VALUE_STACK. */
+ /* The architecture, used only for DWARF_VALUE_DWARF_STACK. */
struct gdbarch *arch;
/* The pieces themselves. */
@@ -275,7 +275,11 @@ read_pieced_value (struct value *v)
read_memory (p->v.value, contents + offset, p->size);
break;
- case DWARF_VALUE_STACK:
+ case DWARF_VALUE_MEMORY_STACK:
+ read_stack (p->v.value, contents + offset, p->size);
+ break;
+
+ case DWARF_VALUE_DWARF_STACK:
{
gdb_byte bytes[sizeof (ULONGEST)];
size_t n;
@@ -335,6 +339,7 @@ write_pieced_value (struct value *to, st
}
break;
case DWARF_VALUE_MEMORY:
+ case DWARF_VALUE_MEMORY_STACK:
write_memory (p->v.value, contents + offset, p->size);
break;
default:
@@ -432,18 +437,20 @@ dwarf2_evaluate_loc_desc (struct symbol
break;
case DWARF_VALUE_MEMORY:
+ case DWARF_VALUE_MEMORY_STACK:
{
CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
retval = allocate_value (SYMBOL_TYPE (var));
VALUE_LVAL (retval) = lval_memory;
set_value_lazy (retval, 1);
- set_value_stack (retval, 1);
+ if (ctx->location == DWARF_VALUE_MEMORY_STACK)
+ set_value_stack (retval, 1);
set_value_address (retval, address);
}
break;
- case DWARF_VALUE_STACK:
+ case DWARF_VALUE_DWARF_STACK:
{
gdb_byte bytes[sizeof (ULONGEST)];
ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0);
@@ -485,10 +492,6 @@ dwarf2_evaluate_loc_desc (struct symbol
return retval;
}
-
-
-
-
/* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
--- ../../../dcache-for-stack2/src/gdb/dwarf2-frame.c 2009-09-10 11:23:40.000000000 -0700
+++ ./dwarf2-frame.c 2009-09-10 11:42:07.000000000 -0700
@@ -381,7 +381,8 @@ execute_stack_op (gdb_byte *exp, ULONGES
if (ctx->location == DWARF_VALUE_REGISTER)
result = read_reg (this_frame, result);
- else if (ctx->location != DWARF_VALUE_MEMORY)
+ else if (ctx->location != DWARF_VALUE_MEMORY
+ && ctx->location != DWARF_VALUE_MEMORY_STACK)
{
/* This is actually invalid DWARF, but if we ever do run across
it somehow, we might as well support it. So, instead, report