(elfNN_aarch64_gc_sweep_hook): Likewise.
(elfNN_aarch64_check_relocs): Likewise.
+2015-08-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/18841
+ * elf-bfd.h (elf_link_hash_table): Add dynsym.
+ * elf32-i386.c (elf_i386_reloc_type_class): Return
+ reloc_class_ifunc for relocation against STT_GNU_IFUNC symbol.
+ * elf64-x86-64.c (elf_x86_64_reloc_type_class): Likewise.
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Set dynsym.
+ (bfd_elf_size_dynsym_hash_dynstr): Use dynsym.
+ (elf_final_link_info): Remove dynsym_sec.
+ (elf_link_output_extsym): Replace dynsym_sec with dynsym.
+ (bfd_elf_final_link): Remove reference to dynsym_sec. Replace
+ dynsym_sec with dynsym.
+
2015-08-18 H.J. Lu <hongjiu.lu@intel.com>
* bfd/aoutx.h: Replace shared, executable, relocatable and pie
asection *iplt;
asection *irelplt;
asection *irelifunc;
+ asection *dynsym;
};
/* Look up an entry in an ELF linker hash table. */
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_i386_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf_i386_reloc_type_class (const struct bfd_link_info *info,
const asection *rel_sec ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *rela)
{
+ bfd *abfd = info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ unsigned long r_symndx = ELF32_R_SYM (rela->r_info);
+ Elf_Internal_Sym sym;
+
+ if (htab->dynsym == NULL
+ || !bed->s->swap_symbol_in (abfd,
+ (htab->dynsym->contents
+ + r_symndx * sizeof (Elf32_External_Sym)),
+ 0, &sym))
+ abort ();
+
+ /* Check relocation against STT_GNU_IFUNC symbol. */
+ if (ELF32_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+ return reloc_class_ifunc;
+
switch (ELF32_R_TYPE (rela->r_info))
{
case R_386_RELATIVE:
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_x86_64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
const asection *rel_sec ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *rela)
{
+ bfd *abfd = info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
+ unsigned long r_symndx = htab->r_sym (rela->r_info);
+ Elf_Internal_Sym sym;
+
+ if (htab->elf.dynsym == NULL
+ || !bed->s->swap_symbol_in (abfd,
+ (htab->elf.dynsym->contents
+ + r_symndx * bed->s->sizeof_sym),
+ 0, &sym))
+ abort ();
+
+ /* Check relocation against STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+ return reloc_class_ifunc;
+
switch ((int) ELF32_R_TYPE (rela->r_info))
{
case R_X86_64_RELATIVE:
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
+ elf_hash_table (info)->dynsym = s;
s = bfd_make_section_anyway_with_flags (abfd, ".dynstr",
flags | SEC_READONLY);
the final symbol table, because until then we do not know the
correct value to give the symbols. We built the .dynstr
section as we went along in elf_link_add_object_symbols. */
- s = bfd_get_linker_section (dynobj, ".dynsym");
+ s = elf_hash_table (info)->dynsym;
BFD_ASSERT (s != NULL);
s->size = dynsymcount * bed->s->sizeof_sym;
bfd *output_bfd;
/* Symbol string table. */
struct elf_strtab_hash *symstrtab;
- /* .dynsym section. */
- asection *dynsym_sec;
/* .hash section. */
asection *hash_sec;
/* symbol version section (.gnu.version). */
/* If this symbol should be put in the .dynsym section, then put it
there now. We already know the symbol index. We also fill in
the entry in the .hash section. */
- if (flinfo->dynsym_sec != NULL
+ if (elf_hash_table (flinfo->info)->dynsym != NULL
&& h->dynindx != -1
&& elf_hash_table (flinfo->info)->dynamic_sections_created)
{
}
sym.st_name = h->dynstr_index;
- esym = flinfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym;
+ esym = (elf_hash_table (flinfo->info)->dynsym->contents
+ + h->dynindx * bed->s->sizeof_sym);
if (!check_dynsym (flinfo->output_bfd, &sym))
{
eoinfo->failed = TRUE;
if (! dynamic)
{
- flinfo.dynsym_sec = NULL;
flinfo.hash_sec = NULL;
flinfo.symver_sec = NULL;
}
else
{
- flinfo.dynsym_sec = bfd_get_linker_section (dynobj, ".dynsym");
flinfo.hash_sec = bfd_get_linker_section (dynobj, ".hash");
/* Note that dynsym_sec can be NULL (on VMS). */
flinfo.symver_sec = bfd_get_linker_section (dynobj, ".gnu.version");
symtab_hdr->sh_info = bfd_get_symcount (abfd);
if (dynamic
- && flinfo.dynsym_sec != NULL
- && flinfo.dynsym_sec->output_section != bfd_abs_section_ptr)
+ && elf_hash_table (info)->dynsym != NULL
+ && (elf_hash_table (info)->dynsym->output_section
+ != bfd_abs_section_ptr))
{
Elf_Internal_Sym sym;
- bfd_byte *dynsym = flinfo.dynsym_sec->contents;
+ bfd_byte *dynsym = elf_hash_table (info)->dynsym->contents;
long last_local = 0;
/* Write out the section symbols for the output sections. */
}
}
- elf_section_data (flinfo.dynsym_sec->output_section)->this_hdr.sh_info =
+ elf_section_data (elf_hash_table (info)->dynsym->output_section)->this_hdr.sh_info =
last_local + 1;
}
+2015-08-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/18841
+ * ld-ifunc/ifunc.exp: Add a test for PR ld/18841.
+ * ld-ifunc/pr18841.out: New file.
+ * ld-ifunc/pr18841a.c: Likewise.
+ * ld-ifunc/pr18841b.c: Likewise.
+
2015-08-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/18801
{} \
"libpr18808.so" \
] \
+ [list \
+ "Build libpr18841.so" \
+ "-shared" \
+ "-fPIC -O0 -g" \
+ { pr18841b.c } \
+ {} \
+ "libpr18841.so" \
+ ] \
]
run_ld_link_exec_tests [] [list \
"pr18808" \
"pr18808.out" \
] \
+ [list \
+ "Run pr18841" \
+ "tmpdir/libpr18841.so" \
+ "" \
+ { pr18841a.c } \
+ "pr18841" \
+ "pr18841.out" \
+ ] \
]
--- /dev/null
+#include <stdio.h>
+
+extern void test(void);
+
+void zoo(){}
+
+int main()
+{
+ test();
+ printf("OK\n");
+ return 0;
+}
--- /dev/null
+void foo() __attribute__((ifunc("resolve_foo")));
+
+static void foo_impl() {}
+
+extern void abort (void);
+void test()
+{
+ void (*pg)(void) = foo;
+ if (pg != foo_impl)
+ abort ();
+ pg();
+}
+
+static void* resolve_foo()
+{
+ extern void zoo(void);
+
+ void (*pz)(void) = zoo;
+ pz();
+ return foo_impl;
+}