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