diff options
Diffstat (limited to 'bfd/elfxx-x86.c')
-rw-r--r-- | bfd/elfxx-x86.c | 56 |
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; } |