gdb/gdb-vla-intel-09of23.patch

317 lines
12 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Subject: [PATCH 09/23] vla: changed string length semantic.
Message-Id: <1401861266-6240-10-git-send-email-keven.boell@intel.com>
This patch changes the semantic of the Dwarf string length
attribute to reflect the standard. This serves as pre-work
to get variable strings in Fortran to work.
2014-05-28 Keven Boell <keven.boell@intel.com>
Sanimir Agovic <sanimir.agovic@intel.com>
* dwarf2read.c (read_tag_string_type): changed
semantic of DW_AT_string_length to be able to
handle Dwarf blocks as well. Support for
DW_AT_byte_length added to get correct length
if specified in combination with
DW_AT_string_length.
(attr_to_dynamic_prop): added
functionality to add Dwarf operators to baton
data attribute. Added post values to baton
as required by the string evaluation case.
(read_subrange_type): Adapt caller.
(set_die_type): Adapt caller.
(add_post_values_to_baton): New function.
* dwarf2loc.c (dwarf2_evaluate_property): Evaluate
post processing dwarf.
* dwarf2loc.h (struct dwarf2_property_baton): Add
post dwarf values attribute.
Change-Id: I6edfa005f416cddc8e364d34891b9abf6b44f757
Signed-off-by: Keven Boell <keven.boell@intel.com>
---
gdb/dwarf2loc.c | 10 +++++
gdb/dwarf2loc.h | 3 ++
gdb/dwarf2read.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 127 insertions(+), 15 deletions(-)
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 7ab734d..2473f80 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2533,6 +2533,11 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
*value = value_as_address (val);
}
+ if (baton->post_values.data && baton->post_values.size > 0)
+ {
+ CORE_ADDR new_addr = *value;
+ dwarf2_locexpr_baton_eval (&baton->post_values, new_addr, value);
+ }
return 1;
}
}
@@ -2555,6 +2560,11 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
if (!value_optimized_out (val))
{
*value = value_as_address (val);
+ if (baton->post_values.data && baton->post_values.size > 0)
+ {
+ CORE_ADDR new_addr = *value;
+ dwarf2_locexpr_baton_eval (&baton->post_values, new_addr, value);
+ }
return 1;
}
}
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index fb65c5c..cf648eb 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -168,6 +168,9 @@ struct dwarf2_property_baton
/* Location list to be evaluated in the context of REFERENCED_TYPE. */
struct dwarf2_loclist_baton loclist;
};
+
+ /* Attributes, which will be pushed after evaluating locexpr or loclist. */
+ struct dwarf2_locexpr_baton post_values;
};
extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ea66602..0b23701 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1842,6 +1842,15 @@ static void free_dwo_file_cleanup (void *);
static void process_cu_includes (void);
static void check_producer (struct dwarf2_cu *cu);
+
+static int
+attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
+ struct dwarf2_cu *cu, struct dynamic_prop *prop,
+ const gdb_byte *additional_data, int additional_data_size);
+
+static void add_post_values_to_baton (struct dwarf2_property_baton *baton,
+ const gdb_byte *data, int size, struct dwarf2_cu *cu);
+
/* Various complaints about symbol reading that don't abort the process. */
@@ -14029,29 +14038,90 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type, *range_type, *index_type, *char_type;
struct attribute *attr;
- unsigned int length;
+ unsigned int length = UINT_MAX;
+
+ index_type = objfile_type (objfile)->builtin_int;
+ range_type = create_static_range_type (NULL, index_type, 1, length);
+ /* If DW_AT_string_length is defined, the length is stored at some location
+ * in memory. */
attr = dwarf2_attr (die, DW_AT_string_length, cu);
if (attr)
{
- length = DW_UNSND (attr);
+ if (attr_form_is_block (attr))
+ {
+ struct attribute *byte_size, *bit_size;
+ struct dynamic_prop high;
+
+ byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
+ bit_size = dwarf2_attr (die, DW_AT_bit_size, cu);
+
+ /* DW_AT_byte_size should never occur together in combination with
+ DW_AT_string_length. */
+ if ((byte_size == NULL && bit_size != NULL) ||
+ (byte_size != NULL && bit_size == NULL))
+ complaint (&symfile_complaints, _("DW_AT_byte_size AND "
+ "DW_AT_bit_size found together at the same time."));
+
+ /* If DW_AT_string_length AND DW_AT_byte_size exist together, it
+ describes the number of bytes that should be read from the length
+ memory location. */
+ if (byte_size != NULL && bit_size == NULL)
+ {
+ /* Build new dwarf2_locexpr_baton structure with additions to the
+ data attribute, to reflect DWARF specialities to get address
+ sizes. */
+ const gdb_byte append_ops[] = {
+ DW_OP_push_object_address,
+ /* DW_OP_deref_size: size of an address on the target machine
+ (bytes), where the size will be specified by the next
+ operand. */
+ DW_OP_deref_size,
+ /* Operand for DW_OP_deref_size. */
+ DW_UNSND (byte_size) };
+
+ if (!attr_to_dynamic_prop (attr, die, cu, &high,
+ append_ops, ARRAY_SIZE (append_ops)))
+ complaint (&symfile_complaints,
+ _("Could not parse DW_AT_byte_size"));
+ }
+ else if (bit_size != NULL && byte_size == NULL)
+ complaint (&symfile_complaints, _("DW_AT_string_length AND "
+ "DW_AT_bit_size found but not supported yet."));
+ /* If DW_AT_string_length WITHOUT DW_AT_byte_size exist, the default
+ is the address size of the target machine. */
+ else
+ {
+ if (!attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0))
+ complaint (&symfile_complaints,
+ _("Could not parse DW_AT_string_length"));
+ }
+
+ TYPE_RANGE_DATA (range_type)->high = high;
+ }
+ else
+ {
+ TYPE_HIGH_BOUND (range_type) = DW_UNSND (attr);
+ TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST;
+ }
}
else
{
- /* Check for the DW_AT_byte_size attribute. */
+ /* Check for the DW_AT_byte_size attribute, which represents the length
+ in this case. */
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
- length = DW_UNSND (attr);
+ TYPE_HIGH_BOUND (range_type) = DW_UNSND (attr);
+ TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST;
}
else
{
- length = 1;
+ TYPE_HIGH_BOUND (range_type) = 1;
+ TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST;
}
}
- index_type = objfile_type (objfile)->builtin_int;
- range_type = create_static_range_type (NULL, index_type, 1, length);
char_type = language_string_char_type (cu->language_defn, gdbarch);
type = create_string_type (NULL, char_type, range_type);
@@ -14368,13 +14438,36 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, type, cu);
}
+/* Add post processing op-codes to a dwarf2_property_baton. */
+
+static void add_post_values_to_baton (struct dwarf2_property_baton *baton,
+ const gdb_byte *data, int size, struct dwarf2_cu *cu)
+{
+ if (data != NULL && size > 0)
+ {
+ struct obstack *obstack = &cu->objfile->objfile_obstack;
+ gdb_byte *post_data;
+
+ post_data = obstack_alloc (obstack, size);
+ memcpy(post_data, data, size);
+ baton->post_values.data = post_data;
+ baton->post_values.size = size;
+ baton->post_values.per_cu = cu->per_cu;
+ } else {
+ baton->post_values.data = NULL;
+ baton->post_values.size = 0;
+ baton->post_values.per_cu = NULL;
+ }
+}
+
/* Parse dwarf attribute if it's a block, reference or constant and put the
resulting value of the attribute into struct bound_prop.
Returns 1 if ATTR could be resolved into PROP, 0 otherwise. */
static int
attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
- struct dwarf2_cu *cu, struct dynamic_prop *prop)
+ struct dwarf2_cu *cu, struct dynamic_prop *prop,
+ const gdb_byte *additional_data, int additional_data_size)
{
struct dwarf2_property_baton *baton;
struct obstack *obstack = &cu->objfile->objfile_obstack;
@@ -14387,8 +14480,10 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
baton = obstack_alloc (obstack, sizeof (*baton));
baton->referenced_type = NULL;
baton->locexpr.per_cu = cu->per_cu;
- baton->locexpr.size = DW_BLOCK (attr)->size;
baton->locexpr.data = DW_BLOCK (attr)->data;
+ baton->locexpr.size = DW_BLOCK (attr)->size;
+ add_post_values_to_baton (baton, additional_data,
+ additional_data_size, cu);
prop->data.baton = baton;
prop->kind = PROP_LOCEXPR;
gdb_assert (prop->data.baton != NULL);
@@ -14409,6 +14504,8 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
baton = obstack_alloc (obstack, sizeof (*baton));
baton->referenced_type = die_type (target_die, target_cu);
fill_in_loclist_baton (cu, &baton->loclist, target_attr);
+ add_post_values_to_baton (baton, additional_data,
+ additional_data_size, cu);
prop->data.baton = baton;
prop->kind = PROP_LOCLIST;
gdb_assert (prop->data.baton != NULL);
@@ -14420,6 +14517,8 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.size = DW_BLOCK (target_attr)->size;
baton->locexpr.data = DW_BLOCK (target_attr)->data;
+ add_post_values_to_baton (baton, additional_data,
+ additional_data_size, cu);
prop->data.baton = baton;
prop->kind = PROP_LOCEXPR;
gdb_assert (prop->data.baton != NULL);
@@ -14509,17 +14608,17 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
if (attr)
- attr_to_dynamic_prop (attr, die, cu, &low);
+ attr_to_dynamic_prop (attr, die, cu, &low, NULL, 0);
else if (!low_default_is_valid)
complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
"- DIE at 0x%x [in module %s]"),
die->offset.sect_off, objfile_name (cu->objfile));
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
- if (!attr_to_dynamic_prop (attr, die, cu, &high))
+ if (!attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0))
{
attr = dwarf2_attr (die, DW_AT_count, cu);
- if (attr_to_dynamic_prop (attr, die, cu, &high))
+ if (attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0))
{
/* If bounds are constant do the final calculation here. */
if (low.kind == PROP_CONST && high.kind == PROP_CONST)
@@ -21520,7 +21619,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct dynamic_prop prop;
- if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0))
{
TYPE_ALLOCATED_PROP (type)
= obstack_alloc (&objfile->objfile_obstack, sizeof (prop));
@@ -21534,7 +21633,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct dynamic_prop prop;
- if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0))
{
TYPE_ASSOCIATED_PROP (type)
= obstack_alloc (&objfile->objfile_obstack, sizeof (prop));
@@ -21548,7 +21647,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct dynamic_prop prop;
- if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0))
{
TYPE_DATA_LOCATION (type)
= obstack_alloc (&objfile->objfile_obstack, sizeof (prop));
--
1.7.9.5