Add support for DW_AT_data_location.
authorJoel Brobecker <brobecker@adacore.com>
Mon, 11 Aug 2014 23:37:10 +0000 (16:37 -0700)
committerJoel Brobecker <brobecker@adacore.com>
Mon, 18 Aug 2014 16:12:53 +0000 (18:12 +0200)
gdb/ChangeLog:

        * gdbtypes.h (struct main_type): Add field "data_location".
        (TYPE_DATA_LOCATION, TYPE_DATA_LOCATION_BATON)
        (TYPE_DATA_LOCATION_ADDR, TYPE_DATA_LOCATION_KIND): New macros.
        * gdbtypes.c (is_dynamic_type): Return 1 if the type has
        a dynamic data location.
        (resolve_dynamic_type): Add DW_AT_data_location handling.
        (copy_recursive, copy_type): Copy the data_location information
        when present.
        * dwarf2read.c (set_die_type): Add DW_AT_data_location handling.
        * value.c (value_from_contents_and_address): Add
        DW_AT_data_location handling.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/value.c

index 607a5c31d93963698f4089a69f52e407f989ae26..1d35ac3f37450590c62c4826ec1525d9c88848ac 100644 (file)
@@ -1,3 +1,18 @@
+2014-08-18  Keven Boell  <keven.boell@intel.com>
+           Joel Brobecker  <brobecker@adacore.com>
+
+       * gdbtypes.h (struct main_type): Add field "data_location".
+       (TYPE_DATA_LOCATION, TYPE_DATA_LOCATION_BATON)
+       (TYPE_DATA_LOCATION_ADDR, TYPE_DATA_LOCATION_KIND): New macros.
+       * gdbtypes.c (is_dynamic_type): Return 1 if the type has
+       a dynamic data location.
+       (resolve_dynamic_type): Add DW_AT_data_location handling.
+       (copy_recursive, copy_type): Copy the data_location information
+       when present.
+       * dwarf2read.c (set_die_type): Add DW_AT_data_location handling.
+       * value.c (value_from_contents_and_address): Add
+       DW_AT_data_location handling.
+
 2014-08-18  Keven Boell  <keven.boell@intel.com>
            Joel Brobecker  <brobecker@adacore.com>
 
index 801f05d9b996887da7bbb99e1114a83f36e5ed10..11580cc632317deae92538f0db3279ca83cd5655 100644 (file)
@@ -21669,6 +21669,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
   struct dwarf2_per_cu_offset_and_type **slot, ofs;
   struct objfile *objfile = cu->objfile;
+  struct attribute *attr;
+  struct dynamic_prop prop;
 
   /* For Ada types, make sure that the gnat-specific data is always
      initialized (if not already set).  There are a few types where
@@ -21683,6 +21685,15 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
       && !HAVE_GNAT_AUX_INFO (type))
     INIT_GNAT_SPECIFIC (type);
 
+  /* Read DW_AT_data_location and set in type.  */
+  attr = dwarf2_attr (die, DW_AT_data_location, cu);
+  if (attr_to_dynamic_prop (attr, die, cu, &prop))
+    {
+      TYPE_DATA_LOCATION (type)
+        = obstack_alloc (&objfile->objfile_obstack, sizeof (prop));
+      *TYPE_DATA_LOCATION (type) = prop;
+    }
+
   if (dwarf2_per_objfile->die_type_hash == NULL)
     {
       dwarf2_per_objfile->die_type_hash =
index 0e18304d74791735f3e0f0fb9c68bd8f4dd3902a..1326f85c6acdc17be3408016ed9dc33cbeacc27a 100644 (file)
@@ -1620,6 +1620,17 @@ is_dynamic_type_internal (struct type *type, int top_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:
@@ -1852,6 +1863,8 @@ resolve_dynamic_type_internal (struct type *type, CORE_ADDR addr,
 {
   struct type *real_type = check_typedef (type);
   struct type *resolved_type = type;
+  const struct dynamic_prop *prop;
+  CORE_ADDR value;
 
   if (!is_dynamic_type_internal (real_type, top_level))
     return type;
@@ -1893,6 +1906,16 @@ resolve_dynamic_type_internal (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;
 }
 
@@ -4110,6 +4133,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) = 
@@ -4155,6 +4187,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;
 }
index 5008ef4f42135e14862cfc2deca54fe8e729692f..bd1a0ab2fe0b1ee09592d309618c0e1563d29bd7 100644 (file)
@@ -724,6 +724,11 @@ struct main_type
 
     struct func_type *func_stuff;
   } type_specific;
+
+  /* * Contains a location description value for the current type. Evaluating
+     this field yields to the location of the data for an object.  */
+
+  struct dynamic_prop *data_location;
 };
 
 /* * A ``struct type'' describes a particular instance of a type, with
@@ -1203,6 +1208,16 @@ extern void allocate_gnat_aux_type (struct type *);
 #define TYPE_LOW_BOUND_KIND(range_type) \
   TYPE_RANGE_DATA(range_type)->low.kind
 
+/* Attribute accessors for the type data location.  */
+#define TYPE_DATA_LOCATION(thistype) \
+  TYPE_MAIN_TYPE(thistype)->data_location
+#define TYPE_DATA_LOCATION_BATON(thistype) \
+  TYPE_DATA_LOCATION (thistype)->data.baton
+#define TYPE_DATA_LOCATION_ADDR(thistype) \
+  TYPE_DATA_LOCATION (thistype)->data.const_val
+#define TYPE_DATA_LOCATION_KIND(thistype) \
+  TYPE_DATA_LOCATION (thistype)->kind
+
 /* Moto-specific stuff for FORTRAN arrays.  */
 
 #define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \
index 355194e33afd8ff61cb691f7c79d64ea99a63c16..3d460bd3d0be9b6555dbfb0f85bc7376bf89cd30 100644 (file)
@@ -3398,6 +3398,9 @@ value_from_contents_and_address (struct type *type,
     v = allocate_value_lazy (resolved_type);
   else
     v = value_from_contents (resolved_type, valaddr);
+  if (TYPE_DATA_LOCATION (resolved_type) != NULL
+      && TYPE_DATA_LOCATION_KIND (resolved_type) == PROP_CONST)
+    address = TYPE_DATA_LOCATION_ADDR (resolved_type);
   set_value_address (v, address);
   VALUE_LVAL (v) = lval_memory;
   return v;