Line 27... |
Line 27... |
#include "libbfd.h"
|
#include "libbfd.h"
|
#include "elf-bfd.h"
|
#include "elf-bfd.h"
|
#include "bfd_stdint.h"
|
#include "bfd_stdint.h"
|
#include "objalloc.h"
|
#include "objalloc.h"
|
#include "hashtab.h"
|
#include "hashtab.h"
|
|
#include "dwarf2.h"
|
|
#include "libiberty.h"
|
|
|
#include "elf/x86-64.h"
|
#include "elf/x86-64.h"
|
|
|
|
#ifdef CORE_HEADER
|
|
#include <stdarg.h>
|
|
#include CORE_HEADER
|
|
#endif
|
|
|
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
|
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
|
#define MINUS_ONE (~ (bfd_vma) 0)
|
#define MINUS_ONE (~ (bfd_vma) 0)
|
|
|
/* Since both 32-bit and 64-bit x86-64 encode relocation type in the
|
/* Since both 32-bit and 64-bit x86-64 encode relocation type in the
|
identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
|
identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
|
Line 155... |
Line 162... |
"R_X86_64_TLSDESC",
|
"R_X86_64_TLSDESC",
|
FALSE, MINUS_ONE, MINUS_ONE, FALSE),
|
FALSE, MINUS_ONE, MINUS_ONE, FALSE),
|
HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
|
HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
|
bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
|
bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
|
MINUS_ONE, FALSE),
|
MINUS_ONE, FALSE),
|
|
HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
|
|
bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE,
|
|
MINUS_ONE, FALSE),
|
|
|
/* We have a gap in the reloc numbers here.
|
/* We have a gap in the reloc numbers here.
|
R_X86_64_standard counts the number up to this point, and
|
R_X86_64_standard counts the number up to this point, and
|
R_X86_64_vt_offset is the value to subtract from a reloc type of
|
R_X86_64_vt_offset is the value to subtract from a reloc type of
|
R_X86_64_GNU_VT* to form an index into this table. */
|
R_X86_64_GNU_VT* to form an index into this table. */
|
Line 170... |
Line 180... |
NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
|
NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
|
|
|
/* GNU extension to record C++ vtable member usage. */
|
/* GNU extension to record C++ vtable member usage. */
|
HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
|
HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
|
_bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
|
_bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
|
|
FALSE),
|
|
|
|
/* Use complain_overflow_bitfield on R_X86_64_32 for x32. */
|
|
HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
|
|
bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
|
FALSE)
|
FALSE)
|
};
|
};
|
|
|
#define IS_X86_64_PCREL_TYPE(TYPE) \
|
#define IS_X86_64_PCREL_TYPE(TYPE) \
|
( ((TYPE) == R_X86_64_PC8) \
|
( ((TYPE) == R_X86_64_PC8) \
|
Line 233... |
Line 248... |
static reloc_howto_type *
|
static reloc_howto_type *
|
elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
|
elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
|
{
|
{
|
unsigned i;
|
unsigned i;
|
|
|
if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
|
if (r_type == (unsigned int) R_X86_64_32)
|
|
{
|
|
if (ABI_64_P (abfd))
|
|
i = r_type;
|
|
else
|
|
i = ARRAY_SIZE (x86_64_elf_howto_table) - 1;
|
|
}
|
|
else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
|
|| r_type >= (unsigned int) R_X86_64_max)
|
|| r_type >= (unsigned int) R_X86_64_max)
|
{
|
{
|
if (r_type >= (unsigned int) R_X86_64_standard)
|
if (r_type >= (unsigned int) R_X86_64_standard)
|
{
|
{
|
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
|
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
|
Line 268... |
Line 290... |
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static reloc_howto_type *
|
static reloc_howto_type *
|
elf_x86_64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
elf_x86_64_reloc_name_lookup (bfd *abfd,
|
const char *r_name)
|
const char *r_name)
|
{
|
{
|
unsigned int i;
|
unsigned int i;
|
|
|
for (i = 0;
|
if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0)
|
i < (sizeof (x86_64_elf_howto_table)
|
{
|
/ sizeof (x86_64_elf_howto_table[0]));
|
/* Get x32 R_X86_64_32. */
|
i++)
|
reloc_howto_type *reloc
|
|
= &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1];
|
|
BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32);
|
|
return reloc;
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++)
|
if (x86_64_elf_howto_table[i].name != NULL
|
if (x86_64_elf_howto_table[i].name != NULL
|
&& strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
|
&& strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
|
return &x86_64_elf_howto_table[i];
|
return &x86_64_elf_howto_table[i];
|
|
|
return NULL;
|
return NULL;
|
Line 309... |
Line 337... |
switch (note->descsz)
|
switch (note->descsz)
|
{
|
{
|
default:
|
default:
|
return FALSE;
|
return FALSE;
|
|
|
|
case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */
|
|
/* pr_cursig */
|
|
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
|
|
|
|
/* pr_pid */
|
|
elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
|
|
|
|
/* pr_reg */
|
|
offset = 72;
|
|
size = 216;
|
|
|
|
break;
|
|
|
case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
|
case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
|
/* pr_cursig */
|
/* pr_cursig */
|
elf_tdata (abfd)->core_signal
|
elf_tdata (abfd)->core_signal
|
= bfd_get_16 (abfd, note->descdata + 12);
|
= bfd_get_16 (abfd, note->descdata + 12);
|
|
|
Line 338... |
Line 379... |
switch (note->descsz)
|
switch (note->descsz)
|
{
|
{
|
default:
|
default:
|
return FALSE;
|
return FALSE;
|
|
|
|
case 124: /* sizeof(struct elf_prpsinfo) on Linux/x32 */
|
|
elf_tdata (abfd)->core_pid
|
|
= bfd_get_32 (abfd, note->descdata + 12);
|
|
elf_tdata (abfd)->core_program
|
|
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
|
elf_tdata (abfd)->core_command
|
|
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
|
|
break;
|
|
|
case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
|
case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
|
elf_tdata (abfd)->core_pid
|
elf_tdata (abfd)->core_pid
|
= bfd_get_32 (abfd, note->descdata + 24);
|
= bfd_get_32 (abfd, note->descdata + 24);
|
elf_tdata (abfd)->core_program
|
elf_tdata (abfd)->core_program
|
= _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
|
= _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
|
Line 361... |
Line 411... |
command[n - 1] = '\0';
|
command[n - 1] = '\0';
|
}
|
}
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
|
#ifdef CORE_HEADER
|
|
static char *
|
|
elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
|
|
int note_type, ...)
|
|
{
|
|
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
|
const void *p;
|
|
int size;
|
|
va_list ap;
|
|
const char *fname, *psargs;
|
|
long pid;
|
|
int cursig;
|
|
const void *gregs;
|
|
|
|
switch (note_type)
|
|
{
|
|
default:
|
|
return NULL;
|
|
|
|
case NT_PRPSINFO:
|
|
va_start (ap, note_type);
|
|
fname = va_arg (ap, const char *);
|
|
psargs = va_arg (ap, const char *);
|
|
va_end (ap);
|
|
|
|
if (bed->s->elfclass == ELFCLASS32)
|
|
{
|
|
prpsinfo32_t data;
|
|
memset (&data, 0, sizeof (data));
|
|
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
|
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
|
p = (const void *) &data;
|
|
size = sizeof (data);
|
|
}
|
|
else
|
|
{
|
|
prpsinfo_t data;
|
|
memset (&data, 0, sizeof (data));
|
|
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
|
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
|
p = (const void *) &data;
|
|
size = sizeof (data);
|
|
}
|
|
break;
|
|
|
|
case NT_PRSTATUS:
|
|
va_start (ap, note_type);
|
|
pid = va_arg (ap, long);
|
|
cursig = va_arg (ap, int);
|
|
gregs = va_arg (ap, const void *);
|
|
va_end (ap);
|
|
|
|
if (bed->s->elfclass == ELFCLASS32)
|
|
{
|
|
if (bed->elf_machine_code == EM_X86_64)
|
|
{
|
|
prstatusx32_t prstat;
|
|
memset (&prstat, 0, sizeof (prstat));
|
|
prstat.pr_pid = pid;
|
|
prstat.pr_cursig = cursig;
|
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
|
p = (const void *) &prstat;
|
|
size = sizeof (prstat);
|
|
}
|
|
else
|
|
{
|
|
prstatus32_t prstat;
|
|
memset (&prstat, 0, sizeof (prstat));
|
|
prstat.pr_pid = pid;
|
|
prstat.pr_cursig = cursig;
|
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
|
p = (const void *) &prstat;
|
|
size = sizeof (prstat);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
prstatus_t prstat;
|
|
memset (&prstat, 0, sizeof (prstat));
|
|
prstat.pr_pid = pid;
|
|
prstat.pr_cursig = cursig;
|
|
memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
|
p = (const void *) &prstat;
|
|
size = sizeof (prstat);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, p,
|
|
size);
|
|
}
|
|
#endif
|
|
|
/* Functions for the x86-64 ELF linker. */
|
/* Functions for the x86-64 ELF linker. */
|
|
|
/* The name of the dynamic interpreter. This is put in the .interp
|
/* The name of the dynamic interpreter. This is put in the .interp
|
section. */
|
section. */
|
Line 406... |
Line 549... |
0, 0, 0, 0, /* replaced with index into relocation table. */
|
0, 0, 0, 0, /* replaced with index into relocation table. */
|
0xe9, /* jmp relative */
|
0xe9, /* jmp relative */
|
0, 0, 0, 0 /* replaced with offset to start of .plt0. */
|
0, 0, 0, 0 /* replaced with offset to start of .plt0. */
|
};
|
};
|
|
|
|
/* .eh_frame covering the .plt section. */
|
|
|
|
static const bfd_byte elf_x86_64_eh_frame_plt[] =
|
|
{
|
|
#define PLT_CIE_LENGTH 20
|
|
#define PLT_FDE_LENGTH 36
|
|
#define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8
|
|
#define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12
|
|
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 + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
|
|
DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
|
|
11, /* Block length */
|
|
DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
|
|
DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
|
|
DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
|
|
DW_OP_lit3, DW_OP_shl, DW_OP_plus,
|
|
DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
|
|
};
|
|
|
/* x86-64 ELF linker hash entry. */
|
/* x86-64 ELF linker hash entry. */
|
|
|
struct elf_x86_64_link_hash_entry
|
struct elf_x86_64_link_hash_entry
|
{
|
{
|
struct elf_link_hash_entry elf;
|
struct elf_link_hash_entry elf;
|
Line 479... |
Line 661... |
struct elf_link_hash_table elf;
|
struct elf_link_hash_table elf;
|
|
|
/* Short-cuts to get to dynamic linker sections. */
|
/* Short-cuts to get to dynamic linker sections. */
|
asection *sdynbss;
|
asection *sdynbss;
|
asection *srelbss;
|
asection *srelbss;
|
|
asection *plt_eh_frame;
|
|
|
union
|
union
|
{
|
{
|
bfd_signed_vma refcount;
|
bfd_signed_vma refcount;
|
bfd_vma offset;
|
bfd_vma offset;
|
Line 647... |
Line 830... |
return NULL;
|
return NULL;
|
}
|
}
|
|
|
ret->sdynbss = NULL;
|
ret->sdynbss = NULL;
|
ret->srelbss = NULL;
|
ret->srelbss = NULL;
|
|
ret->plt_eh_frame = NULL;
|
ret->sym_cache.abfd = NULL;
|
ret->sym_cache.abfd = NULL;
|
ret->tlsdesc_plt = 0;
|
ret->tlsdesc_plt = 0;
|
ret->tlsdesc_got = 0;
|
ret->tlsdesc_got = 0;
|
ret->tls_ld_got.refcount = 0;
|
ret->tls_ld_got.refcount = 0;
|
ret->sgotplt_jump_table_size = 0;
|
ret->sgotplt_jump_table_size = 0;
|
Line 725... |
Line 909... |
|
|
if (!htab->sdynbss
|
if (!htab->sdynbss
|
|| (!info->shared && !htab->srelbss))
|
|| (!info->shared && !htab->srelbss))
|
abort ();
|
abort ();
|
|
|
|
if (!info->no_ld_generated_unwind_info
|
|
&& bfd_get_section_by_name (dynobj, ".eh_frame") == NULL
|
|
&& htab->elf.splt != NULL)
|
|
{
|
|
flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
|
|
htab->plt_eh_frame
|
|
= bfd_make_section_with_flags (dynobj, ".eh_frame",
|
|
flags | SEC_READONLY);
|
|
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;
|
return TRUE;
|
}
|
}
|
|
|
/* Copy the extra info we tack onto an elf_link_hash_entry. */
|
/* Copy the extra info we tack onto an elf_link_hash_entry. */
|
|
|
Line 1214... |
Line 1416... |
switch (r_type)
|
switch (r_type)
|
{
|
{
|
default:
|
default:
|
break;
|
break;
|
|
|
case R_X86_64_64:
|
|
/* Allow R_X86_64_64 relocations in SEC_DEBUGGING sections
|
|
when building shared libraries. */
|
|
if (info->shared
|
|
&& !info->executable
|
|
&& (sec->flags & SEC_DEBUGGING) != 0)
|
|
break;
|
|
|
|
case R_X86_64_DTPOFF64:
|
case R_X86_64_DTPOFF64:
|
case R_X86_64_TPOFF64:
|
case R_X86_64_TPOFF64:
|
case R_X86_64_PC64:
|
case R_X86_64_PC64:
|
case R_X86_64_GOTOFF64:
|
case R_X86_64_GOTOFF64:
|
case R_X86_64_GOT64:
|
case R_X86_64_GOT64:
|
Line 2599... |
Line 2793... |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
|
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
|
if (s->contents == NULL)
|
if (s->contents == NULL)
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
|
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);
|
|
|
if (htab->elf.dynamic_sections_created)
|
if (htab->elf.dynamic_sections_created)
|
{
|
{
|
/* Add some entries to the .dynamic section. We fill in the
|
/* Add some entries to the .dynamic section. We fill in the
|
values later, in elf_x86_64_finish_dynamic_sections, but we
|
values later, in elf_x86_64_finish_dynamic_sections, but we
|
must add the entries now so that we get the correct size for
|
must add the entries now so that we get the correct size for
|
Line 2833... |
Line 3034... |
{
|
{
|
bfd_set_error (bfd_error_bad_value);
|
bfd_set_error (bfd_error_bad_value);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
|
if (r_type != (int) R_X86_64_32
|
|
|| ABI_64_P (output_bfd))
|
howto = x86_64_elf_howto_table + r_type;
|
howto = x86_64_elf_howto_table + r_type;
|
|
else
|
|
howto = (x86_64_elf_howto_table
|
|
+ ARRAY_SIZE (x86_64_elf_howto_table) - 1);
|
r_symndx = htab->r_sym (rel->r_info);
|
r_symndx = htab->r_sym (rel->r_info);
|
h = NULL;
|
h = NULL;
|
sym = NULL;
|
sym = NULL;
|
sec = NULL;
|
sec = NULL;
|
unresolved_reloc = FALSE;
|
unresolved_reloc = FALSE;
|
Line 2878... |
Line 3084... |
rel, relend, howto, contents);
|
rel, relend, howto, contents);
|
|
|
if (info->relocatable)
|
if (info->relocatable)
|
continue;
|
continue;
|
|
|
|
if (rel->r_addend == 0
|
|
&& r_type == R_X86_64_64
|
|
&& !ABI_64_P (output_bfd))
|
|
{
|
|
/* For x32, treat R_X86_64_64 like R_X86_64_32 and zero-extend
|
|
it to 64bit if addend is zero. */
|
|
r_type = R_X86_64_32;
|
|
memset (contents + rel->r_offset + 4, 0, 4);
|
|
}
|
|
|
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle
|
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle
|
it here if it is defined in a non-shared object. */
|
it here if it is defined in a non-shared object. */
|
if (h != NULL
|
if (h != NULL
|
&& h->type == STT_GNU_IFUNC
|
&& h->type == STT_GNU_IFUNC
|
&& h->def_regular)
|
&& h->def_regular)
|
Line 3392... |
Line 3608... |
{
|
{
|
relocate = TRUE;
|
relocate = TRUE;
|
outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
outrel.r_addend = relocation + rel->r_addend;
|
outrel.r_addend = relocation + rel->r_addend;
|
}
|
}
|
|
else if (r_type == R_X86_64_64
|
|
&& !ABI_64_P (output_bfd))
|
|
{
|
|
relocate = TRUE;
|
|
outrel.r_info = htab->r_info (0,
|
|
R_X86_64_RELATIVE64);
|
|
outrel.r_addend = relocation + rel->r_addend;
|
|
}
|
else
|
else
|
{
|
{
|
long sindx;
|
long sindx;
|
|
|
if (bfd_is_abs_section (sec))
|
if (bfd_is_abs_section (sec))
|
Line 4399... |
Line 4623... |
|
|
elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
|
elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
|
GOT_ENTRY_SIZE;
|
GOT_ENTRY_SIZE;
|
}
|
}
|
|
|
|
/* Adjust .eh_frame for .plt section. */
|
|
if (htab->plt_eh_frame != NULL)
|
|
{
|
|
if (htab->elf.splt != NULL
|
|
&& htab->elf.splt->size != 0
|
|
&& (htab->elf.splt->flags & SEC_EXCLUDE) == 0
|
|
&& htab->elf.splt->output_section != NULL
|
|
&& htab->plt_eh_frame->output_section != NULL)
|
|
{
|
|
bfd_vma plt_start = htab->elf.splt->output_section->vma;
|
|
bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
|
|
+ htab->plt_eh_frame->output_offset
|
|
+ PLT_FDE_START_OFFSET;
|
|
bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
|
|
htab->plt_eh_frame->contents
|
|
+ PLT_FDE_START_OFFSET);
|
|
}
|
|
if (htab->plt_eh_frame->sec_info_type
|
|
== ELF_INFO_TYPE_EH_FRAME)
|
|
{
|
|
if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
|
|
htab->plt_eh_frame,
|
|
htab->plt_eh_frame->contents))
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
if (htab->elf.sgot && htab->elf.sgot->size > 0)
|
if (htab->elf.sgot && htab->elf.sgot->size > 0)
|
elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
|
elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
|
= GOT_ENTRY_SIZE;
|
= GOT_ENTRY_SIZE;
|
|
|
/* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
|
/* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
|
Line 4665... |
Line 4916... |
#define elf_backend_want_got_plt 1
|
#define elf_backend_want_got_plt 1
|
#define elf_backend_plt_readonly 1
|
#define elf_backend_plt_readonly 1
|
#define elf_backend_want_plt_sym 0
|
#define elf_backend_want_plt_sym 0
|
#define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
|
#define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
|
#define elf_backend_rela_normal 1
|
#define elf_backend_rela_normal 1
|
|
#define elf_backend_plt_alignment 4
|
|
|
#define elf_info_to_howto elf_x86_64_info_to_howto
|
#define elf_info_to_howto elf_x86_64_info_to_howto
|
|
|
#define bfd_elf64_bfd_link_hash_table_create \
|
#define bfd_elf64_bfd_link_hash_table_create \
|
elf_x86_64_link_hash_table_create
|
elf_x86_64_link_hash_table_create
|
Line 4687... |
Line 4939... |
#define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
|
#define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
|
#define elf_backend_gc_mark_hook elf_x86_64_gc_mark_hook
|
#define elf_backend_gc_mark_hook elf_x86_64_gc_mark_hook
|
#define elf_backend_gc_sweep_hook elf_x86_64_gc_sweep_hook
|
#define elf_backend_gc_sweep_hook elf_x86_64_gc_sweep_hook
|
#define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
|
#define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
|
#define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
|
#define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
|
|
#ifdef CORE_HEADER
|
|
#define elf_backend_write_core_note elf_x86_64_write_core_note
|
|
#endif
|
#define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
|
#define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
|
#define elf_backend_relocate_section elf_x86_64_relocate_section
|
#define elf_backend_relocate_section elf_x86_64_relocate_section
|
#define elf_backend_size_dynamic_sections elf_x86_64_size_dynamic_sections
|
#define elf_backend_size_dynamic_sections elf_x86_64_size_dynamic_sections
|
#define elf_backend_always_size_sections elf_x86_64_always_size_sections
|
#define elf_backend_always_size_sections elf_x86_64_always_size_sections
|
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
|
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
|
Line 4720... |
Line 4975... |
#define elf_backend_additional_program_headers \
|
#define elf_backend_additional_program_headers \
|
elf_x86_64_additional_program_headers
|
elf_x86_64_additional_program_headers
|
#define elf_backend_hash_symbol \
|
#define elf_backend_hash_symbol \
|
elf_x86_64_hash_symbol
|
elf_x86_64_hash_symbol
|
|
|
#undef elf_backend_post_process_headers
|
|
#define elf_backend_post_process_headers _bfd_elf_set_osabi
|
#define elf_backend_post_process_headers _bfd_elf_set_osabi
|
|
|
#include "elf64-target.h"
|
#include "elf64-target.h"
|
|
|
/* FreeBSD support. */
|
/* FreeBSD support. */
|
Line 4796... |
Line 5050... |
#define elf64_bed elf64_l1om_bed
|
#define elf64_bed elf64_l1om_bed
|
|
|
#undef elf_backend_object_p
|
#undef elf_backend_object_p
|
#define elf_backend_object_p elf64_l1om_elf_object_p
|
#define elf_backend_object_p elf64_l1om_elf_object_p
|
|
|
#undef elf_backend_post_process_headers
|
|
#undef elf_backend_static_tls_alignment
|
#undef elf_backend_static_tls_alignment
|
|
|
#undef elf_backend_want_plt_sym
|
#undef elf_backend_want_plt_sym
|
#define elf_backend_want_plt_sym 0
|
#define elf_backend_want_plt_sym 0
|
|
|
Line 4817... |
Line 5070... |
#define ELF_OSABI ELFOSABI_FREEBSD
|
#define ELF_OSABI ELFOSABI_FREEBSD
|
|
|
#undef elf64_bed
|
#undef elf64_bed
|
#define elf64_bed elf64_l1om_fbsd_bed
|
#define elf64_bed elf64_l1om_fbsd_bed
|
|
|
#undef elf_backend_post_process_headers
|
#include "elf64-target.h"
|
#define elf_backend_post_process_headers _bfd_elf_set_osabi
|
|
|
/* Intel K1OM support. */
|
|
|
|
static bfd_boolean
|
|
elf64_k1om_elf_object_p (bfd *abfd)
|
|
{
|
|
/* Set the right machine number for an K1OM elf64 file. */
|
|
bfd_default_set_arch_mach (abfd, bfd_arch_k1om, bfd_mach_k1om);
|
|
return TRUE;
|
|
}
|
|
|
|
#undef TARGET_LITTLE_SYM
|
|
#define TARGET_LITTLE_SYM bfd_elf64_k1om_vec
|
|
#undef TARGET_LITTLE_NAME
|
|
#define TARGET_LITTLE_NAME "elf64-k1om"
|
|
#undef ELF_ARCH
|
|
#define ELF_ARCH bfd_arch_k1om
|
|
|
|
#undef ELF_MACHINE_CODE
|
|
#define ELF_MACHINE_CODE EM_K1OM
|
|
|
|
#undef ELF_OSABI
|
|
|
|
#undef elf64_bed
|
|
#define elf64_bed elf64_k1om_bed
|
|
|
|
#undef elf_backend_object_p
|
|
#define elf_backend_object_p elf64_k1om_elf_object_p
|
|
|
|
#undef elf_backend_static_tls_alignment
|
|
|
|
#undef elf_backend_want_plt_sym
|
|
#define elf_backend_want_plt_sym 0
|
|
|
|
#include "elf64-target.h"
|
|
|
|
/* FreeBSD K1OM support. */
|
|
|
|
#undef TARGET_LITTLE_SYM
|
|
#define TARGET_LITTLE_SYM bfd_elf64_k1om_freebsd_vec
|
|
#undef TARGET_LITTLE_NAME
|
|
#define TARGET_LITTLE_NAME "elf64-k1om-freebsd"
|
|
|
|
#undef ELF_OSABI
|
|
#define ELF_OSABI ELFOSABI_FREEBSD
|
|
|
|
#undef elf64_bed
|
|
#define elf64_bed elf64_k1om_fbsd_bed
|
|
|
#include "elf64-target.h"
|
#include "elf64-target.h"
|
|
|
/* 32bit x86-64 support. */
|
/* 32bit x86-64 support. */
|
|
|
Line 4856... |
Line 5156... |
#define bfd_elf32_mkobject \
|
#define bfd_elf32_mkobject \
|
elf_x86_64_mkobject
|
elf_x86_64_mkobject
|
|
|
#undef ELF_OSABI
|
#undef ELF_OSABI
|
|
|
#undef elf_backend_post_process_headers
|
|
|
|
#undef elf_backend_object_p
|
#undef elf_backend_object_p
|
#define elf_backend_object_p \
|
#define elf_backend_object_p \
|
elf32_x86_64_elf_object_p
|
elf32_x86_64_elf_object_p
|
|
|
#undef elf_backend_bfd_from_remote_memory
|
#undef elf_backend_bfd_from_remote_memory
|