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 |