+2013-03-28 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (enum elf_reloc_type_class): Add reloc_class_ifunc.
+ (struct elf_backend_data <elf_backed_reloc_type_class>): Add
+ bfd_link_info* and asection* params.
+ (_bfd_elf_reloc_type_class): Likewise.
+ * elf.c (_bfd_elf_reloc_type_class): Likewise.
+ * elflink.c (elf_link_sort_cmp2): Sort first on reloc class.
+ (elf_link_sort_relocs): Update elf_backed_reloc_type_class call.
+ * elf32-ppc.c (ppc_elf_reloc_type_class): Return reloc_class_ifunc
+ for any reliplt reloc. Don't return reloc_class_plt for
+ R_PPC_REL24 and R_PPC_ADDR24.
+ * elf64-ppc.c (allocate_got): Formatting.
+ (ppc64_elf_reloc_type_class): Return reloc_class_ifunc for any
+ reliplt reloc.
+ * elf-m10300.c, * elf32-arm.c, * elf32-bfin.c, * elf32-cr16.c,
+ * elf32-cris.c, * elf32-hppa.c, * elf32-i386.c, * elf32-lm32.c,
+ * elf32-m32r.c, * elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c,
+ * elf32-s390.c, * elf32-sh.c, * elf32-sparc.c, * elf32-tilepro.c,
+ * elf32-vax.c, * elf32-xtensa.c, * elf64-aarch64.c, * elf64-alpha.c,
+ * elf64-hppa.c, * elf64-ia64-vms.c, * elf64-s390.c, * elf64-sparc.c,
+ * elf64-x86-64.c, * elfnn-ia64.c, * elfxx-tilegx.c, * elfxx-tilegx.h:
+ Add extra params to the various reloc_type_class functions.
+
2013-03-27 Alan Modra <amodra@gmail.com>
* elf32-ppc.c (ppc_elf_check_relocs): Set PLT_IFUNC in local got
reloc_class_normal,
reloc_class_relative,
reloc_class_plt,
- reloc_class_copy
+ reloc_class_copy,
+ reloc_class_ifunc
};
struct elf_reloc_cookie
/* This function returns class of a reloc type. */
enum elf_reloc_type_class (*elf_backend_reloc_type_class)
- (const Elf_Internal_Rela *);
+ (const struct bfd_link_info *, const asection *, const Elf_Internal_Rela *);
/* This function, if defined, removes information about discarded functions
from other sections which mention them. */
(bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
- (const Elf_Internal_Rela *);
+ (const struct bfd_link_info *, const asection *,
+ const Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rela_local_sym
(bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rel_local_sym
properly. */
static enum elf_reloc_type_class
-_bfd_mn10300_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+_bfd_mn10300_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
enum elf_reloc_type_class
-_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
+_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
{
return reloc_class_normal;
}
}
static enum elf_reloc_type_class
-elf32_arm_reloc_type_class (const Elf_Internal_Rela *rela)
+elf32_arm_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
+elf32_bfin_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela * rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
properly. */
static enum elf_reloc_type_class
-_bfd_cr16_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+_bfd_cr16_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf_cris_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_cris_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rela->r_info);
switch (r_type)
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf32_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
+elf32_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
/* Handle TLS relocs first; we don't want them to be marked
relative by the "if (ELF32_R_SYM (rela->r_info) == STN_UNDEF)"
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_i386_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_i386_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch (ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-lm32_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+lm32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
};
static enum elf_reloc_type_class
-m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf32_m68k_reloc_type_class (const Elf_Internal_Rela *rela)
+elf32_m68k_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_metag_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_metag_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
/* Implement elf_backend_reloc_type_class. */
static enum elf_reloc_type_class
-nios2_elf32_reloc_type_class (const Elf_Internal_Rela *rela)
+nios2_elf32_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
\f
static enum elf_reloc_type_class
-ppc_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+ppc_elf_reloc_type_class (const struct bfd_link_info *info,
+ const asection *rel_sec,
+ const Elf_Internal_Rela *rela)
{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+
+ if (rel_sec == htab->reliplt)
+ return reloc_class_ifunc;
+
switch (ELF32_R_TYPE (rela->r_info))
{
case R_PPC_RELATIVE:
return reloc_class_relative;
- case R_PPC_REL24:
- case R_PPC_ADDR24:
case R_PPC_JMP_SLOT:
return reloc_class_plt;
case R_PPC_COPY:
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_s390_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
#define elf_backend_relocate_section elf_s390_relocate_section
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
-#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_grok_prstatus elf_s390_grok_prstatus
#define elf_backend_plt_sym_val elf_s390_plt_sym_val
#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
}
static enum elf_reloc_type_class
-sh_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+sh_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf32_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
+elf32_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-tilepro_reloc_type_class (const Elf_Internal_Rela *rela)
+tilepro_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf_vax_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_vax_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
static enum elf_reloc_type_class
-elf_xtensa_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_xtensa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf64_aarch64_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
}
static enum elf_reloc_type_class
-elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_alpha_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
(bfd *, struct bfd_link_info *,
struct elf_link_hash_entry *, Elf_Internal_Sym *);
-static enum elf_reloc_type_class elf64_hppa_reloc_type_class
- (const Elf_Internal_Rela *);
-
static bfd_boolean elf64_hppa_finish_dynamic_sections
(bfd *, struct bfd_link_info *);
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf64_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
if (ELF64_R_SYM (rela->r_info) == STN_UNDEF)
return reloc_class_relative;
}
static enum elf_reloc_type_class
-elf64_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_ia64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
dyn = htab->elf.dynamic_sections_created;
if ((info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
- && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak))
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
{
asection *relgot = ppc64_elf_tdata (gent->owner)->relgot;
relgot->size += rentsize;
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-ppc64_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+ppc64_elf_reloc_type_class (const struct bfd_link_info *info,
+ const asection *rel_sec,
+ const Elf_Internal_Rela *rela)
{
enum elf_ppc64_reloc_type r_type;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (rel_sec == htab->reliplt)
+ return reloc_class_ifunc;
r_type = ELF64_R_TYPE (rela->r_info);
switch (r_type)
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_s390_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
#define elf_backend_relocate_section elf_s390_relocate_section
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
-#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_plt_sym_val elf_s390_plt_sym_val
#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
}
\f
static enum elf_reloc_type_class
-elf64_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_x86_64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
{
const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A;
const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B;
- int copya, copyb;
- if (a->u.offset < b->u.offset)
+ if (a->type < b->type)
return -1;
- if (a->u.offset > b->u.offset)
+ if (a->type > b->type)
return 1;
- copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt);
- copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt);
- if (copya < copyb)
+ if (a->u.offset < b->u.offset)
return -1;
- if (copya > copyb)
+ if (a->u.offset > b->u.offset)
return 1;
if (a->rela->r_offset < b->rela->r_offset)
return -1;
struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
(*swap_in) (abfd, erel, s->rela);
- s->type = (*bed->elf_backend_reloc_type_class) (s->rela);
+ s->type = (*bed->elf_backend_reloc_type_class) (info, o, s->rela);
s->u.sym_mask = r_sym_mask;
p += sort_elt;
erel += ext_size;
}
static enum elf_reloc_type_class
-elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
+elfNN_ia64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELFNN_R_TYPE (rela->r_info))
{
}
enum elf_reloc_type_class
-tilegx_reloc_type_class (const Elf_Internal_Rela *rela)
+tilegx_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) TILEGX_ELF_R_TYPE (rela->r_info))
{
#include "elf/internal.h"
extern enum elf_reloc_type_class
-tilegx_reloc_type_class (const Elf_Internal_Rela *);
+tilegx_reloc_type_class (const struct bfd_link_info *,
+ const asection *,
+ const Elf_Internal_Rela *);
extern reloc_howto_type *
tilegx_reloc_name_lookup (bfd *, const char *);