[RFC 5/6] aarch64 gas: Record dynamic allocations during startup

Alice Carlotti alice.carlotti@arm.com
Tue Mar 3 12:41:27 GMT 2026


This allows them to be freed at exit, removing them from LeakSanitizer
reports.


diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index b580815bdfa20f358c818925b44f8bb2e2adba94..3dde65e3d91e346bd271189f11d119f78355a92d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -10454,6 +10454,41 @@ aarch64_adjust_symtab (void)
 #endif
 }
 
+struct aarch64_pointer_list
+{
+  void *ptr;
+  struct aarch64_pointer_list *next;
+};
+
+/* A linked list of dynamic memory allocations that are created once during
+   startup.  These allocations can be freed when the assembler finishes, to
+   prevent them appearing in memory leak reports.  */
+
+static struct
+aarch64_pointer_list *aarch64_startup_allocations = NULL;
+
+static inline void
+push_startup_allocation (void *ptr)
+{
+  struct aarch64_pointer_list *head = XNEW (struct aarch64_pointer_list);
+  head->ptr = ptr;
+  head->next = aarch64_startup_allocations;
+  aarch64_startup_allocations = head;
+}
+
+static void
+free_startup_allocations (void)
+{
+  struct aarch64_pointer_list *strings = aarch64_startup_allocations;
+  while (strings)
+    {
+      struct aarch64_pointer_list *next = strings->next;
+      free (strings->ptr);
+      free (strings);
+      strings = next;
+    }
+}
+
 static void
 checked_hash_insert (htab_t table, const char *key, const void *value)
 {
@@ -10478,6 +10513,7 @@ fill_instruction_hash_table (void)
       templ = str_hash_find (aarch64_ops_hsh, opcode->name);
 
       new_templ = XNEW (templates);
+      push_startup_allocation (new_templ);
       new_templ->opcode = opcode;
       new_templ->next = NULL;
 
@@ -10503,7 +10539,7 @@ convert_to_upper (char *dst, const char *src, size_t num)
 
 /* Assume STR point to a lower-case string, allocate, convert and return
    the corresponding upper-case string.  */
-static inline const char*
+static inline char*
 get_upper_str (const char *str)
 {
   char *ret;
@@ -10513,6 +10549,20 @@ get_upper_str (const char *str)
   return ret;
 }
 
+/* Some operands are recognised in either lower case or upper case forms.
+   Create entries for both versions.  Record a pointer to the dynamically
+   allocated upper case string so that we can free it later.  */
+
+static void
+checked_hash_insert_with_upper (htab_t table, const char *key,
+				const void *value)
+{
+  checked_hash_insert (table, key, value);
+  char *upper = get_upper_str (key);
+  checked_hash_insert (table, upper, value);
+  push_startup_allocation (upper);
+}
+
 /* MD interface: Initialization.  */
 
 void
@@ -10608,11 +10658,8 @@ md_begin (void)
   for (i = 0; aarch64_operand_modifiers[i].name != NULL; i++)
     {
       const char *name = aarch64_operand_modifiers[i].name;
-      checked_hash_insert (aarch64_shift_hsh, name,
-			   aarch64_operand_modifiers + i);
-      /* Also hash the name in the upper case.  */
-      checked_hash_insert (aarch64_shift_hsh, get_upper_str (name),
-			   aarch64_operand_modifiers + i);
+      checked_hash_insert_with_upper (aarch64_shift_hsh, name,
+				      aarch64_operand_modifiers + i);
     }
 
   for (i = 0; i < ARRAY_SIZE (aarch64_conds); i++)
@@ -10625,11 +10672,8 @@ md_begin (void)
 	  const char *name = aarch64_conds[i].names[j];
 	  if (name == NULL)
 	    break;
-	  checked_hash_insert (aarch64_cond_hsh, name,
-			       aarch64_conds + i);
-	  /* Also hash the name in the upper case.  */
-	  checked_hash_insert (aarch64_cond_hsh, get_upper_str (name),
-			       aarch64_conds + i);
+	  checked_hash_insert_with_upper (aarch64_cond_hsh, name,
+					  aarch64_conds + i);
 	}
     }
 
@@ -10639,21 +10683,15 @@ md_begin (void)
       /* Skip xx00 - the unallocated values of option.  */
       if ((i & 0x3) == 0)
 	continue;
-      checked_hash_insert (aarch64_barrier_opt_hsh, name,
-			   aarch64_barrier_options + i);
-      /* Also hash the name in the upper case.  */
-      checked_hash_insert (aarch64_barrier_opt_hsh, get_upper_str (name),
-			   aarch64_barrier_options + i);
+      checked_hash_insert_with_upper (aarch64_barrier_opt_hsh, name,
+				      aarch64_barrier_options + i);
     }
 
   for (i = 0; i < ARRAY_SIZE (aarch64_barrier_dsb_nxs_options); i++)
     {
       const char *name = aarch64_barrier_dsb_nxs_options[i].name;
-      checked_hash_insert (aarch64_barrier_opt_hsh, name,
-			   aarch64_barrier_dsb_nxs_options + i);
-      /* Also hash the name in the upper case.  */
-      checked_hash_insert (aarch64_barrier_opt_hsh, get_upper_str (name),
-			   aarch64_barrier_dsb_nxs_options + i);
+      checked_hash_insert_with_upper (aarch64_barrier_opt_hsh, name,
+				      aarch64_barrier_dsb_nxs_options + i);
     }
 
   for (i = 0; i < ARRAY_SIZE (aarch64_prfops); i++)
@@ -10662,11 +10700,8 @@ md_begin (void)
       /* Skip the unallocated hint encodings.  */
       if (name == NULL)
 	continue;
-      checked_hash_insert (aarch64_pldop_hsh, name,
-			   aarch64_prfops + i);
-      /* Also hash the name in the upper case.  */
-      checked_hash_insert (aarch64_pldop_hsh, get_upper_str (name),
-			   aarch64_prfops + i);
+      checked_hash_insert_with_upper (aarch64_pldop_hsh, name,
+				      aarch64_prfops + i);
     }
 
   for (i = 0; aarch64_hint_options[i].name != NULL; i++)
@@ -10676,11 +10711,8 @@ md_begin (void)
 	 up in the hash table.  */
       if (*name == '\0')
 	continue;
-      checked_hash_insert (aarch64_hint_opt_hsh, name,
-			   aarch64_hint_options + i);
-      /* Also hash the name in the upper case.  */
-      checked_hash_insert (aarch64_hint_opt_hsh, get_upper_str (name),
-			   aarch64_hint_options + i);
+      checked_hash_insert_with_upper (aarch64_hint_opt_hsh, name,
+				      aarch64_hint_options + i);
     }
 
   for (i = 0; aarch64_sys_ins_gic[i].name != NULL; i++)
@@ -10745,6 +10777,8 @@ aarch64_md_end (void)
   htab_delete (aarch64_barrier_opt_hsh);
   htab_delete (aarch64_pldop_hsh);
   htab_delete (aarch64_hint_opt_hsh);
+
+  free_startup_allocations();
 }
 
 /* Command line processing.  */


More information about the Binutils mailing list