diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-04-27 13:55:31 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-04-27 13:55:48 -0700 |
commit | de9a3c4285fad1914929ee304ddaa26e76af8031 (patch) | |
tree | e3368c31ed041c51a8a396d4e758a3f10417ab25 /bfd/elf32-i386.c | |
parent | da3d25afa26476bf24247b8696fd00ab31f39db9 (diff) | |
download | binutils-gdb-de9a3c4285fad1914929ee304ddaa26e76af8031.tar.gz |
x86: Create dynamic sections in create_dynamic_sections
This patch creates dynamic sections in i386/x86-64 create_dynamic_sections
instead of creating them on demend. Linker will strip them if they are
empty. It changes order in x86-64 .eh_frame section. The extra DW_CFA_nop
paddings is due to
https://sourceware.org/bugzilla/show_bug.cgi?id=21441
bfd/
* elf32-i386.c (elf_i386_create_dynamic_sections): Create the
.plt.got section here.
(elf_i386_check_relocs): Don't create the .plt.got section.
* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Create
the .plt.got and .plt.bnd sections here.
(elf_x86_64_check_relocs): Don't create the .plt.got nor
.plt.bnd sections.
ld/
* testsuite/ld-x86-64/pr21038a.d: Update DW_CFA_nop paddings
in .eh_frame section.
* testsuite/ld-x86-64/pr21038c.d: Update .eh_frame order.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 131 |
1 files changed, 63 insertions, 68 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 45c6c0ed7ef..c995ef563f3 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1124,18 +1124,70 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) &htab->srelplt2)) return FALSE; - if (!info->no_ld_generated_unwind_info - && htab->plt_eh_frame == NULL - && htab->elf.splt != NULL) + if (htab->elf.splt != NULL) { - flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY - | SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_LINKER_CREATED); - htab->plt_eh_frame - = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags); - if (htab->plt_eh_frame == NULL - || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2)) - return FALSE; + if (htab->plt_got == NULL + && !get_elf_i386_backend_data (dynobj)->is_vxworks + && get_elf_i386_backend_data (dynobj) == &elf_i386_arch_bed) + { + /* Create the GOT procedure linkage table. */ + unsigned int plt_got_align; + const struct elf_backend_data *bed; + + bed = get_elf_backend_data (dynobj); + BFD_ASSERT (sizeof (elf_i386_got_plt_entry) == 8 + && (sizeof (elf_i386_got_plt_entry) + == sizeof (elf_i386_pic_got_plt_entry))); + plt_got_align = 3; + + htab->plt_got + = bfd_make_section_anyway_with_flags (dynobj, + ".plt.got", + (bed->dynamic_sec_flags + | SEC_ALLOC + | SEC_CODE + | SEC_LOAD + | SEC_READONLY)); + if (htab->plt_got == NULL + || !bfd_set_section_alignment (dynobj, + htab->plt_got, + plt_got_align)) + return FALSE; + } + + if (!info->no_ld_generated_unwind_info) + { + flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY + | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_LINKER_CREATED); + + if (htab->plt_eh_frame == NULL) + { + htab->plt_eh_frame + = bfd_make_section_anyway_with_flags (dynobj, + ".eh_frame", + flags); + if (htab->plt_eh_frame == NULL + || !bfd_set_section_alignment (dynobj, + htab->plt_eh_frame, + 2)) + return FALSE; + } + + if (htab->plt_got_eh_frame == NULL + && htab->plt_got != NULL) + { + htab->plt_got_eh_frame + = bfd_make_section_anyway_with_flags (dynobj, + ".eh_frame", + flags); + if (htab->plt_got_eh_frame == NULL + || !bfd_set_section_alignment (dynobj, + htab->plt_got_eh_frame, + 2)) + return FALSE; + } + } } return TRUE; @@ -1858,7 +1910,6 @@ elf_i386_check_relocs (bfd *abfd, const Elf_Internal_Rela *rel_end; asection *sreloc; bfd_byte *contents; - bfd_boolean use_plt_got; if (bfd_link_relocatable (info)) return TRUE; @@ -1890,10 +1941,6 @@ elf_i386_check_relocs (bfd *abfd, return FALSE; } - use_plt_got = (!get_elf_i386_backend_data (abfd)->is_vxworks - && (get_elf_i386_backend_data (abfd) - == &elf_i386_arch_bed)); - symtab_hdr = &elf_symtab_hdr (abfd); sym_hashes = elf_sym_hashes (abfd); @@ -2353,58 +2400,6 @@ do_size: break; } - if (use_plt_got - && h != NULL - && h->plt.refcount > 0 - && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed) - || h->got.refcount > 0) - && htab->plt_got == NULL) - { - /* Create the GOT procedure linkage table. */ - unsigned int plt_got_align; - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (info->output_bfd); - BFD_ASSERT (sizeof (elf_i386_got_plt_entry) == 8 - && (sizeof (elf_i386_got_plt_entry) - == sizeof (elf_i386_pic_got_plt_entry))); - plt_got_align = 3; - - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - htab->plt_got - = bfd_make_section_anyway_with_flags (htab->elf.dynobj, - ".plt.got", - (bed->dynamic_sec_flags - | SEC_ALLOC - | SEC_CODE - | SEC_LOAD - | SEC_READONLY)); - if (htab->plt_got == NULL - || !bfd_set_section_alignment (htab->elf.dynobj, - htab->plt_got, - plt_got_align)) - goto error_return; - - if (!info->no_ld_generated_unwind_info - && htab->plt_got_eh_frame == NULL - && get_elf_i386_backend_data (abfd)->plt->eh_frame_plt_got != NULL) - { - flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY - | SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_LINKER_CREATED); - htab->plt_got_eh_frame - = bfd_make_section_anyway_with_flags (htab->elf.dynobj, - ".eh_frame", - flags); - if (htab->plt_got_eh_frame == NULL - || !bfd_set_section_alignment (htab->elf.dynobj, - htab->plt_got_eh_frame, - 2)) - goto error_return; - } - } - if (r_type == R_386_GOT32X && (h == NULL || h->type != STT_GNU_IFUNC)) sec->need_convert_load = 1; |