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.
This commit is contained in:
Joel Brobecker
2014-08-11 16:37:10 -07:00
parent 08412b0722
commit 3cdcd0ce16
5 changed files with 83 additions and 0 deletions

View 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;
}