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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user