x86: Create dynamic sections in create_dynamic_sections
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 27 Apr 2017 20:55:31 +0000 (13:55 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 27 Apr 2017 20:55:48 +0000 (13:55 -0700)
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.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/ChangeLog
ld/testsuite/ld-x86-64/pr21038a.d
ld/testsuite/ld-x86-64/pr21038c.d

index 9435b94..0d328b4 100644 (file)
@@ -1,5 +1,15 @@
 2017-04-27  H.J. Lu  <hongjiu.lu@intel.com>
 
+       * 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.
+
+2017-04-27  H.J. Lu  <hongjiu.lu@intel.com>
+
        * elf64-x86-64.c (elf_x86_64_link_hash_entry): Remove
        has_bnd_reloc.
        (elf_x86_64_link_hash_newfunc): Don't clear has_bnd_reloc.
index 45c6c0e..c995ef5 100644 (file)
@@ -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;
index c491628..5985319 100644 (file)
@@ -1197,19 +1197,106 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
       htab->interp = s;
     }
 
-  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,
-                                        ABI_64_P (dynobj) ? 3 : 2))
-       return FALSE;
+      const struct elf_backend_data *bed
+       = get_elf_backend_data (dynobj);
+      flagword pltflags = (bed->dynamic_sec_flags
+                          | SEC_ALLOC
+                          | SEC_CODE
+                          | SEC_LOAD
+                          | SEC_READONLY);
+
+      if (htab->plt_got == NULL
+         && get_elf_x86_64_backend_data (dynobj) == &elf_x86_64_arch_bed)
+       {
+         /* Create the GOT procedure linkage table.  */
+         unsigned int plt_got_align;
+
+         BFD_ASSERT (sizeof (elf_x86_64_legacy_plt2_entry) == 8
+                     && (sizeof (elf_x86_64_bnd_plt2_entry)
+                         == sizeof (elf_x86_64_legacy_plt2_entry)));
+         plt_got_align = 3;
+
+         htab->plt_got
+           = bfd_make_section_anyway_with_flags (dynobj,
+                                                 ".plt.got",
+                                                 pltflags);
+         if (htab->plt_got == NULL
+             || !bfd_set_section_alignment (dynobj,
+                                            htab->plt_got,
+                                            plt_got_align))
+           return FALSE;
+       }
+
+      /* MPX PLT is supported only if elf_x86_64_arch_bed is used in
+        64-bit mode.  */
+      if (ABI_64_P (dynobj)
+         && info->bndplt
+         && get_elf_x86_64_backend_data (dynobj) == &elf_x86_64_arch_bed
+         && htab->plt_bnd == NULL)
+       {
+         /* Create the second PLT for Intel MPX support.  */
+         BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry) == 8
+                     && (sizeof (elf_x86_64_bnd_plt2_entry)
+                         == sizeof (elf_x86_64_legacy_plt2_entry)));
+
+         htab->plt_bnd
+           = bfd_make_section_anyway_with_flags (dynobj,
+                                                 ".plt.bnd",
+                                                 pltflags);
+         if (htab->plt_bnd == NULL
+             || !bfd_set_section_alignment (dynobj, htab->plt_bnd, 3))
+           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,
+                                                ABI_64_P (dynobj) ? 3 : 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 (htab->elf.dynobj,
+                                                     ".eh_frame",
+                                                     flags);
+             if (htab->plt_got_eh_frame == NULL
+                 || !bfd_set_section_alignment (dynobj,
+                                                htab->plt_got_eh_frame,
+                                                ABI_64_P (dynobj) ? 3 : 2))
+               return FALSE;
+           }
+
+         if (htab->plt_bnd_eh_frame == NULL
+             && htab->plt_bnd != NULL)
+           {
+             htab->plt_bnd_eh_frame
+               = bfd_make_section_anyway_with_flags (dynobj,
+                                                     ".eh_frame",
+                                                     flags);
+             if (htab->plt_bnd_eh_frame == NULL
+                 || !bfd_set_section_alignment (dynobj,
+                                                htab->plt_bnd_eh_frame,
+                                                3))
+               return FALSE;
+           }
+       }
     }
 
   /* Align .got section to its entry size.  */
@@ -2198,7 +2285,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   const Elf_Internal_Rela *rel_end;
   asection *sreloc;
   bfd_byte *contents;
-  bfd_boolean use_plt_got;
 
   if (bfd_link_relocatable (info))
     return TRUE;
@@ -2230,8 +2316,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
       return FALSE;
     }
 
-  use_plt_got = get_elf_x86_64_backend_data (abfd) == &elf_x86_64_arch_bed;
-
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
@@ -2340,59 +2424,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case R_X86_64_PLT32:
            case R_X86_64_32:
            case R_X86_64_64:
-             /* MPX PLT is supported only if elf_x86_64_arch_bed
-                is used in 64-bit mode.  */
-             if (ABI_64_P (abfd)
-                 && info->bndplt
-                 && (get_elf_x86_64_backend_data (abfd)
-                     == &elf_x86_64_arch_bed))
-               {
-                 /* Create the second PLT for Intel MPX support.  */
-                 if (htab->plt_bnd == NULL)
-                   {
-                     const struct elf_backend_data *bed;
-
-                     bed = get_elf_backend_data (info->output_bfd);
-                     BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry) == 8
-                                 && (sizeof (elf_x86_64_bnd_plt2_entry)
-                                     == sizeof (elf_x86_64_legacy_plt2_entry)));
-
-                     if (htab->elf.dynobj == NULL)
-                       htab->elf.dynobj = abfd;
-                     htab->plt_bnd
-                       = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
-                                                             ".plt.bnd",
-                                                            (bed->dynamic_sec_flags
-                                                             | SEC_ALLOC
-                                                             | SEC_CODE
-                                                             | SEC_LOAD
-                                                             | SEC_READONLY));
-                     if (htab->plt_bnd == NULL
-                         || !bfd_set_section_alignment (htab->elf.dynobj,
-                                                        htab->plt_bnd,
-                                                        3))
-                       goto error_return;
-                   }
-
-                 if (!info->no_ld_generated_unwind_info
-                     && htab->plt_bnd_eh_frame == NULL)
-                   {
-                     flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
-                                       | SEC_HAS_CONTENTS | SEC_IN_MEMORY
-                                       | SEC_LINKER_CREATED);
-                     htab->plt_bnd_eh_frame
-                       = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
-                                                             ".eh_frame",
-                                                             flags);
-                     if (htab->plt_bnd_eh_frame == NULL
-                         || !bfd_set_section_alignment (htab->elf.dynobj,
-                                                        htab->plt_bnd_eh_frame,
-                                                        3))
-                       goto error_return;
-                   }
-               }
-             /* Fall through.  */
-
            case R_X86_64_32S:
            case R_X86_64_PC64:
            case R_X86_64_GOTPCREL:
@@ -2798,58 +2829,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_x86_64_legacy_plt2_entry) == 8
-                     && (sizeof (elf_x86_64_bnd_plt2_entry)
-                         == sizeof (elf_x86_64_legacy_plt2_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_x86_64_backend_data (abfd)->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,
-                                                ABI_64_P (htab->elf.dynobj) ? 3 : 2))
-               goto error_return;
-           }
-       }
-
       if ((r_type == R_X86_64_GOTPCREL
           || r_type == R_X86_64_GOTPCRELX
           || r_type == R_X86_64_REX_GOTPCRELX)
index c93d903..008e8c9 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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.
+
 2017-04-26  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/ld-i386/tlsdesc2.d: New test.
index e6829d5..f2f88eb 100644 (file)
@@ -40,7 +40,11 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
+0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
index 5b6c22f..05b3622 100644 (file)
@@ -40,7 +40,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000288..0000000000000290
+0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000280..0000000000000288
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop
@@ -49,7 +49,7 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
-0+70 0000000000000010 00000074 FDE cie=00000000 pc=0000000000000280..0000000000000288
+0+70 0000000000000010 00000074 FDE cie=00000000 pc=0000000000000288..0000000000000290
   DW_CFA_nop
   DW_CFA_nop
   DW_CFA_nop