mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-15 13:48:26 +08:00
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:
97
ld/ldlang.c
97
ld/ldlang.c
@@ -188,6 +188,12 @@ stat_alloc (size_t size)
|
|||||||
return obstack_alloc (&stat_obstack, size);
|
return obstack_alloc (&stat_obstack, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stat_free (void *str)
|
||||||
|
{
|
||||||
|
obstack_free (&stat_obstack, str);
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
stat_memdup (const void *src, size_t copy_size, size_t alloc_size)
|
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);
|
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,
|
/* Code for handling simple wildcards without going through fnmatch,
|
||||||
which can be expensive because of charset translations etc. */
|
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))
|
|| sec->spec.sorted == by_none))
|
||||||
{
|
{
|
||||||
/* We might be called even if _this_ spec doesn't need sorting,
|
/* 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;
|
return wild->rightmost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,7 +734,7 @@ wild_sort (lang_wild_statement_type *wild,
|
|||||||
i = filename_cmp (ln, fn);
|
i = filename_cmp (ln, fn);
|
||||||
else
|
else
|
||||||
i = filename_cmp (fn, ln);
|
i = filename_cmp (fn, ln);
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{ tree = &((*tree)->right); continue; }
|
{ tree = &((*tree)->right); continue; }
|
||||||
else if (i < 0)
|
else if (i < 0)
|
||||||
@@ -1233,9 +1264,9 @@ new_afile (const char *name,
|
|||||||
p->filename = name;
|
p->filename = name;
|
||||||
p->local_sym_name = name;
|
p->local_sym_name = name;
|
||||||
/* If name is a relative path, search the directory of the current linker
|
/* If name is a relative path, search the directory of the current linker
|
||||||
script first. */
|
script first. */
|
||||||
if (from_filename && !IS_ABSOLUTE_PATH (name))
|
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.real = true;
|
||||||
p->flags.search_dirs = true;
|
p->flags.search_dirs = true;
|
||||||
break;
|
break;
|
||||||
@@ -2147,7 +2178,7 @@ lang_insert_orphan (asection *s,
|
|||||||
else if (first_orphan_note)
|
else if (first_orphan_note)
|
||||||
{
|
{
|
||||||
/* Don't place non-note sections in the middle of orphan
|
/* Don't place non-note sections in the middle of orphan
|
||||||
note sections. */
|
note sections. */
|
||||||
after_sec_note = true;
|
after_sec_note = true;
|
||||||
after_sec = as;
|
after_sec = as;
|
||||||
for (sec = as->next;
|
for (sec = as->next;
|
||||||
@@ -4959,18 +4990,18 @@ ld_is_local_symbol (asymbol * sym)
|
|||||||
/* FIXME: This is intended to skip ARM mapping symbols,
|
/* FIXME: This is intended to skip ARM mapping symbols,
|
||||||
which for some reason are not excluded by bfd_is_local_label,
|
which for some reason are not excluded by bfd_is_local_label,
|
||||||
but maybe it is wrong for other architectures.
|
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 == '$')
|
if (*name == '$')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present
|
/* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present
|
||||||
in the hash table, so do not print duplicates here. */
|
in the hash table, so do not print duplicates here. */
|
||||||
struct bfd_link_hash_entry * h;
|
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 */);
|
false /* copy */, true /* follow */);
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Symbols from the plugin owned BFD will not get their own
|
/* Symbols from the plugin owned BFD will not get their own
|
||||||
iteration of this function, but can be on the link_info
|
iteration of this function, but can be on the link_info
|
||||||
list. So include them here. */
|
list. So include them here. */
|
||||||
@@ -5060,7 +5091,7 @@ print_input_section (asection *i, bool is_discarded)
|
|||||||
{
|
{
|
||||||
asymbol * sym = symbol_table[j];
|
asymbol * sym = symbol_table[j];
|
||||||
bfd_vma sym_addr = sym->value + i->output_section->vma;
|
bfd_vma sym_addr = sym->value + i->output_section->vma;
|
||||||
|
|
||||||
if (sym->section == i->output_section
|
if (sym->section == i->output_section
|
||||||
&& (sym->flags & BSF_LOCAL) != 0
|
&& (sym->flags & BSF_LOCAL) != 0
|
||||||
&& sym_addr >= addr
|
&& sym_addr >= addr
|
||||||
@@ -5536,9 +5567,9 @@ size_input_section
|
|||||||
then to the output section's requirement. If this alignment
|
then to the output section's requirement. If this alignment
|
||||||
is greater than any seen before, then record it too. Perform
|
is greater than any seen before, then record it too. Perform
|
||||||
the alignment by inserting a magic 'padding' statement.
|
the alignment by inserting a magic 'padding' statement.
|
||||||
We can force input section alignment within an output section
|
We can force input section alignment within an output section
|
||||||
by using SUBALIGN. The value specified overrides any alignment
|
by using SUBALIGN. The value specified overrides any alignment
|
||||||
given by input sections, whether larger or smaller. */
|
given by input sections, whether larger or smaller. */
|
||||||
|
|
||||||
if (output_section_statement->subsection_alignment != NULL)
|
if (output_section_statement->subsection_alignment != NULL)
|
||||||
o->alignment_power = i->alignment_power =
|
o->alignment_power = i->alignment_power =
|
||||||
@@ -8788,7 +8819,7 @@ lang_add_string (const char *s)
|
|||||||
case 'n': c = '\n'; break;
|
case 'n': c = '\n'; break;
|
||||||
case 'r': c = '\r'; break;
|
case 'r': c = '\r'; break;
|
||||||
case 't': c = '\t'; break;
|
case 't': c = '\t'; break;
|
||||||
|
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
@@ -9898,30 +9929,30 @@ lang_do_memory_regions (bool update_regions_p)
|
|||||||
if (r->origin_exp)
|
if (r->origin_exp)
|
||||||
{
|
{
|
||||||
exp_fold_tree_no_dot (r->origin_exp, NULL);
|
exp_fold_tree_no_dot (r->origin_exp, NULL);
|
||||||
if (update_regions_p)
|
if (update_regions_p)
|
||||||
{
|
{
|
||||||
if (expld.result.valid_p)
|
if (expld.result.valid_p)
|
||||||
{
|
{
|
||||||
r->origin = expld.result.value;
|
r->origin = expld.result.value;
|
||||||
r->current = r->origin;
|
r->current = r->origin;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
einfo (_("%P: invalid origin for memory region %s\n"),
|
einfo (_("%P: invalid origin for memory region %s\n"),
|
||||||
r->name_list.name);
|
r->name_list.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r->length_exp)
|
if (r->length_exp)
|
||||||
{
|
{
|
||||||
exp_fold_tree_no_dot (r->length_exp, NULL);
|
exp_fold_tree_no_dot (r->length_exp, NULL);
|
||||||
if (update_regions_p)
|
if (update_regions_p)
|
||||||
{
|
{
|
||||||
if (expld.result.valid_p)
|
if (expld.result.valid_p)
|
||||||
r->length = expld.result.value;
|
r->length = expld.result.value;
|
||||||
else
|
else
|
||||||
einfo (_("%P: invalid length for memory region %s\n"),
|
einfo (_("%P: invalid length for memory region %s\n"),
|
||||||
r->name_list.name);
|
r->name_list.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -664,10 +664,14 @@ extern void lang_for_each_statement_worker
|
|||||||
(void (*) (lang_statement_union_type *), lang_statement_union_type *);
|
(void (*) (lang_statement_union_type *), lang_statement_union_type *);
|
||||||
extern void *stat_alloc
|
extern void *stat_alloc
|
||||||
(size_t);
|
(size_t);
|
||||||
extern void * stat_memdup
|
extern void stat_free
|
||||||
|
(void *);
|
||||||
|
extern void *stat_memdup
|
||||||
(const void *, size_t, size_t);
|
(const void *, size_t, size_t);
|
||||||
extern char *stat_strdup
|
extern char *stat_strdup
|
||||||
(const char *);
|
(const char *);
|
||||||
|
extern char *stat_concat
|
||||||
|
(const char *, ...);
|
||||||
extern void strip_excluded_output_sections
|
extern void strip_excluded_output_sections
|
||||||
(void);
|
(void);
|
||||||
extern void lang_clear_os_map
|
extern void lang_clear_os_map
|
||||||
|
|||||||
@@ -366,7 +366,8 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
|
|||||||
|
|
||||||
asym->the_bfd = abfd;
|
asym->the_bfd = abfd;
|
||||||
asym->name = (ldsym->version
|
asym->name = (ldsym->version
|
||||||
? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
|
? stat_concat (ldsym->name, "@", ldsym->version,
|
||||||
|
(const char *) NULL)
|
||||||
: ldsym->name);
|
: ldsym->name);
|
||||||
asym->value = 0;
|
asym->value = 0;
|
||||||
switch (ldsym->def)
|
switch (ldsym->def)
|
||||||
@@ -378,11 +379,11 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
|
|||||||
flags |= BSF_GLOBAL;
|
flags |= BSF_GLOBAL;
|
||||||
if (ldsym->comdat_key)
|
if (ldsym->comdat_key)
|
||||||
{
|
{
|
||||||
char *name = concat (".gnu.linkonce.t.", ldsym->comdat_key,
|
char *name = stat_concat (".gnu.linkonce.t.", ldsym->comdat_key,
|
||||||
(const char *) NULL);
|
(const char *) NULL);
|
||||||
section = bfd_get_section_by_name (abfd, name);
|
section = bfd_get_section_by_name (abfd, name);
|
||||||
if (section != NULL)
|
if (section != NULL)
|
||||||
free (name);
|
stat_free (name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flagword sflags;
|
flagword sflags;
|
||||||
|
|||||||
Reference in New Issue
Block a user