aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfxx-x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elfxx-x86.c')
-rw-r--r--bfd/elfxx-x86.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 6ea41f2..6dc1586 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -366,7 +366,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
htab->elf.srelgot->size += htab->sizeof_reloc;
if (GOT_TLS_GDESC_P (tls_type))
{
- htab->elf.srelplt->size += htab->sizeof_reloc;
+ htab->rel_tls_desc->size += htab->sizeof_reloc;
if (bed->target_id == X86_64_ELF_DATA)
htab->elf.tlsdesc_plt = (bfd_vma) -1;
}
@@ -609,8 +609,7 @@ _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab,
return &ret->elf;
}
-/* Create an entry in a x86 ELF linker hash table. NB: THIS MUST BE IN
- SYNC WITH _bfd_elf_link_hash_newfunc. */
+/* Create an entry in an x86 ELF linker hash table. */
struct bfd_hash_entry *
_bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
@@ -629,27 +628,14 @@ _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
}
/* Call the allocation method of the superclass. */
- entry = _bfd_link_hash_newfunc (entry, table, string);
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
if (entry != NULL)
{
struct elf_x86_link_hash_entry *eh
= (struct elf_x86_link_hash_entry *) entry;
- struct elf_link_hash_table *htab
- = (struct elf_link_hash_table *) table;
- memset (&eh->elf.size, 0,
- (sizeof (struct elf_x86_link_hash_entry)
- - offsetof (struct elf_link_hash_entry, size)));
+ memset (&eh->elf + 1, 0, sizeof (*eh) - sizeof (eh->elf));
/* Set local fields. */
- eh->elf.indx = -1;
- eh->elf.dynindx = -1;
- eh->elf.got = htab->init_got_refcount;
- eh->elf.plt = htab->init_plt_refcount;
- /* Assume that we have been called by a non-ELF symbol reader.
- This flag is then reset by the code which reads an ELF input
- file. This ensures that a symbol created by a non-ELF symbol
- reader will have the flag set correctly. */
- eh->elf.non_elf = 1;
eh->plt_second.offset = (bfd_vma) -1;
eh->plt_got.offset = (bfd_vma) -1;
eh->tlsdesc_got = (bfd_vma) -1;
@@ -896,6 +882,8 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
elf_x86_hash_entry (h)->tls_get_addr = 1;
}
+
+ htab->has_tls_get_addr_call = 1;
}
/* Pass NULL for __ehdr_start which will be defined by
@@ -1905,7 +1893,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
}
*ectx = sframe_encode (SFRAME_VERSION_2,
- 0,
+ SFRAME_F_FDE_FUNC_START_PCREL,
SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset. */
@@ -2169,6 +2157,16 @@ _bfd_elf_x86_finish_relative_relocs (struct bfd_link_info *info)
return true;
}
+asection *
+_bfd_elf_x86_get_reloc_section (bfd *abfd, const char *name)
+{
+ /* Treat .rel.tls/.rela.tls section the same as .rel.plt/.rela.plt
+ section. */
+ if (strcmp (name, ".tls") == 0)
+ name = ".plt";
+ return _bfd_elf_plt_get_reloc_section (abfd, name);
+}
+
bool
_bfd_elf_x86_valid_reloc_p (asection *input_section,
struct bfd_link_info *info,
@@ -2388,7 +2386,7 @@ _bfd_x86_elf_late_size_sections (bfd *output_bfd,
srel->size += htab->sizeof_reloc;
if (GOT_TLS_GDESC_P (*local_tls_type))
{
- htab->elf.srelplt->size += htab->sizeof_reloc;
+ htab->rel_tls_desc->size += htab->sizeof_reloc;
if (bed->target_id == X86_64_ELF_DATA)
htab->elf.tlsdesc_plt = (bfd_vma) -1;
}
@@ -2429,7 +2427,6 @@ _bfd_x86_elf_late_size_sections (bfd *output_bfd,
so that R_{386,X86_64}_IRELATIVE entries come last. */
if (htab->elf.srelplt)
{
- htab->next_tls_desc_index = htab->elf.srelplt->reloc_count;
htab->sgotplt_jump_table_size
= elf_x86_compute_jump_table_size (htab);
htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
@@ -4618,6 +4615,8 @@ _bfd_x86_elf_link_setup_gnu_properties
htab->sframe_plt = init_table->sframe_non_lazy_plt;
}
}
+ else if (lazy_plt)
+ htab->sframe_plt = init_table->sframe_lazy_plt;
else
htab->sframe_plt = NULL;
@@ -4752,6 +4751,14 @@ _bfd_x86_elf_link_setup_gnu_properties
}
}
+ sec = bfd_make_section_anyway_with_flags
+ (dynobj, bed->rela_plts_and_copies_p ? ".rela.tls" : ".rel.tls",
+ bed->dynamic_sec_flags | SEC_READONLY);
+ if (sec == NULL
+ || !bfd_set_section_alignment (sec, bed->s->log_file_align))
+ return false;
+ htab->rel_tls_desc = sec;
+
if (!info->no_ld_generated_unwind_info)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
@@ -4799,11 +4806,10 @@ _bfd_x86_elf_link_setup_gnu_properties
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
- sec = bfd_make_section_anyway_with_flags (dynobj,
- ".sframe",
- flags);
+ sec = bfd_make_section_anyway_with_flags (dynobj, ".sframe", flags);
if (sec == NULL)
info->callbacks->fatal (_("%P: failed to create PLT .sframe section\n"));
+ elf_section_type (sec) = SHT_GNU_SFRAME;
// FIXME check this
// if (!bfd_set_section_alignment (sec, class_align))
@@ -4819,6 +4825,7 @@ _bfd_x86_elf_link_setup_gnu_properties
flags);
if (sec == NULL)
info->callbacks->fatal (_("%P: failed to create second PLT .sframe section\n"));
+ elf_section_type (sec) = SHT_GNU_SFRAME;
htab->plt_second_sframe = sec;
}
@@ -4831,6 +4838,7 @@ _bfd_x86_elf_link_setup_gnu_properties
flags);
if (sec == NULL)
info->callbacks->fatal (_("%P: failed to create PLT GOT .sframe section\n"));
+ elf_section_type (sec) = SHT_GNU_SFRAME;
htab->plt_got_sframe = sec;
}