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 1/5] Lazy register values


This patch allows a register value to be lazy.  Lazy register values
are created by value_of_register_lazy and fetched by value_fetch_lazy,
like lazy memory values.  I went through every check of value_lazy and
updated the ones which assumed this implied memory; the others guard
calls to value_fetch_lazy, which is still correct.

-- 
Daniel Jacobowitz
CodeSourcery

2008-03-31  Daniel Jacobowitz  <dan@codesourcery.com>

	* ada-lang.c (ada_value_primitive_packed_val): Only check
	value_lazy for memory lvals.
	* findvar.c (value_of_register_lazy): New function.
	(locate_var_value): Only check value_lazy for memory lvals.
	* valarith.c (value_subscripted_rvalue): Likewise.
	* valops.c (value_fetch_lazy): Handle both memory and register
	lvals.
	(search_struct_field, value_slice): Only check value_lazy for memory
	lvals.
	* value.c (struct value): Update comment for lazy.
	(value_primitive_field): Only check value_lazy for memory lvals.
	* value.h (value_lazy): Update comment.
	(value_of_register_lazy): Declare.

---
 gdb/ada-lang.c |    2 +-
 gdb/findvar.c  |   26 +++++++++++++++++++++++++-
 gdb/valarith.c |    2 +-
 gdb/valops.c   |   40 +++++++++++++++++++++++++++++++++-------
 gdb/value.c    |   10 +++++-----
 gdb/value.h    |    8 +++++---
 6 files changed, 70 insertions(+), 18 deletions(-)

Index: gdb/ada-lang.c
===================================================================
--- gdb/ada-lang.c.orig	2008-03-31 13:34:20.000000000 -0400
+++ gdb/ada-lang.c	2008-03-31 13:34:22.000000000 -0400
@@ -2039,7 +2039,7 @@ ada_value_primitive_packed_val (struct v
       v = allocate_value (type);
       bytes = (unsigned char *) (valaddr + offset);
     }
-  else if (value_lazy (obj))
+  else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
     {
       v = value_at (type,
                     VALUE_ADDRESS (obj) + value_offset (obj) + offset);
Index: gdb/findvar.c
===================================================================
--- gdb/findvar.c.orig	2008-03-31 13:34:20.000000000 -0400
+++ gdb/findvar.c	2008-03-31 13:34:22.000000000 -0400
@@ -281,6 +281,30 @@ value_of_register (int regnum, struct fr
   return reg_val;
 }
 
+/* Return a `value' with the contents of (virtual or cooked) register
+   REGNUM as found in the specified FRAME.  The register's type is
+   determined by register_type().  The value is not fetched.  */
+
+struct value *
+value_of_register_lazy (struct frame_info *frame, int regnum)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct value *reg_val;
+
+  gdb_assert (regnum < (gdbarch_num_regs (gdbarch)
+			+ gdbarch_num_pseudo_regs (gdbarch)));
+
+  /* We should have a valid (i.e. non-sentinel) frame.  */
+  gdb_assert (frame_id_p (get_frame_id (frame)));
+
+  reg_val = allocate_value (register_type (gdbarch, regnum));
+  VALUE_LVAL (reg_val) = lval_register;
+  VALUE_REGNUM (reg_val) = regnum;
+  VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
+  set_value_lazy (reg_val, 1);
+  return reg_val;
+}
+
 /* Given a pointer of type TYPE in target form in BUF, return the
    address it represents.  */
 CORE_ADDR
@@ -695,7 +719,7 @@ locate_var_value (struct symbol *var, st
   if (lazy_value == 0)
     error (_("Address of \"%s\" is unknown."), SYMBOL_PRINT_NAME (var));
 
-  if (value_lazy (lazy_value)
+  if ((VALUE_LVAL (lazy_value) == lval_memory && value_lazy (lazy_value))
       || TYPE_CODE (type) == TYPE_CODE_FUNC)
     {
       struct value *val;
Index: gdb/valarith.c
===================================================================
--- gdb/valarith.c.orig	2008-03-31 13:34:20.000000000 -0400
+++ gdb/valarith.c	2008-03-31 13:34:22.000000000 -0400
@@ -271,7 +271,7 @@ value_subscripted_rvalue (struct value *
     error (_("no such vector element"));
 
   v = allocate_value (elt_type);
-  if (value_lazy (array))
+  if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
     set_value_lazy (v, 1);
   else
     memcpy (value_contents_writeable (v),
Index: gdb/valops.c
===================================================================
--- gdb/valops.c.orig	2008-03-31 13:34:20.000000000 -0400
+++ gdb/valops.c	2008-03-31 13:34:22.000000000 -0400
@@ -571,12 +571,38 @@ value_at_lazy (struct type *type, CORE_A
 int
 value_fetch_lazy (struct value *val)
 {
-  CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
-  int length = TYPE_LENGTH (value_enclosing_type (val));
+  if (VALUE_LVAL (val) == lval_memory)
+    {
+      CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
+      int length = TYPE_LENGTH (value_enclosing_type (val));
 
-  struct type *type = value_type (val);
-  if (length)
-    read_memory (addr, value_contents_all_raw (val), length);
+      struct type *type = value_type (val);
+      if (length)
+	read_memory (addr, value_contents_all_raw (val), length);
+    }
+  else if (VALUE_LVAL (val) == lval_register)
+    {
+      struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (val));
+      int regnum = VALUE_REGNUM (val);
+      struct type *type = check_typedef (value_type (val));
+
+      gdb_assert (frame != NULL);
+
+      /* Convertible register routines are used for multi-register
+	 values and for interpretation in different types (e.g. float
+	 or int from a double register).  Lazy register values should
+	 have the register's natural type, so they do not apply.  */
+      gdb_assert (!gdbarch_convert_register_p (get_frame_arch (frame), regnum,
+					       type));
+
+      /* Get the data.  */
+      if (!get_frame_register_bytes (frame, regnum, value_offset (val),
+				     TYPE_LENGTH (value_type (val)),
+				     value_contents_raw (val)))
+	set_value_optimized_out (val, 1);
+    }
+  else
+    internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
 
   set_value_lazy (val, 0);
   return 0;
@@ -1424,7 +1450,7 @@ search_struct_field (char *name, struct 
 	      VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
 	      VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
 	      set_value_offset (v2, value_offset (arg1) + boffset);
-	      if (value_lazy (arg1))
+	      if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
 		set_value_lazy (v2, 1);
 	      else
 		memcpy (value_contents_raw (v2),
@@ -2852,7 +2878,7 @@ value_slice (struct value *array, int lo
       TYPE_CODE (slice_type) = TYPE_CODE (array_type);
 
       slice = allocate_value (slice_type);
-      if (value_lazy (array))
+      if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
 	set_value_lazy (slice, 1);
       else
 	memcpy (value_contents_writeable (slice),
Index: gdb/value.c
===================================================================
--- gdb/value.c.orig	2008-03-31 13:34:20.000000000 -0400
+++ gdb/value.c	2008-03-31 13:34:22.000000000 -0400
@@ -137,9 +137,9 @@ struct value
   short regnum;
 
   /* If zero, contents of this value are in the contents field.  If
-     nonzero, contents are in inferior memory at address in the
-     location.address field plus the offset field (and the lval field
-     should be lval_memory).
+     nonzero, contents are in inferior.  If the lval field is lval_memory,
+     the contents are in inferior memory at location.address plus offset.
+     The lval field may also be lval_register.
 
      WARNING: This field is used by the code which handles watchpoints
      (see breakpoint.c) to decide whether a particular value can be
@@ -1353,7 +1353,7 @@ value_primitive_field (struct value *arg
          bases, etc.  */
       v = allocate_value (value_enclosing_type (arg1));
       v->type = type;
-      if (value_lazy (arg1))
+      if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
 	set_value_lazy (v, 1);
       else
 	memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
@@ -1367,7 +1367,7 @@ value_primitive_field (struct value *arg
       /* Plain old data member */
       offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
       v = allocate_value (type);
-      if (value_lazy (arg1))
+      if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
 	set_value_lazy (v, 1);
       else
 	memcpy (value_contents_raw (v),
Index: gdb/value.h
===================================================================
--- gdb/value.h.orig	2008-03-31 13:34:20.000000000 -0400
+++ gdb/value.h	2008-03-31 13:34:22.000000000 -0400
@@ -135,9 +135,9 @@ extern int value_embedded_offset (struct
 extern void set_value_embedded_offset (struct value *value, int val);
 
 /* If zero, contents of this value are in the contents field.  If
-   nonzero, contents are in inferior memory at address in the
-   location.address field plus the offset field (and the lval field
-   should be lval_memory).
+   nonzero, contents are in inferior.  If the lval field is lval_memory,
+   the contents are in inferior memory at location.address plus offset.
+   The lval field may also be lval_register.
 
    WARNING: This field is used by the code which handles watchpoints
    (see breakpoint.c) to decide whether a particular value can be
@@ -301,6 +301,8 @@ extern struct value *value_of_variable (
 
 extern struct value *value_of_register (int regnum, struct frame_info *frame);
 
+struct value *value_of_register_lazy (struct frame_info *frame, int regnum);
+
 extern int symbol_read_needs_frame (struct symbol *);
 
 extern struct value *read_var_value (struct symbol *var,


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