[PATCH 07/11] Introduce structure to hold DW_TAG_const_type, DW_TAG_volatile_type and DW_TAG_pointer_type information from DWARF info section to determine complex variable types

Guillaume VACHERIAS guillaume.vacherias@foss.st.com
Thu May 22 11:03:31 GMT 2025
A Debug Information Entries (DIE) may point to another. For example a DW_TAG_variable DIE
may hold an attribute offset (DW_AT_type) which points to a DW_TAG_const_type DIE. This
means that the defined variable is a constant type. The same goes for DW_TAG_const_type
DIE which also holds an attribute offset (DW_AT_type) that leads to another, until reaching
a DIE that we can determine the size of the variable.

We define a structure that holds the attribute offset (DW_AT_type) for the  concerned DIE.
This will be useful when resolving the type and size of a variable.
---
 binutils/dwarf.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
 binutils/dwarf.h |  8 +++++++
 2 files changed, 70 insertions(+)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 2cd02f3a1e7..049446e24d3 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -67,6 +67,9 @@ 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;
+type_ref_pair *m_const_type = NULL;
+type_ref_pair *m_volatile_type = NULL;
+type_ref_pair *m_pointer_type = 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
@@ -3191,6 +3194,48 @@ insert_element_in_map (enum dwarf_tag dw_tag,
 	    }
 	}
 	break;
+      case DW_TAG_const_type:
+      case DW_TAG_volatile_type:
+      case DW_TAG_pointer_type:
+	{
+	  if (dw_attr == DW_AT_type)
+	    {
+	      if (svalue == NULL && uvalue == NULL)
+		{
+		  fprintf (stderr,
+		    _ ("insert_element_in_map: "
+		    "DW_TAG_const_type/"
+		    "DW_TAG_volatile_type/"
+		    "DW_TAG_pointer_type-DW_AT_type "
+		    "svalue and uvalue should not be NULL!\n"));
+		  free_mapping_info_struct ();
+		  xexit (1);
+		}
+	      type_ref_pair *head = (type_ref_pair *) xmalloc (
+		sizeof (type_ref_pair));
+	      head->offset = offset;
+	      head->address = ((svalue != NULL)
+		? (uint64_t) *svalue : *uvalue);
+	      head->next = NULL;
+
+	      if (dw_tag == DW_TAG_const_type)
+		{
+		  head->next = m_const_type;
+		  m_const_type = head;
+		}
+	      else if (dw_tag == DW_TAG_volatile_type)
+		{
+		  head->next = m_volatile_type;
+		  m_volatile_type = head;
+		}
+	      else if (dw_tag == DW_TAG_pointer_type)
+		{
+		  head->next = m_pointer_type;
+		  m_pointer_type = head;
+		}
+	      }
+	}
+	break;
       default:
       break;
     }
@@ -14194,6 +14239,20 @@ free_array_type (void)
   m_array_map = NULL;
 }
 
+static void
+free_type_ref (type_ref_pair **head)
+{
+  type_ref_pair *current = *head;
+  type_ref_pair *next = NULL;
+  while (current != NULL)
+    {
+      next = current->next;
+      free (current);
+      current = next;
+    }
+  *head = NULL;
+}
+
 void
 free_mapping_info_struct ()
 {
@@ -14203,4 +14262,7 @@ free_mapping_info_struct ()
   free_struct_or_union (&m_struct_map);
   free_struct_or_union (&m_union_map);
   free_array_type ();
+  free_type_ref (&m_const_type);
+  free_type_ref (&m_volatile_type);
+  free_type_ref (&m_pointer_type);
 }
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 497839ae002..eac5983b2d2 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -293,6 +293,14 @@ typedef struct tab_pair
 }
 tab_pair;
 
+typedef struct type_ref_pair
+{
+  uint64_t offset;
+  uint64_t address;
+  struct type_ref_pair *next;
+}
+type_ref_pair;
+
 extern unsigned int eh_addr_size;
 
 extern int do_debug_info;
-- 
2.25.1



More information about the Binutils mailing list