aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c837
1 files changed, 465 insertions, 372 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 83656ae..a50dccc 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1,4 +1,4 @@
-/* X86-64 specific support for 64-bit ELF
+/* X86-64 specific support for ELF
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>.
@@ -34,6 +34,14 @@
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
#define MINUS_ONE (~ (bfd_vma) 0)
+/* Since both 32-bit and 64-bit x86-64 encode relocation type in the
+ identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
+ relocation type. We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
+ since they are the same. */
+
+#define ABI_64_P(abfd) \
+ (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
/* The relocation "howto" table. Order of fields:
type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */
@@ -222,7 +230,7 @@ static const struct elf_reloc_map x86_64_reloc_map[] =
};
static reloc_howto_type *
-elf64_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
+elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
{
unsigned i;
@@ -245,8 +253,8 @@ elf64_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
/* Given a BFD reloc type, return a HOWTO structure. */
static reloc_howto_type *
-elf64_x86_64_reloc_type_lookup (bfd *abfd,
- bfd_reloc_code_real_type code)
+elf_x86_64_reloc_type_lookup (bfd *abfd,
+ bfd_reloc_code_real_type code)
{
unsigned int i;
@@ -254,15 +262,15 @@ elf64_x86_64_reloc_type_lookup (bfd *abfd,
i++)
{
if (x86_64_reloc_map[i].bfd_reloc_val == code)
- return elf64_x86_64_rtype_to_howto (abfd,
- x86_64_reloc_map[i].elf_reloc_val);
+ return elf_x86_64_rtype_to_howto (abfd,
+ x86_64_reloc_map[i].elf_reloc_val);
}
return 0;
}
static reloc_howto_type *
-elf64_x86_64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
- const char *r_name)
+elf_x86_64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
{
unsigned int i;
@@ -280,19 +288,19 @@ elf64_x86_64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
/* Given an x86_64 ELF reloc type, fill in an arelent structure. */
static void
-elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
- Elf_Internal_Rela *dst)
+elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
{
unsigned r_type;
- r_type = ELF64_R_TYPE (dst->r_info);
- cache_ptr->howto = elf64_x86_64_rtype_to_howto (abfd, r_type);
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
BFD_ASSERT (r_type == cache_ptr->howto->type);
}
/* Support for core dump NOTE sections. */
static bfd_boolean
-elf64_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
size_t size;
@@ -324,7 +332,7 @@ elf64_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
}
static bfd_boolean
-elf64_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
switch (note->descsz)
{
@@ -360,7 +368,8 @@ elf64_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
/* The name of the dynamic interpreter. This is put in the .interp
section. */
-#define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
+#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
+#define ELF32_DYNAMIC_INTERPRETER "/lib/ld32.so.1"
/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
copying dynamic variables from a shared lib into an app's dynbss
@@ -379,7 +388,7 @@ elf64_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
/* The first entry in a procedure linkage table looks like this. See the
SVR4 ABI i386 supplement and the x86-64 ABI to see how this works. */
-static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
{
0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */
@@ -388,7 +397,7 @@ static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
/* Subsequent entries in a procedure linkage table look like this. */
-static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_x86_64_plt_entry[PLT_ENTRY_SIZE] =
{
0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
@@ -400,7 +409,7 @@ static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] =
/* x86-64 ELF linker hash entry. */
-struct elf64_x86_64_link_hash_entry
+struct elf_x86_64_link_hash_entry
{
struct elf_link_hash_entry elf;
@@ -427,10 +436,10 @@ struct elf64_x86_64_link_hash_entry
bfd_vma tlsdesc_got;
};
-#define elf64_x86_64_hash_entry(ent) \
- ((struct elf64_x86_64_link_hash_entry *)(ent))
+#define elf_x86_64_hash_entry(ent) \
+ ((struct elf_x86_64_link_hash_entry *)(ent))
-struct elf64_x86_64_obj_tdata
+struct elf_x86_64_obj_tdata
{
struct elf_obj_tdata root;
@@ -441,14 +450,14 @@ struct elf64_x86_64_obj_tdata
bfd_vma *local_tlsdesc_gotent;
};
-#define elf64_x86_64_tdata(abfd) \
- ((struct elf64_x86_64_obj_tdata *) (abfd)->tdata.any)
+#define elf_x86_64_tdata(abfd) \
+ ((struct elf_x86_64_obj_tdata *) (abfd)->tdata.any)
-#define elf64_x86_64_local_got_tls_type(abfd) \
- (elf64_x86_64_tdata (abfd)->local_got_tls_type)
+#define elf_x86_64_local_got_tls_type(abfd) \
+ (elf_x86_64_tdata (abfd)->local_got_tls_type)
-#define elf64_x86_64_local_tlsdesc_gotent(abfd) \
- (elf64_x86_64_tdata (abfd)->local_tlsdesc_gotent)
+#define elf_x86_64_local_tlsdesc_gotent(abfd) \
+ (elf_x86_64_tdata (abfd)->local_tlsdesc_gotent)
#define is_x86_64_elf(bfd) \
(bfd_get_flavour (bfd) == bfd_target_elf_flavour \
@@ -456,15 +465,15 @@ struct elf64_x86_64_obj_tdata
&& elf_object_id (bfd) == X86_64_ELF_DATA)
static bfd_boolean
-elf64_x86_64_mkobject (bfd *abfd)
+elf_x86_64_mkobject (bfd *abfd)
{
- return bfd_elf_allocate_object (abfd, sizeof (struct elf64_x86_64_obj_tdata),
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_x86_64_obj_tdata),
X86_64_ELF_DATA);
}
/* x86-64 ELF linker hash table. */
-struct elf64_x86_64_link_hash_table
+struct elf_x86_64_link_hash_table
{
struct elf_link_hash_table elf;
@@ -484,6 +493,12 @@ struct elf64_x86_64_link_hash_table
/* Small local sym cache. */
struct sym_cache sym_cache;
+ bfd_vma (*r_info) (bfd_vma, bfd_vma);
+ bfd_vma (*r_sym) (bfd_vma);
+ void (*swap_reloca_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+ const char *dynamic_interpreter;
+ int dynamic_interpreter_size;
+
/* _TLS_MODULE_BASE_ symbol. */
struct bfd_link_hash_entry *tls_module_base;
@@ -503,19 +518,19 @@ struct elf64_x86_64_link_hash_table
/* Get the x86-64 ELF linker hash table from a link_info structure. */
-#define elf64_x86_64_hash_table(p) \
+#define elf_x86_64_hash_table(p) \
(elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == X86_64_ELF_DATA ? ((struct elf64_x86_64_link_hash_table *) ((p)->hash)) : NULL)
+ == X86_64_ELF_DATA ? ((struct elf_x86_64_link_hash_table *) ((p)->hash)) : NULL)
-#define elf64_x86_64_compute_jump_table_size(htab) \
+#define elf_x86_64_compute_jump_table_size(htab) \
((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
/* Create an entry in an x86-64 ELF linker hash table. */
static struct bfd_hash_entry *
-elf64_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
- struct bfd_hash_table *table,
- const char *string)
+elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
{
/* Allocate the structure if it has not already been allocated by a
subclass. */
@@ -523,7 +538,7 @@ elf64_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
{
entry = (struct bfd_hash_entry *)
bfd_hash_allocate (table,
- sizeof (struct elf64_x86_64_link_hash_entry));
+ sizeof (struct elf_x86_64_link_hash_entry));
if (entry == NULL)
return entry;
}
@@ -532,9 +547,9 @@ elf64_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
entry = _bfd_elf_link_hash_newfunc (entry, table, string);
if (entry != NULL)
{
- struct elf64_x86_64_link_hash_entry *eh;
+ struct elf_x86_64_link_hash_entry *eh;
- eh = (struct elf64_x86_64_link_hash_entry *) entry;
+ eh = (struct elf_x86_64_link_hash_entry *) entry;
eh->dyn_relocs = NULL;
eh->tls_type = GOT_UNKNOWN;
eh->tlsdesc_got = (bfd_vma) -1;
@@ -549,7 +564,7 @@ elf64_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
hash since they aren't used by global symbols in this backend. */
static hashval_t
-elf64_x86_64_local_htab_hash (const void *ptr)
+elf_x86_64_local_htab_hash (const void *ptr)
{
struct elf_link_hash_entry *h
= (struct elf_link_hash_entry *) ptr;
@@ -559,7 +574,7 @@ elf64_x86_64_local_htab_hash (const void *ptr)
/* Compare local hash entries. */
static int
-elf64_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
+elf_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
{
struct elf_link_hash_entry *h1
= (struct elf_link_hash_entry *) ptr1;
@@ -572,18 +587,18 @@ elf64_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
/* Find and/or create a hash entry for local symbol. */
static struct elf_link_hash_entry *
-elf64_x86_64_get_local_sym_hash (struct elf64_x86_64_link_hash_table *htab,
- bfd *abfd, const Elf_Internal_Rela *rel,
- bfd_boolean create)
+elf_x86_64_get_local_sym_hash (struct elf_x86_64_link_hash_table *htab,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
{
- struct elf64_x86_64_link_hash_entry e, *ret;
+ struct elf_x86_64_link_hash_entry e, *ret;
asection *sec = abfd->sections;
hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
- ELF64_R_SYM (rel->r_info));
+ htab->r_sym (rel->r_info));
void **slot;
e.elf.indx = sec->id;
- e.elf.dynstr_index = ELF64_R_SYM (rel->r_info);
+ e.elf.dynstr_index = htab->r_sym (rel->r_info);
slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
create ? INSERT : NO_INSERT);
@@ -592,18 +607,18 @@ elf64_x86_64_get_local_sym_hash (struct elf64_x86_64_link_hash_table *htab,
if (*slot)
{
- ret = (struct elf64_x86_64_link_hash_entry *) *slot;
+ ret = (struct elf_x86_64_link_hash_entry *) *slot;
return &ret->elf;
}
- ret = (struct elf64_x86_64_link_hash_entry *)
+ ret = (struct elf_x86_64_link_hash_entry *)
objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
- sizeof (struct elf64_x86_64_link_hash_entry));
+ sizeof (struct elf_x86_64_link_hash_entry));
if (ret)
{
memset (ret, 0, sizeof (*ret));
ret->elf.indx = sec->id;
- ret->elf.dynstr_index = ELF64_R_SYM (rel->r_info);
+ ret->elf.dynstr_index = htab->r_sym (rel->r_info);
ret->elf.dynindx = -1;
*slot = ret;
}
@@ -613,18 +628,18 @@ elf64_x86_64_get_local_sym_hash (struct elf64_x86_64_link_hash_table *htab,
/* Create an X86-64 ELF linker hash table. */
static struct bfd_link_hash_table *
-elf64_x86_64_link_hash_table_create (bfd *abfd)
+elf_x86_64_link_hash_table_create (bfd *abfd)
{
- struct elf64_x86_64_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct elf64_x86_64_link_hash_table);
+ struct elf_x86_64_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table);
- ret = (struct elf64_x86_64_link_hash_table *) bfd_malloc (amt);
+ ret = (struct elf_x86_64_link_hash_table *) bfd_malloc (amt);
if (ret == NULL)
return NULL;
if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
- elf64_x86_64_link_hash_newfunc,
- sizeof (struct elf64_x86_64_link_hash_entry),
+ elf_x86_64_link_hash_newfunc,
+ sizeof (struct elf_x86_64_link_hash_entry),
X86_64_ELF_DATA))
{
free (ret);
@@ -640,9 +655,26 @@ elf64_x86_64_link_hash_table_create (bfd *abfd)
ret->sgotplt_jump_table_size = 0;
ret->tls_module_base = NULL;
+ if (ABI_64_P (abfd))
+ {
+ ret->r_info = elf64_r_info;
+ ret->r_sym = elf64_r_sym;
+ ret->swap_reloca_out = bfd_elf64_swap_reloca_out;
+ ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
+ ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
+ }
+ else
+ {
+ ret->r_info = elf32_r_info;
+ ret->r_sym = elf32_r_sym;
+ ret->swap_reloca_out = bfd_elf32_swap_reloca_out;
+ ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
+ ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER;
+ }
+
ret->loc_hash_table = htab_try_create (1024,
- elf64_x86_64_local_htab_hash,
- elf64_x86_64_local_htab_eq,
+ elf_x86_64_local_htab_hash,
+ elf_x86_64_local_htab_eq,
NULL);
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
@@ -657,10 +689,10 @@ elf64_x86_64_link_hash_table_create (bfd *abfd)
/* Destroy an X86-64 ELF linker hash table. */
static void
-elf64_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
+elf_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
{
- struct elf64_x86_64_link_hash_table *htab
- = (struct elf64_x86_64_link_hash_table *) hash;
+ struct elf_x86_64_link_hash_table *htab
+ = (struct elf_x86_64_link_hash_table *) hash;
if (htab->loc_hash_table)
htab_delete (htab->loc_hash_table);
@@ -674,14 +706,15 @@ elf64_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
hash table. */
static bfd_boolean
-elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+elf_x86_64_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -699,14 +732,14 @@ elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf64_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
- struct elf_link_hash_entry *dir,
- struct elf_link_hash_entry *ind)
+elf_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
{
- struct elf64_x86_64_link_hash_entry *edir, *eind;
+ struct elf_x86_64_link_hash_entry *edir, *eind;
- edir = (struct elf64_x86_64_link_hash_entry *) dir;
- eind = (struct elf64_x86_64_link_hash_entry *) ind;
+ edir = (struct elf_x86_64_link_hash_entry *) dir;
+ eind = (struct elf_x86_64_link_hash_entry *) ind;
if (eind->dyn_relocs != NULL)
{
@@ -789,18 +822,21 @@ x86_64_opcode32;
from R_TYPE. */
static bfd_boolean
-elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
- bfd_byte *contents,
- Elf_Internal_Shdr *symtab_hdr,
- struct elf_link_hash_entry **sym_hashes,
- unsigned int r_type,
- const Elf_Internal_Rela *rel,
- const Elf_Internal_Rela *relend)
+elf_x86_64_check_tls_transition (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Shdr *symtab_hdr,
+ struct elf_link_hash_entry **sym_hashes,
+ unsigned int r_type,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend)
{
unsigned int val;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
bfd_vma offset;
+ struct elf_x86_64_link_hash_table *htab;
/* Get the section contents. */
if (contents == NULL)
@@ -818,6 +854,7 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
}
}
+ htab = elf_x86_64_hash_table (info);
offset = rel->r_offset;
switch (r_type)
{
@@ -860,7 +897,7 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
return FALSE;
}
- r_symndx = ELF64_R_SYM (rel[1].r_info);
+ r_symndx = htab->r_sym (rel[1].r_info);
if (r_symndx < symtab_hdr->sh_info)
return FALSE;
@@ -869,8 +906,8 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
may be versioned. */
return (h != NULL
&& h->root.root.string != NULL
- && (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PC32
- || ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32)
+ && (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
+ || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32)
&& (strncmp (h->root.root.string,
"__tls_get_addr", 14) == 0));
@@ -937,15 +974,15 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
will be performed. Update R_TYPE if there is a transition. */
static bfd_boolean
-elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
- asection *sec, bfd_byte *contents,
- Elf_Internal_Shdr *symtab_hdr,
- struct elf_link_hash_entry **sym_hashes,
- unsigned int *r_type, int tls_type,
- const Elf_Internal_Rela *rel,
- const Elf_Internal_Rela *relend,
- struct elf_link_hash_entry *h,
- unsigned long r_symndx)
+elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
+ asection *sec, bfd_byte *contents,
+ Elf_Internal_Shdr *symtab_hdr,
+ struct elf_link_hash_entry **sym_hashes,
+ unsigned int *r_type, int tls_type,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend,
+ struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
{
unsigned int from_type = *r_type;
unsigned int to_type = from_type;
@@ -971,7 +1008,7 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
to_type = R_X86_64_GOTTPOFF;
}
- /* When we are called from elf64_x86_64_relocate_section,
+ /* When we are called from elf_x86_64_relocate_section,
CONTENTS isn't NULL and there may be additional transitions
based on TLS_TYPE. */
if (contents != NULL)
@@ -993,7 +1030,7 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
}
/* We checked the transition before when we were called from
- elf64_x86_64_check_relocs. We only want to check the new
+ elf_x86_64_check_relocs. We only want to check the new
transition which hasn't been checked before. */
check = new_to_type != to_type && from_type == to_type;
to_type = new_to_type;
@@ -1016,23 +1053,23 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
/* Check if the transition can be performed. */
if (check
- && ! elf64_x86_64_check_tls_transition (abfd, sec, contents,
- symtab_hdr, sym_hashes,
- from_type, rel, relend))
+ && ! elf_x86_64_check_tls_transition (abfd, info, sec, contents,
+ symtab_hdr, sym_hashes,
+ from_type, rel, relend))
{
reloc_howto_type *from, *to;
const char *name;
- from = elf64_x86_64_rtype_to_howto (abfd, from_type);
- to = elf64_x86_64_rtype_to_howto (abfd, to_type);
+ from = elf_x86_64_rtype_to_howto (abfd, from_type);
+ to = elf_x86_64_rtype_to_howto (abfd, to_type);
if (h)
name = h->root.root.string;
else
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
name = "*unknown*";
else
@@ -1063,11 +1100,11 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
linkage table, and dynamic reloc sections. */
static bfd_boolean
-elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
- asection *sec,
- const Elf_Internal_Rela *relocs)
+elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel;
@@ -1079,7 +1116,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
BFD_ASSERT (is_x86_64_elf (abfd));
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -1097,8 +1134,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
Elf_Internal_Sym *isym;
const char *name;
- r_symndx = ELF64_R_SYM (rel->r_info);
- r_type = ELF64_R_TYPE (rel->r_info);
+ r_symndx = htab->r_sym (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
@@ -1116,10 +1153,10 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
return FALSE;
/* Check relocation against local STT_GNU_IFUNC symbol. */
- if (ELF64_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
{
- h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
- TRUE);
+ h = elf_x86_64_get_local_sym_hash (htab, abfd, rel,
+ TRUE);
if (h == NULL)
return FALSE;
@@ -1208,7 +1245,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
make room for this reloc. */
sreloc = _bfd_elf_create_ifunc_dyn_reloc
(abfd, info, sec, sreloc,
- &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs);
+ &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs);
if (sreloc == NULL)
return FALSE;
}
@@ -1241,10 +1278,10 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
}
}
- if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
- symtab_hdr, sym_hashes,
- &r_type, GOT_UNKNOWN,
- rel, rel_end, h, r_symndx))
+ if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, rel_end, h, r_symndx))
return FALSE;
switch (r_type)
@@ -1254,7 +1291,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
goto create_got;
case R_X86_64_TPOFF32:
- if (!info->executable)
+ if (!info->executable && ABI_64_P (abfd))
{
if (h)
name = h->root.root.string;
@@ -1308,7 +1345,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
h->plt.refcount += 1;
}
h->got.refcount += 1;
- old_tls_type = elf64_x86_64_hash_entry (h)->tls_type;
+ old_tls_type = elf_x86_64_hash_entry (h)->tls_type;
}
else
{
@@ -1328,14 +1365,14 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- elf64_x86_64_local_tlsdesc_gotent (abfd)
+ elf_x86_64_local_tlsdesc_gotent (abfd)
= (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
- elf64_x86_64_local_got_tls_type (abfd)
+ elf_x86_64_local_got_tls_type (abfd)
= (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
}
local_got_refcounts[r_symndx] += 1;
old_tls_type
- = elf64_x86_64_local_got_tls_type (abfd) [r_symndx];
+ = elf_x86_64_local_got_tls_type (abfd) [r_symndx];
}
/* If a TLS symbol is accessed using IE at least once,
@@ -1366,9 +1403,9 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (old_tls_type != tls_type)
{
if (h != NULL)
- elf64_x86_64_hash_entry (h)->tls_type = tls_type;
+ elf_x86_64_hash_entry (h)->tls_type = tls_type;
else
- elf64_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ elf_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
}
}
/* Fall through */
@@ -1423,6 +1460,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
sections we don't care about, such as debug sections or
non-constant sections. */
if (info->shared
+ && ABI_64_P (abfd)
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0)
{
@@ -1517,7 +1555,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
relocations we need for this symbol. */
if (h != NULL)
{
- head = &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs;
+ head = &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs;
}
else
{
@@ -1592,14 +1630,14 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
relocation. */
static asection *
-elf64_x86_64_gc_mark_hook (asection *sec,
- struct bfd_link_info *info,
- Elf_Internal_Rela *rel,
- struct elf_link_hash_entry *h,
- Elf_Internal_Sym *sym)
+elf_x86_64_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
{
if (h != NULL)
- switch (ELF64_R_TYPE (rel->r_info))
+ switch (ELF32_R_TYPE (rel->r_info))
{
case R_X86_64_GNU_VTINHERIT:
case R_X86_64_GNU_VTENTRY:
@@ -1612,11 +1650,11 @@ elf64_x86_64_gc_mark_hook (asection *sec,
/* Update the got entry reference counts for the section being removed. */
static bfd_boolean
-elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
- asection *sec,
- const Elf_Internal_Rela *relocs)
+elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
@@ -1625,7 +1663,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
if (info->relocatable)
return TRUE;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -1635,6 +1673,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
+ htab = elf_x86_64_hash_table (info);
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
{
@@ -1642,10 +1681,10 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
unsigned int r_type;
struct elf_link_hash_entry *h = NULL;
- r_symndx = ELF64_R_SYM (rel->r_info);
+ r_symndx = htab->r_sym (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
- struct elf64_x86_64_link_hash_entry *eh;
+ struct elf_x86_64_link_hash_entry *eh;
struct elf_dyn_relocs **pp;
struct elf_dyn_relocs *p;
@@ -1653,7 +1692,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
- eh = (struct elf64_x86_64_link_hash_entry *) h;
+ eh = (struct elf_x86_64_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
@@ -1675,18 +1714,17 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
if (isym != NULL
&& ELF64_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
{
- h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
- FALSE);
+ h = elf_x86_64_get_local_sym_hash (htab, abfd, rel, FALSE);
if (h == NULL)
abort ();
}
}
- r_type = ELF64_R_TYPE (rel->r_info);
- if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
- symtab_hdr, sym_hashes,
- &r_type, GOT_UNKNOWN,
- rel, relend, h, r_symndx))
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, relend, h, r_symndx))
return FALSE;
switch (r_type)
@@ -1761,10 +1799,10 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
understand. */
static bfd_boolean
-elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
asection *s;
/* STT_GNU_IFUNC symbol must go through PLT. */
@@ -1846,10 +1884,10 @@ elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
if (ELIMINATE_COPY_RELOCS)
{
- struct elf64_x86_64_link_hash_entry * eh;
+ struct elf_x86_64_link_hash_entry * eh;
struct elf_dyn_relocs *p;
- eh = (struct elf64_x86_64_link_hash_entry *) h;
+ eh = (struct elf_x86_64_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
@@ -1883,7 +1921,7 @@ elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -1892,7 +1930,9 @@ elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
runtime process image. */
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
{
- htab->srelbss->size += sizeof (Elf64_External_Rela);
+ const struct elf_backend_data *bed;
+ bed = get_elf_backend_data (info->output_bfd);
+ htab->srelbss->size += bed->s->sizeof_rela;
h->needs_copy = 1;
}
@@ -1905,24 +1945,26 @@ elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
dynamic relocs. */
static bfd_boolean
-elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{
struct bfd_link_info *info;
- struct elf64_x86_64_link_hash_table *htab;
- struct elf64_x86_64_link_hash_entry *eh;
+ struct elf_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_entry *eh;
struct elf_dyn_relocs *p;
+ const struct elf_backend_data *bed;
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
- eh = (struct elf64_x86_64_link_hash_entry *) h;
+ eh = (struct elf_x86_64_link_hash_entry *) h;
info = (struct bfd_link_info *) inf;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
+ bed = get_elf_backend_data (info->output_bfd);
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
here if it is defined and referenced in a non-shared object. */
@@ -1976,7 +2018,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
/* We also need to make an entry in the .rela.plt section. */
- htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
+ htab->elf.srelplt->size += bed->s->sizeof_rela;
htab->elf.srelplt->reloc_count++;
}
else
@@ -1998,7 +2040,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (h->got.refcount > 0
&& info->executable
&& h->dynindx == -1
- && elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
+ && elf_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
{
h->got.offset = (bfd_vma) -1;
}
@@ -2006,7 +2048,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{
asection *s;
bfd_boolean dyn;
- int tls_type = elf64_x86_64_hash_entry (h)->tls_type;
+ int tls_type = elf_x86_64_hash_entry (h)->tls_type;
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
@@ -2020,7 +2062,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (GOT_TLS_GDESC_P (tls_type))
{
eh->tlsdesc_got = htab->elf.sgotplt->size
- - elf64_x86_64_compute_jump_table_size (htab);
+ - elf_x86_64_compute_jump_table_size (htab);
htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
h->got.offset = (bfd_vma) -2;
}
@@ -2039,18 +2081,18 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
R_X86_64_GOTTPOFF needs one dynamic relocation. */
if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
|| tls_type == GOT_TLS_IE)
- htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
+ htab->elf.srelgot->size += bed->s->sizeof_rela;
else if (GOT_TLS_GD_P (tls_type))
- htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
+ htab->elf.srelgot->size += 2 * bed->s->sizeof_rela;
else if (! GOT_TLS_GDESC_P (tls_type)
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
&& (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
- htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
+ htab->elf.srelgot->size += bed->s->sizeof_rela;
if (GOT_TLS_GDESC_P (tls_type))
{
- htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
+ htab->elf.srelplt->size += bed->s->sizeof_rela;
htab->tlsdesc_plt = (bfd_vma) -1;
}
}
@@ -2146,7 +2188,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
BFD_ASSERT (sreloc != NULL);
- sreloc->size += p->count * sizeof (Elf64_External_Rela);
+ sreloc->size += p->count * bed->s->sizeof_rela;
}
return TRUE;
@@ -2156,7 +2198,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
local dynamic relocs. */
static bfd_boolean
-elf64_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
+elf_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
{
struct elf_link_hash_entry *h
= (struct elf_link_hash_entry *) *slot;
@@ -2168,21 +2210,22 @@ elf64_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
|| h->root.type != bfd_link_hash_defined)
abort ();
- return elf64_x86_64_allocate_dynrelocs (h, inf);
+ return elf_x86_64_allocate_dynrelocs (h, inf);
}
/* Find any dynamic relocs that apply to read-only sections. */
static bfd_boolean
-elf64_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+elf_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h,
+ void * inf)
{
- struct elf64_x86_64_link_hash_entry *eh;
+ struct elf_x86_64_link_hash_entry *eh;
struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
- eh = (struct elf64_x86_64_link_hash_entry *) h;
+ eh = (struct elf_x86_64_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
asection *s = p->sec->output_section;
@@ -2203,18 +2246,20 @@ elf64_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
/* Set the sizes of the dynamic sections. */
static bfd_boolean
-elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info)
+elf_x86_64_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
bfd *dynobj;
asection *s;
bfd_boolean relocs;
bfd *ibfd;
+ const struct elf_backend_data *bed;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
+ bed = get_elf_backend_data (output_bfd);
dynobj = htab->elf.dynobj;
if (dynobj == NULL)
@@ -2228,8 +2273,8 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
s = bfd_get_section_by_name (dynobj, ".interp");
if (s == NULL)
abort ();
- s->size = sizeof ELF_DYNAMIC_INTERPRETER;
- s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ s->size = htab->dynamic_interpreter_size;
+ s->contents = (unsigned char *) htab->dynamic_interpreter;
}
}
@@ -2268,7 +2313,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
else if (p->count != 0)
{
srel = elf_section_data (p->sec)->sreloc;
- srel->size += p->count * sizeof (Elf64_External_Rela);
+ srel->size += p->count * bed->s->sizeof_rela;
if ((p->sec->output_section->flags & SEC_READONLY) != 0)
info->flags |= DF_TEXTREL;
}
@@ -2282,8 +2327,8 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
symtab_hdr = &elf_symtab_hdr (ibfd);
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
- local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
- local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd);
+ local_tls_type = elf_x86_64_local_got_tls_type (ibfd);
+ local_tlsdesc_gotent = elf_x86_64_local_tlsdesc_gotent (ibfd);
s = htab->elf.sgot;
srel = htab->elf.srelgot;
for (; local_got < end_local_got;
@@ -2295,7 +2340,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (GOT_TLS_GDESC_P (*local_tls_type))
{
*local_tlsdesc_gotent = htab->elf.sgotplt->size
- - elf64_x86_64_compute_jump_table_size (htab);
+ - elf_x86_64_compute_jump_table_size (htab);
htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
*local_got = (bfd_vma) -2;
}
@@ -2314,12 +2359,12 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (GOT_TLS_GDESC_P (*local_tls_type))
{
htab->elf.srelplt->size
- += sizeof (Elf64_External_Rela);
+ += bed->s->sizeof_rela;
htab->tlsdesc_plt = (bfd_vma) -1;
}
if (! GOT_TLS_GDESC_P (*local_tls_type)
|| GOT_TLS_GD_P (*local_tls_type))
- srel->size += sizeof (Elf64_External_Rela);
+ srel->size += bed->s->sizeof_rela;
}
}
else
@@ -2333,19 +2378,19 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
relocs. */
htab->tls_ld_got.offset = htab->elf.sgot->size;
htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
- htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
+ htab->elf.srelgot->size += bed->s->sizeof_rela;
}
else
htab->tls_ld_got.offset = -1;
/* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */
- elf_link_hash_traverse (&htab->elf, elf64_x86_64_allocate_dynrelocs,
+ elf_link_hash_traverse (&htab->elf, elf_x86_64_allocate_dynrelocs,
info);
/* Allocate .plt and .got entries, and space for local symbols. */
htab_traverse (htab->loc_hash_table,
- elf64_x86_64_allocate_local_dynrelocs,
+ elf_x86_64_allocate_local_dynrelocs,
info);
/* For every jump slot reserved in the sgotplt, reloc_count is
@@ -2355,7 +2400,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
slot size. */
if (htab->elf.srelplt)
htab->sgotplt_jump_table_size
- = elf64_x86_64_compute_jump_table_size (htab);
+ = elf_x86_64_compute_jump_table_size (htab);
if (htab->tlsdesc_plt)
{
@@ -2466,7 +2511,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (htab->elf.dynamic_sections_created)
{
/* Add some entries to the .dynamic section. We fill in the
- values later, in elf64_x86_64_finish_dynamic_sections, but we
+ values later, in elf_x86_64_finish_dynamic_sections, but we
must add the entries now so that we get the correct size for
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
@@ -2497,14 +2542,14 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{
if (!add_dynamic_entry (DT_RELA, 0)
|| !add_dynamic_entry (DT_RELASZ, 0)
- || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
+ || !add_dynamic_entry (DT_RELAENT, bed->s->sizeof_rela))
return FALSE;
/* If any dynamic relocs apply to a read-only section,
then we need a DT_TEXTREL entry. */
if ((info->flags & DF_TEXTREL) == 0)
elf_link_hash_traverse (&htab->elf,
- elf64_x86_64_readonly_dynrelocs,
+ elf_x86_64_readonly_dynrelocs,
info);
if ((info->flags & DF_TEXTREL) != 0)
@@ -2520,8 +2565,8 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
}
static bfd_boolean
-elf64_x86_64_always_size_sections (bfd *output_bfd,
- struct bfd_link_info *info)
+elf_x86_64_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
{
asection *tls_sec = elf_hash_table (info)->tls_sec;
@@ -2535,12 +2580,12 @@ elf64_x86_64_always_size_sections (bfd *output_bfd,
if (tlsbase && tlsbase->type == STT_TLS)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
struct bfd_link_hash_entry *bh = NULL;
const struct elf_backend_data *bed
= get_elf_backend_data (output_bfd);
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -2568,15 +2613,15 @@ elf64_x86_64_always_size_sections (bfd *output_bfd,
multiple times, it is idempotent. */
static void
-elf64_x86_64_set_tls_module_base (struct bfd_link_info *info)
+elf_x86_64_set_tls_module_base (struct bfd_link_info *info)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
struct bfd_link_hash_entry *base;
if (!info->executable)
return;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return;
@@ -2592,7 +2637,7 @@ elf64_x86_64_set_tls_module_base (struct bfd_link_info *info)
This is PT_TLS segment p_vaddr. */
static bfd_vma
-elf64_x86_64_dtpoff_base (struct bfd_link_info *info)
+elf_x86_64_dtpoff_base (struct bfd_link_info *info)
{
/* If tls_sec is NULL, we should have signalled an error already. */
if (elf_hash_table (info)->tls_sec == NULL)
@@ -2604,7 +2649,7 @@ elf64_x86_64_dtpoff_base (struct bfd_link_info *info)
if STT_TLS virtual address is ADDRESS. */
static bfd_vma
-elf64_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
+elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
{
struct elf_link_hash_table *htab = elf_hash_table (info);
const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
@@ -2637,26 +2682,19 @@ is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
&& (contents [offset - 1] & 0xf0) == 0x80));
}
-static void
-elf64_x86_64_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
-{
- bfd_byte *loc = s->contents;
- loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
- BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
- <= s->contents + s->size);
- bfd_elf64_swap_reloca_out (abfd, rel, loc);
-}
-
/* Relocate an x86_64 ELF section. */
static bfd_boolean
-elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
- bfd *input_bfd, asection *input_section,
- bfd_byte *contents, Elf_Internal_Rela *relocs,
- Elf_Internal_Sym *local_syms,
- asection **local_sections)
+elf_x86_64_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
bfd_vma *local_got_offsets;
@@ -2666,15 +2704,15 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (is_x86_64_elf (input_bfd));
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
symtab_hdr = &elf_symtab_hdr (input_bfd);
sym_hashes = elf_sym_hashes (input_bfd);
local_got_offsets = elf_local_got_offsets (input_bfd);
- local_tlsdesc_gotents = elf64_x86_64_local_tlsdesc_gotent (input_bfd);
+ local_tlsdesc_gotents = elf_x86_64_local_tlsdesc_gotent (input_bfd);
- elf64_x86_64_set_tls_module_base (info);
+ elf_x86_64_set_tls_module_base (info);
rel = relocs;
relend = relocs + input_section->reloc_count;
@@ -2693,7 +2731,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
int tls_type;
asection *base_got;
- r_type = ELF64_R_TYPE (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_X86_64_GNU_VTINHERIT
|| r_type == (int) R_X86_64_GNU_VTENTRY)
continue;
@@ -2705,7 +2743,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
howto = x86_64_elf_howto_table + r_type;
- r_symndx = ELF64_R_SYM (rel->r_info);
+ r_symndx = htab->r_sym (rel->r_info);
h = NULL;
sym = NULL;
sec = NULL;
@@ -2720,10 +2758,10 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* Relocate against local STT_GNU_IFUNC symbol. */
if (!info->relocatable
- && ELF64_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
{
- h = elf64_x86_64_get_local_sym_hash (htab, input_bfd,
- rel, FALSE);
+ h = elf_x86_64_get_local_sym_hash (htab, input_bfd,
+ rel, FALSE);
if (h == NULL)
abort ();
@@ -2831,19 +2869,19 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|| info->executable)
{
/* This symbol is resolved locally. */
- outrel.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
+ outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
outrel.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else
{
- outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
+ outrel.r_info = htab->r_info (h->dynindx, r_type);
outrel.r_addend = 0;
}
sreloc = htab->elf.irelifunc;
- elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
+ elf_append_rela (output_bfd, sreloc, &outrel);
/* If this reloc is against an external symbol, we
do not want to fiddle with the addend. Otherwise,
@@ -3036,9 +3074,9 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_offset = (base_got->output_section->vma
+ base_got->output_offset
+ off);
- outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
+ outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
outrel.r_addend = relocation;
- elf64_x86_64_append_rela (output_bfd, s, &outrel);
+ elf_append_rela (output_bfd, s, &outrel);
}
local_got_offsets[r_symndx] |= 1;
@@ -3139,6 +3177,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_X86_64_PC16:
case R_X86_64_PC32:
if (info->shared
+ && ABI_64_P (output_bfd)
&& (input_section->flags & SEC_ALLOC) != 0
&& (input_section->flags & SEC_READONLY) != 0
&& h != NULL)
@@ -3259,7 +3298,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|| ! SYMBOLIC_BIND (info, h)
|| ! h->def_regular))
{
- outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
+ outrel.r_info = htab->r_info (h->dynindx, r_type);
outrel.r_addend = rel->r_addend;
}
else
@@ -3268,7 +3307,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (r_type == R_X86_64_64)
{
relocate = TRUE;
- outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
+ outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
outrel.r_addend = relocation + rel->r_addend;
}
else
@@ -3301,7 +3340,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (sindx != 0);
}
- outrel.r_info = ELF64_R_INFO (sindx, r_type);
+ outrel.r_info = htab->r_info (sindx, r_type);
outrel.r_addend = relocation + rel->r_addend;
}
}
@@ -3310,7 +3349,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
- elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
+ elf_append_rela (output_bfd, sreloc, &outrel);
/* If this reloc is against an external symbol, we do
not want to fiddle with the addend. Otherwise, we
@@ -3328,15 +3367,15 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_X86_64_GOTTPOFF:
tls_type = GOT_UNKNOWN;
if (h == NULL && local_got_offsets)
- tls_type = elf64_x86_64_local_got_tls_type (input_bfd) [r_symndx];
+ tls_type = elf_x86_64_local_got_tls_type (input_bfd) [r_symndx];
else if (h != NULL)
- tls_type = elf64_x86_64_hash_entry (h)->tls_type;
+ tls_type = elf_x86_64_hash_entry (h)->tls_type;
- if (! elf64_x86_64_tls_transition (info, input_bfd,
- input_section, contents,
- symtab_hdr, sym_hashes,
- &r_type, tls_type, rel,
- relend, h, r_symndx))
+ if (! elf_x86_64_tls_transition (info, input_bfd,
+ input_section, contents,
+ symtab_hdr, sym_hashes,
+ &r_type, tls_type, rel,
+ relend, h, r_symndx))
return FALSE;
if (r_type == R_X86_64_TPOFF32)
@@ -3345,7 +3384,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (! unresolved_reloc);
- if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
+ if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
{
/* GD->LE transition.
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
@@ -3357,13 +3396,13 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
16);
bfd_put_32 (output_bfd,
- elf64_x86_64_tpoff (info, relocation),
+ elf_x86_64_tpoff (info, relocation),
contents + roff + 8);
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
rel++;
continue;
}
- else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
{
/* GDesc -> LE transition.
It's originally something like:
@@ -3382,11 +3421,11 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
contents + roff - 1);
bfd_put_32 (output_bfd,
- elf64_x86_64_tpoff (info, relocation),
+ elf_x86_64_tpoff (info, relocation),
contents + roff);
continue;
}
- else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
{
/* GDesc -> LE transition.
It's originally:
@@ -3397,7 +3436,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
continue;
}
- else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
{
/* IE->LE transition:
Originally it can be one of:
@@ -3449,7 +3488,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
contents + roff - 1);
}
bfd_put_32 (output_bfd,
- elf64_x86_64_tpoff (info, relocation),
+ elf_x86_64_tpoff (info, relocation),
contents + roff);
continue;
}
@@ -3463,7 +3502,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (h != NULL)
{
off = h->got.offset;
- offplt = elf64_x86_64_hash_entry (h)->tlsdesc_got;
+ offplt = elf_x86_64_hash_entry (h)->tlsdesc_got;
}
else
{
@@ -3489,7 +3528,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (GOT_TLS_GDESC_P (tls_type))
{
- outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC);
+ outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC);
BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
+ 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
outrel.r_offset = (htab->elf.sgotplt->output_section->vma
@@ -3498,10 +3537,10 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+ htab->sgotplt_jump_table_size);
sreloc = htab->elf.srelplt;
if (indx == 0)
- outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
+ outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
else
outrel.r_addend = 0;
- elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
+ elf_append_rela (output_bfd, sreloc, &outrel);
}
sreloc = htab->elf.srelgot;
@@ -3520,10 +3559,10 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_addend = 0;
if ((dr_type == R_X86_64_TPOFF64
|| dr_type == R_X86_64_TLSDESC) && indx == 0)
- outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
- outrel.r_info = ELF64_R_INFO (indx, dr_type);
+ outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
+ outrel.r_info = htab->r_info (indx, dr_type);
- elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
+ elf_append_rela (output_bfd, sreloc, &outrel);
if (GOT_TLS_GD_P (tls_type))
{
@@ -3531,17 +3570,17 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
BFD_ASSERT (! unresolved_reloc);
bfd_put_64 (output_bfd,
- relocation - elf64_x86_64_dtpoff_base (info),
+ relocation - elf_x86_64_dtpoff_base (info),
htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
}
else
{
bfd_put_64 (output_bfd, 0,
htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
- outrel.r_info = ELF64_R_INFO (indx,
+ outrel.r_info = htab->r_info (indx,
R_X86_64_DTPOFF64);
outrel.r_offset += GOT_ENTRY_SIZE;
- elf64_x86_64_append_rela (output_bfd, sreloc,
+ elf_append_rela (output_bfd, sreloc,
&outrel);
}
}
@@ -3556,7 +3595,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (off >= (bfd_vma) -2
&& ! GOT_TLS_GDESC_P (tls_type))
abort ();
- if (r_type == ELF64_R_TYPE (rel->r_info))
+ if (r_type == ELF32_R_TYPE (rel->r_info))
{
if (r_type == R_X86_64_GOTPC32_TLSDESC
|| r_type == R_X86_64_TLSDESC_CALL)
@@ -3572,7 +3611,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
bfd_vma roff = rel->r_offset;
- if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
+ if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
{
/* GD->IE transition.
.byte 0x66; leaq foo@tlsgd(%rip), %rdi
@@ -3596,7 +3635,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
rel++;
continue;
}
- else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
{
/* GDesc -> IE transition.
It's originally something like:
@@ -3621,7 +3660,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
contents + roff);
continue;
}
- else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
{
/* GDesc -> IE transition.
It's originally:
@@ -3640,11 +3679,11 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break;
case R_X86_64_TLSLD:
- if (! elf64_x86_64_tls_transition (info, input_bfd,
- input_section, contents,
- symtab_hdr, sym_hashes,
- &r_type, GOT_UNKNOWN,
- rel, relend, h, r_symndx))
+ if (! elf_x86_64_tls_transition (info, input_bfd,
+ input_section, contents,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, relend, h, r_symndx))
return FALSE;
if (r_type != R_X86_64_TLSLD)
@@ -3682,9 +3721,9 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
htab->elf.sgot->contents + off);
bfd_put_64 (output_bfd, 0,
htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
- outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
+ outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64);
outrel.r_addend = 0;
- elf64_x86_64_append_rela (output_bfd, htab->elf.srelgot,
+ elf_append_rela (output_bfd, htab->elf.srelgot,
&outrel);
htab->tls_ld_got.offset |= 1;
}
@@ -3695,14 +3734,14 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_X86_64_DTPOFF32:
if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
- relocation -= elf64_x86_64_dtpoff_base (info);
+ relocation -= elf_x86_64_dtpoff_base (info);
else
- relocation = elf64_x86_64_tpoff (info, relocation);
+ relocation = elf_x86_64_tpoff (info, relocation);
break;
case R_X86_64_TPOFF32:
BFD_ASSERT (info->executable);
- relocation = elf64_x86_64_tpoff (info, relocation);
+ relocation = elf_x86_64_tpoff (info, relocation);
break;
default:
@@ -3771,14 +3810,14 @@ do_relocation:
dynamic sections here. */
static bfd_boolean
-elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
- struct bfd_link_info *info,
- struct elf_link_hash_entry *h,
- Elf_Internal_Sym *sym)
+elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -3789,6 +3828,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
Elf_Internal_Rela rela;
bfd_byte *loc;
asection *plt, *gotplt, *relplt;
+ const struct elf_backend_data *bed;
/* When building a static executable, use .iplt, .igot.plt and
.rela.iplt sections for STT_GNU_IFUNC symbols. */
@@ -3839,7 +3879,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
}
/* Fill in the entry in the procedure linkage table. */
- memcpy (plt->contents + h->plt.offset, elf64_x86_64_plt_entry,
+ memcpy (plt->contents + h->plt.offset, elf_x86_64_plt_entry,
PLT_ENTRY_SIZE);
/* Insert the relocation positions of the plt section. The magic
@@ -3887,18 +3927,20 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
{
/* If an STT_GNU_IFUNC symbol is locally defined, generate
R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */
- rela.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
+ rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
rela.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else
{
- rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
+ rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
rela.r_addend = 0;
}
- loc = relplt->contents + plt_index * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+
+ bed = get_elf_backend_data (output_bfd);
+ loc = relplt->contents + plt_index * bed->s->sizeof_rela;
+ htab->swap_reloca_out (output_bfd, &rela, loc);
if (!h->def_regular)
{
@@ -3917,8 +3959,8 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
}
if (h->got.offset != (bfd_vma) -1
- && ! GOT_TLS_GD_ANY_P (elf64_x86_64_hash_entry (h)->tls_type)
- && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
+ && ! GOT_TLS_GD_ANY_P (elf_x86_64_hash_entry (h)->tls_type)
+ && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
{
Elf_Internal_Rela rela;
@@ -3968,7 +4010,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
if (!h->def_regular)
return FALSE;
BFD_ASSERT((h->got.offset & 1) != 0);
- rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
+ rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
rela.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
@@ -3979,11 +4021,11 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
do_glob_dat:
bfd_put_64 (output_bfd, (bfd_vma) 0,
htab->elf.sgot->contents + h->got.offset);
- rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);
+ rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT);
rela.r_addend = 0;
}
- elf64_x86_64_append_rela (output_bfd, htab->elf.srelgot, &rela);
+ elf_append_rela (output_bfd, htab->elf.srelgot, &rela);
}
if (h->needs_copy)
@@ -4001,9 +4043,9 @@ do_glob_dat:
rela.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
- rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
+ rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
rela.r_addend = 0;
- elf64_x86_64_append_rela (output_bfd, htab->srelbss, &rela);
+ elf_append_rela (output_bfd, htab->srelbss, &rela);
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
@@ -4020,14 +4062,14 @@ do_glob_dat:
various dynamic sections here. */
static bfd_boolean
-elf64_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
+elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
{
struct elf_link_hash_entry *h
= (struct elf_link_hash_entry *) *slot;
struct bfd_link_info *info
= (struct bfd_link_info *) inf;
- return elf64_x86_64_finish_dynamic_symbol (info->output_bfd,
+ return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
info, h, NULL);
}
@@ -4035,9 +4077,9 @@ elf64_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf64_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
{
- switch ((int) ELF64_R_TYPE (rela->r_info))
+ switch ((int) ELF32_R_TYPE (rela->r_info))
{
case R_X86_64_RELATIVE:
return reloc_class_relative;
@@ -4053,13 +4095,14 @@ elf64_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
/* Finish up the dynamic sections. */
static bfd_boolean
-elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
{
- struct elf64_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_table *htab;
bfd *dynobj;
asection *sdyn;
- htab = elf64_x86_64_hash_table (info);
+ htab = elf_x86_64_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -4136,7 +4179,7 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
if (htab->elf.splt && htab->elf.splt->size > 0)
{
/* Fill in the first entry in the procedure linkage table. */
- memcpy (htab->elf.splt->contents, elf64_x86_64_plt0_entry,
+ memcpy (htab->elf.splt->contents, elf_x86_64_plt0_entry,
PLT_ENTRY_SIZE);
/* Add offset for pushq GOT+8(%rip), since the instruction
uses 6 bytes subtract this value. */
@@ -4168,7 +4211,7 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
htab->elf.sgot->contents + htab->tlsdesc_got);
memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
- elf64_x86_64_plt0_entry,
+ elf_x86_64_plt0_entry,
PLT_ENTRY_SIZE);
/* Add offset for pushq GOT+8(%rip), since the
@@ -4233,7 +4276,7 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
/* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
htab_traverse (htab->loc_hash_table,
- elf64_x86_64_finish_local_dynamic_symbol,
+ elf_x86_64_finish_local_dynamic_symbol,
info);
return TRUE;
@@ -4243,8 +4286,8 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
or (bfd_vma) -1 if it should not be included. */
static bfd_vma
-elf64_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
- const arelent *rel ATTRIBUTE_UNUSED)
+elf_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
{
return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
}
@@ -4253,7 +4296,7 @@ elf64_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
is called when elfcode.h finds a section with an unknown type. */
static bfd_boolean
-elf64_x86_64_section_from_shdr (bfd *abfd,
+elf_x86_64_section_from_shdr (bfd *abfd,
Elf_Internal_Shdr *hdr,
const char *name,
int shindex)
@@ -4272,13 +4315,13 @@ elf64_x86_64_section_from_shdr (bfd *abfd,
of .bss. */
static bfd_boolean
-elf64_x86_64_add_symbol_hook (bfd *abfd,
- struct bfd_link_info *info,
- Elf_Internal_Sym *sym,
- const char **namep ATTRIBUTE_UNUSED,
- flagword *flagsp ATTRIBUTE_UNUSED,
- asection **secp,
- bfd_vma *valp)
+elf_x86_64_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
{
asection *lcomm;
@@ -4314,8 +4357,8 @@ elf64_x86_64_add_symbol_hook (bfd *abfd,
index. */
static bfd_boolean
-elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
- asection *sec, int *index_return)
+elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, int *index_return)
{
if (sec == &_bfd_elf_large_com_section)
{
@@ -4328,8 +4371,8 @@ elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
/* Process a symbol. */
static void
-elf64_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
- asymbol *asym)
+elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *asym)
{
elf_symbol_type *elfsym = (elf_symbol_type *) asym;
@@ -4345,14 +4388,14 @@ elf64_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
}
static bfd_boolean
-elf64_x86_64_common_definition (Elf_Internal_Sym *sym)
+elf_x86_64_common_definition (Elf_Internal_Sym *sym)
{
return (sym->st_shndx == SHN_COMMON
|| sym->st_shndx == SHN_X86_64_LCOMMON);
}
static unsigned int
-elf64_x86_64_common_section_index (asection *sec)
+elf_x86_64_common_section_index (asection *sec)
{
if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
return SHN_COMMON;
@@ -4361,7 +4404,7 @@ elf64_x86_64_common_section_index (asection *sec)
}
static asection *
-elf64_x86_64_common_section (asection *sec)
+elf_x86_64_common_section (asection *sec)
{
if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
return bfd_com_section_ptr;
@@ -4370,29 +4413,29 @@ elf64_x86_64_common_section (asection *sec)
}
static bfd_boolean
-elf64_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
- struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED,
- struct elf_link_hash_entry *h,
- Elf_Internal_Sym *sym,
- asection **psec,
- bfd_vma *pvalue ATTRIBUTE_UNUSED,
- unsigned int *pold_alignment ATTRIBUTE_UNUSED,
- bfd_boolean *skip ATTRIBUTE_UNUSED,
- bfd_boolean *override ATTRIBUTE_UNUSED,
- bfd_boolean *type_change_ok ATTRIBUTE_UNUSED,
- bfd_boolean *size_change_ok ATTRIBUTE_UNUSED,
- bfd_boolean *newdef ATTRIBUTE_UNUSED,
- bfd_boolean *newdyn,
- bfd_boolean *newdyncommon ATTRIBUTE_UNUSED,
- bfd_boolean *newweak ATTRIBUTE_UNUSED,
- bfd *abfd ATTRIBUTE_UNUSED,
- asection **sec,
- bfd_boolean *olddef ATTRIBUTE_UNUSED,
- bfd_boolean *olddyn,
- bfd_boolean *olddyncommon ATTRIBUTE_UNUSED,
- bfd_boolean *oldweak ATTRIBUTE_UNUSED,
- bfd *oldbfd,
- asection **oldsec)
+elf_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym,
+ asection **psec,
+ bfd_vma *pvalue ATTRIBUTE_UNUSED,
+ unsigned int *pold_alignment ATTRIBUTE_UNUSED,
+ bfd_boolean *skip ATTRIBUTE_UNUSED,
+ bfd_boolean *override ATTRIBUTE_UNUSED,
+ bfd_boolean *type_change_ok ATTRIBUTE_UNUSED,
+ bfd_boolean *size_change_ok ATTRIBUTE_UNUSED,
+ bfd_boolean *newdef ATTRIBUTE_UNUSED,
+ bfd_boolean *newdyn,
+ bfd_boolean *newdyncommon ATTRIBUTE_UNUSED,
+ bfd_boolean *newweak ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection **sec,
+ bfd_boolean *olddef ATTRIBUTE_UNUSED,
+ bfd_boolean *olddyn,
+ bfd_boolean *olddyncommon ATTRIBUTE_UNUSED,
+ bfd_boolean *oldweak ATTRIBUTE_UNUSED,
+ bfd *oldbfd,
+ asection **oldsec)
{
/* A normal common symbol and a large common symbol result in a
normal common symbol. We turn the large common symbol into a
@@ -4419,8 +4462,8 @@ elf64_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
}
static int
-elf64_x86_64_additional_program_headers (bfd *abfd,
- struct bfd_link_info *info ATTRIBUTE_UNUSED)
+elf_x86_64_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
asection *s;
int count = 0;
@@ -4443,7 +4486,7 @@ elf64_x86_64_additional_program_headers (bfd *abfd,
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
static bfd_boolean
-elf64_x86_64_hash_symbol (struct elf_link_hash_entry *h)
+elf_x86_64_hash_symbol (struct elf_link_hash_entry *h)
{
if (h->plt.offset != (bfd_vma) -1
&& !h->def_regular
@@ -4454,7 +4497,7 @@ elf64_x86_64_hash_symbol (struct elf_link_hash_entry *h)
}
static const struct bfd_elf_special_section
- elf64_x86_64_special_sections[]=
+ elf_x86_64_special_sections[]=
{
{ STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
{ STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
@@ -4482,59 +4525,59 @@ static const struct bfd_elf_special_section
#define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
#define elf_backend_rela_normal 1
-#define elf_info_to_howto elf64_x86_64_info_to_howto
+#define elf_info_to_howto elf_x86_64_info_to_howto
#define bfd_elf64_bfd_link_hash_table_create \
- elf64_x86_64_link_hash_table_create
+ elf_x86_64_link_hash_table_create
#define bfd_elf64_bfd_link_hash_table_free \
- elf64_x86_64_link_hash_table_free
-#define bfd_elf64_bfd_reloc_type_lookup elf64_x86_64_reloc_type_lookup
+ elf_x86_64_link_hash_table_free
+#define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup
#define bfd_elf64_bfd_reloc_name_lookup \
- elf64_x86_64_reloc_name_lookup
+ elf_x86_64_reloc_name_lookup
-#define elf_backend_adjust_dynamic_symbol elf64_x86_64_adjust_dynamic_symbol
+#define elf_backend_adjust_dynamic_symbol elf_x86_64_adjust_dynamic_symbol
#define elf_backend_relocs_compatible _bfd_elf_relocs_compatible
-#define elf_backend_check_relocs elf64_x86_64_check_relocs
-#define elf_backend_copy_indirect_symbol elf64_x86_64_copy_indirect_symbol
-#define elf_backend_create_dynamic_sections elf64_x86_64_create_dynamic_sections
-#define elf_backend_finish_dynamic_sections elf64_x86_64_finish_dynamic_sections
-#define elf_backend_finish_dynamic_symbol elf64_x86_64_finish_dynamic_symbol
-#define elf_backend_gc_mark_hook elf64_x86_64_gc_mark_hook
-#define elf_backend_gc_sweep_hook elf64_x86_64_gc_sweep_hook
-#define elf_backend_grok_prstatus elf64_x86_64_grok_prstatus
-#define elf_backend_grok_psinfo elf64_x86_64_grok_psinfo
-#define elf_backend_reloc_type_class elf64_x86_64_reloc_type_class
-#define elf_backend_relocate_section elf64_x86_64_relocate_section
-#define elf_backend_size_dynamic_sections elf64_x86_64_size_dynamic_sections
-#define elf_backend_always_size_sections elf64_x86_64_always_size_sections
+#define elf_backend_check_relocs elf_x86_64_check_relocs
+#define elf_backend_copy_indirect_symbol elf_x86_64_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
+#define elf_backend_gc_mark_hook elf_x86_64_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_x86_64_gc_sweep_hook
+#define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
+#define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
+#define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
+#define elf_backend_relocate_section elf_x86_64_relocate_section
+#define elf_backend_size_dynamic_sections elf_x86_64_size_dynamic_sections
+#define elf_backend_always_size_sections elf_x86_64_always_size_sections
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
-#define elf_backend_plt_sym_val elf64_x86_64_plt_sym_val
+#define elf_backend_plt_sym_val elf_x86_64_plt_sym_val
#define elf_backend_object_p elf64_x86_64_elf_object_p
-#define bfd_elf64_mkobject elf64_x86_64_mkobject
+#define bfd_elf64_mkobject elf_x86_64_mkobject
#define elf_backend_section_from_shdr \
- elf64_x86_64_section_from_shdr
+ elf_x86_64_section_from_shdr
#define elf_backend_section_from_bfd_section \
- elf64_x86_64_elf_section_from_bfd_section
+ elf_x86_64_elf_section_from_bfd_section
#define elf_backend_add_symbol_hook \
- elf64_x86_64_add_symbol_hook
+ elf_x86_64_add_symbol_hook
#define elf_backend_symbol_processing \
- elf64_x86_64_symbol_processing
+ elf_x86_64_symbol_processing
#define elf_backend_common_section_index \
- elf64_x86_64_common_section_index
+ elf_x86_64_common_section_index
#define elf_backend_common_section \
- elf64_x86_64_common_section
+ elf_x86_64_common_section
#define elf_backend_common_definition \
- elf64_x86_64_common_definition
+ elf_x86_64_common_definition
#define elf_backend_merge_symbol \
- elf64_x86_64_merge_symbol
+ elf_x86_64_merge_symbol
#define elf_backend_special_sections \
- elf64_x86_64_special_sections
+ elf_x86_64_special_sections
#define elf_backend_additional_program_headers \
- elf64_x86_64_additional_program_headers
+ elf_x86_64_additional_program_headers
#define elf_backend_hash_symbol \
- elf64_x86_64_hash_symbol
+ elf_x86_64_hash_symbol
#undef elf_backend_post_process_headers
#define elf_backend_post_process_headers _bfd_elf_set_osabi
@@ -4634,3 +4677,53 @@ elf64_l1om_elf_object_p (bfd *abfd)
#define elf_backend_post_process_headers _bfd_elf_set_osabi
#include "elf64-target.h"
+
+/* 32bit x86-64 support. */
+
+static bfd_boolean
+elf32_x86_64_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an x86-64 elf32 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32);
+ return TRUE;
+}
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf32_x86_64_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-x86-64"
+
+#undef ELF_ARCH
+#define ELF_ARCH bfd_arch_i386
+
+#undef ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE EM_X86_64
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_x86_64_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_free \
+ elf_x86_64_link_hash_table_free
+#define bfd_elf32_bfd_reloc_type_lookup \
+ elf_x86_64_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ elf_x86_64_reloc_name_lookup
+#define bfd_elf32_mkobject \
+ elf_x86_64_mkobject
+
+#undef ELF_OSABI
+
+#undef elf_backend_post_process_headers
+
+#undef elf_backend_object_p
+#define elf_backend_object_p \
+ elf32_x86_64_elf_object_p
+
+#undef elf_backend_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory \
+ _bfd_elf32_bfd_from_remote_memory
+
+#undef elf_backend_size_info
+#define elf_backend_size_info \
+ _bfd_elf32_size_info
+
+#include "elf32-target.h"