bfd_boolean newweak, oldweak, newfunc, oldfunc;
const struct elf_backend_data *bed;
char *new_version;
+ bfd_boolean default_sym = *matched;
*skip = FALSE;
*override = FALSE;
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. */
sec = *psec;
}
+ /* There are multiple definitions of a normal symbol.
+ Skip the default symbol as well. */
+ if (olddef && !olddyn && !oldweak && newdef && !newdyn && !newweak
+ && !default_sym && h->def_regular)
+ {
+ /* Handle a multiple definition. */
+ (*info->callbacks->multiple_definition) (info, &h->root,
+ abfd, sec, *pvalue);
+ *skip = TRUE;
+ return TRUE;
+ }
+
/* If both the old and the new symbols look like common symbols in a
dynamic object, set the size of the symbol to the larger of the
two. */
_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
{
struct elf_info_failed *eif = (struct elf_info_failed *) data;
- bfd *dynobj;
+ struct elf_link_hash_table *htab;
const struct elf_backend_data *bed;
if (! is_elf_hash_table (eif->info->hash))
if (! _bfd_elf_fix_symbol_flags (h, eif))
return FALSE;
+ htab = elf_hash_table (eif->info);
+ bed = get_elf_backend_data (htab->dynobj);
+
if (h->root.type == bfd_link_hash_undefweak)
{
if (eif->info->dynamic_undefined_weak == 0)
- _bfd_elf_link_hash_hide_symbol (eif->info, h, TRUE);
+ (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
else if (eif->info->dynamic_undefined_weak > 0
&& h->ref_regular
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
(_("warning: type and size of dynamic symbol `%s' are not defined"),
h->root.root.string);
- dynobj = elf_hash_table (eif->info)->dynobj;
- bed = get_elf_backend_data (dynobj);
-
if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
{
eif->failed = TRUE;
&& !(*bed->check_directives) (abfd, info))
return FALSE;
- if (!info->check_relocs_after_open_input
- && !_bfd_elf_link_check_relocs (abfd, info))
- return FALSE;
-
/* If this is a non-traditional link, try to optimize the handling
of the .stab/.stabstr sections. */
if (! dynamic
relocatable output or when needed for --emit-relocs. */
else if (input_sec == bfd_und_section_ptr
&& h->indx != -2
+ /* PR 22319 Do not strip global undefined symbols marked as being needed. */
+ && (h->mark != 1 || ELF_ST_BIND (sym.st_info) != STB_GLOBAL)
&& !bfd_link_relocatable (flinfo->info))
return TRUE;
+
/* Also strip others that we couldn't earlier due to dynamic symbol
processing. */
if (strip)
return TRUE;
}
-/* The sweep phase of garbage collection. Remove all garbage sections. */
-
-typedef bfd_boolean (*gc_sweep_hook_fn)
- (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
-
static bfd_boolean
elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
{
bfd *sub;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
- gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook;
for (sub = info->input_bfds; sub != NULL; sub = sub->link.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;
/* xgettext:c-format */
_bfd_error_handler (_("Removing unused section '%A' in file '%B'"),
o, sub);
-
- /* But we also have to update some of the relocation
- info we collected before. */
- if (gc_sweep_hook
- && (o->flags & SEC_RELOC) != 0
- && o->reloc_count != 0
- && !((info->strip == strip_all || info->strip == strip_debugger)
- && (o->flags & SEC_DEBUGGING) != 0)
- && !bfd_is_abs_section (o->output_section))
- {
- Elf_Internal_Rela *internal_relocs;
- bfd_boolean r;
-
- internal_relocs
- = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL,
- info->keep_memory);
- if (internal_relocs == NULL)
- return FALSE;
-
- r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);
-
- if (elf_section_data (o)->relocs != internal_relocs)
- free (internal_relocs);
-
- if (!r)
- return FALSE;
- }
}
}
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;
if (symbol[0] == '.')
{
/* .startof. and .sizeof. symbols are local. */
- _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+ const struct elf_backend_data *bed;
+ bed = get_elf_backend_data (info->output_bfd);
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
}
else if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_PROTECTED;