(_("%s: undefined versioned symbol name %s"),
bfd_get_filename (sinfo->output_bfd), h->root.root.string);
bfd_set_error (bfd_error_bad_value);
+error_return:
sinfo->failed = true;
return false;
}
(*bed->elf_backend_hide_symbol) (info, h, true);
}
}
+
+ /* We need to check if a hidden versioned definition should
+ hide the default one. */
+ if (h->dynindx != -1 && h->verinfo.vertree != NULL)
+ {
+ const char *verstr, *name;
+ size_t namelen, verlen, newlen;
+ char *newname;
+ struct elf_link_hash_entry *newh;
+
+ name = h->root.root.string;
+ namelen = strlen (name);
+ verstr = h->verinfo.vertree->name;
+ verlen = strlen (verstr);
+ newlen = namelen + verlen + 2;
+
+ newname = (char *) bfd_malloc ((bfd_size_type) newlen);
+ if (newname == NULL)
+ goto error_return;
+ memcpy (newname, name, namelen);
+
+ /* Check the hidden versioned definition. */
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+ newh = elf_link_hash_lookup (elf_hash_table (info), newname,
+ false, false, false);
+
+ if (newh
+ && (newh->root.type == bfd_link_hash_defined
+ || newh->root.type == bfd_link_hash_defweak))
+ /* We find a hidden versioned definition. Hide the default
+ one. */
+ (*bed->elf_backend_hide_symbol) (info, h, true);
+
+ free (newname);
+ }
}
return true;
Elf_Internal_Rela *irela;
Elf_Internal_Rela *irelaend;
struct elf_link_hash_entry **rel_hash;
- Elf_Internal_Shdr *input_rel_hdr;
+ Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
unsigned int next_erel;
boolean (*reloc_emitter) PARAMS ((bfd *, asection *,
Elf_Internal_Shdr *,
else
reloc_emitter = elf_link_output_relocs;
- if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
- internal_relocs))
+ if (input_rel_hdr->sh_size != 0
+ && ! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
+ internal_relocs))
return false;
- input_rel_hdr = elf_section_data (o)->rel_hdr2;
- if (input_rel_hdr)
+ input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
+ if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0)
{
internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel);
- if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
+ if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr2,
internal_relocs))
return false;
}