[PATCH 1/2 v2] Introduce a new lval_type lval_mirrored_on_inferior_stack

Siva Chandra sivachandra@google.com
Wed Oct 1 00:44:00 GMT 2014


Introduce a new lval_type lval_mirrored_on_inferior_stack.

Add support for values with the new lval_type.

Link to description: https://sourceware.org/ml/gdb-patches/2014-09/msg00788.html

gdb/ChangeLog:

2014-09-30  Siva Chandra Reddy  <sivachandra@google.com>

        * defs.h (enum lval_type): Add new lval_type
        lval_mirrored_on_inferior_stack.
        * valops.c (value_coerce_array, value_from_pointer)
        (value_addr): Do not error on values with lval_type
        lval_mirrored_on_inferior_stack.
        * value.c (struct value): Add field stack_mirror to the location
        field.
        (allocate_value_mirrored_on_stack, setup_stack_mirror): New functions.
        (value_address): Handle values with lval_type
        lval_mirrored_on_inferior_stack.
        * value.h (allocate_value_mirrored_on_stack)
        (setup_stack_mirror): Declare.
-------------- next part --------------
diff --git a/gdb/defs.h b/gdb/defs.h
index 8914512..4e64b75 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -342,7 +342,10 @@ enum lval_type
     lval_internalvar_component,
     /* * Value's bits are fetched and stored using functions provided
        by its creator.  */
-    lval_computed
+    lval_computed,
+    /* * Value mirrored on inferior stack.  The value on stack is an
+       lval_memory value.  */
+    lval_mirrored_on_inferior_stack
   };
 
 /* * Control types for commands.  */
diff --git a/gdb/valops.c b/gdb/valops.c
index e1decf0..564d282 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1440,7 +1440,8 @@ value_coerce_array (struct value *arg1)
      be a good time to do so.  */
   arg1 = value_coerce_to_target (arg1);
 
-  if (VALUE_LVAL (arg1) != lval_memory)
+  if (VALUE_LVAL (arg1) != lval_memory
+      && VALUE_LVAL (arg1) != lval_mirrored_on_inferior_stack)
     error (_("Attempt to take address of value not located in memory."));
 
   return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
@@ -1455,7 +1456,8 @@ value_coerce_function (struct value *arg1)
 {
   struct value *retval;
 
-  if (VALUE_LVAL (arg1) != lval_memory)
+  if (VALUE_LVAL (arg1) != lval_memory
+      && VALUE_LVAL (arg1) != lval_mirrored_on_inferior_stack)
     error (_("Attempt to take address of value not located in memory."));
 
   retval = value_from_pointer (lookup_pointer_type (value_type (arg1)),
@@ -1489,7 +1491,8 @@ value_addr (struct value *arg1)
      then this would be a good time to force it to memory.  */
   arg1 = value_coerce_to_target (arg1);
 
-  if (VALUE_LVAL (arg1) != lval_memory)
+  if (VALUE_LVAL (arg1) != lval_memory
+      && VALUE_LVAL (arg1) != lval_mirrored_on_inferior_stack)
     error (_("Attempt to take address of value not located in memory."));
 
   /* Get target memory address.  */
diff --git a/gdb/value.c b/gdb/value.c
index fdc8858d..cace2aa 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -233,6 +233,8 @@ struct value
       /* Closure for those functions to use.  */
       void *closure;
     } computed;
+
+    struct value *stack_mirror;
   } location;
 
   /* Describes offset of a value within lval of a structure in bytes.
@@ -998,6 +1000,43 @@ allocate_computed_value (struct type *type,
   return v;
 }
 
+/* Allocate a value which is mirrored on inferior stack.
+   MIRROR is a value whose lval is lval_memory.  It is an error if MIRROR has
+   an lval of any other type.  */
+
+struct value *
+allocate_value_mirrored_on_stack (struct value *mirror)
+{
+  struct value *v;
+
+  gdb_assert (VALUE_LVAL (mirror) == lval_memory);
+
+  v = allocate_value (value_type (mirror));
+  VALUE_LVAL (v) = lval_mirrored_on_inferior_stack;
+  v->location.stack_mirror = mirror;
+
+  return v;
+}
+
+/* Sets up a mirror of V at MIRROR_ADDR and return it.  It is implicitly
+   assumed that V does not have a dynamic type different from its static
+   type.  */
+
+struct value *
+setup_stack_mirror (struct value *v, CORE_ADDR mirror_addr)
+{
+  struct value *mirror;
+
+  write_memory (mirror_addr, value_contents_raw (v),
+		TYPE_LENGTH (value_type (v)));
+  mirror = value_from_contents_and_address (value_type (v), NULL, mirror_addr);
+
+  VALUE_LVAL (v) = lval_mirrored_on_inferior_stack;
+  v->location.stack_mirror = mirror;
+
+  return mirror;
+}
+
 /* Allocate NOT_LVAL value for type TYPE being OPTIMIZED_OUT.  */
 
 struct value *
@@ -1446,6 +1485,8 @@ value_address (const struct value *value)
     return 0;
   if (value->parent != NULL)
     return value_address (value->parent) + value->offset;
+  else if (value->lval == lval_mirrored_on_inferior_stack)
+    return value_address (value->location.stack_mirror);
   else
     return value->location.address + value->offset;
 }
diff --git a/gdb/value.h b/gdb/value.h
index e3603c3..0ce3aa0 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -677,6 +677,10 @@ extern struct value *default_read_var_value (struct symbol *var,
 
 extern struct value *allocate_value (struct type *type);
 extern struct value *allocate_value_lazy (struct type *type);
+
+extern struct value *allocate_value_mirrored_on_stack (struct value *mirror);
+extern struct value *setup_stack_mirror (struct value *v, CORE_ADDR addr);
+
 extern void value_contents_copy (struct value *dst, int dst_offset,
 				 struct value *src, int src_offset,
 				 int length);


More information about the Gdb-patches mailing list