[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