diff options
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 837 |
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" |