mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
[gdb/DWARF] Introduce linked list for dynamic attributes
This patch introduces a linked list for dynamic attributes of a type. This is a pre-work for the Fortran dynamic array support. The Fortran dynamic array support will add more dynamic attributes to a type. As only a few types will have such dynamic attributes set, a linked list is more efficient in terms of memory consumption than adding multiple attributes to main_type. gdb/ChangeLog: * gdbtypes.c (resolve_dynamic_type_internal): Adapt data_location usage to linked list. (resolve_dynamic_type_internal): Adapt data_location to linked list. (get_dyn_prop, add_dyn_prop, copy_dynamic_prop_list): New function. (copy_type_recursive, copy_type): Add copy of linked list. * gdbtypes.h (enum dynamic_prop_node_kind): New enum. (struct dynamic_prop_list): New struct. * dwarf2read.c (set_die_type): Set data_location data.
This commit is contained in:
parent
2e7bf1d721
commit
d9823cbb39
@ -1,3 +1,15 @@
|
||||
2015-03-20 Keven Boell <keven.boell@intel.com>
|
||||
|
||||
* gdbtypes.c (resolve_dynamic_type_internal): Adapt
|
||||
data_location usage to linked list.
|
||||
(resolve_dynamic_type_internal): Adapt data_location to
|
||||
linked list.
|
||||
(get_dyn_prop, add_dyn_prop, copy_dynamic_prop_list): New function.
|
||||
(copy_type_recursive, copy_type): Add copy of linked list.
|
||||
* gdbtypes.h (enum dynamic_prop_node_kind): New enum.
|
||||
(struct dynamic_prop_list): New struct.
|
||||
* dwarf2read.c (set_die_type): Set data_location data.
|
||||
|
||||
2015-03-20 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* i386-sol2-tdep.c (i386_sol2_static_transform_name): Move "p" to
|
||||
|
@ -22085,11 +22085,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||
/* 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;
|
||||
}
|
||||
add_dyn_prop (DYN_ATTR_DATA_LOCATION, prop, type, objfile);
|
||||
|
||||
if (dwarf2_per_objfile->die_type_hash == NULL)
|
||||
{
|
||||
|
@ -2025,7 +2025,7 @@ resolve_dynamic_type_internal (struct type *type,
|
||||
{
|
||||
struct type *real_type = check_typedef (type);
|
||||
struct type *resolved_type = type;
|
||||
const struct dynamic_prop *prop;
|
||||
struct dynamic_prop *prop;
|
||||
CORE_ADDR value;
|
||||
|
||||
if (!is_dynamic_type_internal (real_type, top_level))
|
||||
@ -2080,13 +2080,11 @@ resolve_dynamic_type_internal (struct type *type,
|
||||
|
||||
/* Resolve data_location attribute. */
|
||||
prop = TYPE_DATA_LOCATION (resolved_type);
|
||||
if (dwarf2_evaluate_property (prop, addr_stack, &value))
|
||||
if (prop != NULL && dwarf2_evaluate_property (prop, addr_stack, &value))
|
||||
{
|
||||
TYPE_DATA_LOCATION_ADDR (resolved_type) = value;
|
||||
TYPE_DATA_LOCATION_KIND (resolved_type) = PROP_CONST;
|
||||
TYPE_DYN_PROP_ADDR (prop) = value;
|
||||
TYPE_DYN_PROP_KIND (prop) = PROP_CONST;
|
||||
}
|
||||
else
|
||||
TYPE_DATA_LOCATION (resolved_type) = NULL;
|
||||
|
||||
return resolved_type;
|
||||
}
|
||||
@ -2101,6 +2099,42 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr)
|
||||
return resolve_dynamic_type_internal (type, &pinfo, 1);
|
||||
}
|
||||
|
||||
/* See gdbtypes.h */
|
||||
|
||||
struct dynamic_prop *
|
||||
get_dyn_prop (enum dynamic_prop_node_kind prop_kind, const struct type *type)
|
||||
{
|
||||
struct dynamic_prop_list *node = TYPE_DYN_PROP_LIST (type);
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
if (node->prop_kind == prop_kind)
|
||||
return node->prop;
|
||||
node = node->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* See gdbtypes.h */
|
||||
|
||||
void
|
||||
add_dyn_prop (enum dynamic_prop_node_kind prop_kind, struct dynamic_prop prop,
|
||||
struct type *type, struct objfile *objfile)
|
||||
{
|
||||
struct dynamic_prop_list *temp;
|
||||
|
||||
gdb_assert (TYPE_OBJFILE_OWNED (type));
|
||||
|
||||
temp = obstack_alloc (&objfile->objfile_obstack,
|
||||
sizeof (struct dynamic_prop_list));
|
||||
temp->prop_kind = prop_kind;
|
||||
temp->prop = obstack_copy (&objfile->objfile_obstack, &prop, sizeof (prop));
|
||||
temp->next = TYPE_DYN_PROP_LIST (type);
|
||||
|
||||
TYPE_DYN_PROP_LIST (type) = temp;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
@ -4230,6 +4264,31 @@ create_copied_types_hash (struct objfile *objfile)
|
||||
dummy_obstack_deallocate);
|
||||
}
|
||||
|
||||
/* Recursively copy (deep copy) a dynamic attribute list of a type. */
|
||||
|
||||
static struct dynamic_prop_list *
|
||||
copy_dynamic_prop_list (struct obstack *objfile_obstack,
|
||||
struct dynamic_prop_list *list)
|
||||
{
|
||||
struct dynamic_prop_list *copy = list;
|
||||
struct dynamic_prop_list **node_ptr = ©
|
||||
|
||||
while (*node_ptr != NULL)
|
||||
{
|
||||
struct dynamic_prop_list *node_copy;
|
||||
|
||||
node_copy = obstack_copy (objfile_obstack, *node_ptr,
|
||||
sizeof (struct dynamic_prop_list));
|
||||
node_copy->prop = obstack_copy (objfile_obstack, (*node_ptr)->prop,
|
||||
sizeof (struct dynamic_prop));
|
||||
*node_ptr = node_copy;
|
||||
|
||||
node_ptr = &node_copy->next;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* Recursively copy (deep copy) TYPE, if it is associated with
|
||||
OBJFILE. Return a new type allocated using malloc, a saved type if
|
||||
we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
|
||||
@ -4333,14 +4392,11 @@ 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));
|
||||
}
|
||||
if (TYPE_DYN_PROP_LIST (type) != NULL)
|
||||
TYPE_DYN_PROP_LIST (new_type)
|
||||
= copy_dynamic_prop_list (&objfile->objfile_obstack,
|
||||
TYPE_DYN_PROP_LIST (type));
|
||||
|
||||
|
||||
/* Copy pointers to other types. */
|
||||
if (TYPE_TARGET_TYPE (type))
|
||||
@ -4404,13 +4460,10 @@ 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));
|
||||
}
|
||||
if (TYPE_DYN_PROP_LIST (type) != NULL)
|
||||
TYPE_DYN_PROP_LIST (new_type)
|
||||
= copy_dynamic_prop_list (&TYPE_OBJFILE (type) -> objfile_obstack,
|
||||
TYPE_DYN_PROP_LIST (type));
|
||||
|
||||
return new_type;
|
||||
}
|
||||
|
@ -434,6 +434,26 @@ struct dynamic_prop
|
||||
union dynamic_prop_data data;
|
||||
};
|
||||
|
||||
/* * Define a type's dynamic property node kind. */
|
||||
enum dynamic_prop_node_kind
|
||||
{
|
||||
/* A property providing a type's data location.
|
||||
Evaluating this field yields to the location of an object's data. */
|
||||
DYN_ATTR_DATA_LOCATION,
|
||||
};
|
||||
|
||||
/* * List for dynamic type attributes. */
|
||||
struct dynamic_prop_list
|
||||
{
|
||||
/* The kind of dynamic prop in this node. */
|
||||
enum dynamic_prop_node_kind prop_kind;
|
||||
|
||||
/* The dynamic property itself. */
|
||||
struct dynamic_prop *prop;
|
||||
|
||||
/* A pointer to the next dynamic property. */
|
||||
struct dynamic_prop_list *next;
|
||||
};
|
||||
|
||||
/* * Determine which field of the union main_type.fields[x].loc is
|
||||
used. */
|
||||
@ -719,10 +739,8 @@ struct main_type
|
||||
|
||||
union type_specific 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;
|
||||
/* * Contains all dynamic type properties. */
|
||||
struct dynamic_prop_list *dyn_prop_list;
|
||||
};
|
||||
|
||||
/* * A ``struct type'' describes a particular instance of a type, with
|
||||
@ -1238,9 +1256,9 @@ 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. */
|
||||
/* Property accessors for the type data location. */
|
||||
#define TYPE_DATA_LOCATION(thistype) \
|
||||
TYPE_MAIN_TYPE(thistype)->data_location
|
||||
get_dyn_prop (DYN_ATTR_DATA_LOCATION, thistype)
|
||||
#define TYPE_DATA_LOCATION_BATON(thistype) \
|
||||
TYPE_DATA_LOCATION (thistype)->data.baton
|
||||
#define TYPE_DATA_LOCATION_ADDR(thistype) \
|
||||
@ -1248,6 +1266,17 @@ extern void allocate_gnat_aux_type (struct type *);
|
||||
#define TYPE_DATA_LOCATION_KIND(thistype) \
|
||||
TYPE_DATA_LOCATION (thistype)->kind
|
||||
|
||||
/* Attribute accessors for dynamic properties. */
|
||||
#define TYPE_DYN_PROP_LIST(thistype) \
|
||||
TYPE_MAIN_TYPE(thistype)->dyn_prop_list
|
||||
#define TYPE_DYN_PROP_BATON(dynprop) \
|
||||
dynprop->data.baton
|
||||
#define TYPE_DYN_PROP_ADDR(dynprop) \
|
||||
dynprop->data.const_val
|
||||
#define TYPE_DYN_PROP_KIND(dynprop) \
|
||||
dynprop->kind
|
||||
|
||||
|
||||
/* Moto-specific stuff for FORTRAN arrays. */
|
||||
|
||||
#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \
|
||||
@ -1767,6 +1796,20 @@ extern struct type *resolve_dynamic_type (struct type *type, CORE_ADDR addr);
|
||||
/* * Predicate if the type has dynamic values, which are not resolved yet. */
|
||||
extern int is_dynamic_type (struct type *type);
|
||||
|
||||
/* * Return the dynamic property of the requested KIND from TYPE's
|
||||
list of dynamic properties. */
|
||||
extern struct dynamic_prop *get_dyn_prop
|
||||
(enum dynamic_prop_node_kind kind, const struct type *type);
|
||||
|
||||
/* * Given a dynamic property PROP of a given KIND, add this dynamic
|
||||
property to the given TYPE.
|
||||
|
||||
This function assumes that TYPE is objfile-owned, and that OBJFILE
|
||||
is the TYPE's objfile. */
|
||||
extern void add_dyn_prop
|
||||
(enum dynamic_prop_node_kind kind, struct dynamic_prop prop,
|
||||
struct type *type, struct objfile *objfile);
|
||||
|
||||
extern struct type *check_typedef (struct type *);
|
||||
|
||||
#define CHECK_TYPEDEF(TYPE) \
|
||||
|
Loading…
Reference in New Issue
Block a user