aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2014-08-11 16:37:10 -0700
committerJoel Brobecker <brobecker@adacore.com>2014-08-18 18:12:53 +0200
commit3cdcd0ce16272ae8e8183699a341d081b6eb1b21 (patch)
tree3309ad37199b955af054b55452df2af528117a60
parent08412b0722301c4ffbd9fd51d4056bc436b69658 (diff)
downloadgdb-3cdcd0ce16272ae8e8183699a341d081b6eb1b21.zip
gdb-3cdcd0ce16272ae8e8183699a341d081b6eb1b21.tar.gz
gdb-3cdcd0ce16272ae8e8183699a341d081b6eb1b21.tar.bz2
Add support for DW_AT_data_location.
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.
-rw-r--r--gdb/ChangeLog15
-rw-r--r--gdb/dwarf2read.c11
-rw-r--r--gdb/gdbtypes.c39
-rw-r--r--gdb/gdbtypes.h15
-rw-r--r--gdb/value.c3
5 files changed, 83 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 607a5c3..1d35ac3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,21 @@
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>
+
* dwarf2expr.h (struct dwarf_expr_context_funcs): Uncomment
field "get_object_address".
* dwarf2expr.c (execute_stack_op): Add handling for
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 801f05d..11580cc 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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 =
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 0e18304..1326f85 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -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;
}
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 5008ef4..bd1a0ab 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -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) \
diff --git a/gdb/value.c b/gdb/value.c
index 355194e..3d460bd 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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;