| Index: bfd/elf64-x86-64.c
|
| diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
|
| index fe0db0e8dc4b82f3479e5bf43aa55dd766712c58..a29ba8a324c3adbff9fe5969b7d09d88e9c7a65b 100644
|
| --- a/bfd/elf64-x86-64.c
|
| +++ b/bfd/elf64-x86-64.c
|
| @@ -26,6 +26,7 @@
|
| #include "bfdlink.h"
|
| #include "libbfd.h"
|
| #include "elf-bfd.h"
|
| +#include "elf-nacl.h"
|
| #include "bfd_stdint.h"
|
| #include "objalloc.h"
|
| #include "hashtab.h"
|
| @@ -508,7 +509,7 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
|
| section. */
|
|
|
| #define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
|
| -#define ELF32_DYNAMIC_INTERPRETER "/lib/ld32.so.1"
|
| +#define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.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
|
| @@ -585,6 +586,70 @@ static const bfd_byte elf_x86_64_eh_frame_plt[] =
|
| DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
|
| };
|
|
|
| +/* Architecture-specific backend data for x86-64. */
|
| +
|
| +struct elf_x86_64_backend_data
|
| +{
|
| + /* 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 .plt section. */
|
| + const bfd_byte *eh_frame_plt;
|
| + unsigned int eh_frame_plt_size;
|
| +};
|
| +
|
| +#define get_elf_x86_64_backend_data(abfd) \
|
| + ((const struct elf_x86_64_backend_data *) \
|
| + get_elf_backend_data (abfd)->arch_data)
|
| +
|
| +#define GET_PLT_ENTRY_SIZE(abfd) \
|
| + get_elf_x86_64_backend_data (abfd)->plt_entry_size
|
| +
|
| +/* These are the standard parameters. */
|
| +static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
|
| + {
|
| + elf_x86_64_plt0_entry, /* plt0_entry */
|
| + elf_x86_64_plt_entry, /* plt_entry */
|
| + sizeof (elf_x86_64_plt_entry), /* plt_entry_size */
|
| + 2, /* plt0_got1_offset */
|
| + 8, /* plt0_got2_offset */
|
| + 12, /* plt0_got2_insn_end */
|
| + 2, /* plt_got_offset */
|
| + 7, /* plt_reloc_offset */
|
| + 12, /* plt_plt_offset */
|
| + 6, /* plt_got_insn_size */
|
| + PLT_ENTRY_SIZE, /* plt_plt_insn_end */
|
| + 6, /* plt_lazy_offset */
|
| + elf_x86_64_eh_frame_plt, /* eh_frame_plt */
|
| + sizeof (elf_x86_64_eh_frame_plt), /* eh_frame_plt_size */
|
| + };
|
| +
|
| +#define elf_backend_arch_data &elf_x86_64_arch_bed
|
| +
|
| /* x86-64 ELF linker hash entry. */
|
|
|
| struct elf_x86_64_link_hash_entry
|
| @@ -721,8 +786,8 @@ elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
|
| if (entry == NULL)
|
| {
|
| entry = (struct bfd_hash_entry *)
|
| - bfd_hash_allocate (table,
|
| - sizeof (struct elf_x86_64_link_hash_entry));
|
| + bfd_hash_allocate (table,
|
| + sizeof (struct elf_x86_64_link_hash_entry));
|
| if (entry == NULL)
|
| return entry;
|
| }
|
| @@ -839,7 +904,7 @@ elf_x86_64_link_hash_table_create (bfd *abfd)
|
| ret->tls_ld_got.refcount = 0;
|
| ret->sgotplt_jump_table_size = 0;
|
| ret->tls_module_base = NULL;
|
| - ret->next_jump_slot_index = 0;
|
| + ret->next_jump_slot_index = 0;
|
| ret->next_irelative_index = 0;
|
|
|
| if (ABI_64_P (abfd))
|
| @@ -905,31 +970,26 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
|
| if (htab == NULL)
|
| return FALSE;
|
|
|
| - htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
|
| + htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
|
| if (!info->shared)
|
| - htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
|
| + htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
|
|
|
| if (!htab->sdynbss
|
| || (!info->shared && !htab->srelbss))
|
| abort ();
|
|
|
| if (!info->no_ld_generated_unwind_info
|
| - && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL
|
| + && htab->plt_eh_frame == NULL
|
| && htab->elf.splt != NULL)
|
| {
|
| - flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
|
| + flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
|
| + | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
| + | SEC_LINKER_CREATED);
|
| htab->plt_eh_frame
|
| - = bfd_make_section_with_flags (dynobj, ".eh_frame",
|
| - flags | SEC_READONLY);
|
| + = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
|
| if (htab->plt_eh_frame == NULL
|
| || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3))
|
| return FALSE;
|
| -
|
| - htab->plt_eh_frame->size = sizeof (elf_x86_64_eh_frame_plt);
|
| - htab->plt_eh_frame->contents
|
| - = bfd_alloc (dynobj, htab->plt_eh_frame->size);
|
| - memcpy (htab->plt_eh_frame->contents, elf_x86_64_eh_frame_plt,
|
| - sizeof (elf_x86_64_eh_frame_plt));
|
| }
|
| return TRUE;
|
| }
|
| @@ -1009,6 +1069,14 @@ elf64_x86_64_elf_object_p (bfd *abfd)
|
| return TRUE;
|
| }
|
|
|
| +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;
|
| +}
|
| +
|
| /* Return TRUE if the TLS access code sequence support transition
|
| from R_TYPE. */
|
|
|
| @@ -1107,7 +1175,7 @@ elf_x86_64_check_tls_transition (bfd *abfd,
|
|
|
| h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
| /* Use strncmp to check __tls_get_addr since __tls_get_addr
|
| - may be versioned. */
|
| + may be versioned. */
|
| return (h != NULL
|
| && h->root.root.string != NULL
|
| && (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
|
| @@ -2007,7 +2075,7 @@ elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
| if (h != NULL)
|
| {
|
| if (r_type == R_X86_64_GOTPLT64 && h->plt.refcount > 0)
|
| - h->plt.refcount -= 1;
|
| + h->plt.refcount -= 1;
|
| if (h->got.refcount > 0)
|
| h->got.refcount -= 1;
|
| if (h->type == STT_GNU_IFUNC)
|
| @@ -2166,13 +2234,6 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
| }
|
| }
|
|
|
| - if (h->size == 0)
|
| - {
|
| - (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
|
| - h->root.root.string);
|
| - return TRUE;
|
| - }
|
| -
|
| /* We must allocate the symbol in our .dynbss section, which will
|
| become part of the .bss section of the executable. There will be
|
| an entry for this symbol in the .dynsym section. The dynamic
|
| @@ -2190,7 +2251,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
| /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
|
| to copy the initial value out of the dynamic object and into the
|
| runtime process image. */
|
| - if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
|
| + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
|
| {
|
| const struct elf_backend_data *bed;
|
| bed = get_elf_backend_data (info->output_bfd);
|
| @@ -2214,6 +2275,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
| struct elf_x86_64_link_hash_entry *eh;
|
| struct elf_dyn_relocs *p;
|
| const struct elf_backend_data *bed;
|
| + unsigned int plt_entry_size;
|
|
|
| if (h->root.type == bfd_link_hash_indirect)
|
| return TRUE;
|
| @@ -2225,6 +2287,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
| if (htab == NULL)
|
| return FALSE;
|
| bed = get_elf_backend_data (info->output_bfd);
|
| + plt_entry_size = GET_PLT_ENTRY_SIZE (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. */
|
| @@ -2232,7 +2295,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
| && h->def_regular)
|
| return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
|
| &eh->dyn_relocs,
|
| - PLT_ENTRY_SIZE,
|
| + plt_entry_size,
|
| GOT_ENTRY_SIZE);
|
| else if (htab->elf.dynamic_sections_created
|
| && h->plt.refcount > 0)
|
| @@ -2254,7 +2317,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
| /* If this is the first .plt entry, make room for the special
|
| first entry. */
|
| if (s->size == 0)
|
| - s->size += PLT_ENTRY_SIZE;
|
| + s->size += plt_entry_size;
|
|
|
| h->plt.offset = s->size;
|
|
|
| @@ -2271,7 +2334,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
| }
|
|
|
| /* Make room for this entry. */
|
| - s->size += PLT_ENTRY_SIZE;
|
| + s->size += 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 script. */
|
| @@ -2536,7 +2599,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
| /* Set the contents of the .interp section to the interpreter. */
|
| if (info->executable)
|
| {
|
| - s = bfd_get_section_by_name (dynobj, ".interp");
|
| + s = bfd_get_linker_section (dynobj, ".interp");
|
| if (s == NULL)
|
| abort ();
|
| s->size = htab->dynamic_interpreter_size;
|
| @@ -2695,9 +2758,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_ENTRY_SIZE;
|
| + htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
|
| htab->tlsdesc_plt = htab->elf.splt->size;
|
| - htab->elf.splt->size += PLT_ENTRY_SIZE;
|
| + htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
|
| }
|
| }
|
|
|
| @@ -2709,7 +2772,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
| FALSE, FALSE, FALSE);
|
|
|
| /* Don't allocate .got.plt section if there are no GOT nor PLT
|
| - entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
|
| + entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
|
| if ((got == NULL
|
| || !got->ref_regular_nonweak)
|
| && (htab->elf.sgotplt->size
|
| @@ -2725,6 +2788,17 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
| htab->elf.sgotplt->size = 0;
|
| }
|
|
|
| + if (htab->plt_eh_frame != NULL
|
| + && htab->elf.splt != NULL
|
| + && htab->elf.splt->size != 0
|
| + && !bfd_is_abs_section (htab->elf.splt->output_section)
|
| + && _bfd_elf_eh_frame_present (info))
|
| + {
|
| + const struct elf_x86_64_backend_data *arch_data
|
| + = (const struct elf_x86_64_backend_data *) bed->arch_data;
|
| + htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
|
| + }
|
| +
|
| /* We now have determined the sizes of the various dynamic sections.
|
| Allocate memory for them. */
|
| relocs = FALSE;
|
| @@ -2738,6 +2812,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
| || s == htab->elf.sgotplt
|
| || s == htab->elf.iplt
|
| || s == htab->elf.igotplt
|
| + || s == htab->plt_eh_frame
|
| || s == htab->sdynbss)
|
| {
|
| /* Strip this section if we don't need it; see the
|
| @@ -2789,11 +2864,16 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
| }
|
|
|
| if (htab->plt_eh_frame != NULL
|
| - && htab->elf.splt != NULL
|
| - && htab->elf.splt->size != 0
|
| - && (htab->elf.splt->flags & SEC_EXCLUDE) == 0)
|
| - bfd_put_32 (dynobj, htab->elf.splt->size,
|
| - htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
|
| + && htab->plt_eh_frame->contents != NULL)
|
| + {
|
| + const struct elf_x86_64_backend_data *arch_data
|
| + = (const struct elf_x86_64_backend_data *) bed->arch_data;
|
| +
|
| + memcpy (htab->plt_eh_frame->contents,
|
| + arch_data->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);
|
| + }
|
|
|
| if (htab->elf.dynamic_sections_created)
|
| {
|
| @@ -2835,7 +2915,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
| /* 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,
|
| + elf_link_hash_traverse (&htab->elf,
|
| elf_x86_64_readonly_dynrelocs,
|
| info);
|
|
|
| @@ -2988,6 +3068,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| bfd_vma *local_tlsdesc_gotents;
|
| Elf_Internal_Rela *rel;
|
| Elf_Internal_Rela *relend;
|
| + const unsigned int plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
|
|
|
| BFD_ASSERT (is_x86_64_elf (input_bfd));
|
|
|
| @@ -3030,7 +3111,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| }
|
|
|
| if (r_type != (int) R_X86_64_32
|
| - || ABI_64_P (output_bfd))
|
| + || ABI_64_P (output_bfd))
|
| howto = x86_64_elf_howto_table + r_type;
|
| else
|
| howto = (x86_64_elf_howto_table
|
| @@ -3057,7 +3138,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| if (h == NULL)
|
| abort ();
|
|
|
| - /* Set STT_GNU_IFUNC symbol value. */
|
| + /* Set STT_GNU_IFUNC symbol value. */
|
| h->root.u.def.value = sym->st_value;
|
| h->root.u.def.section = sec;
|
| }
|
| @@ -3072,9 +3153,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| unresolved_reloc, warned);
|
| }
|
|
|
| - if (sec != NULL && elf_discarded_section (sec))
|
| + if (sec != NULL && discarded_section (sec))
|
| RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
|
| - rel, relend, howto, contents);
|
| + rel, 1, relend, howto, 0, contents);
|
|
|
| if (info->relocatable)
|
| continue;
|
| @@ -3133,7 +3214,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| if (ABI_64_P (output_bfd))
|
| goto do_relocation;
|
| /* FALLTHROUGH */
|
| - case R_X86_64_64:
|
| + case R_X86_64_64:
|
| if (rel->r_addend != 0)
|
| {
|
| if (h->root.root.string)
|
| @@ -3156,7 +3237,6 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| {
|
| Elf_Internal_Rela outrel;
|
| asection *sreloc;
|
| - bfd_boolean relocate;
|
|
|
| /* Need a dynamic relocation to get the real function
|
| address. */
|
| @@ -3176,15 +3256,15 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| || info->executable)
|
| {
|
| /* This symbol is resolved locally. */
|
| - outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
| - outrel.r_addend = relocation;
|
| - relocate = FALSE;
|
| + 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 = htab->r_info (h->dynindx, r_type);
|
| outrel.r_addend = 0;
|
| - relocate = FALSE;
|
| }
|
|
|
| sreloc = htab->elf.irelifunc;
|
| @@ -3195,8 +3275,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| we need to include the symbol value so that it
|
| becomes an addend for the dynamic reloc. For an
|
| internal symbol, we have updated addend. */
|
| - if (! relocate)
|
| - continue;
|
| + continue;
|
| }
|
| /* FALLTHROUGH */
|
| case R_X86_64_PC32:
|
| @@ -3220,13 +3299,13 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|
|
| if (htab->elf.splt != NULL)
|
| {
|
| - plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
|
| + plt_index = h->plt.offset / plt_entry_size - 1;
|
| off = (plt_index + 3) * GOT_ENTRY_SIZE;
|
| base_got = htab->elf.sgotplt;
|
| }
|
| else
|
| {
|
| - plt_index = h->plt.offset / PLT_ENTRY_SIZE;
|
| + plt_index = h->plt.offset / plt_entry_size;
|
| off = plt_index * GOT_ENTRY_SIZE;
|
| base_got = htab->elf.igotplt;
|
| }
|
| @@ -3235,9 +3314,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| || h->forced_local
|
| || info->symbolic)
|
| {
|
| - /* This references the local defitionion. We must
|
| + /* This references the local defitionion. We must
|
| initialize this entry in the global offset table.
|
| - Since the offset must always be a multiple of 8,
|
| + Since the offset must always be a multiple of 8,
|
| we use the least significant bit to record
|
| whether we have initialized it already.
|
|
|
| @@ -3293,14 +3372,14 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|
|
| off = h->got.offset;
|
| if (h->needs_plt
|
| - && h->plt.offset != (bfd_vma)-1
|
| + && h->plt.offset != (bfd_vma)-1
|
| && off == (bfd_vma)-1)
|
| {
|
| /* We can't use h->got.offset here to save
|
| state, or even just remember the offset, as
|
| finish_dynamic_symbol would use that as offset into
|
| .got. */
|
| - bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
|
| + bfd_vma plt_index = h->plt.offset / plt_entry_size - 1;
|
| off = (plt_index + 3) * GOT_ENTRY_SIZE;
|
| base_got = htab->elf.sgotplt;
|
| }
|
| @@ -3331,7 +3410,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| bfd_put_64 (output_bfd, relocation,
|
| base_got->contents + off);
|
| /* Note that this is harmless for the GOTPLT64 case,
|
| - as -1 | 1 still is -1. */
|
| + as -1 | 1 still is -1. */
|
| h->got.offset |= 1;
|
| }
|
| }
|
| @@ -3396,8 +3475,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| /* Check to make sure it isn't a protected function symbol
|
| for shared library since it may not be local when used
|
| as function address. */
|
| - if (info->shared
|
| + if (!info->executable
|
| && h
|
| + && !SYMBOLIC_BIND (info, h)
|
| && h->def_regular
|
| && h->type == STT_FUNC
|
| && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
|
| @@ -3429,7 +3509,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| case R_X86_64_PLTOFF64:
|
| /* Relocation is PLT entry relative to GOT. For local
|
| symbols it's the symbol itself relative to GOT. */
|
| - if (h != NULL
|
| + if (h != NULL
|
| /* See PLT32 handling. */
|
| && h->plt.offset != (bfd_vma) -1
|
| && htab->elf.splt != NULL)
|
| @@ -3472,7 +3552,6 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| 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)
|
| @@ -3612,6 +3691,36 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| outrel.r_info = htab->r_info (0,
|
| R_X86_64_RELATIVE64);
|
| outrel.r_addend = relocation + rel->r_addend;
|
| + /* Check addend overflow. */
|
| + if ((outrel.r_addend & 0x80000000)
|
| + != (rel->r_addend & 0x80000000))
|
| + {
|
| + const char *name;
|
| + int addend = rel->r_addend;
|
| + if (h && h->root.root.string)
|
| + name = h->root.root.string;
|
| + else
|
| + name = bfd_elf_sym_name (input_bfd, symtab_hdr,
|
| + sym, NULL);
|
| + if (addend < 0)
|
| + (*_bfd_error_handler)
|
| + (_("%B: addend -0x%x in relocation %s against "
|
| + "symbol `%s' at 0x%lx in section `%A' is "
|
| + "out of range"),
|
| + input_bfd, input_section, addend,
|
| + x86_64_elf_howto_table[r_type].name,
|
| + name, (unsigned long) rel->r_offset);
|
| + else
|
| + (*_bfd_error_handler)
|
| + (_("%B: addend 0x%x in relocation %s against "
|
| + "symbol `%s' at 0x%lx in section `%A' is "
|
| + "out of range"),
|
| + input_bfd, input_section, addend,
|
| + x86_64_elf_howto_table[r_type].name,
|
| + name, (unsigned long) rel->r_offset);
|
| + bfd_set_error (bfd_error_bad_value);
|
| + return FALSE;
|
| + }
|
| }
|
| else
|
| {
|
| @@ -4101,13 +4210,16 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
| && h->def_dynamic)
|
| && _bfd_elf_section_offset (output_bfd, info, input_section,
|
| rel->r_offset) != (bfd_vma) -1)
|
| - (*_bfd_error_handler)
|
| - (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
|
| - input_bfd,
|
| - input_section,
|
| - (long) rel->r_offset,
|
| - howto->name,
|
| - h->root.root.string);
|
| + {
|
| + (*_bfd_error_handler)
|
| + (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
|
| + input_bfd,
|
| + input_section,
|
| + (long) rel->r_offset,
|
| + howto->name,
|
| + h->root.root.string);
|
| + return FALSE;
|
| + }
|
|
|
| do_relocation:
|
| r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
| @@ -4161,9 +4273,11 @@ static bfd_boolean
|
| elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
| struct bfd_link_info *info,
|
| struct elf_link_hash_entry *h,
|
| - Elf_Internal_Sym *sym)
|
| + Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
|
| {
|
| struct elf_x86_64_link_hash_table *htab;
|
| + const struct elf_x86_64_backend_data *const abed
|
| + = get_elf_x86_64_backend_data (output_bfd);
|
|
|
| htab = elf_x86_64_hash_table (info);
|
| if (htab == NULL)
|
| @@ -4217,39 +4331,38 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
|
|
| if (plt == htab->elf.splt)
|
| {
|
| - got_offset = h->plt.offset / PLT_ENTRY_SIZE - 1;
|
| + got_offset = h->plt.offset / abed->plt_entry_size - 1;
|
| got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
|
| }
|
| else
|
| {
|
| - got_offset = h->plt.offset / PLT_ENTRY_SIZE;
|
| + got_offset = h->plt.offset / abed->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, elf_x86_64_plt_entry,
|
| - PLT_ENTRY_SIZE);
|
| -
|
| - /* Insert the relocation positions of the plt section. The magic
|
| - numbers at the end of the statements are the positions of the
|
| - relocations in the plt section. */
|
| - /* Put offset for jmp *name@GOTPCREL(%rip), since the
|
| - instruction uses 6 bytes, subtract this value. */
|
| + memcpy (plt->contents + h->plt.offset, abed->plt_entry,
|
| + abed->plt_entry_size);
|
| +
|
| + /* Insert the relocation positions of the plt section. */
|
| +
|
| + /* Put offset the PC-relative instruction referring to the GOT entry,
|
| + subtracting the size of that instruction. */
|
| bfd_put_32 (output_bfd,
|
| - (gotplt->output_section->vma
|
| - + gotplt->output_offset
|
| - + got_offset
|
| - - plt->output_section->vma
|
| - - plt->output_offset
|
| - - h->plt.offset
|
| - - 6),
|
| - plt->contents + h->plt.offset + 2);
|
| + (gotplt->output_section->vma
|
| + + gotplt->output_offset
|
| + + got_offset
|
| + - plt->output_section->vma
|
| + - plt->output_offset
|
| + - h->plt.offset
|
| + - abed->plt_got_insn_size),
|
| + plt->contents + h->plt.offset + abed->plt_got_offset);
|
|
|
| /* Fill in the entry in the global offset table, initially this
|
| - points to the pushq instruction in the PLT which is at offset 6. */
|
| + points to the second part of the PLT entry. */
|
| bfd_put_64 (output_bfd, (plt->output_section->vma
|
| + plt->output_offset
|
| - + h->plt.offset + 6),
|
| + + h->plt.offset + abed->plt_lazy_offset),
|
| gotplt->contents + got_offset);
|
|
|
| /* Fill in the entry in the .rela.plt section. */
|
| @@ -4283,10 +4396,10 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
| {
|
| /* Put relocation index. */
|
| bfd_put_32 (output_bfd, plt_index,
|
| - plt->contents + h->plt.offset + 7);
|
| + plt->contents + h->plt.offset + abed->plt_reloc_offset);
|
| /* Put offset for jmp .PLT0. */
|
| - bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
|
| - plt->contents + h->plt.offset + 12);
|
| + bfd_put_32 (output_bfd, - (h->plt.offset + abed->plt_plt_insn_end),
|
| + plt->contents + h->plt.offset + abed->plt_plt_offset);
|
| }
|
|
|
| bed = get_elf_backend_data (output_bfd);
|
| @@ -4399,13 +4512,6 @@ do_glob_dat:
|
| elf_append_rela (output_bfd, htab->srelbss, &rela);
|
| }
|
|
|
| - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
|
| - be NULL for local symbols. */
|
| - if (sym != NULL
|
| - && (strcmp (h->root.root.string, "_DYNAMIC") == 0
|
| - || h == htab->elf.hgot))
|
| - sym->st_shndx = SHN_ABS;
|
| -
|
| return TRUE;
|
| }
|
|
|
| @@ -4418,7 +4524,7 @@ 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;
|
| + = (struct bfd_link_info *) inf;
|
|
|
| return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
|
| info, h, NULL);
|
| @@ -4433,6 +4539,7 @@ elf_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
|
| switch ((int) ELF32_R_TYPE (rela->r_info))
|
| {
|
| case R_X86_64_RELATIVE:
|
| + case R_X86_64_RELATIVE64:
|
| return reloc_class_relative;
|
| case R_X86_64_JUMP_SLOT:
|
| return reloc_class_plt;
|
| @@ -4452,13 +4559,15 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| struct elf_x86_64_link_hash_table *htab;
|
| bfd *dynobj;
|
| asection *sdyn;
|
| + const struct elf_x86_64_backend_data *const abed
|
| + = get_elf_x86_64_backend_data (output_bfd);
|
|
|
| htab = elf_x86_64_hash_table (info);
|
| if (htab == NULL)
|
| return FALSE;
|
|
|
| dynobj = htab->elf.dynobj;
|
| - sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
|
| + sdyn = bfd_get_linker_section (dynobj, ".dynamic");
|
|
|
| if (htab->elf.dynamic_sections_created)
|
| {
|
| @@ -4534,8 +4643,8 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| if (htab->elf.splt && htab->elf.splt->size > 0)
|
| {
|
| /* Fill in the first entry in the procedure linkage table. */
|
| - memcpy (htab->elf.splt->contents, elf_x86_64_plt0_entry,
|
| - PLT_ENTRY_SIZE);
|
| + memcpy (htab->elf.splt->contents,
|
| + abed->plt0_entry, abed->plt_entry_size);
|
| /* Add offset for pushq GOT+8(%rip), since the instruction
|
| uses 6 bytes subtract this value. */
|
| bfd_put_32 (output_bfd,
|
| @@ -4545,20 +4654,20 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| - htab->elf.splt->output_section->vma
|
| - htab->elf.splt->output_offset
|
| - 6),
|
| - htab->elf.splt->contents + 2);
|
| - /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to
|
| - the end of the instruction. */
|
| + htab->elf.splt->contents + abed->plt0_got1_offset);
|
| + /* Add offset for the PC-relative instruction accessing GOT+16,
|
| + subtracting the offset to the end of that instruction. */
|
| bfd_put_32 (output_bfd,
|
| (htab->elf.sgotplt->output_section->vma
|
| + htab->elf.sgotplt->output_offset
|
| + 16
|
| - htab->elf.splt->output_section->vma
|
| - htab->elf.splt->output_offset
|
| - - 12),
|
| - htab->elf.splt->contents + 8);
|
| + - abed->plt0_got2_insn_end),
|
| + htab->elf.splt->contents + abed->plt0_got2_offset);
|
|
|
| - elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize =
|
| - PLT_ENTRY_SIZE;
|
| + elf_section_data (htab->elf.splt->output_section)
|
| + ->this_hdr.sh_entsize = abed->plt_entry_size;
|
|
|
| if (htab->tlsdesc_plt)
|
| {
|
| @@ -4566,8 +4675,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| htab->elf.sgot->contents + htab->tlsdesc_got);
|
|
|
| memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
|
| - elf_x86_64_plt0_entry,
|
| - PLT_ENTRY_SIZE);
|
| + abed->plt0_entry, abed->plt_entry_size);
|
|
|
| /* Add offset for pushq GOT+8(%rip), since the
|
| instruction uses 6 bytes subtract this value. */
|
| @@ -4579,10 +4687,11 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| - htab->elf.splt->output_offset
|
| - htab->tlsdesc_plt
|
| - 6),
|
| - htab->elf.splt->contents + htab->tlsdesc_plt + 2);
|
| - /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for
|
| - htab->tlsdesc_got. The 12 is the offset to the end of
|
| - the instruction. */
|
| + htab->elf.splt->contents
|
| + + htab->tlsdesc_plt + abed->plt0_got1_offset);
|
| + /* Add offset for the PC-relative instruction accessing GOT+TDG,
|
| + where TGD stands for htab->tlsdesc_got, subtracting the offset
|
| + to the end of that instruction. */
|
| bfd_put_32 (output_bfd,
|
| (htab->elf.sgot->output_section->vma
|
| + htab->elf.sgot->output_offset
|
| @@ -4590,8 +4699,9 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| - htab->elf.splt->output_section->vma
|
| - htab->elf.splt->output_offset
|
| - htab->tlsdesc_plt
|
| - - 12),
|
| - htab->elf.splt->contents + htab->tlsdesc_plt + 8);
|
| + - abed->plt0_got2_insn_end),
|
| + htab->elf.splt->contents
|
| + + htab->tlsdesc_plt + abed->plt0_got2_offset);
|
| }
|
| }
|
| }
|
| @@ -4626,7 +4736,8 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| }
|
|
|
| /* Adjust .eh_frame for .plt section. */
|
| - if (htab->plt_eh_frame != NULL)
|
| + if (htab->plt_eh_frame != NULL
|
| + && htab->plt_eh_frame->contents != NULL)
|
| {
|
| if (htab->elf.splt != NULL
|
| && htab->elf.splt->size != 0
|
| @@ -4642,8 +4753,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
| htab->plt_eh_frame->contents
|
| + PLT_FDE_START_OFFSET);
|
| }
|
| - if (htab->plt_eh_frame->sec_info_type
|
| - == ELF_INFO_TYPE_EH_FRAME)
|
| + if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
|
| {
|
| if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
|
| htab->plt_eh_frame,
|
| @@ -4671,7 +4781,7 @@ static bfd_vma
|
| 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;
|
| + return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
|
| }
|
|
|
| /* Handle an x86-64 specific section when reading an object file. This
|
| @@ -5024,6 +5134,189 @@ static const struct bfd_elf_special_section
|
|
|
| #include "elf64-target.h"
|
|
|
| +/* Native Client support. */
|
| +
|
| +#undef TARGET_LITTLE_SYM
|
| +#define TARGET_LITTLE_SYM bfd_elf64_x86_64_nacl_vec
|
| +#undef TARGET_LITTLE_NAME
|
| +#define TARGET_LITTLE_NAME "elf64-x86-64-nacl"
|
| +#undef elf64_bed
|
| +#define elf64_bed elf64_x86_64_nacl_bed
|
| +
|
| +#undef ELF_MAXPAGESIZE
|
| +#undef ELF_MINPAGESIZE
|
| +#undef ELF_COMMONPAGESIZE
|
| +#define ELF_MAXPAGESIZE 0x10000
|
| +#define ELF_MINPAGESIZE 0x10000
|
| +#define ELF_COMMONPAGESIZE 0x10000
|
| +
|
| +/* Restore defaults. */
|
| +#undef ELF_OSABI
|
| +#undef elf_backend_static_tls_alignment
|
| +#undef elf_backend_want_plt_sym
|
| +#define elf_backend_want_plt_sym 0
|
| +
|
| +/* NaCl uses substantially different PLT entries for the same effects. */
|
| +
|
| +#undef elf_backend_plt_alignment
|
| +#define elf_backend_plt_alignment 5
|
| +#define NACL_PLT_ENTRY_SIZE 64
|
| +#define NACLMASK 0xe0 /* 32-byte alignment mask. */
|
| +
|
| +static const bfd_byte elf_x86_64_nacl_plt0_entry[NACL_PLT_ENTRY_SIZE] =
|
| + {
|
| + 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
|
| + 0x4c, 0x8b, 0x1d, 16, 0, 0, 0, /* mov GOT+16(%rip), %r11 */
|
| + 0x41, 0x83, 0xe3, NACLMASK, /* and $-32, %r11d */
|
| + 0x4d, 0x01, 0xfb, /* add %r15, %r11 */
|
| + 0x41, 0xff, 0xe3, /* jmpq *%r11 */
|
| +
|
| + /* 9-byte nop sequence to pad out to the next 32-byte boundary. */
|
| + 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopl %cs:0x0(%rax,%rax,1) */
|
| +
|
| + /* 32 bytes of nop to pad out to the standard size. */
|
| + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
|
| + 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
|
| + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
|
| + 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
|
| + 0x66, /* excess data32 prefix */
|
| + 0x90 /* nop */
|
| + };
|
| +
|
| +static const bfd_byte elf_x86_64_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
|
| + {
|
| + 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, /* mov name@GOTPCREL(%rip),%r11 */
|
| + 0x41, 0x83, 0xe3, NACLMASK, /* and $-32, %r11d */
|
| + 0x4d, 0x01, 0xfb, /* add %r15, %r11 */
|
| + 0x41, 0xff, 0xe3, /* jmpq *%r11 */
|
| +
|
| + /* 15-byte nop sequence to pad out to the next 32-byte boundary. */
|
| + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
|
| + 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
|
| +
|
| + /* Lazy GOT entries point here (32-byte aligned). */
|
| + 0x68, /* pushq immediate */
|
| + 0, 0, 0, 0, /* replaced with index into relocation table. */
|
| + 0xe9, /* jmp relative */
|
| + 0, 0, 0, 0, /* replaced with offset to start of .plt0. */
|
| +
|
| + /* 22 bytes of nop to pad out to the standard size. */
|
| + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
|
| + 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
|
| + 0x0f, 0x1f, 0x80, 0, 0, 0, 0, /* nopl 0x0(%rax) */
|
| + };
|
| +
|
| +/* .eh_frame covering the .plt section. */
|
| +
|
| +static const bfd_byte elf_x86_64_nacl_eh_frame_plt[] =
|
| + {
|
| +#if (PLT_CIE_LENGTH != 20 \
|
| + || PLT_FDE_LENGTH != 36 \
|
| + || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
|
| + || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
|
| +# error "Need elf_x86_64_backend_data parameters for eh_frame_plt offsets!"
|
| +#endif
|
| + PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
|
| + 0, 0, 0, 0, /* CIE ID */
|
| + 1, /* CIE version */
|
| + 'z', 'R', 0, /* Augmentation string */
|
| + 1, /* Code alignment factor */
|
| + 0x78, /* Data alignment factor */
|
| + 16, /* Return address column */
|
| + 1, /* Augmentation size */
|
| + DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
|
| + DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
|
| + DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
|
| + DW_CFA_nop, DW_CFA_nop,
|
| +
|
| + PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
|
| + PLT_CIE_LENGTH + 8, 0, 0, 0,/* CIE pointer */
|
| + 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
|
| + 0, 0, 0, 0, /* .plt size goes here */
|
| + 0, /* Augmentation size */
|
| + DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
|
| + DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
|
| + DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
|
| + DW_CFA_advance_loc + 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */
|
| + DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
|
| + 13, /* Block length */
|
| + DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
|
| + DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
|
| + DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
|
| + DW_OP_lit3, DW_OP_shl, DW_OP_plus,
|
| + DW_CFA_nop, DW_CFA_nop
|
| + };
|
| +
|
| +static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
|
| + {
|
| + elf_x86_64_nacl_plt0_entry, /* plt0_entry */
|
| + elf_x86_64_nacl_plt_entry, /* plt_entry */
|
| + NACL_PLT_ENTRY_SIZE, /* plt_entry_size */
|
| + 2, /* plt0_got1_offset */
|
| + 9, /* plt0_got2_offset */
|
| + 13, /* plt0_got2_insn_end */
|
| + 3, /* plt_got_offset */
|
| + 33, /* plt_reloc_offset */
|
| + 38, /* plt_plt_offset */
|
| + 7, /* plt_got_insn_size */
|
| + 42, /* plt_plt_insn_end */
|
| + 32, /* plt_lazy_offset */
|
| + elf_x86_64_nacl_eh_frame_plt, /* eh_frame_plt */
|
| + sizeof (elf_x86_64_nacl_eh_frame_plt), /* eh_frame_plt_size */
|
| + };
|
| +
|
| +#undef elf_backend_arch_data
|
| +#define elf_backend_arch_data &elf_x86_64_nacl_arch_bed
|
| +
|
| +#undef elf_backend_modify_segment_map
|
| +#define elf_backend_modify_segment_map nacl_modify_segment_map
|
| +#undef elf_backend_modify_program_headers
|
| +#define elf_backend_modify_program_headers nacl_modify_program_headers
|
| +
|
| +#include "elf64-target.h"
|
| +
|
| +/* Native Client x32 support. */
|
| +
|
| +#undef TARGET_LITTLE_SYM
|
| +#define TARGET_LITTLE_SYM bfd_elf32_x86_64_nacl_vec
|
| +#undef TARGET_LITTLE_NAME
|
| +#define TARGET_LITTLE_NAME "elf32-x86-64-nacl"
|
| +#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_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_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"
|
| +
|
| +/* Restore defaults. */
|
| +#undef elf_backend_object_p
|
| +#define elf_backend_object_p elf64_x86_64_elf_object_p
|
| +#undef elf_backend_bfd_from_remote_memory
|
| +#undef elf_backend_size_info
|
| +#undef elf_backend_modify_segment_map
|
| +#undef elf_backend_modify_program_headers
|
| +
|
| /* Intel L1OM support. */
|
|
|
| static bfd_boolean
|
| @@ -5052,10 +5345,17 @@ elf64_l1om_elf_object_p (bfd *abfd)
|
| #undef elf_backend_object_p
|
| #define elf_backend_object_p elf64_l1om_elf_object_p
|
|
|
| -#undef elf_backend_static_tls_alignment
|
| -
|
| -#undef elf_backend_want_plt_sym
|
| -#define elf_backend_want_plt_sym 0
|
| +/* Restore defaults. */
|
| +#undef ELF_MAXPAGESIZE
|
| +#undef ELF_MINPAGESIZE
|
| +#undef ELF_COMMONPAGESIZE
|
| +#define ELF_MAXPAGESIZE 0x200000
|
| +#define ELF_MINPAGESIZE 0x1000
|
| +#define ELF_COMMONPAGESIZE 0x1000
|
| +#undef elf_backend_plt_alignment
|
| +#define elf_backend_plt_alignment 4
|
| +#undef elf_backend_arch_data
|
| +#define elf_backend_arch_data &elf_x86_64_arch_bed
|
|
|
| #include "elf64-target.h"
|
|
|
| @@ -5126,18 +5426,11 @@ elf64_k1om_elf_object_p (bfd *abfd)
|
|
|
| /* 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 elf32_bed
|
|
|
| #undef ELF_ARCH
|
| #define ELF_ARCH bfd_arch_i386
|
| @@ -5145,17 +5438,6 @@ elf32_x86_64_elf_object_p (bfd *abfd)
|
| #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_object_p
|
|
|