int bind;
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
- bfd_boolean newweak, oldweak;
+ bfd_boolean newweak, oldweak, old_asneeded;
*skip = FALSE;
*override = FALSE;
else
olddef = TRUE;
+ /* If the old definition came from an as-needed dynamic library which
+ wasn't found to be needed, treat the sym as undefined. */
+ old_asneeded = FALSE;
+ if (newdyn
+ && olddyn
+ && (elf_dyn_lib_class (oldbfd) & DYN_AS_NEEDED) != 0)
+ old_asneeded = TRUE;
+
/* Check TLS symbol. */
if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
&& ELF_ST_TYPE (sym->st_info) != h->type)
if (olddyn
&& olddef
+ && !old_asneeded
&& h->root.type == bfd_link_hash_defined
&& h->def_dynamic
&& (h->root.u.def.section->flags & SEC_ALLOC) != 0
if (newdyn
&& newdef
- && (olddef
+ && ((olddef && !old_asneeded)
|| (h->root.type == bfd_link_hash_common
&& (newweak
|| ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
symbol is a function or is weak. */
flip = NULL;
- if (! newdyn
+ if ((!newdyn || old_asneeded)
&& (newdef
|| (bfd_is_com_section (sec)
&& (oldweak
if (dynamic)
{
/* Read in any version definitions. */
- if (! _bfd_elf_slurp_version_tables (abfd))
+ if (!_bfd_elf_slurp_version_tables (abfd,
+ info->default_imported_symver))
goto error_free_sym;
/* Read in the symbol versions, but don't bother to convert them
sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
if (sec == NULL)
sec = bfd_abs_section_ptr;
+ else if (sec->kept_section)
+ {
+ /* Symbols from discarded section are undefined. */
+ sec = bfd_und_section_ptr;
+ isym->st_shndx = SHN_UNDEF;
+ }
else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
value -= sec->vma;
}
unsigned int vernum = 0;
bfd_boolean skip;
- if (ever != NULL)
+ if (ever == NULL)
{
- _bfd_elf_swap_versym_in (abfd, ever, &iver);
- vernum = iver.vs_vers & VERSYM_VERSION;
-
- /* If this is a hidden symbol, or if it is not version
- 1, we append the version name to the symbol name.
- However, we do not modify a non-hidden absolute
- symbol, because it might be the version symbol
- itself. FIXME: What if it isn't? */
- if ((iver.vs_vers & VERSYM_HIDDEN) != 0
- || (vernum > 1 && ! bfd_is_abs_section (sec)))
+ if (info->default_imported_symver)
+ /* Use the default symbol version created earlier. */
+ iver.vs_vers = elf_tdata (abfd)->cverdefs;
+ else
+ iver.vs_vers = 0;
+ }
+ else
+ _bfd_elf_swap_versym_in (abfd, ever, &iver);
+
+ vernum = iver.vs_vers & VERSYM_VERSION;
+
+ /* If this is a hidden symbol, or if it is not version
+ 1, we append the version name to the symbol name.
+ However, we do not modify a non-hidden absolute
+ symbol, because it might be the version symbol
+ itself. FIXME: What if it isn't? */
+ if ((iver.vs_vers & VERSYM_HIDDEN) != 0
+ || (vernum > 1 && ! bfd_is_abs_section (sec)))
+ {
+ const char *verstr;
+ size_t namelen, verlen, newlen;
+ char *newname, *p;
+
+ if (isym->st_shndx != SHN_UNDEF)
{
- const char *verstr;
- size_t namelen, verlen, newlen;
- char *newname, *p;
+ if (vernum > elf_tdata (abfd)->cverdefs)
+ verstr = NULL;
+ else if (vernum > 1)
+ verstr =
+ elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+ else
+ verstr = "";
- if (isym->st_shndx != SHN_UNDEF)
+ if (verstr == NULL)
{
- if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
- {
- (*_bfd_error_handler)
- (_("%B: %s: invalid version %u (max %d)"),
- abfd, name, vernum,
- elf_tdata (abfd)->dynverdef_hdr.sh_info);
- bfd_set_error (bfd_error_bad_value);
- goto error_free_vers;
- }
- else if (vernum > 1)
- verstr =
- elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
- else
- verstr = "";
+ (*_bfd_error_handler)
+ (_("%B: %s: invalid version %u (max %d)"),
+ abfd, name, vernum,
+ elf_tdata (abfd)->cverdefs);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
}
- else
+ }
+ else
+ {
+ /* We cannot simply test for the number of
+ entries in the VERNEED section since the
+ numbers for the needed versions do not start
+ at 0. */
+ Elf_Internal_Verneed *t;
+
+ verstr = NULL;
+ for (t = elf_tdata (abfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
{
- /* We cannot simply test for the number of
- entries in the VERNEED section since the
- numbers for the needed versions do not start
- at 0. */
- Elf_Internal_Verneed *t;
-
- verstr = NULL;
- for (t = elf_tdata (abfd)->verref;
- t != NULL;
- t = t->vn_nextref)
- {
- Elf_Internal_Vernaux *a;
+ Elf_Internal_Vernaux *a;
- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ {
+ if (a->vna_other == vernum)
{
- if (a->vna_other == vernum)
- {
- verstr = a->vna_nodename;
- break;
- }
+ verstr = a->vna_nodename;
+ break;
}
- if (a != NULL)
- break;
- }
- if (verstr == NULL)
- {
- (*_bfd_error_handler)
- (_("%B: %s: invalid needed version %d"),
- abfd, name, vernum);
- bfd_set_error (bfd_error_bad_value);
- goto error_free_vers;
}
+ if (a != NULL)
+ break;
+ }
+ if (verstr == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: %s: invalid needed version %d"),
+ abfd, name, vernum);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
}
+ }
- namelen = strlen (name);
- verlen = strlen (verstr);
- newlen = namelen + verlen + 2;
- if ((iver.vs_vers & VERSYM_HIDDEN) == 0
- && isym->st_shndx != SHN_UNDEF)
- ++newlen;
+ namelen = strlen (name);
+ verlen = strlen (verstr);
+ newlen = namelen + verlen + 2;
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && isym->st_shndx != SHN_UNDEF)
+ ++newlen;
- newname = bfd_alloc (abfd, newlen);
- if (newname == NULL)
- goto error_free_vers;
- memcpy (newname, name, namelen);
- p = newname + namelen;
- *p++ = ELF_VER_CHR;
- /* If this is a defined non-hidden version symbol,
- we add another @ to the name. This indicates the
- default version of the symbol. */
- if ((iver.vs_vers & VERSYM_HIDDEN) == 0
- && isym->st_shndx != SHN_UNDEF)
- *p++ = ELF_VER_CHR;
- memcpy (p, verstr, verlen + 1);
+ newname = bfd_alloc (abfd, newlen);
+ if (newname == NULL)
+ goto error_free_vers;
+ memcpy (newname, name, namelen);
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ /* If this is a defined non-hidden version symbol,
+ we add another @ to the name. This indicates the
+ default version of the symbol. */
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && isym->st_shndx != SHN_UNDEF)
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
- name = newname;
- }
+ name = newname;
}
if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
goto error_free_vers;
}
+ elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
+
add_needed = TRUE;
ret = elf_add_dt_needed_tag (info, soname, add_needed);
if (ret < 0)
{
Elf_Internal_Sym *sym = isymbuf + r_symndx;
ps = &finfo->sections[r_symndx];
- sym_name = bfd_elf_local_sym_name (input_bfd, sym);
+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym);
}
/* Complain if the definition comes from a