From 765e526c75506a7d9644bc7c137ac1923fdb1369 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 30 Aug 2017 09:10:08 -0700 Subject: [PATCH] x86: Add _bfd_x86_elf_link_hash_table_create Share _bfd_x86_elf_link_hash_table_create in elf32-i386.c and elf64-x86-64.c by: 1. Replace elf_i386_lazy_plt_layout, elf_i386_non_lazy_plt_layout, elf_i386_plt_layout, elf_x86_64_lazy_plt_layout, elf_x86_64_non_lazy_plt_layout and elf_x86_64_plt_layout with elf_x86_lazy_plt_layout, elf_x86_non_lazy_plt_layout and elf_x86_plt_layout. 2. Move plt, lazy_plt, non_lazy_plt, srelplt2 and next_tls_desc_index from elf_i386_link_hash_table to elf_x86_link_hash_table. 3. Remove elf_i386_link_hash_table and elf_x86_64_link_hash_table. * elf32-i386.c (ELF_DYNAMIC_INTERPRETER): Removed. (elf_i386_lazy_plt_layout): Likewise. (elf_i386_non_lazy_plt_layout): Likewise. (elf_i386_plt_layout): Likewise. (elf_i386_link_hash_table): Likewise. (elf_i386_next_tls_desc_index): Likewise. (elf_i386_srelplt2): Likewise. (elf_i386_plt): Likewise. (elf_i386_lazy_plt): Likewise. (elf_i386_non_lazy_plt): Likewise. (elf_i386_link_hash_table_create): Likewise. (bfd_elf32_bfd_link_hash_table_create): Likewise. (elf_i386_lazy_plt): Updated. (elf_i386_non_lazy_plt): Likewise. (elf_i386_lazy_ibt_plt): Likewise. (elf_i386_non_lazy_ibt_plt): Likewise. (elf_i386_allocate_dynrelocs): Likewise. (elf_i386_size_dynamic_sections): Likewise. (elf_i386_relocate_section): Likewise. (elf_i386_finish_dynamic_symbol): Likewise. (elf_i386_finish_dynamic_sections): Likewise. (elf_i386_get_synthetic_symtab): Likewise. (elf_i386_link_setup_gnu_properties): Likewise. (elf_i386_nacl_plt): Likewise. * elf64-x86-64.c (ABI_64_P): Removed. (ELF64_DYNAMIC_INTERPRETER): Likewise. (ELF32_DYNAMIC_INTERPRETER): Likewise. (elf_x86_64_lazy_plt_layout): Likewise. (elf_x86_64_non_lazy_plt_layout): Likewise. (elf_x86_64_plt_layout): Likewise. (elf_x86_64_link_hash_table): Likewise. (elf_x86_64_plt): Likewise. (elf_x86_64_lazy_plt): Likewise. (elf_x86_64_non_lazy_plt): Likewise. (elf_x86_64_link_hash_table_create): Likewise. (bfd_elf64_bfd_link_hash_table_create): Likewise. (bfd_elf32_bfd_link_hash_table_create): Likewise. (elf_x86_64_lazy_plt): Updated. (elf_x86_64_non_lazy_plt): Likewise. (elf_x86_64_lazy_bnd_plt): Likewise. (elf_x86_64_non_lazy_bnd_plt): Likewise. (elf_x86_64_lazy_ibt_plt): Likewise. (elf_x32_lazy_ibt_plt): Likewise. (elf_x86_64_non_lazy_ibt_plt): Likewise. (elf_x32_non_lazy_ibt_plt): Likewise. (elf_x86_64_allocate_dynrelocs): Likewise. (elf_x86_64_size_dynamic_sections): Likewise. (elf_x86_64_relocate_section): Likewise. (elf_x86_64_finish_dynamic_symbol): Likewise. (elf_x86_64_finish_dynamic_sections): Likewise. (elf_x86_64_get_synthetic_symtab): Likewise. (elf_x86_64_link_setup_gnu_properties): Likewise. (elf_x86_64_nacl_plt): Likewise. * elfxx-x86.c: Include "objalloc.h", "elf/i386.h" and "elf/x86-64.h". (ELF32_DYNAMIC_INTERPRETER): New. (ELF64_DYNAMIC_INTERPRETER): Likewise. (ELFX32_DYNAMIC_INTERPRETER): Likewise. (_bfd_x86_elf_link_hash_table_create): Likewise. (_bfd_x86_elf_link_hash_table_free): Renamed to ... (elf_x86_link_hash_table_free): This. Make it static. * elfxx-x86.h: Don't include "objalloc.h". (ABI_64_P): New. (elf_x86_lazy_plt_layout): Likewise. (elf_x86_non_lazy_plt_layout): Likewise. (elf_x86_plt_layout): Likewise. (_bfd_x86_elf_link_hash_table_create): Likewise. (bfd_elf64_bfd_link_hash_table_create): Likewise. (bfd_elf32_bfd_link_hash_table_create): Likewise. (elf_x86_link_hash_table): Add plt, lazy_plt, non_lazy_plt, srelplt2 and next_tls_desc_index. (_bfd_x86_elf_link_hash_table_free): Removed. --- bfd/ChangeLog | 75 ++++++++++ bfd/elf32-i386.c | 415 +++++++++++++++------------------------------------- bfd/elf64-x86-64.c | 418 +++++++++++++++-------------------------------------- bfd/elfxx-x86.c | 85 ++++++++++- bfd/elfxx-x86.h | 126 +++++++++++++++- 5 files changed, 515 insertions(+), 604 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f52e75d..095373e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,78 @@ +2017-08-30 H.J. Lu + + * elf32-i386.c (ELF_DYNAMIC_INTERPRETER): Removed. + (elf_i386_lazy_plt_layout): Likewise. + (elf_i386_non_lazy_plt_layout): Likewise. + (elf_i386_plt_layout): Likewise. + (elf_i386_link_hash_table): Likewise. + (elf_i386_next_tls_desc_index): Likewise. + (elf_i386_srelplt2): Likewise. + (elf_i386_plt): Likewise. + (elf_i386_lazy_plt): Likewise. + (elf_i386_non_lazy_plt): Likewise. + (elf_i386_link_hash_table_create): Likewise. + (bfd_elf32_bfd_link_hash_table_create): Likewise. + (elf_i386_lazy_plt): Updated. + (elf_i386_non_lazy_plt): Likewise. + (elf_i386_lazy_ibt_plt): Likewise. + (elf_i386_non_lazy_ibt_plt): Likewise. + (elf_i386_allocate_dynrelocs): Likewise. + (elf_i386_size_dynamic_sections): Likewise. + (elf_i386_relocate_section): Likewise. + (elf_i386_finish_dynamic_symbol): Likewise. + (elf_i386_finish_dynamic_sections): Likewise. + (elf_i386_get_synthetic_symtab): Likewise. + (elf_i386_link_setup_gnu_properties): Likewise. + (elf_i386_nacl_plt): Likewise. + * elf64-x86-64.c (ABI_64_P): Removed. + (ELF64_DYNAMIC_INTERPRETER): Likewise. + (ELF32_DYNAMIC_INTERPRETER): Likewise. + (elf_x86_64_lazy_plt_layout): Likewise. + (elf_x86_64_non_lazy_plt_layout): Likewise. + (elf_x86_64_plt_layout): Likewise. + (elf_x86_64_link_hash_table): Likewise. + (elf_x86_64_plt): Likewise. + (elf_x86_64_lazy_plt): Likewise. + (elf_x86_64_non_lazy_plt): Likewise. + (elf_x86_64_link_hash_table_create): Likewise. + (bfd_elf64_bfd_link_hash_table_create): Likewise. + (bfd_elf32_bfd_link_hash_table_create): Likewise. + (elf_x86_64_lazy_plt): Updated. + (elf_x86_64_non_lazy_plt): Likewise. + (elf_x86_64_lazy_bnd_plt): Likewise. + (elf_x86_64_non_lazy_bnd_plt): Likewise. + (elf_x86_64_lazy_ibt_plt): Likewise. + (elf_x32_lazy_ibt_plt): Likewise. + (elf_x86_64_non_lazy_ibt_plt): Likewise. + (elf_x32_non_lazy_ibt_plt): Likewise. + (elf_x86_64_allocate_dynrelocs): Likewise. + (elf_x86_64_size_dynamic_sections): Likewise. + (elf_x86_64_relocate_section): Likewise. + (elf_x86_64_finish_dynamic_symbol): Likewise. + (elf_x86_64_finish_dynamic_sections): Likewise. + (elf_x86_64_get_synthetic_symtab): Likewise. + (elf_x86_64_link_setup_gnu_properties): Likewise. + (elf_x86_64_nacl_plt): Likewise. + * elfxx-x86.c: Include "objalloc.h", "elf/i386.h" and + "elf/x86-64.h". + (ELF32_DYNAMIC_INTERPRETER): New. + (ELF64_DYNAMIC_INTERPRETER): Likewise. + (ELFX32_DYNAMIC_INTERPRETER): Likewise. + (_bfd_x86_elf_link_hash_table_create): Likewise. + (_bfd_x86_elf_link_hash_table_free): Renamed to ... + (elf_x86_link_hash_table_free): This. Make it static. + * elfxx-x86.h: Don't include "objalloc.h". + (ABI_64_P): New. + (elf_x86_lazy_plt_layout): Likewise. + (elf_x86_non_lazy_plt_layout): Likewise. + (elf_x86_plt_layout): Likewise. + (_bfd_x86_elf_link_hash_table_create): Likewise. + (bfd_elf64_bfd_link_hash_table_create): Likewise. + (bfd_elf32_bfd_link_hash_table_create): Likewise. + (elf_x86_link_hash_table): Add plt, lazy_plt, non_lazy_plt, + srelplt2 and next_tls_desc_index. + (_bfd_x86_elf_link_hash_table_free): Removed. + 2017-08-30 Maciej W. Rozycki * elfxx-mips.c (mips_elf_perform_relocation): Correct microMIPS diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 4fcfff1..8e41c6e 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -522,12 +522,6 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) early in the link process, elf_i386_finish_dynamic_sections is one of the last functions. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - /* The size in bytes of an entry in the lazy procedure linkage table. */ #define LAZY_PLT_ENTRY_SIZE 16 @@ -758,94 +752,21 @@ static const bfd_byte elf_i386_eh_frame_non_lazy_plt[] = DW_CFA_nop, DW_CFA_nop, DW_CFA_nop }; -struct elf_i386_lazy_plt_layout -{ - /* The first entry in an absolute lazy procedure linkage table looks - like this. */ - const bfd_byte *plt0_entry; - unsigned int plt0_entry_size; - - /* Offsets into plt0_entry that are to be replaced with GOT[1] and - GOT[2]. */ - unsigned int plt0_got1_offset; - unsigned int plt0_got2_offset; - - /* Later entries in an absolute lazy procedure linkage table look - like this. */ - const bfd_byte *plt_entry; - unsigned int plt_entry_size; - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - unsigned int plt_reloc_offset; /* ... offset into relocation table. */ - unsigned int plt_plt_offset; /* ... offset to start of .plt. */ - - /* Offset into plt_entry where the initial value of the GOT entry - points. */ - unsigned int plt_lazy_offset; - - /* The first entry in a PIC lazy procedure linkage table looks like - this. */ - const bfd_byte *pic_plt0_entry; - - /* Subsequent entries in a PIC lazy procedure linkage table look - like this. */ - const bfd_byte *pic_plt_entry; - - /* .eh_frame covering the lazy .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - -struct elf_i386_non_lazy_plt_layout -{ - /* Entries in an absolute non-lazy procedure linkage table look like - this. */ - const bfd_byte *plt_entry; - /* Entries in a PIC non-lazy procedure linkage table look like this. */ - const bfd_byte *pic_plt_entry; - - unsigned int plt_entry_size; - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - - /* .eh_frame covering the non-lazy .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - -struct elf_i386_plt_layout -{ - /* The first entry in a lazy procedure linkage table looks like this. */ - const bfd_byte *plt0_entry; - /* Entries in a procedure linkage table look like this. */ - const bfd_byte *plt_entry; - unsigned int plt_entry_size; - - /* 1 has PLT0. */ - unsigned int has_plt0; - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - - /* .eh_frame covering the .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - /* These are the standard parameters. */ -static const struct elf_i386_lazy_plt_layout elf_i386_lazy_plt = +static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt = { elf_i386_lazy_plt0_entry, /* plt0_entry */ sizeof (elf_i386_lazy_plt0_entry), /* plt0_entry_size */ - 2, /* plt0_got1_offset */ - 8, /* plt0_got2_offset */ elf_i386_lazy_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ + 2, /* plt0_got1_offset */ + 8, /* plt0_got2_offset */ + 0, /* plt0_got2_insn_end */ 2, /* plt_got_offset */ 7, /* plt_reloc_offset */ 12, /* plt_plt_offset */ + 0, /* plt_got_insn_size */ + 0, /* plt_plt_insn_end */ 6, /* plt_lazy_offset */ elf_i386_pic_lazy_plt0_entry, /* pic_plt0_entry */ elf_i386_pic_lazy_plt_entry, /* pic_plt_entry */ @@ -853,27 +774,31 @@ static const struct elf_i386_lazy_plt_layout elf_i386_lazy_plt = sizeof (elf_i386_eh_frame_lazy_plt) /* eh_frame_plt_size */ }; -static const struct elf_i386_non_lazy_plt_layout elf_i386_non_lazy_plt = +static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_plt = { elf_i386_non_lazy_plt_entry, /* plt_entry */ elf_i386_pic_non_lazy_plt_entry, /* pic_plt_entry */ NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt_got_offset */ + 0, /* plt_got_insn_size */ elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */ sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ }; -static const struct elf_i386_lazy_plt_layout elf_i386_lazy_ibt_plt = +static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt = { elf_i386_lazy_ibt_plt0_entry, /* plt0_entry */ sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */ - 2, /* plt0_got1_offset */ - 8, /* plt0_got2_offset */ elf_i386_lazy_ibt_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ + 2, /* plt0_got1_offset */ + 8, /* plt0_got2_offset */ + 0, /* plt0_got2_insn_end */ 4+2, /* plt_got_offset */ 4+1, /* plt_reloc_offset */ 4+6, /* plt_plt_offset */ + 0, /* plt_got_insn_size */ + 0, /* plt_plt_insn_end */ 0, /* plt_lazy_offset */ elf_i386_pic_lazy_ibt_plt0_entry, /* pic_plt0_entry */ elf_i386_lazy_ibt_plt_entry, /* pic_plt_entry */ @@ -881,12 +806,13 @@ static const struct elf_i386_lazy_plt_layout elf_i386_lazy_ibt_plt = sizeof (elf_i386_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */ }; -static const struct elf_i386_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt = +static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt = { elf_i386_non_lazy_ibt_plt_entry, /* plt_entry */ elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 4+2, /* plt_got_offset */ + 0, /* plt_got_insn_size */ elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */ sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ }; @@ -955,88 +881,9 @@ elf_i386_mkobject (bfd *abfd) I386_ELF_DATA); } -/* i386 ELF linker hash table. */ - -struct elf_i386_link_hash_table -{ - struct elf_x86_link_hash_table x86; - - /* Parameters describing PLT generation, lazy or non-lazy. */ - struct elf_i386_plt_layout plt; - - /* Parameters describing lazy PLT generation. */ - const struct elf_i386_lazy_plt_layout *lazy_plt; - - /* Parameters describing non-lazy PLT generation. */ - const struct elf_i386_non_lazy_plt_layout *non_lazy_plt; - - /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. */ - asection *srelplt2; - - /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. */ - bfd_vma next_tls_desc_index; -}; - -#define elf_i386_next_tls_desc_index(htab) \ - ((struct elf_i386_link_hash_table *) (htab))->next_tls_desc_index - -#define elf_i386_srelplt2(htab) \ - ((struct elf_i386_link_hash_table *) (htab))->srelplt2 - -#define elf_i386_plt(htab) \ - ((struct elf_i386_link_hash_table *) (htab))->plt - -#define elf_i386_lazy_plt(htab) \ - ((struct elf_i386_link_hash_table *) (htab))->lazy_plt - -#define elf_i386_non_lazy_plt(htab) \ - ((struct elf_i386_link_hash_table *) (htab))->non_lazy_plt - #define elf_i386_compute_jump_table_size(htab) \ ((htab)->elf.srelplt->reloc_count * 4) -/* Create an i386 ELF linker hash table. */ - -static struct bfd_link_hash_table * -elf_i386_link_hash_table_create (bfd *abfd) -{ - struct elf_x86_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_i386_link_hash_table); - - ret = (struct elf_x86_link_hash_table *) bfd_zmalloc (amt); - if (ret == NULL) - return NULL; - - if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, - _bfd_x86_elf_link_hash_newfunc, - sizeof (struct elf_x86_link_hash_entry), - I386_ELF_DATA)) - { - free (ret); - return NULL; - } - - ret->r_info = elf32_r_info; - ret->r_sym = elf32_r_sym; - ret->pointer_r_type = R_386_32; - ret->dynamic_interpreter_size = sizeof ELF_DYNAMIC_INTERPRETER; - ret->dynamic_interpreter = ELF_DYNAMIC_INTERPRETER; - ret->tls_get_addr = "___tls_get_addr"; - ret->loc_hash_table = htab_try_create (1024, - _bfd_x86_elf_local_htab_hash, - _bfd_x86_elf_local_htab_eq, - NULL); - ret->loc_hash_memory = objalloc_create (); - if (!ret->loc_hash_table || !ret->loc_hash_memory) - { - _bfd_x86_elf_link_hash_table_free (abfd); - return NULL; - } - ret->elf.root.hash_table_free = _bfd_x86_elf_link_hash_table_free; - - return &ret->elf.root; -} - /* Return TRUE if the TLS access code sequence support transition from R_TYPE. */ @@ -2362,8 +2209,6 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) unsigned plt_entry_size; bfd_boolean resolved_to_zero; const struct elf_i386_backend_data *bed; - const struct elf_i386_plt_layout *plt_layout; - const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout; if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -2377,9 +2222,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) bed = get_elf_i386_backend_data (info->output_bfd); - plt_layout = &elf_i386_plt (htab); - non_lazy_plt_layout = elf_i386_non_lazy_plt (htab); - plt_entry_size = plt_layout->plt_entry_size; + plt_entry_size = htab->plt.plt_entry_size; resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, I386_ELF_DATA, @@ -2417,7 +2260,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs, &htab->readonly_dynrelocs_against_ifunc, plt_entry_size, - (plt_layout->has_plt0 + (htab->plt.has_plt0 * plt_entry_size), 4, TRUE)) { @@ -2428,7 +2271,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) eh->plt_second.offset = s->size; /* Make room for this entry in the second PLT section. */ - s->size += non_lazy_plt_layout->plt_entry_size; + s->size += htab->non_lazy_plt->plt_entry_size; } return TRUE; @@ -2470,7 +2313,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) first entry. The .plt section is used by prelink to undo prelinking for dynamic relocations. */ if (s->size == 0) - s->size = plt_layout->has_plt0 * plt_entry_size; + s->size = htab->plt.has_plt0 * plt_entry_size; if (use_plt_got) eh->plt_got.offset = got_s->size; @@ -2515,12 +2358,12 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Make room for this entry. */ if (use_plt_got) - got_s->size += non_lazy_plt_layout->plt_entry_size; + got_s->size += htab->non_lazy_plt->plt_entry_size; else { s->size += plt_entry_size; if (second_s) - second_s->size += non_lazy_plt_layout->plt_entry_size; + second_s->size += htab->non_lazy_plt->plt_entry_size; /* We also need to make an entry in the .got.plt section, which will be placed in the .got section by the linker @@ -2548,7 +2391,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8. */ - asection *srelplt2 = elf_i386_srelplt2 (htab); + asection *srelplt2 = htab->srelplt2; if (h->plt.offset == plt_entry_size) srelplt2->size += (sizeof (Elf32_External_Rel) * 2); @@ -3096,10 +2939,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) so that R_386_IRELATIVE entries come last. */ if (htab->elf.srelplt) { - elf_i386_next_tls_desc_index(htab) - = htab->elf.srelplt->reloc_count; - htab->sgotplt_jump_table_size - = elf_i386_next_tls_desc_index(htab) * 4; + htab->next_tls_desc_index = htab->elf.srelplt->reloc_count; + htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4; htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1; } else if (htab->elf.irelplt) @@ -3131,14 +2972,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) && htab->elf.splt != NULL && htab->elf.splt->size != 0 && !bfd_is_abs_section (htab->elf.splt->output_section)) - htab->plt_eh_frame->size = elf_i386_plt (htab).eh_frame_plt_size; + htab->plt_eh_frame->size = htab->plt.eh_frame_plt_size; if (htab->plt_got_eh_frame != NULL && htab->plt_got != NULL && htab->plt_got->size != 0 && !bfd_is_abs_section (htab->plt_got->output_section)) htab->plt_got_eh_frame->size - = elf_i386_non_lazy_plt (htab)->eh_frame_plt_size; + = htab->non_lazy_plt->eh_frame_plt_size; /* Unwind info for the second PLT and .plt.got sections are identical. */ @@ -3147,7 +2988,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) && htab->plt_second->size != 0 && !bfd_is_abs_section (htab->plt_second->output_section)) htab->plt_second_eh_frame->size - = elf_i386_non_lazy_plt (htab)->eh_frame_plt_size; + = htab->non_lazy_plt->eh_frame_plt_size; } /* We now have determined the sizes of the various dynamic sections. @@ -3189,7 +3030,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { if (s->size != 0 && s != htab->elf.srelplt - && s != elf_i386_srelplt2 (htab)) + && s != htab->srelplt2) relocs = TRUE; /* We use the reloc_count field as a counter if we need @@ -3235,7 +3076,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) && htab->plt_eh_frame->contents != NULL) { memcpy (htab->plt_eh_frame->contents, - elf_i386_plt (htab).eh_frame_plt, + htab->plt.eh_frame_plt, htab->plt_eh_frame->size); bfd_put_32 (dynobj, htab->elf.splt->size, htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET); @@ -3245,7 +3086,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) && htab->plt_got_eh_frame->contents != NULL) { memcpy (htab->plt_got_eh_frame->contents, - elf_i386_non_lazy_plt (htab)->eh_frame_plt, + htab->non_lazy_plt->eh_frame_plt, htab->plt_got_eh_frame->size); bfd_put_32 (dynobj, htab->plt_got->size, (htab->plt_got_eh_frame->contents @@ -3256,7 +3097,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) && htab->plt_second_eh_frame->contents != NULL) { memcpy (htab->plt_second_eh_frame->contents, - elf_i386_non_lazy_plt (htab)->eh_frame_plt, + htab->non_lazy_plt->eh_frame_plt, htab->plt_second_eh_frame->size); bfd_put_32 (dynobj, htab->plt_second->size, (htab->plt_second_eh_frame->contents @@ -3431,7 +3272,7 @@ elf_i386_relocate_section (bfd *output_bfd, _bfd_x86_elf_set_tls_module_base (info); - plt_entry_size = elf_i386_plt (htab).plt_entry_size; + plt_entry_size = htab->plt.plt_entry_size; rel = wrel = relocs; relend = relocs + input_section->reloc_count; @@ -3676,7 +3517,7 @@ elf_i386_relocate_section (bfd *output_bfd, if (htab->elf.splt != NULL) { plt_index = (h->plt.offset / plt_entry_size - - elf_i386_plt (htab).has_plt0); + - htab->plt.has_plt0); off = (plt_index + 3) * 4; base_got = htab->elf.sgotplt; } @@ -3894,7 +3735,7 @@ do_ifunc_pointer: else /* Use GOTPLT entry. */ relocation = (h->plt.offset / plt_entry_size - - elf_i386_plt (htab).has_plt0 + 3) * 4; + - htab->plt.has_plt0 + 3) * 4; if (!bfd_link_pic (info)) { @@ -4523,7 +4364,7 @@ disallow_got32: + htab->sgotplt_jump_table_size); sreloc = htab->elf.srelplt; loc = sreloc->contents; - loc += (elf_i386_next_tls_desc_index (htab)++ + loc += (htab->next_tls_desc_index++ * sizeof (Elf32_External_Rel)); BFD_ASSERT (loc + sizeof (Elf32_External_Rel) <= sreloc->contents + sreloc->size); @@ -4983,19 +4824,13 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, struct elf_x86_link_hash_entry *eh; bfd_boolean local_undefweak; bfd_boolean use_plt_second; - const struct elf_i386_plt_layout *plt_layout; - const struct elf_i386_lazy_plt_layout *lazy_plt_layout; - const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout; htab = elf_x86_hash_table (info, I386_ELF_DATA); if (htab == NULL) return FALSE; abed = get_elf_i386_backend_data (output_bfd); - plt_layout = &elf_i386_plt (htab); - lazy_plt_layout = elf_i386_lazy_plt (htab); - non_lazy_plt_layout = elf_i386_non_lazy_plt (htab); - plt_entry_size = plt_layout->plt_entry_size; + plt_entry_size = htab->plt.plt_entry_size; /* Use the second PLT section only if there is .plt section. */ use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL; @@ -5061,7 +4896,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, if (plt == htab->elf.splt) { got_offset = (h->plt.offset / plt_entry_size - - plt_layout->has_plt0); + - htab->plt.has_plt0); got_offset = (got_offset + 3) * 4; } else @@ -5072,18 +4907,18 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, /* Fill in the entry in the procedure linkage table and update the first slot. */ - memcpy (plt->contents + h->plt.offset, plt_layout->plt_entry, + memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry, plt_entry_size); if (use_plt_second) { const bfd_byte *plt_entry; if (bfd_link_pic (info)) - plt_entry = non_lazy_plt_layout->pic_plt_entry; + plt_entry = htab->non_lazy_plt->pic_plt_entry; else - plt_entry = non_lazy_plt_layout->plt_entry; + plt_entry = htab->non_lazy_plt->plt_entry; memcpy (htab->plt_second->contents + eh->plt_second.offset, - plt_entry, non_lazy_plt_layout->plt_entry_size); + plt_entry, htab->non_lazy_plt->plt_entry_size); resolved_plt = htab->plt_second; plt_offset = eh->plt_second.offset; @@ -5101,7 +4936,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, + gotplt->output_offset + got_offset), resolved_plt->contents + plt_offset - + plt_layout->plt_got_offset); + + htab->plt.plt_got_offset); if (abed->os == is_vxworks) { @@ -5111,8 +4946,8 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, for this PLT entry. */ /* S: Current slot number (zero-based). */ - s = ((h->plt.offset - plt_layout->plt_entry_size) - / plt_layout->plt_entry_size); + s = ((h->plt.offset - htab->plt.plt_entry_size) + / htab->plt.plt_entry_size); /* K: Number of relocations for PLTResolve. */ if (bfd_link_pic (info)) k = PLTRESOLVE_RELOCS_SHLIB; @@ -5121,7 +4956,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, /* Skip the PLTresolve relocations, and the relocations for the other PLT slots. */ reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS; - loc = (elf_i386_srelplt2 (htab)->contents + reloc_index + loc = (htab->srelplt2->contents + reloc_index * sizeof (Elf32_External_Rel)); rel.r_offset = (plt->output_section->vma @@ -5144,7 +4979,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, { bfd_put_32 (output_bfd, got_offset, resolved_plt->contents + plt_offset - + plt_layout->plt_got_offset); + + htab->plt.plt_got_offset); } /* Fill in the entry in the global offset table. Leave the entry @@ -5152,12 +4987,12 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, against undefined weak symbol in PIE. */ if (!local_undefweak) { - if (plt_layout->has_plt0) + if (htab->plt.has_plt0) bfd_put_32 (output_bfd, (plt->output_section->vma + plt->output_offset + h->plt.offset - + lazy_plt_layout->plt_lazy_offset), + + htab->lazy_plt->plt_lazy_offset), gotplt->contents + got_offset); /* Fill in the entry in the .rel.plt section. */ @@ -5197,17 +5032,17 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, /* Don't fill the second and third slots in PLT entry for static executables nor without PLT0. */ - if (plt == htab->elf.splt && plt_layout->has_plt0) + if (plt == htab->elf.splt && htab->plt.has_plt0) { bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), plt->contents + h->plt.offset - + lazy_plt_layout->plt_reloc_offset); + + htab->lazy_plt->plt_reloc_offset); bfd_put_32 (output_bfd, - (h->plt.offset - + lazy_plt_layout->plt_plt_offset + 4), + + htab->lazy_plt->plt_plt_offset + 4), (plt->contents + h->plt.offset - + lazy_plt_layout->plt_plt_offset)); + + htab->lazy_plt->plt_plt_offset)); } } } @@ -5232,12 +5067,12 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, /* Fill in the entry in the GOT procedure linkage table. */ if (! bfd_link_pic (info)) { - got_plt_entry = non_lazy_plt_layout->plt_entry; + got_plt_entry = htab->non_lazy_plt->plt_entry; got_offset += got->output_section->vma + got->output_offset; } else { - got_plt_entry = non_lazy_plt_layout->pic_plt_entry; + got_plt_entry = htab->non_lazy_plt->pic_plt_entry; got_offset += (got->output_section->vma + got->output_offset - gotplt->output_section->vma @@ -5246,10 +5081,10 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, plt_offset = eh->plt_got.offset; memcpy (plt->contents + plt_offset, got_plt_entry, - non_lazy_plt_layout->plt_entry_size); + htab->non_lazy_plt->plt_entry_size); bfd_put_32 (output_bfd, got_offset, (plt->contents + plt_offset - + non_lazy_plt_layout->plt_got_offset)); + + htab->non_lazy_plt->plt_got_offset)); } if (!local_undefweak @@ -5505,9 +5340,6 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, if (htab->elf.dynamic_sections_created) { Elf32_External_Dyn *dyncon, *dynconend; - const struct elf_i386_plt_layout *plt_layout; - const struct elf_i386_lazy_plt_layout *lazy_plt_layout; - const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout; if (sdyn == NULL || htab->elf.sgot == NULL) abort (); @@ -5548,10 +5380,6 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); } - plt_layout = &elf_i386_plt (htab); - lazy_plt_layout = elf_i386_lazy_plt (htab); - non_lazy_plt_layout = elf_i386_non_lazy_plt (htab); - if (htab->elf.splt && htab->elf.splt->size > 0) { /* UnixWare sets the entsize of .plt to 4, although that doesn't @@ -5559,15 +5387,15 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, elf_section_data (htab->elf.splt->output_section) ->this_hdr.sh_entsize = 4; - if (plt_layout->has_plt0) + if (htab->plt.has_plt0) { /* Fill in the special first entry in the procedure linkage table. */ - memcpy (htab->elf.splt->contents, plt_layout->plt0_entry, - lazy_plt_layout->plt0_entry_size); - memset (htab->elf.splt->contents + lazy_plt_layout->plt0_entry_size, + memcpy (htab->elf.splt->contents, htab->plt.plt0_entry, + htab->lazy_plt->plt0_entry_size); + memset (htab->elf.splt->contents + htab->lazy_plt->plt0_entry_size, abed->plt0_pad_byte, - plt_layout->plt_entry_size - lazy_plt_layout->plt0_entry_size); + htab->plt.plt_entry_size - htab->lazy_plt->plt0_entry_size); if (!bfd_link_pic (info)) { bfd_put_32 (output_bfd, @@ -5575,28 +5403,28 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, + htab->elf.sgotplt->output_offset + 4), htab->elf.splt->contents - + lazy_plt_layout->plt0_got1_offset); + + htab->lazy_plt->plt0_got1_offset); bfd_put_32 (output_bfd, (htab->elf.sgotplt->output_section->vma + htab->elf.sgotplt->output_offset + 8), htab->elf.splt->contents - + lazy_plt_layout->plt0_got2_offset); + + htab->lazy_plt->plt0_got2_offset); if (abed->os == is_vxworks) { Elf_Internal_Rela rel; int num_plts = (htab->elf.splt->size - / plt_layout->plt_entry_size) - 1; + / htab->plt.plt_entry_size) - 1; unsigned char *p; - asection *srelplt2 = elf_i386_srelplt2 (htab); + asection *srelplt2 = htab->srelplt2; /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4. On IA32 we use REL relocations so the addend goes in the PLT directly. */ rel.r_offset = (htab->elf.splt->output_section->vma + htab->elf.splt->output_offset - + lazy_plt_layout->plt0_got1_offset); + + htab->lazy_plt->plt0_got1_offset); rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); bfd_elf32_swap_reloc_out (output_bfd, &rel, @@ -5605,7 +5433,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, + 8. */ rel.r_offset = (htab->elf.splt->output_section->vma + htab->elf.splt->output_offset - + lazy_plt_layout->plt0_got2_offset); + + htab->lazy_plt->plt0_got2_offset); rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); bfd_elf32_swap_reloc_out (output_bfd, &rel, @@ -5639,11 +5467,11 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, if (htab->plt_got != NULL && htab->plt_got->size > 0) elf_section_data (htab->plt_got->output_section) - ->this_hdr.sh_entsize = non_lazy_plt_layout->plt_entry_size; + ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size; if (htab->plt_second != NULL && htab->plt_second->size > 0) elf_section_data (htab->plt_second->output_section) - ->this_hdr.sh_entsize = non_lazy_plt_layout->plt_entry_size; + ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size; } /* Fill in the first three entries in the global offset table. */ @@ -5811,7 +5639,7 @@ struct elf_i386_plt }; /* Forward declaration. */ -static const struct elf_i386_lazy_plt_layout elf_i386_nacl_plt; +static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt; /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all dynamic relocations. */ @@ -5831,10 +5659,10 @@ elf_i386_get_synthetic_symtab (bfd *abfd, bfd_byte *plt_contents; long dynrelcount, relsize; arelent **dynrelbuf, *p; - const struct elf_i386_lazy_plt_layout *lazy_plt; - const struct elf_i386_non_lazy_plt_layout *non_lazy_plt; - const struct elf_i386_lazy_plt_layout *lazy_ibt_plt; - const struct elf_i386_non_lazy_plt_layout *non_lazy_ibt_plt; + const struct elf_x86_lazy_plt_layout *lazy_plt; + const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; + const struct elf_x86_lazy_plt_layout *lazy_ibt_plt; + const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt; asection *plt; bfd_vma got_addr; char *names; @@ -6198,9 +6026,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) bfd *pbfd; bfd *ebfd = NULL; elf_property *prop; - struct elf_i386_plt_layout *plt_layout; - const struct elf_i386_lazy_plt_layout *lazy_plt_layout; - const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout; features = 0; if (info->ibt) @@ -6316,12 +6141,10 @@ error_alignment: } } - plt_layout = &elf_i386_plt (htab); - /* Even when lazy binding is disabled by "-z now", the PLT0 entry may still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for canonical function address. */ - plt_layout->has_plt0 = 1; + htab->plt.has_plt0 = 1; normal_target = FALSE; switch (get_elf_i386_backend_data (info->output_bfd)->os) @@ -6329,82 +6152,70 @@ error_alignment: case is_normal: if (use_ibt_plt) { - elf_i386_lazy_plt (htab) = &elf_i386_lazy_ibt_plt; - elf_i386_non_lazy_plt (htab) = &elf_i386_non_lazy_ibt_plt; + htab->lazy_plt = &elf_i386_lazy_ibt_plt; + htab->non_lazy_plt = &elf_i386_non_lazy_ibt_plt; } else { - elf_i386_lazy_plt (htab) = &elf_i386_lazy_plt; - elf_i386_non_lazy_plt (htab) = &elf_i386_non_lazy_plt; + htab->lazy_plt = &elf_i386_lazy_plt; + htab->non_lazy_plt = &elf_i386_non_lazy_plt; } normal_target = TRUE; break; case is_vxworks: - elf_i386_lazy_plt (htab) = &elf_i386_lazy_plt; - elf_i386_non_lazy_plt (htab) = NULL; + htab->lazy_plt = &elf_i386_lazy_plt; + htab->non_lazy_plt = NULL; if (!elf_vxworks_create_dynamic_sections (dynobj, info, - &elf_i386_srelplt2 (htab))) + &htab->srelplt2)) info->callbacks->einfo (_("%F: failed to create VxWorks dynamic sections\n")); break; case is_nacl: - elf_i386_lazy_plt (htab) = &elf_i386_nacl_plt; - elf_i386_non_lazy_plt (htab) = NULL; + htab->lazy_plt = &elf_i386_nacl_plt; + htab->non_lazy_plt = NULL; break; } - lazy_plt_layout = elf_i386_lazy_plt (htab); - non_lazy_plt_layout = elf_i386_non_lazy_plt (htab); - pltsec = htab->elf.splt; /* If the non-lazy PLT is available, use it for all PLT entries if there are no PLT0 or no .plt section. */ - if (non_lazy_plt_layout != NULL - && (!plt_layout->has_plt0 || pltsec == NULL)) + if (htab->non_lazy_plt != NULL + && (!htab->plt.has_plt0 || pltsec == NULL)) { lazy_plt = FALSE; if (bfd_link_pic (info)) - plt_layout->plt_entry - = non_lazy_plt_layout->pic_plt_entry; + htab->plt.plt_entry = htab->non_lazy_plt->pic_plt_entry; else - plt_layout->plt_entry - = non_lazy_plt_layout->plt_entry; - plt_layout->plt_entry_size - = non_lazy_plt_layout->plt_entry_size; - plt_layout->plt_got_offset - = non_lazy_plt_layout->plt_got_offset; - plt_layout->eh_frame_plt_size - = non_lazy_plt_layout->eh_frame_plt_size; - plt_layout->eh_frame_plt - = non_lazy_plt_layout->eh_frame_plt; + htab->plt.plt_entry = htab->non_lazy_plt->plt_entry; + htab->plt.plt_entry_size = htab->non_lazy_plt->plt_entry_size; + htab->plt.plt_got_offset = htab->non_lazy_plt->plt_got_offset; + htab->plt.eh_frame_plt_size + = htab->non_lazy_plt->eh_frame_plt_size; + htab->plt.eh_frame_plt = htab->non_lazy_plt->eh_frame_plt; } else { lazy_plt = TRUE; if (bfd_link_pic (info)) { - plt_layout->plt0_entry - = lazy_plt_layout->pic_plt0_entry; - plt_layout->plt_entry - = lazy_plt_layout->pic_plt_entry; + htab->plt.plt0_entry = htab->lazy_plt->pic_plt0_entry; + htab->plt.plt_entry = htab->lazy_plt->pic_plt_entry; } else { - plt_layout->plt0_entry - = lazy_plt_layout->plt0_entry; - plt_layout->plt_entry - = lazy_plt_layout->plt_entry; + htab->plt.plt0_entry = htab->lazy_plt->plt0_entry; + htab->plt.plt_entry = htab->lazy_plt->plt_entry; } - plt_layout->plt_entry_size - = lazy_plt_layout->plt_entry_size; - plt_layout->plt_got_offset - = lazy_plt_layout->plt_got_offset; - plt_layout->eh_frame_plt_size - = lazy_plt_layout->eh_frame_plt_size; - plt_layout->eh_frame_plt - = lazy_plt_layout->eh_frame_plt; + + htab->plt.plt_entry_size = htab->lazy_plt->plt_entry_size; + htab->plt.plt_got_offset = htab->lazy_plt->plt_got_offset; + htab->plt.eh_frame_plt_size = htab->lazy_plt->eh_frame_plt_size; + htab->plt.eh_frame_plt = htab->lazy_plt->eh_frame_plt; } + /* This is unused for i386. */ + htab->plt.plt_got_insn_size = 0; + /* Return if there are no normal input files. */ if (dynobj == NULL) return pbfd; @@ -6421,7 +6232,7 @@ error_alignment: if (!_bfd_elf_create_ifunc_sections (dynobj, info)) info->callbacks->einfo (_("%F: failed to create ifunc sections\n")); - plt_alignment = bfd_log2 (plt_layout->plt_entry_size); + plt_alignment = bfd_log2 (htab->plt.plt_entry_size); if (pltsec != NULL) { @@ -6450,7 +6261,7 @@ error_alignment: | SEC_LOAD | SEC_READONLY); unsigned int non_lazy_plt_alignment - = bfd_log2 (non_lazy_plt_layout->plt_entry_size); + = bfd_log2 (htab->non_lazy_plt->plt_entry_size); sec = pltsec; if (!bfd_set_section_alignment (sec->owner, sec, @@ -6567,7 +6378,6 @@ error_alignment: #define bfd_elf32_mkobject elf_i386_mkobject #define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name -#define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup #define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab @@ -6919,17 +6729,20 @@ static const bfd_byte elf_i386_nacl_eh_frame_plt[] = DW_CFA_nop, DW_CFA_nop }; -static const struct elf_i386_lazy_plt_layout elf_i386_nacl_plt = +static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt = { elf_i386_nacl_plt0_entry, /* plt0_entry */ sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */ - 2, /* plt0_got1_offset */ - 8, /* plt0_got2_offset */ elf_i386_nacl_plt_entry, /* plt_entry */ NACL_PLT_ENTRY_SIZE, /* plt_entry_size */ + 2, /* plt0_got1_offset */ + 8, /* plt0_got2_offset */ + 0, /* plt0_got2_insn_end */ 2, /* plt_got_offset */ 33, /* plt_reloc_offset */ 38, /* plt_plt_offset */ + 0, /* plt_got_insn_size */ + 0, /* plt_plt_insn_end */ 32, /* plt_lazy_offset */ elf_i386_nacl_pic_plt0_entry, /* pic_plt0_entry */ elf_i386_nacl_pic_plt_entry, /* pic_plt_entry */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 985f7f6..3bf465b 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -40,9 +40,6 @@ 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. */ @@ -521,12 +518,6 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz, /* Functions for the x86-64 ELF linker. */ -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1" -#define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1" - /* The size in bytes of an entry in the global offset table. */ #define GOT_ENTRY_SIZE 8 @@ -823,77 +814,6 @@ static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] = DW_CFA_nop, DW_CFA_nop, DW_CFA_nop }; -struct elf_x86_64_lazy_plt_layout -{ - /* Templates for the initial PLT entry and for subsequent entries. */ - const bfd_byte *plt0_entry; - const bfd_byte *plt_entry; - unsigned int plt_entry_size; /* Size of each PLT entry. */ - - /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2]. */ - unsigned int plt0_got1_offset; - unsigned int plt0_got2_offset; - - /* Offset of the end of the PC-relative instruction containing - plt0_got2_offset. */ - unsigned int plt0_got2_insn_end; - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - unsigned int plt_reloc_offset; /* ... offset into relocation table. */ - unsigned int plt_plt_offset; /* ... offset to start of .plt. */ - - /* Length of the PC-relative instruction containing plt_got_offset. */ - unsigned int plt_got_insn_size; - - /* Offset of the end of the PC-relative jump to plt0_entry. */ - unsigned int plt_plt_insn_end; - - /* Offset into plt_entry where the initial value of the GOT entry points. */ - unsigned int plt_lazy_offset; - - /* .eh_frame covering the lazy .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - -struct elf_x86_64_non_lazy_plt_layout -{ - /* Template for the lazy PLT entries. */ - const bfd_byte *plt_entry; - unsigned int plt_entry_size; /* Size of each PLT entry. */ - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - - /* Length of the PC-relative instruction containing plt_got_offset. */ - unsigned int plt_got_insn_size; - - /* .eh_frame covering the non-lazy .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - -struct elf_x86_64_plt_layout -{ - /* Template for the PLT entries. */ - const bfd_byte *plt_entry; - unsigned int plt_entry_size; /* Size of each PLT entry. */ - - /* 1 has PLT0. */ - unsigned int has_plt0; - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - - /* Length of the PC-relative instruction containing plt_got_offset. */ - unsigned int plt_got_insn_size; - - /* .eh_frame covering the .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - /* Architecture-specific backend data for x86-64. */ struct elf_x86_64_backend_data @@ -913,9 +833,10 @@ struct elf_x86_64_backend_data get_elf_x86_64_arch_data (get_elf_backend_data (abfd)) /* These are the standard parameters. */ -static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_plt = +static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt = { elf_x86_64_lazy_plt0_entry, /* plt0_entry */ + LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ elf_x86_64_lazy_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt0_got1_offset */ @@ -927,13 +848,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_plt = 6, /* plt_got_insn_size */ LAZY_PLT_ENTRY_SIZE, /* plt_plt_insn_end */ 6, /* plt_lazy_offset */ + NULL, /* pic_plt0_entry */ + NULL, /* pic_plt_entry */ elf_x86_64_eh_frame_lazy_plt, /* eh_frame_plt */ sizeof (elf_x86_64_eh_frame_lazy_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_plt = +static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt = { elf_x86_64_non_lazy_plt_entry, /* plt_entry */ + NULL, /* pic_plt_entry */ NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt_got_offset */ 6, /* plt_got_insn_size */ @@ -941,9 +865,10 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_plt = sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_bnd_plt = +static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt = { elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */ + LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ elf_x86_64_lazy_bnd_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt0_got1_offset */ @@ -955,13 +880,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_bnd_plt = 1+6, /* plt_got_insn_size */ 11, /* plt_plt_insn_end */ 0, /* plt_lazy_offset */ + NULL, /* pic_plt0_entry */ + NULL, /* pic_plt_entry */ elf_x86_64_eh_frame_lazy_bnd_plt, /* eh_frame_plt */ sizeof (elf_x86_64_eh_frame_lazy_bnd_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt = +static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt = { elf_x86_64_non_lazy_bnd_plt_entry, /* plt_entry */ + NULL, /* pic_plt_entry */ NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1+2, /* plt_got_offset */ 1+6, /* plt_got_insn_size */ @@ -969,9 +897,10 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt = sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_ibt_plt = +static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt = { elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */ + LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ elf_x86_64_lazy_ibt_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt0_got1_offset */ @@ -983,13 +912,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_ibt_plt = 4+1+6, /* plt_got_insn_size */ 4+1+5+5, /* plt_plt_insn_end */ 0, /* plt_lazy_offset */ + NULL, /* pic_plt0_entry */ + NULL, /* pic_plt_entry */ elf_x86_64_eh_frame_lazy_ibt_plt, /* eh_frame_plt */ sizeof (elf_x86_64_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_lazy_plt_layout elf_x32_lazy_ibt_plt = +static const struct elf_x86_lazy_plt_layout elf_x32_lazy_ibt_plt = { elf_x86_64_lazy_plt0_entry, /* plt0_entry */ + LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ elf_x32_lazy_ibt_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt0_got1_offset */ @@ -1001,13 +933,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x32_lazy_ibt_plt = 4+6, /* plt_got_insn_size */ 4+5+5, /* plt_plt_insn_end */ 0, /* plt_lazy_offset */ + NULL, /* pic_plt0_entry */ + NULL, /* pic_plt_entry */ elf_x32_eh_frame_lazy_ibt_plt, /* eh_frame_plt */ sizeof (elf_x32_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt = +static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt = { elf_x86_64_non_lazy_ibt_plt_entry, /* plt_entry */ + NULL, /* pic_plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 4+1+2, /* plt_got_offset */ 4+1+6, /* plt_got_insn_size */ @@ -1015,9 +950,10 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt = sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_64_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt = +static const struct elf_x86_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt = { elf_x32_non_lazy_ibt_plt_entry, /* plt_entry */ + NULL, /* pic_plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 4+2, /* plt_got_offset */ 4+6, /* plt_got_insn_size */ @@ -1056,88 +992,9 @@ elf_x86_64_mkobject (bfd *abfd) X86_64_ELF_DATA); } -/* x86-64 ELF linker hash table. */ - -struct elf_x86_64_link_hash_table -{ - struct elf_x86_link_hash_table x86; - - /* Parameters describing PLT generation, lazy or non-lazy. */ - struct elf_x86_64_plt_layout plt; - - /* Parameters describing lazy PLT generation. */ - const struct elf_x86_64_lazy_plt_layout *lazy_plt; - - /* Parameters describing non-lazy PLT generation. */ - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt; -}; - -#define elf_x86_64_plt(htab) \ - ((struct elf_x86_64_link_hash_table *) (htab))->plt - -#define elf_x86_64_lazy_plt(htab) \ - ((struct elf_x86_64_link_hash_table *) (htab))->lazy_plt - -#define elf_x86_64_non_lazy_plt(htab) \ - ((struct elf_x86_64_link_hash_table *) (htab))->non_lazy_plt - #define elf_x86_64_compute_jump_table_size(htab) \ ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE) -/* Create an X86-64 ELF linker hash table. */ - -static struct bfd_link_hash_table * -elf_x86_64_link_hash_table_create (bfd *abfd) -{ - struct elf_x86_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table); - - ret = (struct elf_x86_link_hash_table *) bfd_zmalloc (amt); - if (ret == NULL) - return NULL; - - if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, - _bfd_x86_elf_link_hash_newfunc, - sizeof (struct elf_x86_link_hash_entry), - X86_64_ELF_DATA)) - { - free (ret); - return NULL; - } - - if (ABI_64_P (abfd)) - { - ret->r_info = elf64_r_info; - ret->r_sym = elf64_r_sym; - ret->pointer_r_type = R_X86_64_64; - 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->pointer_r_type = R_X86_64_32; - ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER; - ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER; - } - - ret->tls_get_addr = "__tls_get_addr"; - ret->loc_hash_table = htab_try_create (1024, - _bfd_x86_elf_local_htab_hash, - _bfd_x86_elf_local_htab_eq, - NULL); - ret->loc_hash_memory = objalloc_create (); - if (!ret->loc_hash_table || !ret->loc_hash_memory) - { - _bfd_x86_elf_link_hash_table_free (abfd); - return NULL; - } - ret->elf.root.hash_table_free = _bfd_x86_elf_link_hash_table_free; - - return &ret->elf.root; -} - static bfd_boolean elf64_x86_64_elf_object_p (bfd *abfd) { @@ -2791,8 +2648,6 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) const struct elf_backend_data *bed; unsigned int plt_entry_size; bfd_boolean resolved_to_zero; - const struct elf_x86_64_plt_layout *plt_layout; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout; if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -2805,9 +2660,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) return FALSE; bed = get_elf_backend_data (info->output_bfd); - plt_layout = &elf_x86_64_plt (htab); - non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab); - plt_entry_size = plt_layout->plt_entry_size; + plt_entry_size = htab->plt.plt_entry_size; resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, X86_64_ELF_DATA, @@ -2846,7 +2699,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) &eh->dyn_relocs, &htab->readonly_dynrelocs_against_ifunc, plt_entry_size, - (plt_layout->has_plt0 + (htab->plt.has_plt0 * plt_entry_size), GOT_ENTRY_SIZE, TRUE)) { @@ -2857,7 +2710,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) eh->plt_second.offset = s->size; /* Make room for this entry in the second PLT section. */ - s->size += non_lazy_plt_layout->plt_entry_size; + s->size += htab->non_lazy_plt->plt_entry_size; } return TRUE; @@ -2899,7 +2752,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) first entry. The .plt section is used by prelink to undo prelinking for dynamic relocations. */ if (s->size == 0) - s->size = plt_layout->has_plt0 * plt_entry_size; + s->size = htab->plt.has_plt0 * plt_entry_size; if (use_plt_got) eh->plt_got.offset = got_s->size; @@ -2944,12 +2797,12 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) /* Make room for this entry. */ if (use_plt_got) - got_s->size += non_lazy_plt_layout->plt_entry_size; + got_s->size += htab->non_lazy_plt->plt_entry_size; else { s->size += plt_entry_size; if (second_s) - second_s->size += non_lazy_plt_layout->plt_entry_size; + second_s->size += htab->non_lazy_plt->plt_entry_size; /* We also need to make an entry in the .got.plt section, which will be placed in the .got section by the linker @@ -3332,8 +3185,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, bfd_boolean relocs; bfd *ibfd; const struct elf_backend_data *bed; - const struct elf_x86_64_plt_layout *plt_layout; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout; htab = elf_x86_hash_table (info, X86_64_ELF_DATA); if (htab == NULL) @@ -3344,9 +3195,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, if (dynobj == NULL) abort (); - plt_layout = &elf_x86_64_plt (htab); - non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab); - /* Set up .got offsets for local syms, and space for local dynamic relocs. */ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) @@ -3503,9 +3351,9 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, /* Reserve room for the initial entry. FIXME: we could probably do away with it in this case. */ if (htab->elf.splt->size == 0) - htab->elf.splt->size = plt_layout->plt_entry_size; + htab->elf.splt->size = htab->plt.plt_entry_size; htab->tlsdesc_plt = htab->elf.splt->size; - htab->elf.splt->size += plt_layout->plt_entry_size; + htab->elf.splt->size += htab->plt.plt_entry_size; } } @@ -3534,14 +3382,14 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, && htab->elf.splt != NULL && htab->elf.splt->size != 0 && !bfd_is_abs_section (htab->elf.splt->output_section)) - htab->plt_eh_frame->size = plt_layout->eh_frame_plt_size; + htab->plt_eh_frame->size = htab->plt.eh_frame_plt_size; if (htab->plt_got_eh_frame != NULL && htab->plt_got != NULL && htab->plt_got->size != 0 && !bfd_is_abs_section (htab->plt_got->output_section)) htab->plt_got_eh_frame->size - = non_lazy_plt_layout->eh_frame_plt_size; + = htab->non_lazy_plt->eh_frame_plt_size; /* Unwind info for the second PLT and .plt.got sections are identical. */ @@ -3550,7 +3398,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, && htab->plt_second->size != 0 && !bfd_is_abs_section (htab->plt_second->output_section)) htab->plt_second_eh_frame->size - = non_lazy_plt_layout->eh_frame_plt_size; + = htab->non_lazy_plt->eh_frame_plt_size; } /* We now have determined the sizes of the various dynamic sections. @@ -3626,7 +3474,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, && htab->plt_eh_frame->contents != NULL) { memcpy (htab->plt_eh_frame->contents, - plt_layout->eh_frame_plt, htab->plt_eh_frame->size); + htab->plt.eh_frame_plt, htab->plt_eh_frame->size); bfd_put_32 (dynobj, htab->elf.splt->size, htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET); } @@ -3635,7 +3483,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, && htab->plt_got_eh_frame->contents != NULL) { memcpy (htab->plt_got_eh_frame->contents, - non_lazy_plt_layout->eh_frame_plt, + htab->non_lazy_plt->eh_frame_plt, htab->plt_got_eh_frame->size); bfd_put_32 (dynobj, htab->plt_got->size, (htab->plt_got_eh_frame->contents @@ -3646,7 +3494,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, && htab->plt_second_eh_frame->contents != NULL) { memcpy (htab->plt_second_eh_frame->contents, - non_lazy_plt_layout->eh_frame_plt, + htab->non_lazy_plt->eh_frame_plt, htab->plt_second_eh_frame->size); bfd_put_32 (dynobj, htab->plt_second->size, (htab->plt_second_eh_frame->contents @@ -3792,7 +3640,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, htab = elf_x86_hash_table (info, X86_64_ELF_DATA); if (htab == NULL) return FALSE; - plt_entry_size = elf_x86_64_plt (htab).plt_entry_size; + plt_entry_size = htab->plt.plt_entry_size; symtab_hdr = &elf_symtab_hdr (input_bfd); sym_hashes = elf_sym_hashes (input_bfd); local_got_offsets = elf_local_got_offsets (input_bfd); @@ -3970,7 +3818,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, if (htab->elf.splt != NULL) { plt_index = (h->plt.offset / plt_entry_size - - elf_x86_64_plt (htab).has_plt0); + - htab->plt.has_plt0); off = (plt_index + 3) * GOT_ENTRY_SIZE; base_got = htab->elf.sgotplt; } @@ -4201,7 +4049,7 @@ do_ifunc_pointer: finish_dynamic_symbol would use that as offset into .got. */ bfd_vma plt_index = (h->plt.offset / plt_entry_size - - elf_x86_64_plt (htab).has_plt0); + - htab->plt.has_plt0); off = (plt_index + 3) * GOT_ENTRY_SIZE; base_got = htab->elf.sgotplt; } @@ -5356,9 +5204,6 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, bfd_boolean use_plt_second; struct elf_x86_link_hash_entry *eh; bfd_boolean local_undefweak; - const struct elf_x86_64_plt_layout *plt_layout; - const struct elf_x86_64_lazy_plt_layout *lazy_plt_layout; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout; htab = elf_x86_hash_table (info, X86_64_ELF_DATA); if (htab == NULL) @@ -5371,10 +5216,6 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, if (eh->no_finish_dynamic_symbol) abort (); - plt_layout = &elf_x86_64_plt (htab); - lazy_plt_layout = elf_x86_64_lazy_plt (htab); - non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab); - /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for resolved undefined weak symbols in executable so that their references have value 0 at run-time. */ @@ -5433,24 +5274,24 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, if (plt == htab->elf.splt) { - got_offset = (h->plt.offset / plt_layout->plt_entry_size - - plt_layout->has_plt0); + got_offset = (h->plt.offset / htab->plt.plt_entry_size + - htab->plt.has_plt0); got_offset = (got_offset + 3) * GOT_ENTRY_SIZE; } else { - got_offset = h->plt.offset / plt_layout->plt_entry_size; + got_offset = h->plt.offset / htab->plt.plt_entry_size; got_offset = got_offset * GOT_ENTRY_SIZE; } /* Fill in the entry in the procedure linkage table. */ - memcpy (plt->contents + h->plt.offset, plt_layout->plt_entry, - plt_layout->plt_entry_size); + memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry, + htab->plt.plt_entry_size); if (use_plt_second) { memcpy (htab->plt_second->contents + eh->plt_second.offset, - non_lazy_plt_layout->plt_entry, - non_lazy_plt_layout->plt_entry_size); + htab->non_lazy_plt->plt_entry, + htab->non_lazy_plt->plt_entry_size); resolved_plt = htab->plt_second; plt_offset = eh->plt_second.offset; @@ -5471,7 +5312,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, - resolved_plt->output_section->vma - resolved_plt->output_offset - plt_offset - - plt_layout->plt_got_insn_size); + - htab->plt.plt_got_insn_size); /* Check PC-relative offset overflow in PLT entry. */ if ((plt_got_pcrel_offset + 0x80000000) > 0xffffffff) @@ -5481,7 +5322,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, bfd_put_32 (output_bfd, plt_got_pcrel_offset, (resolved_plt->contents + plt_offset - + plt_layout->plt_got_offset)); + + htab->plt.plt_got_offset)); /* Fill in the entry in the global offset table, initially this points to the second part of the PLT entry. Leave the entry @@ -5489,11 +5330,11 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, against undefined weak symbol in PIE. */ if (!local_undefweak) { - if (plt_layout->has_plt0) + if (htab->plt.has_plt0) bfd_put_64 (output_bfd, (plt->output_section->vma + plt->output_offset + h->plt.offset - + lazy_plt_layout->plt_lazy_offset), + + htab->lazy_plt->plt_lazy_offset), gotplt->contents + got_offset); /* Fill in the entry in the .rela.plt section. */ @@ -5528,15 +5369,15 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, /* Don't fill the second and third slots in PLT entry for static executables nor without PLT0. */ - if (plt == htab->elf.splt && plt_layout->has_plt0) + if (plt == htab->elf.splt && htab->plt.has_plt0) { bfd_vma plt0_offset - = h->plt.offset + lazy_plt_layout->plt_plt_insn_end; + = h->plt.offset + htab->lazy_plt->plt_plt_insn_end; /* Put relocation index. */ bfd_put_32 (output_bfd, plt_index, (plt->contents + h->plt.offset - + lazy_plt_layout->plt_reloc_offset)); + + htab->lazy_plt->plt_reloc_offset)); /* Put offset for jmp .PLT0 and check for overflow. We don't check relocation index for overflow since branch displacement @@ -5547,7 +5388,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, output_bfd, h->root.root.string); bfd_put_32 (output_bfd, - plt0_offset, (plt->contents + h->plt.offset - + lazy_plt_layout->plt_plt_offset)); + + htab->lazy_plt->plt_plt_offset)); } bed = get_elf_backend_data (output_bfd); @@ -5578,8 +5419,8 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, /* Fill in the entry in the GOT procedure linkage table. */ plt_offset = eh->plt_got.offset; memcpy (plt->contents + plt_offset, - non_lazy_plt_layout->plt_entry, - non_lazy_plt_layout->plt_entry_size); + htab->non_lazy_plt->plt_entry, + htab->non_lazy_plt->plt_entry_size); /* Put offset the PC-relative instruction referring to the GOT entry, subtracting the size of that instruction. */ @@ -5589,7 +5430,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, - plt->output_section->vma - plt->output_offset - plt_offset - - non_lazy_plt_layout->plt_got_insn_size); + - htab->non_lazy_plt->plt_got_insn_size); /* Check PC-relative offset overflow in GOT PLT entry. */ got_after_plt = got->output_section->vma > plt->output_section->vma; @@ -5601,7 +5442,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, bfd_put_32 (output_bfd, got_pcrel_offset, (plt->contents + plt_offset - + non_lazy_plt_layout->plt_got_offset)); + + htab->non_lazy_plt->plt_got_offset)); } if (!local_undefweak @@ -5865,9 +5706,6 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, bfd_byte *dyncon, *dynconend; const struct elf_backend_data *bed; bfd_size_type sizeof_dyn; - const struct elf_x86_64_plt_layout *plt_layout; - const struct elf_x86_64_lazy_plt_layout *lazy_plt_layout; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout; if (sdyn == NULL || htab->elf.sgot == NULL) abort (); @@ -5918,22 +5756,18 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon); } - plt_layout = &elf_x86_64_plt (htab); - lazy_plt_layout = elf_x86_64_lazy_plt (htab); - non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab); - if (htab->elf.splt && htab->elf.splt->size > 0) { elf_section_data (htab->elf.splt->output_section) - ->this_hdr.sh_entsize = plt_layout->plt_entry_size; + ->this_hdr.sh_entsize = htab->plt.plt_entry_size; - if (plt_layout->has_plt0) + if (htab->plt.has_plt0) { /* Fill in the special first entry in the procedure linkage table. */ memcpy (htab->elf.splt->contents, - lazy_plt_layout->plt0_entry, - lazy_plt_layout->plt_entry_size); + htab->lazy_plt->plt0_entry, + htab->lazy_plt->plt0_entry_size); /* Add offset for pushq GOT+8(%rip), since the instruction uses 6 bytes subtract this value. */ bfd_put_32 (output_bfd, @@ -5944,7 +5778,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, - htab->elf.splt->output_offset - 6), (htab->elf.splt->contents - + lazy_plt_layout->plt0_got1_offset)); + + htab->lazy_plt->plt0_got1_offset)); /* Add offset for the PC-relative instruction accessing GOT+16, subtracting the offset to the end of that instruction. */ @@ -5954,9 +5788,9 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, + 16 - htab->elf.splt->output_section->vma - htab->elf.splt->output_offset - - lazy_plt_layout->plt0_got2_insn_end), + - htab->lazy_plt->plt0_got2_insn_end), (htab->elf.splt->contents - + lazy_plt_layout->plt0_got2_offset)); + + htab->lazy_plt->plt0_got2_offset)); if (htab->tlsdesc_plt) { @@ -5964,8 +5798,8 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, htab->elf.sgot->contents + htab->tlsdesc_got); memcpy (htab->elf.splt->contents + htab->tlsdesc_plt, - lazy_plt_layout->plt0_entry, - lazy_plt_layout->plt_entry_size); + htab->lazy_plt->plt0_entry, + htab->lazy_plt->plt0_entry_size); /* Add offset for pushq GOT+8(%rip), since the instruction uses 6 bytes subtract this value. */ @@ -5979,7 +5813,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, - 6), (htab->elf.splt->contents + htab->tlsdesc_plt - + lazy_plt_layout->plt0_got1_offset)); + + htab->lazy_plt->plt0_got1_offset)); /* Add offset for the PC-relative instruction accessing GOT+TDG, where TDG stands for htab->tlsdesc_got, subtracting the offset to the end of that @@ -5991,21 +5825,21 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, - htab->elf.splt->output_section->vma - htab->elf.splt->output_offset - htab->tlsdesc_plt - - lazy_plt_layout->plt0_got2_insn_end), + - htab->lazy_plt->plt0_got2_insn_end), (htab->elf.splt->contents + htab->tlsdesc_plt - + lazy_plt_layout->plt0_got2_offset)); + + htab->lazy_plt->plt0_got2_offset)); } } } if (htab->plt_got != NULL && htab->plt_got->size > 0) elf_section_data (htab->plt_got->output_section) - ->this_hdr.sh_entsize = non_lazy_plt_layout->plt_entry_size; + ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size; if (htab->plt_second != NULL && htab->plt_second->size > 0) elf_section_data (htab->plt_second->output_section) - ->this_hdr.sh_entsize = non_lazy_plt_layout->plt_entry_size; + ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size; } /* GOT is always created in setup_gnu_properties. But it may not be @@ -6182,7 +6016,7 @@ struct elf_x86_64_plt }; /* Forward declaration. */ -static const struct elf_x86_64_lazy_plt_layout elf_x86_64_nacl_plt; +static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt; /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all dynamic relocations. */ @@ -6202,12 +6036,12 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd, bfd_byte *plt_contents; long dynrelcount, relsize; arelent **dynrelbuf, *p; - const struct elf_x86_64_lazy_plt_layout *lazy_plt; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt; - const struct elf_x86_64_lazy_plt_layout *lazy_bnd_plt; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_bnd_plt; - const struct elf_x86_64_lazy_plt_layout *lazy_ibt_plt; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_ibt_plt; + const struct elf_x86_lazy_plt_layout *lazy_plt; + const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; + const struct elf_x86_lazy_plt_layout *lazy_bnd_plt; + const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_plt; + const struct elf_x86_lazy_plt_layout *lazy_ibt_plt; + const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt; asection *plt; char *names; enum elf_x86_64_plt_type plt_type; @@ -6730,9 +6564,6 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) bfd *pbfd; bfd *ebfd = NULL; elf_property *prop; - struct elf_x86_64_plt_layout *plt_layout; - const struct elf_x86_64_lazy_plt_layout *lazy_plt_layout; - const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout; features = 0; if (info->ibt) @@ -6849,12 +6680,10 @@ error_alignment: } } - plt_layout = &elf_x86_64_plt (htab); - /* Even when lazy binding is disabled by "-z now", the PLT0 entry may still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for canonical function address. */ - plt_layout->has_plt0 = 1; + htab->plt.has_plt0 = 1; if (get_elf_x86_64_backend_data (info->output_bfd)->os == is_normal) @@ -6863,79 +6692,71 @@ error_alignment: { if (ABI_64_P (dynobj)) { - elf_x86_64_lazy_plt (htab) + htab->lazy_plt = &elf_x86_64_lazy_ibt_plt; - elf_x86_64_non_lazy_plt (htab) + htab->non_lazy_plt = &elf_x86_64_non_lazy_ibt_plt; } else { - elf_x86_64_lazy_plt (htab) + htab->lazy_plt = &elf_x32_lazy_ibt_plt; - elf_x86_64_non_lazy_plt (htab) + htab->non_lazy_plt = &elf_x32_non_lazy_ibt_plt; } } else if (info->bndplt) { - elf_x86_64_lazy_plt (htab) = &elf_x86_64_lazy_bnd_plt; - elf_x86_64_non_lazy_plt (htab) = &elf_x86_64_non_lazy_bnd_plt; + htab->lazy_plt = &elf_x86_64_lazy_bnd_plt; + htab->non_lazy_plt = &elf_x86_64_non_lazy_bnd_plt; } else { - elf_x86_64_lazy_plt (htab) = &elf_x86_64_lazy_plt; - elf_x86_64_non_lazy_plt (htab) = &elf_x86_64_non_lazy_plt; + htab->lazy_plt = &elf_x86_64_lazy_plt; + htab->non_lazy_plt = &elf_x86_64_non_lazy_plt; } normal_target = TRUE; } else { - elf_x86_64_lazy_plt (htab) = &elf_x86_64_nacl_plt; - elf_x86_64_non_lazy_plt (htab) = NULL; + htab->lazy_plt = &elf_x86_64_nacl_plt; + htab->non_lazy_plt = NULL; normal_target = FALSE; } - lazy_plt_layout = elf_x86_64_lazy_plt (htab); - non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab); - pltsec = htab->elf.splt; /* If the non-lazy PLT is available, use it for all PLT entries if there are no PLT0 or no .plt section. */ - if (non_lazy_plt_layout != NULL - && (!plt_layout->has_plt0 || pltsec == NULL)) + if (htab->non_lazy_plt != NULL + && (!htab->plt.has_plt0 || pltsec == NULL)) { lazy_plt = FALSE; - plt_layout->plt_entry - = non_lazy_plt_layout->plt_entry; - plt_layout->plt_entry_size - = non_lazy_plt_layout->plt_entry_size; - plt_layout->plt_got_offset - = non_lazy_plt_layout->plt_got_offset; - plt_layout->plt_got_insn_size - = non_lazy_plt_layout->plt_got_insn_size; - plt_layout->eh_frame_plt_size - = non_lazy_plt_layout->eh_frame_plt_size; - plt_layout->eh_frame_plt - = non_lazy_plt_layout->eh_frame_plt; + htab->plt.plt_entry = htab->non_lazy_plt->plt_entry; + htab->plt.plt_entry_size = htab->non_lazy_plt->plt_entry_size; + htab->plt.plt_got_offset = htab->non_lazy_plt->plt_got_offset; + htab->plt.plt_got_insn_size + = htab->non_lazy_plt->plt_got_insn_size; + htab->plt.eh_frame_plt_size + = htab->non_lazy_plt->eh_frame_plt_size; + htab->plt.eh_frame_plt = htab->non_lazy_plt->eh_frame_plt; } else { lazy_plt = TRUE; - plt_layout->plt_entry - = lazy_plt_layout->plt_entry; - plt_layout->plt_entry_size - = lazy_plt_layout->plt_entry_size; - plt_layout->plt_got_offset - = lazy_plt_layout->plt_got_offset; - plt_layout->plt_got_insn_size - = lazy_plt_layout->plt_got_insn_size; - plt_layout->eh_frame_plt_size - = lazy_plt_layout->eh_frame_plt_size; - plt_layout->eh_frame_plt - = lazy_plt_layout->eh_frame_plt; + htab->plt.plt_entry = htab->lazy_plt->plt_entry; + htab->plt.plt_entry_size = htab->lazy_plt->plt_entry_size; + htab->plt.plt_got_offset = htab->lazy_plt->plt_got_offset; + htab->plt.plt_got_insn_size + = htab->lazy_plt->plt_got_insn_size; + htab->plt.eh_frame_plt_size + = htab->lazy_plt->eh_frame_plt_size; + htab->plt.eh_frame_plt = htab->lazy_plt->eh_frame_plt; } + /* This is unused for x86-64. */ + htab->plt.plt0_entry = NULL; + /* Return if there are no normal input files. */ if (dynobj == NULL) return pbfd; @@ -6963,7 +6784,7 @@ error_alignment: if (!_bfd_elf_create_ifunc_sections (dynobj, info)) info->callbacks->einfo (_("%F: failed to create ifunc sections\n")); - plt_alignment = bfd_log2 (plt_layout->plt_entry_size); + plt_alignment = bfd_log2 (htab->plt.plt_entry_size); if (pltsec != NULL) { @@ -6992,7 +6813,7 @@ error_alignment: | SEC_LOAD | SEC_READONLY); unsigned int non_lazy_plt_alignment - = bfd_log2 (non_lazy_plt_layout->plt_entry_size); + = bfd_log2 (htab->non_lazy_plt->plt_entry_size); sec = pltsec; if (!bfd_set_section_alignment (sec->owner, sec, @@ -7150,8 +6971,6 @@ elf_x86_64_special_sections[]= #define elf_info_to_howto elf_x86_64_info_to_howto -#define bfd_elf64_bfd_link_hash_table_create \ - elf_x86_64_link_hash_table_create #define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup #define bfd_elf64_bfd_reloc_name_lookup \ elf_x86_64_reloc_name_lookup @@ -7401,9 +7220,10 @@ static const bfd_byte elf_x86_64_nacl_eh_frame_plt[] = DW_CFA_nop, DW_CFA_nop }; -static const struct elf_x86_64_lazy_plt_layout elf_x86_64_nacl_plt = +static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt = { elf_x86_64_nacl_plt0_entry, /* plt0_entry */ + NACL_PLT_ENTRY_SIZE, /* plt0_entry_size */ elf_x86_64_nacl_plt_entry, /* plt_entry */ NACL_PLT_ENTRY_SIZE, /* plt_entry_size */ 2, /* plt0_got1_offset */ @@ -7415,6 +7235,8 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_nacl_plt = 7, /* plt_got_insn_size */ 42, /* plt_plt_insn_end */ 32, /* plt_lazy_offset */ + NULL, /* pic_plt0_entry */ + NULL, /* pic_plt_entry */ elf_x86_64_nacl_eh_frame_plt, /* eh_frame_plt */ sizeof (elf_x86_64_nacl_eh_frame_plt) /* eh_frame_plt_size */ }; @@ -7455,8 +7277,6 @@ elf32_x86_64_nacl_elf_object_p (bfd *abfd) #undef elf32_bed #define elf32_bed elf32_x86_64_nacl_bed -#define bfd_elf32_bfd_link_hash_table_create \ - elf_x86_64_link_hash_table_create #define bfd_elf32_bfd_reloc_type_lookup \ elf_x86_64_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup \ diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 1c8380d..ccd6e10 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -19,6 +19,16 @@ MA 02110-1301, USA. */ #include "elfxx-x86.h" +#include "objalloc.h" +#include "elf/i386.h" +#include "elf/x86-64.h" + +/* The name of the dynamic interpreter. This is put in the .interp + section. */ + +#define ELF32_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" +#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1" +#define ELFX32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1" /* _TLS_MODULE_BASE_ needs to be treated especially when linking executables. Rather than setting it to the beginning of the TLS @@ -217,8 +227,8 @@ _bfd_x86_elf_local_htab_eq (const void *ptr1, const void *ptr2) /* Destroy an x86 ELF linker hash table. */ -void -_bfd_x86_elf_link_hash_table_free (bfd *obfd) +static void +elf_x86_link_hash_table_free (bfd *obfd) { struct elf_x86_link_hash_table *htab = (struct elf_x86_link_hash_table *) obfd->link.hash; @@ -230,6 +240,77 @@ _bfd_x86_elf_link_hash_table_free (bfd *obfd) _bfd_elf_link_hash_table_free (obfd); } +/* Create an x86 ELF linker hash table. */ + +struct bfd_link_hash_table * +_bfd_x86_elf_link_hash_table_create (bfd *abfd) +{ + struct elf_x86_link_hash_table *ret; + const struct elf_backend_data *bed; + bfd_size_type amt = sizeof (struct elf_x86_link_hash_table); + + ret = (struct elf_x86_link_hash_table *) bfd_zmalloc (amt); + if (ret == NULL) + return NULL; + + bed = get_elf_backend_data (abfd); + if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, + _bfd_x86_elf_link_hash_newfunc, + sizeof (struct elf_x86_link_hash_entry), + bed->target_id)) + { + free (ret); + return NULL; + } + +#ifdef BFD64 + if (ABI_64_P (abfd)) + { + ret->r_info = elf64_r_info; + ret->r_sym = elf64_r_sym; + ret->pointer_r_type = R_X86_64_64; + ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER; + ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER; + ret->tls_get_addr = "__tls_get_addr"; + } + else +#endif + { + ret->r_info = elf32_r_info; + ret->r_sym = elf32_r_sym; + if (bed->elf_machine_code == EM_X86_64) + { + ret->pointer_r_type = R_X86_64_32; + ret->dynamic_interpreter = ELFX32_DYNAMIC_INTERPRETER; + ret->dynamic_interpreter_size + = sizeof ELFX32_DYNAMIC_INTERPRETER; + ret->tls_get_addr = "__tls_get_addr"; + } + else + { + ret->pointer_r_type = R_386_32; + ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER; + ret->dynamic_interpreter_size + = sizeof ELF32_DYNAMIC_INTERPRETER; + ret->tls_get_addr = "___tls_get_addr"; + } + } + + ret->loc_hash_table = htab_try_create (1024, + _bfd_x86_elf_local_htab_hash, + _bfd_x86_elf_local_htab_eq, + NULL); + ret->loc_hash_memory = objalloc_create (); + if (!ret->loc_hash_table || !ret->loc_hash_memory) + { + elf_x86_link_hash_table_free (abfd); + return NULL; + } + ret->elf.root.hash_table_free = elf_x86_link_hash_table_free; + + return &ret->elf.root; +} + /* Sort relocs into address order. */ int diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 480189b..21e16a2 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -24,9 +24,11 @@ #include "libbfd.h" #include "elf-bfd.h" #include "bfd_stdint.h" -#include "objalloc.h" #include "hashtab.h" +#define ABI_64_P(abfd) \ + (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) + /* 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 section, and instead use a dynamic relocation to point into the @@ -118,6 +120,105 @@ struct elf_x86_link_hash_entry bfd_vma tlsdesc_got; }; +struct elf_x86_lazy_plt_layout +{ + /* The first entry in an absolute lazy procedure linkage table looks + like this. */ + const bfd_byte *plt0_entry; + unsigned int plt0_entry_size; /* Size of PLT0 entry. */ + + /* Later entries in an absolute lazy procedure linkage table look + like this. */ + const bfd_byte *plt_entry; + unsigned int plt_entry_size; /* Size of each PLT entry. */ + + /* Offsets into plt0_entry that are to be replaced with GOT[1] and + GOT[2]. */ + unsigned int plt0_got1_offset; + unsigned int plt0_got2_offset; + + /* Offset of the end of the PC-relative instruction containing + plt0_got2_offset. This is for x86-64 only. */ + unsigned int plt0_got2_insn_end; + + /* Offsets into plt_entry that are to be replaced with... */ + unsigned int plt_got_offset; /* ... address of this symbol in .got. */ + unsigned int plt_reloc_offset; /* ... offset into relocation table. */ + unsigned int plt_plt_offset; /* ... offset to start of .plt. */ + + /* Length of the PC-relative instruction containing plt_got_offset. + This is used for x86-64 only. */ + unsigned int plt_got_insn_size; + + /* Offset of the end of the PC-relative jump to plt0_entry. This is + used for x86-64 only. */ + unsigned int plt_plt_insn_end; + + /* Offset into plt_entry where the initial value of the GOT entry + points. */ + unsigned int plt_lazy_offset; + + /* The first entry in a PIC lazy procedure linkage table looks like + this. This is used for i386 only. */ + const bfd_byte *pic_plt0_entry; + + /* Subsequent entries in a PIC lazy procedure linkage table look + like this. This is used for i386 only. */ + const bfd_byte *pic_plt_entry; + + /* .eh_frame covering the lazy .plt section. */ + const bfd_byte *eh_frame_plt; + unsigned int eh_frame_plt_size; +}; + +struct elf_x86_non_lazy_plt_layout +{ + /* Entries in an absolute non-lazy procedure linkage table look like + this. */ + const bfd_byte *plt_entry; + /* Entries in a PIC non-lazy procedure linkage table look like this. + This is used for i386 only. */ + const bfd_byte *pic_plt_entry; + + unsigned int plt_entry_size; /* Size of each PLT entry. */ + + /* Offsets into plt_entry that are to be replaced with... */ + unsigned int plt_got_offset; /* ... address of this symbol in .got. */ + + /* Length of the PC-relative instruction containing plt_got_offset. + This is used for x86-64 only. */ + unsigned int plt_got_insn_size; + + /* .eh_frame covering the non-lazy .plt section. */ + const bfd_byte *eh_frame_plt; + unsigned int eh_frame_plt_size; +}; + +struct elf_x86_plt_layout +{ + /* The first entry in a lazy procedure linkage table looks like this. + This is only used for i386 where absolute PLT0 and PIC PLT0 are + different. */ + const bfd_byte *plt0_entry; + /* Entries in a procedure linkage table look like this. */ + const bfd_byte *plt_entry; + unsigned int plt_entry_size; /* Size of each PLT entry. */ + + /* 1 has PLT0. */ + unsigned int has_plt0; + + /* Offsets into plt_entry that are to be replaced with... */ + unsigned int plt_got_offset; /* ... address of this symbol in .got. */ + + /* Length of the PC-relative instruction containing plt_got_offset. + This is only used for x86-64. */ + unsigned int plt_got_insn_size; + + /* .eh_frame covering the .plt section. */ + const bfd_byte *eh_frame_plt; + unsigned int eh_frame_plt_size; +}; + /* The first 3 values in tls_type of x86 ELF linker hash entry. */ #define GOT_UNKNOWN 0 #define GOT_NORMAL 1 @@ -140,6 +241,15 @@ struct elf_x86_link_hash_table asection *plt_got; asection *plt_got_eh_frame; + /* Parameters describing PLT generation, lazy or non-lazy. */ + struct elf_x86_plt_layout plt; + + /* Parameters describing lazy PLT generation. */ + const struct elf_x86_lazy_plt_layout *lazy_plt; + + /* Parameters describing non-lazy PLT generation. */ + const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; + union { bfd_signed_vma refcount; @@ -178,6 +288,14 @@ struct elf_x86_link_hash_table to read-only sections. */ bfd_boolean readonly_dynrelocs_against_ifunc; + /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. + This is used for i386 only. */ + asection *srelplt2; + + /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. This + is used for i386 only. */ + bfd_vma next_tls_desc_index; + bfd_vma (*r_info) (bfd_vma, bfd_vma); bfd_vma (*r_sym) (bfd_vma); unsigned int pointer_r_type; @@ -228,7 +346,7 @@ extern int _bfd_x86_elf_local_htab_eq extern struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -extern void _bfd_x86_elf_link_hash_table_free +extern struct bfd_link_hash_table * _bfd_x86_elf_link_hash_table_create (bfd *); extern int _bfd_x86_elf_compare_relocs @@ -260,6 +378,10 @@ extern enum elf_property_kind _bfd_x86_elf_parse_gnu_properties extern bfd_boolean _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *, bfd *, elf_property *, elf_property *); +#define bfd_elf64_bfd_link_hash_table_create \ + _bfd_x86_elf_link_hash_table_create +#define bfd_elf32_bfd_link_hash_table_create \ + _bfd_x86_elf_link_hash_table_create #define bfd_elf64_bfd_link_check_relocs \ _bfd_x86_elf_link_check_relocs #define bfd_elf32_bfd_link_check_relocs \ -- 2.7.4