/* ELF linking support for BFD.
- Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& discarded_section (h->root.u.def.section))
- return h->root.u.def.section;
+ return h->root.u.def.section;
else
return NULL;
}
/* If this is a weak defined symbol, and we know a corresponding
real symbol from the same dynamic object, make sure the real
symbol is also made into a dynamic symbol. */
- if (h->u.weakdef != NULL
- && h->u.weakdef->dynindx == -1)
+ if (h->is_weakalias)
{
- if (! bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
+ struct elf_link_hash_entry *def = weakdef (h);
+
+ if (def->dynindx == -1
+ && !bfd_elf_link_record_dynamic_symbol (info, def))
return FALSE;
}
}
symbol for each output section, which come first. Next come symbols
which have been forced to local binding. Then all of the back-end
allocated local dynamic syms, followed by the rest of the global
- symbols. */
+ symbols. If SECTION_SYM_COUNT is NULL, section dynindx is not set.
+ (This prevents the early call before elf_backend_init_index_section
+ and strip_excluded_output_sections setting dynindx for sections
+ that are stripped.) */
static unsigned long
_bfd_elf_link_renumber_dynsyms (bfd *output_bfd,
unsigned long *section_sym_count)
{
unsigned long dynsymcount = 0;
+ bfd_boolean do_sec = section_sym_count != NULL;
if (bfd_link_pic (info)
|| elf_hash_table (info)->is_relocatable_executable)
if ((p->flags & SEC_EXCLUDE) == 0
&& (p->flags & SEC_ALLOC) != 0
&& !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
- elf_section_data (p)->dynindx = ++dynsymcount;
- else
+ {
+ ++dynsymcount;
+ if (do_sec)
+ elf_section_data (p)->dynindx = dynsymcount;
+ }
+ else if (do_sec)
elf_section_data (p)->dynindx = 0;
}
- *section_sym_count = dynsymcount;
+ if (do_sec)
+ *section_sym_count = dynsymcount;
elf_link_hash_traverse (elf_hash_table (info),
elf_link_renumber_local_hash_table_dynsyms,
if (pold_weak)
*pold_weak = oldweak;
- /* This code is for coping with dynamic objects, and is only useful
- if we are doing an ELF link. */
- if (!(*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
- return TRUE;
-
/* We have to check it for every instance since the first few may be
references and not all compilers emit symbol type for undefined
symbols. */
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;
sec = *psec;
}
- /* There are multiple definitions of a normal symbol.
- Skip the default symbol as well. */
+ /* There are multiple definitions of a normal symbol. Skip the
+ default symbol as well as definition from an IR object. */
if (olddef && !olddyn && !oldweak && newdef && !newdyn && !newweak
- && !default_sym && h->def_regular)
+ && !default_sym && h->def_regular
+ && !(oldbfd != NULL
+ && (oldbfd->flags & BFD_PLUGIN) != 0
+ && (abfd->flags & BFD_PLUGIN) == 0))
{
/* Handle a multiple definition. */
(*info->callbacks->multiple_definition) (info, &h->root,
/* If this is a weak defined symbol in a dynamic object, and we know
the real definition in the dynamic object, copy interesting flags
over to the real definition. */
- if (h->u.weakdef != NULL)
+ if (h->is_weakalias)
{
+ struct elf_link_hash_entry *def = weakdef (h);
+
/* If the real definition is defined by a regular object file,
don't do anything special. See the longer description in
_bfd_elf_adjust_dynamic_symbol, below. */
- if (h->u.weakdef->def_regular)
- h->u.weakdef = NULL;
+ if (def->def_regular)
+ {
+ h = def;
+ while ((h = h->u.alias) != def)
+ h->is_weakalias = 0;
+ }
else
{
- struct elf_link_hash_entry *weakdef = h->u.weakdef;
-
while (h->root.type == bfd_link_hash_indirect)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak);
- BFD_ASSERT (weakdef->def_dynamic);
- BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
- || weakdef->root.type == bfd_link_hash_defweak);
- (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
+ BFD_ASSERT (def->def_dynamic);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ (*bed->elf_backend_copy_indirect_symbol) (eif->info, def, h);
}
}
&& (h->def_regular
|| !h->def_dynamic
|| (!h->ref_regular
- && (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1))))
+ && (!h->is_weakalias || weakdef (h)->dynindx == -1))))
{
h->plt = elf_hash_table (eif->info)->init_plt_offset;
return TRUE;
wind up at different memory locations. The tzset call will set
_timezone, leaving timezone unchanged. */
- if (h->u.weakdef != NULL)
+ if (h->is_weakalias)
{
+ struct elf_link_hash_entry *def = weakdef (h);
+
/* If we get to this point, there is an implicit reference to
- H->U.WEAKDEF by a regular object file via the weak symbol H. */
- h->u.weakdef->ref_regular = 1;
+ the alias by a regular object file via the weak symbol H. */
+ def->ref_regular = 1;
/* Ensure that the backend adjust_dynamic_symbol function sees
- H->U.WEAKDEF before H by recursively calling ourselves. */
- if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif))
+ the strong alias before H by recursively calling ourselves. */
+ if (!_bfd_elf_adjust_dynamic_symbol (def, eif))
return FALSE;
}
bfd_boolean definition;
bfd_boolean size_change_ok;
bfd_boolean type_change_ok;
- bfd_boolean new_weakdef;
bfd_boolean new_weak;
bfd_boolean old_weak;
bfd_boolean override;
*sym_hash = h;
new_weak = (flags & BSF_WEAK) != 0;
- new_weakdef = FALSE;
if (dynamic
&& definition
&& new_weak
&& !bed->is_function_type (ELF_ST_TYPE (isym->st_info))
&& is_elf_hash_table (htab)
- && h->u.weakdef == NULL)
+ && h->u.alias == NULL)
{
/* Keep a list of all weak defined non function symbols from
- a dynamic object, using the weakdef field. Later in this
- function we will set the weakdef field to the correct
+ a dynamic object, using the alias field. Later in this
+ function we will set the alias field to the correct
value. We only put non-function symbols from dynamic
objects on this list, because that happens to be the only
time we need to know the normal symbol corresponding to a
weak symbol, and the information is time consuming to
- figure out. If the weakdef field is not already NULL,
+ figure out. If the alias field is not already NULL,
then this symbol was already defined by some previous
dynamic object, and we will be using that previous
definition anyhow. */
- h->u.weakdef = weaks;
+ h->u.alias = weaks;
weaks = h;
- new_weakdef = TRUE;
}
/* Set the alignment of a common symbol. */
if ((h == hi || !hi->forced_local)
&& (h->def_regular
|| h->ref_regular
- || (h->u.weakdef != NULL
- && ! new_weakdef
- && h->u.weakdef->dynindx != -1)))
+ || (h->is_weakalias
+ && weakdef (h)->dynindx != -1)))
dynsym = TRUE;
}
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
goto error_free_vers;
- if (h->u.weakdef != NULL
- && ! new_weakdef
- && h->u.weakdef->dynindx == -1)
+ if (h->is_weakalias
+ && weakdef (h)->dynindx == -1)
{
- if (!bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
+ if (!bfd_elf_link_record_dynamic_symbol (info, weakdef (h)))
goto error_free_vers;
}
}
}
}
+ if (info->lto_plugin_active
+ && !bfd_link_relocatable (info)
+ && (abfd->flags & BFD_PLUGIN) == 0
+ && !just_syms
+ && extsymcount)
+ {
+ int r_sym_shift;
+
+ if (bed->s->arch_size == 32)
+ r_sym_shift = 8;
+ else
+ r_sym_shift = 32;
+
+ /* If linker plugin is enabled, set non_ir_ref_regular on symbols
+ referenced in regular objects so that linker plugin will get
+ the correct symbol resolution. */
+
+ sym_hash = elf_sym_hashes (abfd);
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *rel, *relend;
+
+ /* Don't check relocations in excluded sections. */
+ if ((s->flags & SEC_RELOC) == 0
+ || s->reloc_count == 0
+ || (s->flags & SEC_EXCLUDE) != 0
+ || ((info->strip == strip_all
+ || info->strip == strip_debugger)
+ && (s->flags & SEC_DEBUGGING) != 0))
+ continue;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, s, NULL,
+ NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_free_vers;
+
+ rel = internal_relocs;
+ relend = rel + s->reloc_count;
+ for ( ; rel < relend; rel++)
+ {
+ unsigned long r_symndx = rel->r_info >> r_sym_shift;
+ struct elf_link_hash_entry *h;
+
+ /* Skip local symbols. */
+ if (r_symndx < extsymoff)
+ continue;
+
+ h = sym_hash[r_symndx - extsymoff];
+ if (h != NULL)
+ h->root.non_ir_ref_regular = 1;
+ }
+
+ if (elf_section_data (s)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+ }
+
if (extversym != NULL)
{
free (extversym);
nondeflt_vers = NULL;
}
- /* Now set the weakdefs field correctly for all the weak defined
+ /* Now set the alias field correctly for all the weak defined
symbols we found. The only way to do this is to search all the
symbols. Since we only need the information for non functions in
dynamic objects, that's the only time we actually put anything on
size_t i, j, idx = 0;
hlook = weaks;
- weaks = hlook->u.weakdef;
- hlook->u.weakdef = NULL;
+ weaks = hlook->u.alias;
+ hlook->u.alias = NULL;
+
+ if (hlook->root.type != bfd_link_hash_defined
+ && hlook->root.type != bfd_link_hash_defweak)
+ continue;
- BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
- || hlook->root.type == bfd_link_hash_defweak
- || hlook->root.type == bfd_link_hash_common
- || hlook->root.type == bfd_link_hash_indirect);
slook = hlook->root.u.def.section;
vlook = hlook->root.u.def.value;
break;
else if (h != hlook)
{
- hlook->u.weakdef = h;
+ struct elf_link_hash_entry *t;
+
+ hlook->u.alias = h;
+ hlook->is_weakalias = 1;
+ t = h;
+ if (t->u.alias != NULL)
+ while (t->u.alias != h)
+ t = t->u.alias;
+ t->u.alias = hlook;
/* If the weak definition is in the list of dynamic
symbols, make sure the real definition is put
if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
{
- unsigned long section_sym_count;
-
if (elf_tdata (output_bfd)->cverdefs)
{
unsigned int crefs = elf_tdata (output_bfd)->cverdefs;
if ((elf_tdata (output_bfd)->cverrefs == 0
&& elf_tdata (output_bfd)->cverdefs == 0)
- || _bfd_elf_link_renumber_dynsyms (output_bfd, info,
- §ion_sym_count) <= 1)
+ || _bfd_elf_link_renumber_dynsyms (output_bfd, info, NULL) <= 1)
{
asection *s;
addend field. The symbol mangling format is:
<node> := <literal>
- | <unary-operator> ':' <node>
- | <binary-operator> ':' <node> ':' <node>
+ | <unary-operator> ':' <node>
+ | <binary-operator> ':' <node> ':' <node>
;
<literal> := 's' <digits=N> ':' <N character symbol name>
- | 'S' <digits=N> ':' <N character section name>
+ | 'S' <digits=N> ':' <N character section name>
| '#' <hexdigits>
;
/* Looks up NAME in SECTIONS. If found sets RESULT to NAME's address (in
bytes) and returns TRUE, otherwise returns FALSE. Accepts pseudo-section
names like "foo.end" which is the end address of section "foo". */
-
+
static bfd_boolean
resolve_section (const char *name,
asection *sections,
unsigned long *trunc_p,
unsigned long encoded)
{
- * start = encoded & 0x3F;
- * len = (encoded >> 6) & 0x3F;
+ * start = encoded & 0x3F;
+ * len = (encoded >> 6) & 0x3F;
* oplen = (encoded >> 12) & 0x3F;
* wordsz = (encoded >> 18) & 0xF;
* chunksz = (encoded >> 22) & 0xF;
keep the non-weak definition because many backends put
dynamic reloc info on the non-weak definition for code
handling copy relocs. */
- if (h->u.weakdef != NULL)
- h->u.weakdef->mark = 1;
+ if (h->is_weakalias)
+ weakdef (h)->mark = 1;
if (start_stop != NULL)
{
ilen = strlen (isec->name);
/* Association is determined by the name of the debug
- section containing the name of the code section as
+ section containing the name of the code section as
a suffix. For example .debug_line.text.foo is a
debug section associated with .text.foo. */
for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
asection *o;
if (bfd_get_flavour (sub) != bfd_target_elf_flavour
+ || elf_object_id (sub) != elf_hash_table_id (elf_hash_table (info))
|| !(*bed->relocs_compatible) (sub->xvec, abfd->xvec))
continue;
o = sub->sections;
asection *o;
if (bfd_get_flavour (sub) != bfd_target_elf_flavour
+ || elf_object_id (sub) != elf_hash_table_id (htab)
|| !(*bed->relocs_compatible) (sub->xvec, abfd->xvec))
continue;
/* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
Also treat note sections as a root, if the section is not part
- of a group. */
+ of a group. We must keep all PREINIT_ARRAY, INIT_ARRAY as
+ well as FINI_ARRAY sections for ld -r. */
for (o = sub->sections; o != NULL; o = o->next)
if (!o->gc_mark
&& (o->flags & SEC_EXCLUDE) == 0
&& ((o->flags & SEC_KEEP) != 0
+ || (bfd_link_relocatable (info)
+ && ((elf_section_data (o)->this_hdr.sh_type
+ == SHT_PREINIT_ARRAY)
+ || (elf_section_data (o)->this_hdr.sh_type
+ == SHT_INIT_ARRAY)
+ || (elf_section_data (o)->this_hdr.sh_type
+ == SHT_FINI_ARRAY)))
|| (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
&& elf_next_in_group (o) == NULL )))
{