summaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-04-27 13:55:31 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-04-27 13:55:48 -0700
commitde9a3c4285fad1914929ee304ddaa26e76af8031 (patch)
treee3368c31ed041c51a8a396d4e758a3f10417ab25 /bfd/elf32-i386.c
parentda3d25afa26476bf24247b8696fd00ab31f39db9 (diff)
downloadbinutils-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.c131
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;