diff mbox

[1/2,v3] Introduce a new lval_type lval_mirrored_on_inferior_stack

Message ID CAGyQ6gw356xWd5YAqj9z4kiGuDeNRuNKDrhA9eE65pe2dPXFqw@mail.gmail.com
State New
Headers show

Commit Message

Siva Chandra Reddy Oct. 20, 2014, 8 p.m. UTC
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-10-20  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)
        (delink_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, delink_stack_mirror): Declare.
diff mbox

Patch

diff --git a/gdb/defs.h b/gdb/defs.h
index 1eb43eb..b0f6a2a 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 7f3e4f5..21b24f4 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1441,7 +1441,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)),
@@ -1456,7 +1457,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)),
@@ -1490,7 +1492,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 ecfb154..69c1cb8 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -232,6 +232,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.
@@ -997,6 +999,56 @@  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;
+}
+
+/* Set 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;
+}
+
+/* If V is of lval_mirrored_on_inferior_stack, then delink the stack mirror
+   from V and set its lval_type to not_lval.  */
+
+void
+delink_stack_mirror (struct value *v)
+{
+  if (VALUE_LVAL (v) != lval_mirrored_on_inferior_stack)
+    return;
+
+  v->location.stack_mirror = NULL;
+  VALUE_LVAL (v) = not_lval;
+}
+
 /* Allocate NOT_LVAL value for type TYPE being OPTIMIZED_OUT.  */
 
 struct value *
@@ -1445,6 +1497,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..55d5ed6 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -677,6 +677,11 @@  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 delink_stack_mirror (struct value *v);
+
 extern void value_contents_copy (struct value *dst, int dst_offset,
 				 struct value *src, int src_offset,
 				 int length);