[PATCH v1 3/4] aarch64 gas: simplify feature-set lifetime management and fix leaks
Matthieu Longo
matthieu.longo@arm.com
Tue Feb 24 16:26:16 GMT 2026
CPU and architecture options can be specified on the command line and
define the set of features (i.e. supported instructions) available to
GAS. These options may later be modified during parsing via the .cpu,
.arch, and .arch_extension directives.
The current implementation suffers from memory leaks when switching
from one feature set to another. This issue was detected by LeakSanitizer
(see the stack trace below).
The usage of pointers instead of a plain aarch64_feature_set value was
originally intended to determine whether the options were set on the
command line, or, if not, to fall back to a default value. In practice,
however, march_cpu_opt does not need to outlive the initial CPU selection.
As for mcpu_cpu_opt, the value does not need to be 'const', preserved
across CPU/architecture/feature changes, or dynamically reallocated on
each directive update. Since copy assignments are unavoidable, treating
it as a temporary value is sufficient and avoids repeated allocations.
As a result, this patch removes most of the dynamic allocations of
feature sets and retains a single one with a well-defined lifetime.
This both fixes the memory leaks and simplifies ownership and
deallocation logic.
==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 48 byte(s) in 2 object(s) allocated from:
#1 in xmalloc ./libiberty/xmalloc.c:149
#2 in aarch64_parse_features ./gas/config/tc-aarch64.c:11216
#3 in s_aarch64_arch ./gas/config/tc-aarch64.c:11621
#4 in read_a_source_file ./gas/read.c:1287
#5 in perform_an_assembly_pass ./gas/as.c:1290
---
gas/config/tc-aarch64.c | 52 +++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 18 deletions(-)
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 050826c0617..b1f85456ef4 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -48,8 +48,8 @@ static aarch64_feature_set cpu_variant;
/* Variables that we set while parsing command-line options. Once all
options have been read we re-process these values to set the real
assembly flags. */
-static const aarch64_feature_set *mcpu_cpu_opt = NULL;
-static const aarch64_feature_set *march_cpu_opt = NULL;
+static aarch64_feature_set *mcpu_cpu_opt = NULL;
+static aarch64_feature_set *march_cpu_opt = NULL;
/* Constants for known architecture features. */
static const aarch64_feature_set cpu_default = AARCH64_ARCH_FEATURES (V8A);
@@ -10441,6 +10441,17 @@ check_mapping_symbols (bfd * abfd ATTRIBUTE_UNUSED, asection * sec,
}
#endif
+static aarch64_feature_set *
+make_aarch64_feature_set (const aarch64_feature_set *other)
+{
+ aarch64_feature_set *ext_set = XNEW (aarch64_feature_set);
+ if (other != NULL)
+ *ext_set = *other;
+ else
+ memset (ext_set, 0, sizeof (aarch64_feature_set));
+ return ext_set;
+}
+
/* Adjust the symbol table. */
void
@@ -10741,9 +10752,12 @@ md_begin (void)
/* Set the cpu variant based on the command-line options. */
if (!mcpu_cpu_opt)
mcpu_cpu_opt = march_cpu_opt;
+ else
+ free (march_cpu_opt);
+ march_cpu_opt = NULL;
if (!mcpu_cpu_opt)
- mcpu_cpu_opt = &cpu_default;
+ mcpu_cpu_opt = make_aarch64_feature_set (&cpu_default);
cpu_variant = *mcpu_cpu_opt;
@@ -10788,6 +10802,8 @@ aarch64_md_end (void)
htab_delete (aarch64_barrier_opt_hsh);
htab_delete (aarch64_pldop_hsh);
htab_delete (aarch64_hint_opt_hsh);
+
+ free (mcpu_cpu_opt);
}
/* Command line processing. */
@@ -11209,14 +11225,9 @@ aarch64_feature_enable_set (aarch64_feature_set set)
}
static bool
-aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
+aarch64_parse_features (const char *str, aarch64_feature_set *ext_set,
bool ext_only)
{
- /* Copy the feature set, so that we can modify it. */
- aarch64_feature_set *ext_set = XNEW (aarch64_feature_set);
- *ext_set = **opt_p;
- *opt_p = ext_set;
-
if (str == NULL)
{
/* No extensions, so just set the virtual feature bits and return. */
@@ -11347,8 +11358,9 @@ aarch64_parse_cpu (const char *str)
for (opt = aarch64_cpus; opt->name != NULL; opt++)
if (strlen (opt->name) == optlen && strncmp (str, opt->name, optlen) == 0)
{
- mcpu_cpu_opt = &opt->value;
- return aarch64_parse_features (ext, &mcpu_cpu_opt, false);
+ gas_assert (mcpu_cpu_opt == NULL);
+ mcpu_cpu_opt = make_aarch64_feature_set (&opt->value);
+ return aarch64_parse_features (ext, mcpu_cpu_opt, false);
}
as_bad (_("unknown cpu `%s'"), str);
@@ -11376,8 +11388,9 @@ aarch64_parse_arch (const char *str)
for (opt = aarch64_archs; opt->name != NULL; opt++)
if (strlen (opt->name) == optlen && strncmp (str, opt->name, optlen) == 0)
{
- march_cpu_opt = &opt->value;
- return aarch64_parse_features (ext, &march_cpu_opt, false);
+ gas_assert (march_cpu_opt == NULL);
+ march_cpu_opt = make_aarch64_feature_set (&opt->value);
+ return aarch64_parse_features (ext, march_cpu_opt, false);
}
as_bad (_("unknown architecture `%s'"), str);
@@ -11573,8 +11586,9 @@ s_aarch64_cpu (int ignored ATTRIBUTE_UNUSED)
if (strlen (opt->name) == optlen
&& strncmp (name, opt->name, optlen) == 0)
{
- mcpu_cpu_opt = &opt->value;
- if (!aarch64_parse_features (ext, &mcpu_cpu_opt, false))
+ gas_assert (mcpu_cpu_opt != NULL);
+ *mcpu_cpu_opt = opt->value;
+ if (!aarch64_parse_features (ext, mcpu_cpu_opt, false))
return;
cpu_variant = *mcpu_cpu_opt;
@@ -11617,8 +11631,9 @@ s_aarch64_arch (int ignored ATTRIBUTE_UNUSED)
if (strlen (opt->name) == optlen
&& strncmp (name, opt->name, optlen) == 0)
{
- mcpu_cpu_opt = &opt->value;
- if (!aarch64_parse_features (ext, &mcpu_cpu_opt, false))
+ gas_assert (mcpu_cpu_opt != NULL);
+ *mcpu_cpu_opt = opt->value;
+ if (!aarch64_parse_features (ext, mcpu_cpu_opt, false))
return;
cpu_variant = *mcpu_cpu_opt;
@@ -11645,7 +11660,8 @@ s_aarch64_arch_extension (int ignored ATTRIBUTE_UNUSED)
saved_char = *input_line_pointer;
*input_line_pointer = 0;
- if (!aarch64_parse_features (ext, &mcpu_cpu_opt, true))
+ gas_assert (mcpu_cpu_opt != NULL);
+ if (!aarch64_parse_features (ext, mcpu_cpu_opt, true))
return;
cpu_variant = *mcpu_cpu_opt;
--
2.53.0
More information about the Binutils
mailing list