[PATCH 06/11] Introduce structure to hold DW_TAG_array_type from DWARF info section to determine all defined array types
Guillaume VACHERIAS
guillaume.vacherias@foss.st.com
Thu May 22 11:03:30 GMT 2025
- Define structure to hold array type information (DW_TAG_array_type).
- The number of elements that the array holds is described by DW_TAG_subrange_type.
Hence treat this information as well.
---
binutils/dwarf.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++
binutils/dwarf.h | 16 +++++++
2 files changed, 128 insertions(+)
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 4ecf3f8930a..2cd02f3a1e7 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -66,6 +66,7 @@ type_def_pair *m_type_def_map = NULL;
enum_pair *m_enum_pair_map = NULL;
struct_or_union_pair *m_struct_map = NULL;
struct_or_union_pair *m_union_map = NULL;
+tab_pair *m_array_map = NULL;
/* Special value for num_debug_info_entries to indicate
that the .debug_info section could not be loaded/parsed. */
#define DEBUG_INFO_UNAVAILABLE (unsigned int) -1
@@ -2679,6 +2680,46 @@ get_or_create_enum_elt (enum_pair *head, uint64_t offset)
return head->enumeration;
}
+static tab_pair *
+get_or_create_array_pair (uint64_t offset)
+{
+ /* We use offset as key which represents the address entry of a DIE.
+ Each DIE retains several attributes. We use offset to track current
+ DIE until we parse all of its attributes and eventually reach another
+ DIE hence a different offset. */
+ if (m_array_map == NULL || m_array_map->offset != offset)
+ {
+ tab_pair *ret = (tab_pair *)
+ xmalloc (sizeof (tab_pair));
+ ret->offset = offset;
+ ret->array = NULL;
+ ret->next = m_array_map;
+ m_array_map = ret;
+ }
+ return m_array_map;
+}
+
+static tab *
+get_or_create_array_elt (tab_pair *head)
+{
+ if (head == NULL)
+ {
+ fprintf (stderr,
+ _ ("get_or_create_array_elt: head should not be NULL!\n"));
+ free_mapping_info_struct ();
+ xexit (1);
+ }
+ if (head->array == NULL)
+ {
+ tab *array = (tab *) xmalloc (sizeof (tab));
+ array->counts = 0;
+ array->element_size = 0;
+ array->address = 0;
+ head->array = array;
+ }
+ return head->array;
+}
+
static struct_or_union_pair *
get_or_create_struct_or_union_pair (bool is_struct, uint64_t offset)
{
@@ -3096,6 +3137,60 @@ insert_element_in_map (enum dwarf_tag dw_tag,
}
}
break;
+ case DW_TAG_array_type:
+ {
+ tab_pair *head = get_or_create_array_pair (offset);
+ tab *array = get_or_create_array_elt (head);
+ if (dw_attr == DW_AT_type)
+ {
+ if (uvalue == NULL && uvalue == NULL)
+ {
+ fprintf (stderr,
+ _ ("insert_element_in_map: "
+ "DW_TAG_array_type-DW_AT_type "
+ "uvalue and svalue are NULL!\n"));
+ free_mapping_info_struct ();
+ xexit (1);
+ }
+ array->address = ((svalue != NULL)
+ ? (uint64_t) *svalue : *uvalue);
+ }
+ }
+ break;
+ case DW_TAG_subrange_type:
+ /* Follows immediatly after DW_TAG_array_type. */
+ {
+ if (dw_attr == DW_AT_upper_bound
+ || dw_attr == DW_AT_count)
+ {
+ if (m_array_map == NULL
+ || m_array_map->array == NULL)
+ {
+ fprintf (stderr,
+ _ ("insert_element_in_map: "
+ "DW_TAG_subrange_type-DW_AT_upper_bound-DW_AT_count "
+ "m_array_map is NULL!\n"));
+ free_mapping_info_struct ();
+ xexit (1);
+ }
+ if (uvalue == NULL && svalue == NULL)
+ {
+ fprintf (stderr,
+ _ ("insert_element_in_map:"
+ "DW_TAG_subrange_type-DW_AT_upper_bound-DW_AT_count "
+ "uvalue and svalue are NULL!\n"));
+ free_mapping_info_struct ();
+ xexit (1);
+ }
+ if (dw_attr == DW_AT_upper_bound)
+ m_array_map->array->counts = ((svalue != NULL)
+ ? (uint64_t) *svalue + 1 : *uvalue + 1);
+ else if (dw_attr == DW_AT_count)
+ m_array_map->array->counts = ((svalue != NULL)
+ ? (uint64_t) *svalue : *uvalue);
+ }
+ }
+ break;
default:
break;
}
@@ -14083,6 +14178,22 @@ free_struct_or_union (struct_or_union_pair **struct_or_union_map)
*struct_or_union_map = NULL;
}
+static void
+free_array_type (void)
+{
+ tab_pair *current = m_array_map;
+ tab_pair *next = NULL;
+ while (current != NULL)
+ {
+ next = current->next;
+ free (current->array);
+ current->array = NULL;
+ free (current);
+ current = next;
+ }
+ m_array_map = NULL;
+}
+
void
free_mapping_info_struct ()
{
@@ -14091,4 +14202,5 @@ free_mapping_info_struct ()
free_enum_type ();
free_struct_or_union (&m_struct_map);
free_struct_or_union (&m_union_map);
+ free_array_type ();
}
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index a83c657e656..497839ae002 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -242,6 +242,14 @@ typedef struct
}
struct_or_union;
+typedef struct
+{
+ uint64_t counts;
+ uint64_t element_size;
+ uint64_t address;
+}
+tab;
+
typedef struct base_type_pair
{
uint64_t offset;
@@ -277,6 +285,14 @@ typedef struct struct_or_union_pair
}
struct_or_union_pair;
+typedef struct tab_pair
+{
+ uint64_t offset;
+ tab *array;
+ struct tab_pair *next;
+}
+tab_pair;
+
extern unsigned int eh_addr_size;
extern int do_debug_info;
--
2.25.1
More information about the Binutils
mailing list