This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]