+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
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
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 */
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 */
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 */
};
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. */
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;
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,
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))
{
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;
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;
/* 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
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);
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)
&& 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. */
&& 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.
{
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
&& 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);
&& 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
&& 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
_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;
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;
}
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))
{
+ 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);
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;
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
/* 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;
+ 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)
{
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;
/* 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
{
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
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. */
/* 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));
}
}
}
/* 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
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
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 ();
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
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,
+ 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,
+ 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,
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. */
};
/* 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. */
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;
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)
}
}
- 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)
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;
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)
{
| 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,
#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
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 */
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. */
\f
/* 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
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
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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)
{
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;
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,
&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))
{
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;
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;
/* 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
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)
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)
/* 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;
}
}
&& 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. */
&& 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.
&& 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);
}
&& 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
&& 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
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);
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;
}
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;
}
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)
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. */
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;
- 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)
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
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. */
/* 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
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);
/* 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. */
- 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;
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
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 ();
(*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,
- 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. */
+ 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)
{
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. */
- 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
- 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
};
/* 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. */
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;
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)
}
}
- 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)
{
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;
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)
{
| 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,
#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
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 */
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 */
};
#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 \
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
/* 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;
_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
#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
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
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;
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;
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
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 \