[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