mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-30 00:52:16 +08:00
Evaluate __start_* and __stop_* symbol PROVIDE expressions early
Makes these symbols defined before bfd_elf_size_dynamic_sections, to avoid horrible hacks elsewhere. The exp_fold_tree undefweak change is necessary to define undefweak symbols early too. The comment was wrong. PROVIDE in fact defines undefweak symbols, via bfd_elf_record_link_assignment. PR ld/19175 * ldlang.c (lang_insert_orphan): Evaluate __start_* and __stop_* symbol PROVIDE expressions. * ldexp.c (exp_fold_tree_1 <etree_provide>): Define undefweak references.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2015-10-27 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR ld/19175
|
||||||
|
* ldlang.c (lang_insert_orphan): Evaluate __start_* and __stop_*
|
||||||
|
symbol PROVIDE expressions.
|
||||||
|
* ldexp.c (exp_fold_tree_1 <etree_provide>): Define undefweak
|
||||||
|
references.
|
||||||
|
|
||||||
2015-10-22 H.J. Lu <hongjiu.lu@intel.com>
|
2015-10-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* configure.ac: Properly check
|
* configure.ac: Properly check
|
||||||
|
@ -1126,11 +1126,14 @@ exp_fold_tree_1 (etree_type *tree)
|
|||||||
if (h == NULL
|
if (h == NULL
|
||||||
|| !(h->type == bfd_link_hash_new
|
|| !(h->type == bfd_link_hash_new
|
||||||
|| h->type == bfd_link_hash_undefined
|
|| h->type == bfd_link_hash_undefined
|
||||||
|
|| h->type == bfd_link_hash_undefweak
|
||||||
|| h->linker_def))
|
|| h->linker_def))
|
||||||
{
|
{
|
||||||
/* Do nothing. The symbol was never referenced, or
|
/* Do nothing. The symbol was never referenced, or
|
||||||
was defined in some object file. Undefined weak
|
was defined in some object file. Note that
|
||||||
symbols stay undefined. */
|
undefweak symbols are defined by PROVIDE. This
|
||||||
|
is to support glibc use of __rela_iplt_start and
|
||||||
|
similar weak references. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
ld/ldlang.c
26
ld/ldlang.c
@ -1805,6 +1805,7 @@ lang_insert_orphan (asection *s,
|
|||||||
{
|
{
|
||||||
lang_statement_list_type add;
|
lang_statement_list_type add;
|
||||||
const char *ps;
|
const char *ps;
|
||||||
|
lang_assignment_statement_type *start_assign;
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
lang_output_section_statement_type **os_tail;
|
lang_output_section_statement_type **os_tail;
|
||||||
|
|
||||||
@ -1827,6 +1828,7 @@ lang_insert_orphan (asection *s,
|
|||||||
NULL, NULL, NULL, constraint, 0);
|
NULL, NULL, NULL, constraint, 0);
|
||||||
|
|
||||||
ps = NULL;
|
ps = NULL;
|
||||||
|
start_assign = NULL;
|
||||||
if (config.build_constructors && *os_tail == os)
|
if (config.build_constructors && *os_tail == os)
|
||||||
{
|
{
|
||||||
/* If the name of the section is representable in C, then create
|
/* If the name of the section is representable in C, then create
|
||||||
@ -1841,9 +1843,10 @@ lang_insert_orphan (asection *s,
|
|||||||
symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
|
symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
|
||||||
symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
|
symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
|
||||||
sprintf (symname + (symname[0] != 0), "__start_%s", secname);
|
sprintf (symname + (symname[0] != 0), "__start_%s", secname);
|
||||||
lang_add_assignment (exp_provide (symname,
|
start_assign
|
||||||
exp_nameop (NAME, "."),
|
= lang_add_assignment (exp_provide (symname,
|
||||||
FALSE));
|
exp_nameop (NAME, "."),
|
||||||
|
FALSE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1866,16 +1869,25 @@ lang_insert_orphan (asection *s,
|
|||||||
lang_leave_output_section_statement (NULL, DEFAULT_MEMORY_REGION, NULL,
|
lang_leave_output_section_statement (NULL, DEFAULT_MEMORY_REGION, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (ps != NULL && *ps == '\0')
|
if (start_assign != NULL)
|
||||||
{
|
{
|
||||||
char *symname;
|
char *symname;
|
||||||
|
lang_assignment_statement_type *stop_assign;
|
||||||
|
bfd_vma dot;
|
||||||
|
|
||||||
symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
|
symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
|
||||||
symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
|
symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
|
||||||
sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
|
sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
|
||||||
lang_add_assignment (exp_provide (symname,
|
stop_assign
|
||||||
exp_nameop (NAME, "."),
|
= lang_add_assignment (exp_provide (symname,
|
||||||
FALSE));
|
exp_nameop (NAME, "."),
|
||||||
|
FALSE));
|
||||||
|
/* Evaluate the expression to define the symbol if referenced,
|
||||||
|
before sizing dynamic sections. */
|
||||||
|
dot = os->bfd_section->vma;
|
||||||
|
exp_fold_tree (start_assign->exp, os->bfd_section, &dot);
|
||||||
|
dot += s->size;
|
||||||
|
exp_fold_tree (stop_assign->exp, os->bfd_section, &dot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the global list pointer. */
|
/* Restore the global list pointer. */
|
||||||
|
Reference in New Issue
Block a user