ld plugin.c concat leaks

* ldlang.c: Whitespace.
	(stat_free, stat_concat): New functions.
	* ldlang.h (stat_free, stat_concat): Declare.
	* plugin.c (asymbol_from_plugin_symbol): Use stat_concat.
This commit is contained in:
Alan Modra
2025-01-23 10:22:58 +10:30
parent 40c7f80788
commit 90bea4932e
3 changed files with 74 additions and 38 deletions

View File

@@ -188,6 +188,12 @@ stat_alloc (size_t size)
return obstack_alloc (&stat_obstack, size);
}
void
stat_free (void *str)
{
obstack_free (&stat_obstack, str);
}
void *
stat_memdup (const void *src, size_t copy_size, size_t alloc_size)
{
@@ -205,6 +211,31 @@ stat_strdup (const char *str)
return stat_memdup (str, len, len);
}
char *
stat_concat (const char *first, ...)
{
va_list args;
va_start (args, first);
size_t length = 0;
for (const char *arg = first; arg; arg = va_arg (args, const char *))
length += strlen (arg);
va_end (args);
char *new_str = stat_alloc (length + 1);
va_start (args, first);
char *end = new_str;
for (const char *arg = first; arg; arg = va_arg (args, const char *))
{
length = strlen (arg);
memcpy (end, arg, length);
end += length;
}
*end = 0;
va_end (args);
return new_str;
}
/* Code for handling simple wildcards without going through fnmatch,
which can be expensive because of charset translations etc. */
@@ -648,7 +679,7 @@ wild_sort (lang_wild_statement_type *wild,
|| sec->spec.sorted == by_none))
{
/* We might be called even if _this_ spec doesn't need sorting,
in which case we simply append at the right end of tree. */
in which case we simply append at the right end of tree. */
return wild->rightmost;
}
@@ -703,7 +734,7 @@ wild_sort (lang_wild_statement_type *wild,
i = filename_cmp (ln, fn);
else
i = filename_cmp (fn, ln);
if (i > 0)
{ tree = &((*tree)->right); continue; }
else if (i < 0)
@@ -1233,9 +1264,9 @@ new_afile (const char *name,
p->filename = name;
p->local_sym_name = name;
/* If name is a relative path, search the directory of the current linker
script first. */
script first. */
if (from_filename && !IS_ABSOLUTE_PATH (name))
p->extra_search_path = ldirname (from_filename);
p->extra_search_path = ldirname (from_filename);
p->flags.real = true;
p->flags.search_dirs = true;
break;
@@ -2147,7 +2178,7 @@ lang_insert_orphan (asection *s,
else if (first_orphan_note)
{
/* Don't place non-note sections in the middle of orphan
note sections. */
note sections. */
after_sec_note = true;
after_sec = as;
for (sec = as->next;
@@ -4959,18 +4990,18 @@ ld_is_local_symbol (asymbol * sym)
/* FIXME: This is intended to skip ARM mapping symbols,
which for some reason are not excluded by bfd_is_local_label,
but maybe it is wrong for other architectures.
It would be better to fix bfd_is_local_label. */
It would be better to fix bfd_is_local_label. */
if (*name == '$')
return false;
/* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present
in the hash table, so do not print duplicates here. */
struct bfd_link_hash_entry * h;
h = bfd_link_hash_lookup (link_info.hash, name, false /* create */,
h = bfd_link_hash_lookup (link_info.hash, name, false /* create */,
false /* copy */, true /* follow */);
if (h == NULL)
return true;
/* Symbols from the plugin owned BFD will not get their own
iteration of this function, but can be on the link_info
list. So include them here. */
@@ -5060,7 +5091,7 @@ print_input_section (asection *i, bool is_discarded)
{
asymbol * sym = symbol_table[j];
bfd_vma sym_addr = sym->value + i->output_section->vma;
if (sym->section == i->output_section
&& (sym->flags & BSF_LOCAL) != 0
&& sym_addr >= addr
@@ -5536,9 +5567,9 @@ size_input_section
then to the output section's requirement. If this alignment
is greater than any seen before, then record it too. Perform
the alignment by inserting a magic 'padding' statement.
We can force input section alignment within an output section
by using SUBALIGN. The value specified overrides any alignment
given by input sections, whether larger or smaller. */
We can force input section alignment within an output section
by using SUBALIGN. The value specified overrides any alignment
given by input sections, whether larger or smaller. */
if (output_section_statement->subsection_alignment != NULL)
o->alignment_power = i->alignment_power =
@@ -8788,7 +8819,7 @@ lang_add_string (const char *s)
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case '0':
case '1':
case '2':
@@ -9898,30 +9929,30 @@ lang_do_memory_regions (bool update_regions_p)
if (r->origin_exp)
{
exp_fold_tree_no_dot (r->origin_exp, NULL);
if (update_regions_p)
{
if (expld.result.valid_p)
{
r->origin = expld.result.value;
r->current = r->origin;
}
else
einfo (_("%P: invalid origin for memory region %s\n"),
r->name_list.name);
}
if (update_regions_p)
{
if (expld.result.valid_p)
{
r->origin = expld.result.value;
r->current = r->origin;
}
else
einfo (_("%P: invalid origin for memory region %s\n"),
r->name_list.name);
}
}
if (r->length_exp)
{
exp_fold_tree_no_dot (r->length_exp, NULL);
if (update_regions_p)
{
if (expld.result.valid_p)
r->length = expld.result.value;
else
einfo (_("%P: invalid length for memory region %s\n"),
r->name_list.name);
}
}
if (update_regions_p)
{
if (expld.result.valid_p)
r->length = expld.result.value;
else
einfo (_("%P: invalid length for memory region %s\n"),
r->name_list.name);
}
}
}
}

View File

@@ -664,10 +664,14 @@ extern void lang_for_each_statement_worker
(void (*) (lang_statement_union_type *), lang_statement_union_type *);
extern void *stat_alloc
(size_t);
extern void * stat_memdup
extern void stat_free
(void *);
extern void *stat_memdup
(const void *, size_t, size_t);
extern char *stat_strdup
(const char *);
extern char *stat_concat
(const char *, ...);
extern void strip_excluded_output_sections
(void);
extern void lang_clear_os_map

View File

@@ -366,7 +366,8 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
asym->the_bfd = abfd;
asym->name = (ldsym->version
? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
? stat_concat (ldsym->name, "@", ldsym->version,
(const char *) NULL)
: ldsym->name);
asym->value = 0;
switch (ldsym->def)
@@ -378,11 +379,11 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
flags |= BSF_GLOBAL;
if (ldsym->comdat_key)
{
char *name = concat (".gnu.linkonce.t.", ldsym->comdat_key,
(const char *) NULL);
char *name = stat_concat (".gnu.linkonce.t.", ldsym->comdat_key,
(const char *) NULL);
section = bfd_get_section_by_name (abfd, name);
if (section != NULL)
free (name);
stat_free (name);
else
{
flagword sflags;