break;
}
+ /* Differentiate strong and weak symbols. */
+ newweak = bind == STB_WEAK;
+ oldweak = (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak);
+
/* In cases involving weak versioned symbols, we may wind up trying
to merge a symbol with itself. Catch that here, to avoid the
confusion that results if we try to override a symbol with
_GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a
dynamic object, which we do want to handle here. */
if (abfd == oldbfd
+ && (newweak || oldweak)
&& ((abfd->flags & DYNAMIC) == 0
|| !h->def_regular))
return TRUE;
return TRUE;
}
- /* Differentiate strong and weak symbols. */
- newweak = bind == STB_WEAK;
- oldweak = (h->root.type == bfd_link_hash_defweak
- || h->root.type == bfd_link_hash_undefweak);
-
if (bind == STB_GNU_UNIQUE)
h->unique_global = 1;
{
if (! dynamic)
{
- if (info->shared
+ if (! info->executable
|| hi->ref_dynamic)
*dynsym = TRUE;
}
{
if (! dynamic)
{
- if (info->shared
+ if (! info->executable
|| hi->ref_dynamic)
*dynsym = TRUE;
}
return best_size;
}
+/* Size any SHT_GROUP section for ld -r. */
+
+bfd_boolean
+_bfd_elf_size_group_sections (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+ && !_bfd_elf_fixup_group_sections (ibfd, bfd_abs_section_ptr))
+ return FALSE;
+ return TRUE;
+}
+
/* Set up the sizes and contents of the ELF dynamic sections. This is
called by the ELF linker emulation before_allocation routine. We
must set the sizes of the sections before the linker sets the
elf_hash_table (info)->init_plt_refcount
= elf_hash_table (info)->init_plt_offset;
+ if (info->relocatable
+ && !_bfd_elf_size_group_sections (info))
+ return FALSE;
+
/* The backend may have to create some sections regardless of whether
we're dynamic or not. */
if (bed->elf_backend_always_size_sections
{
struct bfd_elf_version_deps *n;
+ /* Don't emit base version twice. */
+ if (t->vernum == 0)
+ continue;
+
size += sizeof (Elf_External_Verdef);
size += sizeof (Elf_External_Verdaux);
++cdefs;
unsigned int cdeps;
struct bfd_elf_version_deps *n;
+ /* Don't emit the base version twice. */
+ if (t->vernum == 0)
+ continue;
+
cdeps = 0;
for (n = t->deps; n != NULL; n = n->next)
++cdeps;
def.vd_hash = bfd_elf_hash (t->name);
def.vd_aux = sizeof (Elf_External_Verdef);
def.vd_next = 0;
- if (t->next != NULL)
+
+ /* If a basever node is next, it *must* be the last node in
+ the chain, otherwise Verdef construction breaks. */
+ if (t->next != NULL && t->next->vernum == 0)
+ BFD_ASSERT (t->next->next == NULL);
+
+ if (t->next != NULL && t->next->vernum != 0)
def.vd_next = (sizeof (Elf_External_Verdef)
+ (cdeps + 1) * sizeof (Elf_External_Verdaux));
unsigned int crefs;
bfd_byte *p;
- /* Build the version definition section. */
+ /* Build the version dependency section. */
size = 0;
crefs = 0;
for (t = elf_tdata (output_bfd)->verref;
struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
struct bfd_hash_table *,
const char *),
- unsigned int entsize)
+ unsigned int entsize,
+ enum elf_target_id target_id)
{
bfd_boolean ret;
int can_refcount = get_elf_backend_data (abfd)->can_refcount;
table->dynsymcount = 1;
ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+
table->root.type = bfd_link_elf_hash_table;
+ table->hash_table_id = target_id;
return ret;
}
return NULL;
if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc,
- sizeof (struct elf_link_hash_entry)))
+ sizeof (struct elf_link_hash_entry),
+ GENERIC_ELF_DATA))
{
free (ret);
return NULL;
{
/* If we have an undefined symbol reference here then it must have
come from a shared library that is being linked in. (Undefined
- references in regular files have already been handled). */
+ references in regular files have already been handled unless
+ they are in unreferenced sections which are removed by garbage
+ collection). */
bfd_boolean ignore_undef = FALSE;
/* Some symbols may be special in that the fact that they're
/* If we are reporting errors for this situation then do so now. */
if (ignore_undef == FALSE
&& h->ref_dynamic
- && ! h->ref_regular
+ && (!h->ref_regular || finfo->info->gc_sections)
&& ! elf_link_check_versioned_symbol (finfo->info, bed, h)
&& finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
{
if (! (finfo->info->callbacks->undefined_symbol
- (finfo->info, h->root.root.string, h->root.u.undef.abfd,
+ (finfo->info, h->root.root.string,
+ h->ref_regular ? NULL : h->root.u.undef.abfd,
NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
{
eoinfo->failed = TRUE;