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]

[PATCH 02/10] type: add c99 variable length array support


The dwarf standard allow certain attributes to be expressed as dwarf
expressions rather than constants. For instance upper-/lowerbound attributes.
In case of a c99 variable length array the upperbound is a dynamic attribute.

With this change c99 vla behave the same as with static arrays.

1| void foo (size_t n) {
2|   int ary[n];
3|   memset(ary, 0, sizeof(ary));
4| }

(gdb) print ary
$1 = {0 <repeats 42 times>}

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>                                                                 |
            Keven Boell  <keven.boell@intel.com>

	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
	* dwarf2loc.h (dwarf2_locexpr_baton_eval): New function prototype.
	* dwarf2read.c (attr_to_locexprbaton): New function.
	(attr_to_locexprbaton_1): New function.
	(attr_to_dwarf2_prop): New function.
	(read_subrange_type): Use attr_to_dwarf2_prop to read high bound
	attribute.
	* gdbtypes.c: Include dwarf2loc.h.
	(resolve_dynamic_prop): New function.
	(is_dynamic_type): New function.
	(resolve_dynamic_values_1): New function.
	(resolve_dynamic_type): New function.
	(get_type_length): New function.
	(check_typedef): Use get_type_length to compute type length.
	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): Define.
	(TYPE_LOW_BOUND_KIND): Define.

Change-Id: I97b91b9ad0b8ac8d30294dae6bd0dd4c905713ce
---
 gdb/dwarf2loc.c  |   45 +++++++++
 gdb/dwarf2loc.h  |    7 ++
 gdb/dwarf2read.c |  131 +++++++++++++++++++++------
 gdb/gdbtypes.c   |  272 +++++++++++++++++++++++++++++++++++++++++++----------
 gdb/gdbtypes.h   |    7 ++
 gdb/value.c      |   10 +-
 6 files changed, 389 insertions(+), 83 deletions(-)

diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 8242dca..289cf78 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2416,6 +2416,51 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
 }
 
+int
+dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
+			   CORE_ADDR addr, CORE_ADDR *valp)
+{
+  struct dwarf_expr_context *ctx;
+  struct dwarf_expr_baton baton;
+  struct objfile *objfile;
+  struct cleanup *cleanup;
+
+  if (dlbaton->size == 0)
+    return 0;
+
+  ctx = new_dwarf_expr_context ();
+  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
+
+  baton.frame = get_selected_frame (NULL);
+  baton.per_cu = dlbaton->per_cu;
+
+  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+
+  ctx->gdbarch = get_objfile_arch (objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
+  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
+  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
+  ctx->funcs = &dwarf_expr_ctx_funcs;
+  ctx->baton = &baton;
+
+  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
+
+  switch (ctx->location)
+    {
+    case DWARF_VALUE_REGISTER:
+      *valp = dwarf_expr_read_reg (&baton, dwarf_expr_fetch_address (ctx, 0));
+      break;
+    case DWARF_VALUE_MEMORY:
+      *valp = dwarf_expr_fetch_address (ctx, 0);
+      break;
+    }
+
+  do_cleanups (cleanup);
+
+  return 1;
+}
+
+
 
 /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 9bc8ca5..83c8044 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -90,6 +90,13 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
 					size_t size,
 					struct dwarf2_per_cu_data *per_cu);
 
+/* Evaluate a dwarf expression and stores the result in VAL, expecting
+   that the dwarf expression only produces a single CORE_ADDR.
+   Returns 1 on success, 0 otherwise.   */
+
+int dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
+			       CORE_ADDR addr, CORE_ADDR *value);
+
 CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
 				  unsigned int addr_index);
 
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 36ed9bd..f552df2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1848,6 +1848,17 @@ static void free_dwo_file_cleanup (void *);
 static void process_cu_includes (void);
 
 static void check_producer (struct dwarf2_cu *cu);
+
+static struct dwarf2_locexpr_baton* attr_to_locexprbaton
+(const struct attribute *, struct dwarf2_cu *);
+
+static struct dwarf2_locexpr_baton* attr_to_locexprbaton_1
+(const struct attribute *, struct dwarf2_cu *, const gdb_byte *additional_data,
+ int extra_size);
+
+static int attr_to_dwarf2_prop
+(struct die_info *, const struct attribute *, struct dwarf2_cu *,
+ struct dwarf2_prop *);
 
 /* Various complaints about symbol reading that don't abort the process.  */
 
@@ -14206,27 +14217,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	       die->offset.sect_off, objfile_name (cu->objfile));
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
-  if (attr)
-    {
-      if (attr_form_is_block (attr) || attr_form_is_ref (attr))
-        {
-          /* GCC encodes arrays with unspecified or dynamic length
-             with a DW_FORM_block1 attribute or a reference attribute.
-             FIXME: GDB does not yet know how to handle dynamic
-             arrays properly, treat them as arrays with unspecified
-             length for now.
-
-             FIXME: jimb/2003-09-22: GDB does not really know
-             how to handle arrays of unspecified length
-             either; we just represent them as zero-length
-             arrays.  Choose an appropriate upper bound given
-             the lower bound we've computed above.  */
-          high.data.const_val = low.data.const_val - 1;
-        }
-      else
-        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
-    }
-  else
+  if (!attr_to_dwarf2_prop (die, attr, cu, &high))
     {
       attr = dwarf2_attr (die, DW_AT_count, cu);
       if (attr)
@@ -14290,12 +14281,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type_1 (NULL, orig_base_type, &low, &high);
 
-  /* Mark arrays with dynamic length at least as an array of unspecified
-     length.  GDB could check the boundary but before it gets implemented at
-     least allow accessing the array elements.  */
-  if (attr && attr_form_is_block (attr))
-    TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
-
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
     TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
@@ -22301,6 +22286,98 @@ save_gdb_index_command (char *arg, int from_tty)
   }
 }
 
+/* Turn Dwarf block into location expression baton structure. Used to store
+   baton into "dynamic" types, e.g. VLA's. */
+
+static struct dwarf2_locexpr_baton*
+attr_to_locexprbaton (const struct attribute *attribute, struct dwarf2_cu *cu)
+{
+  return attr_to_locexprbaton_1 (attribute, cu, NULL, 0);
+}
+
+static struct dwarf2_locexpr_baton*
+attr_to_locexprbaton_1 (const struct attribute *attribute, struct dwarf2_cu *cu,
+			const gdb_byte *additional_data, int extra_size)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  struct dwarf2_locexpr_baton *baton;
+
+  gdb_assert (attribute != NULL && cu != NULL &&
+	      attr_form_is_block (attribute));
+
+  baton = obstack_alloc (&objfile->objfile_obstack,
+			 sizeof (struct dwarf2_locexpr_baton));
+  baton->per_cu = cu->per_cu;
+  baton->size = DW_BLOCK (attribute)->size + extra_size;
+
+  if (additional_data != NULL && extra_size > 0)
+    {
+      gdb_byte *data;
+
+      data = obstack_alloc (&objfile->objfile_obstack, baton->size);
+      baton->data = data;
+
+      memcpy (data, DW_BLOCK (attribute)->data, DW_BLOCK (attribute)->size);
+      memcpy (data, additional_data, extra_size);
+    }
+  else
+    /* Copy the data pointer as the blocks lifetime is
+       bound to its object file. */
+    baton->data = DW_BLOCK (attribute)->data;
+
+  gdb_assert(baton->data != NULL);
+
+  return baton;
+}
+
+/* Parse dwarf attribute if it's a block, reference or constant and put the
+   resulting value of the attribute into struct dwarf2_prop. */
+
+static int
+attr_to_dwarf2_prop (struct die_info *die, const struct attribute *attr,
+		     struct dwarf2_cu *cu,
+		     struct dwarf2_prop *prop)
+{
+  if (die == NULL || attr == NULL || cu == NULL || prop == NULL)
+    return 0;
+
+  if (attr_form_is_block (attr))
+    {
+      prop->data.locexpr = attr_to_locexprbaton (attr, cu);
+      prop->kind = DWARF_LOCEXPR;
+      gdb_assert (prop->data.locexpr != NULL);
+    }
+  else if (attr_form_is_ref (attr))
+    {
+      struct dwarf2_cu *target_cu = cu;
+      struct die_info *target_die;
+      struct attribute *target_attr;
+      const gdb_byte append_ops[] = { DW_OP_deref };
+
+      target_die = follow_die_ref (die, attr, &target_cu);
+      target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
+
+      prop->data.locexpr =
+	attr_to_locexprbaton_1 (target_attr, cu, append_ops,
+				sizeof (append_ops) / sizeof (append_ops[0]));
+      prop->kind = DWARF_LOCEXPR;
+      gdb_assert (prop->data.locexpr != NULL);
+    }
+  else if (attr_form_is_constant (attr))
+    {
+      prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
+      prop->kind = DWARF_CONST;
+    }
+  else
+    {
+      dwarf2_invalid_attrib_class_complaint(dwarf_form_name (attr->form),
+					    dwarf2_name (die, cu));
+      return 0;
+    }
+
+  return 1;
+}
+
 
 
 int dwarf2_always_disassemble;
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 3cfcf62..c0f375d 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -38,6 +38,7 @@
 #include "hashtab.h"
 #include "exceptions.h"
 #include "cp-support.h"
+#include "dwarf2loc.h"
 
 /* Initialize BADNESS constants.  */
 
@@ -848,6 +849,17 @@ create_range_type (struct type *result_type, struct type *index_type,
   return result_type;
 }
 
+/* Predicate tests whether BOUNDS are static. Returns 1 if all bounds values
+   are static, otherwise returns 0.  */
+
+static int
+has_static_range (const struct range_bounds *bounds)
+{
+  return bounds->low.kind == DWARF_CONST
+    && bounds->high.kind == DWARF_CONST;
+}
+
+
 /* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
    TYPE.  Return 1 if type is a range type, 0 if it is discrete (and
    bounds will fit in LONGEST), or -1 otherwise.  */
@@ -977,24 +989,28 @@ create_array_type (struct type *result_type,
 		   struct type *element_type,
 		   struct type *range_type)
 {
-  LONGEST low_bound, high_bound;
-
   if (result_type == NULL)
     result_type = alloc_type_copy (range_type);
 
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
-    low_bound = high_bound = 0;
-  CHECK_TYPEDEF (element_type);
-  /* Be careful when setting the array length.  Ada arrays can be
-     empty arrays with the high_bound being smaller than the low_bound.
-     In such cases, the array length should be zero.  */
-  if (high_bound < low_bound)
-    TYPE_LENGTH (result_type) = 0;
-  else
-    TYPE_LENGTH (result_type) =
-      TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+
+  if (has_static_range (TYPE_RANGE_DATA (range_type)))
+    {
+      LONGEST low_bound, high_bound;
+
+      if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+	low_bound = high_bound = 0;
+      CHECK_TYPEDEF (element_type);
+      /* Be careful when setting the array length.  Ada arrays can be
+	 empty arrays with the high_bound being smaller than the low_bound.
+	 In such cases, the array length should be zero.  */
+      if (high_bound < low_bound)
+	TYPE_LENGTH (result_type) = 0;
+      else
+	TYPE_LENGTH (result_type) =
+	  TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+    }
   TYPE_NFIELDS (result_type) = 1;
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
@@ -1525,7 +1541,188 @@ stub_noname_complaint (void)
   complaint (&symfile_complaints, _("stub type has NULL name"));
 }
 
-/* Find the real type of TYPE.  This function returns the real type,
+/* Calculates the size of a type given the upper and lower bound of a dynamic
+   type.  */
+
+static ULONGEST
+get_type_length (const struct type *type)
+{
+  const struct type *range_type, *target_type;
+  ULONGEST len = TYPE_LENGTH (type);
+  LONGEST low_bound, high_bound;
+
+  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+      && TYPE_CODE (type) != TYPE_CODE_STRING)
+    return len;
+
+  range_type = TYPE_INDEX_TYPE (type);
+
+  if (!has_static_range (TYPE_RANGE_DATA (range_type)))
+    return len;
+
+  target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+  /* Now recompute the length of the array type, based on its
+     number of elements and the target type's length.
+     Watch out for Ada null Ada arrays where the high bound
+     is smaller than the low bound.  */
+  low_bound = TYPE_LOW_BOUND (range_type);
+  high_bound = TYPE_HIGH_BOUND (range_type);
+
+  if (high_bound < low_bound)
+    len = 0;
+  else
+    {
+      /* For now, we conservatively take the array length to be 0
+         if its length exceeds UINT_MAX.  The code below assumes
+         that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
+         which is technically not guaranteed by C, but is usually true
+         (because it would be true if x were unsigned with its
+         high-order bit on).  It uses the fact that
+         high_bound-low_bound is always representable in
+         ULONGEST and that if high_bound-low_bound+1 overflows,
+         it overflows to 0.  We must change these tests if we
+         decide to increase the representation of TYPE_LENGTH
+         from unsigned int to ULONGEST.  */
+      ULONGEST ulow = low_bound, uhigh = high_bound;
+      ULONGEST tlen = get_type_length (target_type);
+
+      len = tlen * (uhigh - ulow + 1);
+      if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh || len > UINT_MAX)
+        len = 0;
+    }
+
+  return len;
+}
+
+/* Converts a dynamic value into a static one. Returns 1 if PROP could be
+   converted and the static value is passed back into VALUE, otherwise
+   returns 0.  */
+
+static int
+resolve_dynamic_prop (const struct dwarf2_prop *prop, CORE_ADDR address,
+		      CORE_ADDR *value)
+{
+  if (prop == NULL)
+    return 0;
+
+  switch (prop->kind)
+    {
+    case DWARF_LOCEXPR:
+      {
+	const struct dwarf2_locexpr_baton *baton = prop->data.locexpr;
+
+	return dwarf2_locexpr_baton_eval (baton, address, value);
+      }
+    case DWARF_LOCLIST:
+    case DWARF_CONST:
+      break;
+    }
+
+  return 0;
+}
+
+/* Predicates if the type has dynamic values, which are not resolved yet.  */
+
+static int
+is_dynamic_type (const struct type *type)
+{
+  if (type == NULL)
+    return 0;
+
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+      && TYPE_NFIELDS (type) == 1)
+    {
+      const struct type *range_type = TYPE_INDEX_TYPE (type);
+
+      if (!has_static_range (TYPE_RANGE_DATA (range_type)))
+	return 1;
+    }
+
+  if (TYPE_CODE (type) == TYPE_CODE_PTR
+      || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    return is_dynamic_type (TYPE_TARGET_TYPE (type));
+
+  return 0;
+}
+
+static void
+resolve_dynamic_bounds (struct type *type, CORE_ADDR address)
+{
+  struct type *real_type;
+  const struct dwarf2_prop *prop;
+  CORE_ADDR value;
+
+  if (TYPE_CODE (type) == TYPE_CODE_PTR
+      || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), address);
+  else
+    {
+      real_type = check_typedef (type);
+
+      if (TYPE_CODE (real_type) == TYPE_CODE_ARRAY)
+	{
+	  struct type *ary_dim = real_type;
+
+	  do {
+	    struct type *range_type = TYPE_INDEX_TYPE (ary_dim);
+
+	    prop = &TYPE_RANGE_DATA (range_type)->low;
+	    if (resolve_dynamic_prop (prop, address, &value))
+	      {
+		TYPE_LOW_BOUND (range_type) = value;
+		TYPE_LOW_BOUND_KIND (range_type) = DWARF_CONST;
+	      }
+
+	    prop = &TYPE_RANGE_DATA (range_type)->high;
+	    if (resolve_dynamic_prop (prop, address, &value))
+	      {
+		TYPE_HIGH_BOUND (range_type) = value;
+		TYPE_HIGH_BOUND_KIND (range_type) = DWARF_CONST;
+	      }
+
+	    ary_dim = TYPE_TARGET_TYPE (ary_dim);
+	  } while (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY);
+	}
+    }
+}
+
+/* Resolves all dynamic values of a type e.g. array bounds to static values.
+   If TYPE has no dynamic values returns TYPE otherwise a new type with static
+   values is returned.  */
+
+struct type *
+resolve_dynamic_type (struct type *type, CORE_ADDR address)
+{
+  const struct type *ty = check_typedef (type);
+  struct type *resolved_type, *real_type;
+  struct obstack obstack;
+  struct cleanup *cleanup;
+  const struct dwarf2_prop *prop;
+  htab_t copied_types;
+  CORE_ADDR value;
+
+  if (!TYPE_OBJFILE_OWNED (ty))
+    return type;
+
+  if (!is_dynamic_type (ty))
+    return type;
+
+  /* Make a deep copy of the type.  */
+  copied_types = create_copied_types_hash (TYPE_OBJFILE (type));
+  cleanup = make_cleanup_htab_delete (copied_types);
+  resolved_type = copy_type_recursive
+    (TYPE_OBJFILE (type), type, copied_types);
+  do_cleanups (cleanup);
+
+  resolve_dynamic_bounds (resolved_type, address);
+
+  resolved_type->length = get_type_length (resolved_type);
+
+  return resolved_type;
+}
+
+/* find the real type of TYPE.  This function returns the real type,
    after removing all layers of typedefs, and completing opaque or stub
    types.  Completion changes the TYPE argument, but stripping of
    typedefs does not.
@@ -1701,44 +1898,15 @@ check_typedef (struct type *type)
 	  /* Nothing we can do.  */
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
-	       && TYPE_NFIELDS (type) == 1
-	       && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
-		   == TYPE_CODE_RANGE))
-	{
-	  /* Now recompute the length of the array type, based on its
-	     number of elements and the target type's length.
-	     Watch out for Ada null Ada arrays where the high bound
-	     is smaller than the low bound.  */
-	  const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
-	  const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
-	  ULONGEST len;
-
-	  if (high_bound < low_bound)
-	    len = 0;
-	  else
-	    {
-	      /* For now, we conservatively take the array length to be 0
-		 if its length exceeds UINT_MAX.  The code below assumes
-		 that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
-		 which is technically not guaranteed by C, but is usually true
-		 (because it would be true if x were unsigned with its
-		 high-order bit on).  It uses the fact that
-		 high_bound-low_bound is always representable in
-		 ULONGEST and that if high_bound-low_bound+1 overflows,
-		 it overflows to 0.  We must change these tests if we 
-		 decide to increase the representation of TYPE_LENGTH
-		 from unsigned int to ULONGEST.  */
-	      ULONGEST ulow = low_bound, uhigh = high_bound;
-	      ULONGEST tlen = TYPE_LENGTH (target_type);
-
-	      len = tlen * (uhigh - ulow + 1);
-	      if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh 
-		  || len > UINT_MAX)
-		len = 0;
-	    }
-	  TYPE_LENGTH (type) = len;
-	  TYPE_TARGET_STUB (type) = 0;
-	}
+	       || TYPE_CODE (type) == TYPE_CODE_STRING)
+        {
+          range_type = TYPE_INDEX_TYPE (type);
+          if (has_static_range (TYPE_RANGE_DATA (range_type)))
+            {
+              TYPE_LENGTH (type) = get_type_length (type);
+              TYPE_TARGET_STUB (type) = 0;
+            }
+        }
       else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
 	{
 	  TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index f563a1c..96e0ed7 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1097,6 +1097,11 @@ extern void allocate_gnat_aux_type (struct type *);
    TYPE_RANGE_DATA(range_type)->low_undefined
 #define TYPE_HIGH_BOUND_UNDEFINED(range_type) \
    TYPE_RANGE_DATA(range_type)->high_undefined
+#define TYPE_HIGH_BOUND_KIND(range_type) \
+  TYPE_RANGE_DATA(range_type)->high.kind
+#define TYPE_LOW_BOUND_KIND(range_type) \
+  TYPE_RANGE_DATA(range_type)->low.kind
+
 
 /* Moto-specific stuff for FORTRAN arrays.  */
 
@@ -1575,6 +1580,8 @@ extern struct type *lookup_unsigned_typename (const struct language_defn *,
 extern struct type *lookup_signed_typename (const struct language_defn *,
 					    struct gdbarch *, const char *);
 
+extern struct type *resolve_dynamic_type (struct type *, CORE_ADDR);
+
 extern struct type *check_typedef (struct type *);
 
 #define CHECK_TYPEDEF(TYPE)			\
diff --git a/gdb/value.c b/gdb/value.c
index d96d285..b9266db 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3183,9 +3183,10 @@ value_from_ulongest (struct type *type, ULONGEST num)
 struct value *
 value_from_pointer (struct type *type, CORE_ADDR addr)
 {
-  struct value *val = allocate_value (type);
+  struct type *resolved_type = resolve_dynamic_type (type, addr);
+  struct value *val = allocate_value (resolved_type);
 
-  store_typed_address (value_contents_raw (val), check_typedef (type), addr);
+  store_typed_address (value_contents_raw (val), check_typedef (resolved_type), addr);
   return val;
 }
 
@@ -3199,12 +3200,13 @@ value_from_contents_and_address (struct type *type,
 				 const gdb_byte *valaddr,
 				 CORE_ADDR address)
 {
+  struct type *resolved_type = resolve_dynamic_type (type, address);
   struct value *v;
 
   if (valaddr == NULL)
-    v = allocate_value_lazy (type);
+    v = allocate_value_lazy (resolved_type);
   else
-    v = value_from_contents (type, valaddr);
+    v = value_from_contents (resolved_type, valaddr);
   set_value_address (v, address);
   VALUE_LVAL (v) = lval_memory;
   return v;
-- 
1.7.0.7


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