Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / gdbtypes.c
index d0c002f..ee33d77 100644 (file)
@@ -20,7 +20,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include <string.h>
 #include "bfd.h"
 #include "symtab.h"
 #include "symfile.h"
@@ -34,9 +33,7 @@
 #include "complaints.h"
 #include "gdbcmd.h"
 #include "cp-abi.h"
-#include "gdb_assert.h"
 #include "hashtab.h"
-#include "exceptions.h"
 #include "cp-support.h"
 #include "bcache.h"
 #include "dwarf2loc.h"
@@ -1611,16 +1608,28 @@ stub_noname_complaint (void)
   complaint (&symfile_complaints, _("stub type has NULL name"));
 }
 
-/* See gdbtypes.h.  */
+/* Worker for is_dynamic_type.  */
 
-int
-is_dynamic_type (struct type *type)
+static int
+is_dynamic_type_internal (struct type *type, int top_level)
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  /* We only want to recognize references at the outermost level.  */
+  if (top_level && TYPE_CODE (type) == TYPE_CODE_REF)
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
+  /* Types that have a dynamic TYPE_DATA_LOCATION are considered
+     dynamic, even if the type itself is statically defined.
+     From a user's point of view, this may appear counter-intuitive;
+     but it makes sense in this context, because the point is to determine
+     whether any part of the type needs to be resolved before it can
+     be exploited.  */
+  if (TYPE_DATA_LOCATION (type) != NULL
+      && (TYPE_DATA_LOCATION_KIND (type) == PROP_LOCEXPR
+         || TYPE_DATA_LOCATION_KIND (type) == PROP_LOCLIST))
+    return 1;
+
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_RANGE:
@@ -1632,9 +1641,9 @@ is_dynamic_type (struct type *type)
 
        /* The array is dynamic if either the bounds are dynamic,
           or the elements it contains have a dynamic contents.  */
-       if (is_dynamic_type (TYPE_INDEX_TYPE (type)))
+       if (is_dynamic_type_internal (TYPE_INDEX_TYPE (type), 0))
          return 1;
-       return is_dynamic_type (TYPE_TARGET_TYPE (type));
+       return is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0);
       }
 
     case TYPE_CODE_STRUCT:
@@ -1644,7 +1653,7 @@ is_dynamic_type (struct type *type)
 
        for (i = 0; i < TYPE_NFIELDS (type); ++i)
          if (!field_is_static (&TYPE_FIELD (type, i))
-             && is_dynamic_type (TYPE_FIELD_TYPE (type, i)))
+             && is_dynamic_type_internal (TYPE_FIELD_TYPE (type, i), 0))
            return 1;
       }
       break;
@@ -1653,11 +1662,23 @@ is_dynamic_type (struct type *type)
   return 0;
 }
 
-/* Given a dynamic range type (dyn_range_type), return a static version
-   of that type.  */
+/* See gdbtypes.h.  */
+
+int
+is_dynamic_type (struct type *type)
+{
+  return is_dynamic_type_internal (type, 1);
+}
+
+static struct type *resolve_dynamic_type_internal (struct type *type,
+                                                  CORE_ADDR addr,
+                                                  int top_level);
+
+/* Given a dynamic range type (dyn_range_type) and address,
+   return a static version of that type.  */
 
 static struct type *
-resolve_dynamic_range (struct type *dyn_range_type)
+resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr)
 {
   CORE_ADDR value;
   struct type *static_range_type;
@@ -1668,7 +1689,7 @@ resolve_dynamic_range (struct type *dyn_range_type)
   gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
 
   prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
-  if (dwarf2_evaluate_property (prop, &value))
+  if (dwarf2_evaluate_property (prop, addr, &value))
     {
       low_bound.kind = PROP_CONST;
       low_bound.data.const_val = value;
@@ -1680,7 +1701,7 @@ resolve_dynamic_range (struct type *dyn_range_type)
     }
 
   prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
-  if (dwarf2_evaluate_property (prop, &value))
+  if (dwarf2_evaluate_property (prop, addr, &value))
     {
       high_bound.kind = PROP_CONST;
       high_bound.data.const_val = value;
@@ -1707,7 +1728,7 @@ resolve_dynamic_range (struct type *dyn_range_type)
    of the associated array.  */
 
 static struct type *
-resolve_dynamic_array (struct type *type)
+resolve_dynamic_array (struct type *type, CORE_ADDR addr)
 {
   CORE_ADDR value;
   struct type *elt_type;
@@ -1718,12 +1739,12 @@ resolve_dynamic_array (struct type *type)
 
   elt_type = type;
   range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
-  range_type = resolve_dynamic_range (range_type);
+  range_type = resolve_dynamic_range (range_type, addr);
 
   ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
 
   if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
-    elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type));
+    elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type), addr);
   else
     elt_type = TYPE_TARGET_TYPE (type);
 
@@ -1758,7 +1779,8 @@ resolve_dynamic_union (struct type *type, CORE_ADDR addr)
       if (field_is_static (&TYPE_FIELD (type, i)))
        continue;
 
-      t = resolve_dynamic_type (TYPE_FIELD_TYPE (resolved_type, i), addr);
+      t = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
+                                        addr, 0);
       TYPE_FIELD_TYPE (resolved_type, i) = t;
       if (TYPE_LENGTH (t) > max_len)
        max_len = TYPE_LENGTH (t);
@@ -1776,7 +1798,7 @@ resolve_dynamic_struct (struct type *type, CORE_ADDR addr)
 {
   struct type *resolved_type;
   int i;
-  int vla_field = TYPE_NFIELDS (type) - 1;
+  unsigned resolved_type_bit_length = 0;
 
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);
   gdb_assert (TYPE_NFIELDS (type) > 0);
@@ -1790,48 +1812,60 @@ resolve_dynamic_struct (struct type *type, CORE_ADDR addr)
          TYPE_NFIELDS (resolved_type) * sizeof (struct field));
   for (i = 0; i < TYPE_NFIELDS (resolved_type); ++i)
     {
-      struct type *t;
+      unsigned new_bit_length;
 
       if (field_is_static (&TYPE_FIELD (type, i)))
        continue;
 
-      t = resolve_dynamic_type (TYPE_FIELD_TYPE (resolved_type, i), addr);
-
-      /* This is a bit odd.  We do not support a VLA in any position
-        of a struct except for the last.  GCC does have an extension
-        that allows a VLA in the middle of a structure, but the DWARF
-        it emits is relatively useless to us, so we can't represent
-        such a type properly -- and even if we could, we do not have
-        enough information to redo structure layout anyway.
-        Nevertheless, we check all the fields in case something odd
-        slips through, since it's better to see an error than
-        incorrect results.  */
-      if (t != TYPE_FIELD_TYPE (resolved_type, i)
-         && i != vla_field)
-       error (_("Attempt to resolve a variably-sized type which appears "
-                "in the interior of a structure type"));
-
-      TYPE_FIELD_TYPE (resolved_type, i) = t;
+      TYPE_FIELD_TYPE (resolved_type, i)
+       = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
+                                        addr, 0);
+
+      /* As we know this field is not a static field, the field's
+        field_loc_kind should be FIELD_LOC_KIND_BITPOS.  Verify
+        this is the case, but only trigger a simple error rather
+        than an internal error if that fails.  While failing
+        that verification indicates a bug in our code, the error
+        is not severe enough to suggest to the user he stops
+        his debugging session because of it.  */
+      if (TYPE_FIELD_LOC_KIND (resolved_type, i) != FIELD_LOC_KIND_BITPOS)
+       error (_("Cannot determine struct field location"
+                " (invalid location kind)"));
+      new_bit_length = TYPE_FIELD_BITPOS (resolved_type, i);
+      if (TYPE_FIELD_BITSIZE (resolved_type, i) != 0)
+       new_bit_length += TYPE_FIELD_BITSIZE (resolved_type, i);
+      else
+       new_bit_length += (TYPE_LENGTH (TYPE_FIELD_TYPE (resolved_type, i))
+                          * TARGET_CHAR_BIT);
+
+      /* Normally, we would use the position and size of the last field
+        to determine the size of the enclosing structure.  But GCC seems
+        to be encoding the position of some fields incorrectly when
+        the struct contains a dynamic field that is not placed last.
+        So we compute the struct size based on the field that has
+        the highest position + size - probably the best we can do.  */
+      if (new_bit_length > resolved_type_bit_length)
+       resolved_type_bit_length = new_bit_length;
     }
 
-  /* Due to the above restrictions we can successfully compute
-     the size of the resulting structure here, as the offset of
-     the final field plus its size.  */
   TYPE_LENGTH (resolved_type)
-    = (TYPE_FIELD_BITPOS (resolved_type, vla_field) / TARGET_CHAR_BIT
-       + TYPE_LENGTH (TYPE_FIELD_TYPE (resolved_type, vla_field)));
+    = (resolved_type_bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+
   return resolved_type;
 }
 
-/* See gdbtypes.h  */
+/* Worker for resolved_dynamic_type.  */
 
-struct type *
-resolve_dynamic_type (struct type *type, CORE_ADDR addr)
+static struct type *
+resolve_dynamic_type_internal (struct type *type, CORE_ADDR addr,
+                              int top_level)
 {
   struct type *real_type = check_typedef (type);
   struct type *resolved_type = type;
+  const struct dynamic_prop *prop;
+  CORE_ADDR value;
 
-  if (!is_dynamic_type (real_type))
+  if (!is_dynamic_type_internal (real_type, top_level))
     return type;
 
   switch (TYPE_CODE (type))
@@ -1839,7 +1873,8 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr)
       case TYPE_CODE_TYPEDEF:
        resolved_type = copy_type (type);
        TYPE_TARGET_TYPE (resolved_type)
-         = resolve_dynamic_type (TYPE_TARGET_TYPE (type), addr);
+         = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type), addr,
+                                          top_level);
        break;
 
       case TYPE_CODE_REF:
@@ -1848,16 +1883,17 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr)
 
          resolved_type = copy_type (type);
          TYPE_TARGET_TYPE (resolved_type)
-           = resolve_dynamic_type (TYPE_TARGET_TYPE (type), target_addr);
+           = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type),
+                                            target_addr, top_level);
          break;
        }
 
       case TYPE_CODE_ARRAY:
-       resolved_type = resolve_dynamic_array (type);
+       resolved_type = resolve_dynamic_array (type, addr);
        break;
 
       case TYPE_CODE_RANGE:
-       resolved_type = resolve_dynamic_range (type);
+       resolved_type = resolve_dynamic_range (type, addr);
        break;
 
     case TYPE_CODE_UNION:
@@ -1869,9 +1905,27 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr)
       break;
     }
 
+  /* Resolve data_location attribute.  */
+  prop = TYPE_DATA_LOCATION (resolved_type);
+  if (dwarf2_evaluate_property (prop, addr, &value))
+    {
+      TYPE_DATA_LOCATION_ADDR (resolved_type) = value;
+      TYPE_DATA_LOCATION_KIND (resolved_type) = PROP_CONST;
+    }
+  else
+    TYPE_DATA_LOCATION (resolved_type) = NULL;
+
   return resolved_type;
 }
 
+/* See gdbtypes.h  */
+
+struct type *
+resolve_dynamic_type (struct type *type, CORE_ADDR addr)
+{
+  return resolve_dynamic_type_internal (type, addr, 1);
+}
+
 /* 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
@@ -4078,6 +4132,15 @@ copy_type_recursive (struct objfile *objfile,
       *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
     }
 
+  /* Copy the data location information.  */
+  if (TYPE_DATA_LOCATION (type) != NULL)
+    {
+      TYPE_DATA_LOCATION (new_type)
+       = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
+      memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
+             sizeof (struct dynamic_prop));
+    }
+
   /* Copy pointers to other types.  */
   if (TYPE_TARGET_TYPE (type))
     TYPE_TARGET_TYPE (new_type) = 
@@ -4123,6 +4186,13 @@ copy_type (const struct type *type)
   TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
   memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
          sizeof (struct main_type));
+  if (TYPE_DATA_LOCATION (type) != NULL)
+    {
+      TYPE_DATA_LOCATION (new_type)
+       = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
+      memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
+             sizeof (struct dynamic_prop));
+    }
 
   return new_type;
 }