2017-11-28 Alan Modra <amodra@gmail.com>
+ PR 22471
+ * elflink.c (_bfd_elf_merge_symbol): Allow weak symbols to override
+ early passes over linker script symbols.
+ * linker.c (_bfd_generic_link_add_one_symbol): Allow symbols to
+ override early passes over linker script symbols. Clear ldscript_def
+ on symbol definitions.
+
+2017-11-28 Alan Modra <amodra@gmail.com>
+
* elf64-mmix.c (bfd_elf64_bfd_copy_link_hash_symbol_type): Define.
2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
treated as strong if the new symbol is from a dynamic library.
This reflects the way glibc's ld.so works.
+ Also allow a weak symbol to override a linker script symbol
+ defined by an early pass over the script. This is done so the
+ linker knows the symbol is defined in an object file, for the
+ DEFINED script function.
+
Do this before setting *type_change_ok or *size_change_ok so that
we warn properly when dynamic library symbols are overridden. */
- if (newdef && !newdyn && olddyn)
+ if (newdef && !newdyn && (olddyn || h->root.ldscript_def))
newweak = FALSE;
if (olddef && newdyn)
oldweak = FALSE;
do
{
enum link_action action;
+ int prev;
+ prev = h->type;
+ /* Treat symbols defined by early linker script pass as undefined. */
+ if (h->ldscript_def)
+ prev = bfd_link_hash_undefined;
cycle = FALSE;
- action = link_action[(int) row][(int) h->type];
+ action = link_action[(int) row][prev];
switch (action)
{
case FAIL:
h->u.def.section = section;
h->u.def.value = value;
h->linker_def = 0;
+ h->ldscript_def = 0;
/* If we have been asked to, we act like collect2 and
identify all functions that might be global
else
h->u.c.p->section = section;
h->linker_def = 0;
+ h->ldscript_def = 0;
break;
case REF:
2017-11-28 Alan Modra <amodra@gmail.com>
+ PR 22471
+ * ldexp.c (struct definedness_hash_entry): Delete "by_script". Make
+ "iteration" an 8-bit field, and update mask in all uses.
+ (definedness_newfunc): Don't init "by_script".
+ (update_definedness): Test ldscript_def rather than by_script.
+ (is_sym_value): Likewise.
+ (fold_name <DEFINED>): Return a result for first phase. Test
+ ldscript_def.
+ (fold_name <NAME>): Return a result for first phase.
+ * ldlang.c (open_input_bfds): Process all assignments, not just
+ defsym.
+ (lang_process): Increment lang_statement_iteration before
+ open_input_bfds.
+ * testsuite/ld-mips-elf/tlsdyn-o32-1.d: Adjust for larger .dynsym.
+ * testsuite/ld-mips-elf/tlsdyn-o32-1.got: Likewise.
+ * testsuite/ld-mips-elf/tlsdyn-o32-2.d: Likewise.
+ * testsuite/ld-mips-elf/tlsdyn-o32-2.got: Likewise.
+ * testsuite/ld-mips-elf/tlsdyn-o32-3.d: Likewise.
+ * testsuite/ld-mips-elf/tlsdyn-o32-3.got: Likewise.
+
+2017-11-28 Alan Modra <amodra@gmail.com>
+
* ldexp.h (struct ldexp_control): Add "assign_src".
* ldexp.c (fold_trinary): Save and restore assign_src around
condition evaluation.
section statement, the section we'd like it relative to. */
asection *final_sec;
+ /* Low bits of iteration count. Symbols with matching iteration have
+ been defined in this pass over the script. */
+ unsigned int iteration : 8;
+
/* Symbol was defined by an object file. */
unsigned int by_object : 1;
-
- /* Symbols was defined by a script. */
- unsigned int by_script : 1;
-
- /* Low bit of iteration count. Symbols with matching iteration have
- been defined in this pass over the script. */
- unsigned int iteration : 1;
};
static struct bfd_hash_table definedness_table;
einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name);
ret->by_object = 0;
- ret->by_script = 0;
ret->iteration = 0;
return &ret->root;
}
/* If the symbol was already defined, and not by a script, then it
must be defined by an object file or by the linker target code. */
ret = TRUE;
- if (!defentry->by_script
+ if (!h->ldscript_def
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_common))
ret = FALSE;
}
- defentry->by_script = 1;
defentry->iteration = lang_statement_iteration;
defentry->final_sec = bfd_abs_section_ptr;
if (expld.phase == lang_final_phase_enum
static void
fold_name (etree_type *tree)
{
+ struct bfd_link_hash_entry *h;
+ struct definedness_hash_entry *def;
+
memset (&expld.result, 0, sizeof (expld.result));
switch (tree->type.node_code)
break;
case DEFINED:
- if (expld.phase != lang_first_phase_enum)
- {
- struct bfd_link_hash_entry *h;
- struct definedness_hash_entry *def;
-
- h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
- &link_info,
- tree->name.name,
- FALSE, FALSE, TRUE);
- new_number (h != NULL
- && (h->type == bfd_link_hash_defined
- || h->type == bfd_link_hash_defweak
- || h->type == bfd_link_hash_common)
- && ((def = symbol_defined (tree->name.name)) == NULL
- || def->by_object
- || def->iteration == (lang_statement_iteration & 1)));
- }
+ h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+ &link_info,
+ tree->name.name,
+ FALSE, FALSE, TRUE);
+ new_number (h != NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak
+ || h->type == bfd_link_hash_common)
+ && (!h->ldscript_def
+ || (def = symbol_defined (tree->name.name)) == NULL
+ || def->by_object
+ || def->iteration == (lang_statement_iteration & 255)));
break;
case NAME:
{
/* Self-assignment is only allowed for absolute symbols
defined in a linker script. */
- struct bfd_link_hash_entry *h;
- struct definedness_hash_entry *def;
-
h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
&link_info,
tree->name.name,
|| h->type == bfd_link_hash_defweak)
&& h->u.def.section == bfd_abs_section_ptr
&& (def = symbol_defined (tree->name.name)) != NULL
- && def->iteration == (lang_statement_iteration & 1)))
+ && def->iteration == (lang_statement_iteration & 255)))
expld.assign_name = NULL;
}
- if (expld.phase == lang_first_phase_enum)
- ;
- else if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
+ if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
new_rel_from_abs (expld.dot);
else
{
- struct bfd_link_hash_entry *h;
-
h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
&link_info,
tree->name.name,
output_section = h->u.def.section->output_section;
if (output_section == NULL)
{
- if (expld.phase == lang_mark_phase_enum)
+ if (expld.phase <= lang_mark_phase_enum)
new_rel (h->u.def.value, h->u.def.section);
else
einfo (_("%X%S: unresolvable symbol `%s'"
return (tree->type.node_class == etree_name
&& tree->type.node_code == NAME
&& (def = symbol_defined (tree->name.name)) != NULL
- && def->by_script
- && def->iteration == (lang_statement_iteration & 1)
+ && def->iteration == (lang_statement_iteration & 255)
&& (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
&link_info,
tree->name.name,
FALSE, FALSE, TRUE)) != NULL
+ && h->ldscript_def
&& h->type == bfd_link_hash_defined
&& h->u.def.section == bfd_abs_section_ptr
&& h->u.def.value == val);
#endif
break;
case lang_assignment_statement_enum:
- if (s->assignment_statement.exp->type.node_class != etree_assert
- && s->assignment_statement.exp->assign.defsym)
- /* This is from a --defsym on the command line. */
+ if (s->assignment_statement.exp->type.node_class != etree_assert)
exp_fold_tree_no_dot (s->assignment_statement.exp);
break;
default:
/* Create a bfd for each input file. */
current_target = default_target;
+ lang_statement_iteration++;
open_input_bfds (statement_list.head, OPEN_BFD_NORMAL);
#ifdef ENABLE_PLUGINS
/* Rescan archives in case new undefined symbols have appeared. */
files = file_chain;
+ lang_statement_iteration++;
open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
lang_list_remove_tail (&file_chain, &files);
while (files.head != NULL)
.* <__start>:
.*: 3c1c0fc0 lui gp,0xfc0
- .*: 279c7c30 addiu gp,gp,31792
+ .*: 279c7b80 addiu gp,gp,31616
.*: 0399e021 addu gp,gp,t9
.*: 27bdfff0 addiu sp,sp,-16
.*: afbe0008 sw s8,8\(sp\)
.* <other>:
.*: 3c1c0fc0 lui gp,0xfc0
- .*: 279c7b70 addiu gp,gp,31600
+ .*: 279c7ac0 addiu gp,gp,31424
.*: 0399e021 addu gp,gp,t9
.*: 27bdfff0 addiu sp,sp,-16
.*: afbe0008 sw s8,8\(sp\)
Contents of section .got:
- 10000020 00000000 80000000 0040048c 00000000 .........@......
+ 10000020 00000000 80000000 0040053c 00000000 .........@......
10000030 00000000 00000000 00000000 00000000 ................
10000040 00000000 00000001 00000000 ............
.* <__start>:
.*: 3c1c0fc0 lui gp,0xfc0
- .*: 279c7c30 addiu gp,gp,31792
+ .*: 279c7b80 addiu gp,gp,31616
.*: 0399e021 addu gp,gp,t9
.*: 27bdfff0 addiu sp,sp,-16
.*: afbe0008 sw s8,8\(sp\)
.* <other>:
.*: 3c1c0fc0 lui gp,0xfc0
- .*: 279c7b70 addiu gp,gp,31600
+ .*: 279c7ac0 addiu gp,gp,31424
.*: 0399e021 addu gp,gp,t9
.*: 27bdfff0 addiu sp,sp,-16
.*: afbe0008 sw s8,8\(sp\)
Contents of section .got:
- 10000020 00000000 80000000 0040048c 00000000 .*
+ 10000020 00000000 80000000 0040053c 00000000 .*
10000030 00000000 00000000 00000000 00000000 .*
10000040 00000000 00000001 00000000 .*
.* <other>:
.*: 3c1c0fc0 lui gp,0xfc0
- .*: 279c7c30 addiu gp,gp,31792
+ .*: 279c7b80 addiu gp,gp,31616
.*: 0399e021 addu gp,gp,t9
.*: 27bdfff0 addiu sp,sp,-16
.*: afbe0008 sw s8,8\(sp\)
.* <__start>:
.*: 3c1c0fc0 lui gp,0xfc0
- .*: 279c7b80 addiu gp,gp,31616
+ .*: 279c7ad0 addiu gp,gp,31440
.*: 0399e021 addu gp,gp,t9
.*: 27bdfff0 addiu sp,sp,-16
.*: afbe0008 sw s8,8\(sp\)
Contents of section .got:
- 10000020 00000000 80000000 0040053c 00000000 .*
+ 10000020 00000000 80000000 004005ec 00000000 .*
10000030 00000000 00000000 00000000 00000000 .*
10000040 00000000 00000001 00000000 .*