]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
i386/x86-64: Add unwind info for .plt.got section
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 10 Jan 2017 21:31:59 +0000 (13:31 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 13 Jan 2017 16:23:22 +0000 (08:23 -0800)
When there are both PLT and GOT references to the same function symbol,
linker combines GOTPLT and GOT slots into a single GOT slot and create
an entry in .plt.got section for PLT access via the GOT slot.  This
patch adds unwind info for .plt.got section and places .plt.got section
after .plt section for x32.  .eh_frame section covering PLT sections
should be aligned to 4 bytes for i386 and x32.

bfd/

2017-01-13  H.J. Lu  <hongjiu.lu@intel.com>

Backport from master
2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>

* elf32-i386.c (elf_i386_check_relocs): Align .eh_frame section
to 4 bytes.
* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Align
.eh_frame section to 4 bytes for x32.
(elf_x86_64_check_relocs): Likewise.

2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>

PR ld/20830
* elf32-i386.c (elf_i386_eh_frame_plt_got): New.
(PLT_GOT_FDE_LENGTH): Likewise.
(elf_i386_plt_layout): Add eh_frame_plt_got and
eh_frame_plt_got_size.
(elf_i386_plt): Updated.
(elf_i386_link_hash_table): Add plt_got_eh_frame.
(elf_i386_check_relocs): Create .eh_frame section for .plt.got.
(elf_i386_size_dynamic_sections): Allocate and initialize
.eh_frame section for .plt.got.
(elf_i386_finish_dynamic_sections): Adjust .eh_frame section for
.plt.got.
(elf_i386_nacl_plt): Add FIXME for eh_frame_plt_got and
eh_frame_plt_got_size.
* elf64-x86-64.c (elf_x86_64_eh_frame_plt_got): New.
(PLT_GOT_FDE_LENGTH): Likewise.
(elf_x86_64_backend_data): Add eh_frame_plt_got and
eh_frame_plt_got_size.
(elf_x86_64_arch_bed): Updated.
(elf_x86_64_bnd_arch_bed): Add FIXME for eh_frame_plt_got and
eh_frame_plt_got_size.
(elf_x86_64_nacl_arch_bed): Likewise.
(elf_x86_64_link_hash_table): Add plt_got_eh_frame.
(elf_x86_64_check_relocs): Create .eh_frame section for .plt.got.
(elf_x86_64_size_dynamic_sections): Allocate and initialize
.eh_frame section for .plt.got.
(elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section
for .plt.got.

ld/

2017-01-13  H.J. Lu  <hongjiu.lu@intel.com>

Backport from master
2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>

* testsuite/ld-x86-64/pr20830b.d: Updated.

2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>

* emulparams/elf32_x86_64.sh (TINY_READONLY_SECTION): New.
* testsuite/ld-x86-64/pr20830.d: Renamed to ...
* testsuite/ld-x86-64/pr20830a.d: This.  Updated.
* testsuite/ld-x86-64/pr20830b.d: New file.
* testsuite/ld-x86-64/x86-64.exp: Rename pr20830 to pr20830a.
Run pr20830b.

2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>

PR ld/20830
* testsuite/ld-i386/i386.exp: Run pr20830.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
* testsuite/ld-i386/pr20830.d: New file.
* testsuite/ld-i386/pr20830.s: Likewise.
* testsuite/ld-x86-64/pr20830.d: Likewise.
* testsuite/ld-x86-64/pr20830.s: Likewise.

12 files changed:
bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/ChangeLog
ld/emulparams/elf32_x86_64.sh
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr20830.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr20830.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20830.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20830a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20830b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 7f9e4ef8ea6c4958fc38c73ddd93cb9da4fc0126..f1fd51ff04953e1e08c568f0ae033be32fdb87af 100644 (file)
@@ -1,3 +1,45 @@
+2017-01-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       Backport from master
+       2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf32-i386.c (elf_i386_check_relocs): Align .eh_frame section
+       to 4 bytes.
+       * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Align
+       .eh_frame section to 4 bytes for x32.
+       (elf_x86_64_check_relocs): Likewise.
+
+       2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20830
+       * elf32-i386.c (elf_i386_eh_frame_plt_got): New.
+       (PLT_GOT_FDE_LENGTH): Likewise.
+       (elf_i386_plt_layout): Add eh_frame_plt_got and
+       eh_frame_plt_got_size.
+       (elf_i386_plt): Updated.
+       (elf_i386_link_hash_table): Add plt_got_eh_frame.
+       (elf_i386_check_relocs): Create .eh_frame section for .plt.got.
+       (elf_i386_size_dynamic_sections): Allocate and initialize
+       .eh_frame section for .plt.got.
+       (elf_i386_finish_dynamic_sections): Adjust .eh_frame section for
+       .plt.got.
+       (elf_i386_nacl_plt): Add FIXME for eh_frame_plt_got and
+       eh_frame_plt_got_size.
+       * elf64-x86-64.c (elf_x86_64_eh_frame_plt_got): New.
+       (PLT_GOT_FDE_LENGTH): Likewise.
+       (elf_x86_64_backend_data): Add eh_frame_plt_got and
+       eh_frame_plt_got_size.
+       (elf_x86_64_arch_bed): Updated.
+       (elf_x86_64_bnd_arch_bed): Add FIXME for eh_frame_plt_got and
+       eh_frame_plt_got_size.
+       (elf_x86_64_nacl_arch_bed): Likewise.
+       (elf_x86_64_link_hash_table): Add plt_got_eh_frame.
+       (elf_x86_64_check_relocs): Create .eh_frame section for .plt.got.
+       (elf_x86_64_size_dynamic_sections): Allocate and initialize
+       .eh_frame section for .plt.got.
+       (elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section
+       for .plt.got.
+
 2017-01-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        Backport from master
index a2da987850f2fb9e3ffd7c8ef9df89df9a933d28..0860ada37ef205336133c123e566f49004850b2b 100644 (file)
@@ -648,6 +648,32 @@ static const bfd_byte elf_i386_eh_frame_plt[] =
   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
 };
 
+/* .eh_frame covering the .plt.got section.  */
+
+static const bfd_byte elf_i386_eh_frame_plt_got[] =
+{
+#define PLT_GOT_FDE_LENGTH             16
+  PLT_CIE_LENGTH, 0, 0, 0,     /* CIE length */
+  0, 0, 0, 0,                  /* CIE ID */
+  1,                           /* CIE version */
+  'z', 'R', 0,                 /* Augmentation string */
+  1,                           /* Code alignment factor */
+  0x7c,                                /* Data alignment factor */
+  8,                           /* Return address column */
+  1,                           /* Augmentation size */
+  DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+  DW_CFA_def_cfa, 4, 4,                /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
+  DW_CFA_offset + 8, 1,                /* DW_CFA_offset: r8 (eip) at cfa-4 */
+  DW_CFA_nop, DW_CFA_nop,
+
+  PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+  PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+  0, 0, 0, 0,                  /* the start of .plt.got goes here */
+  0, 0, 0, 0,                  /* .plt.got size goes here */
+  0,                           /* Augmentation size */
+  DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
 struct elf_i386_plt_layout
 {
   /* The first entry in an absolute procedure linkage table looks like this.  */
@@ -679,6 +705,10 @@ struct elf_i386_plt_layout
   /* .eh_frame covering the .plt section.  */
   const bfd_byte *eh_frame_plt;
   unsigned int eh_frame_plt_size;
+
+  /* .eh_frame covering the .plt.got section.  */
+  const bfd_byte *eh_frame_plt_got;
+  unsigned int eh_frame_plt_got_size;
 };
 
 #define GET_PLT_ENTRY_SIZE(abfd) \
@@ -701,6 +731,8 @@ static const struct elf_i386_plt_layout elf_i386_plt =
     elf_i386_pic_plt_entry,             /* pic_plt_entry */
     elf_i386_eh_frame_plt,              /* eh_frame_plt */
     sizeof (elf_i386_eh_frame_plt),     /* eh_frame_plt_size */
+    elf_i386_eh_frame_plt_got,          /* eh_frame_plt_got */
+    sizeof (elf_i386_eh_frame_plt_got), /* eh_frame_plt_got_size */
   };
 \f
 
@@ -850,6 +882,7 @@ struct elf_i386_link_hash_table
   asection *interp;
   asection *plt_eh_frame;
   asection *plt_got;
+  asection *plt_got_eh_frame;
 
   union
   {
@@ -2347,6 +2380,24 @@ do_size:
                                             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
@@ -3379,14 +3430,22 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
        htab->elf.sgotplt->size = 0;
     }
 
-
-  if (htab->plt_eh_frame != NULL
-      && htab->elf.splt != NULL
-      && htab->elf.splt->size != 0
-      && !bfd_is_abs_section (htab->elf.splt->output_section)
-      && _bfd_elf_eh_frame_present (info))
-    htab->plt_eh_frame->size
-      = get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_size;
+  if (_bfd_elf_eh_frame_present (info))
+    {
+      if (htab->plt_eh_frame != NULL
+         && htab->elf.splt != NULL
+         && htab->elf.splt->size != 0
+         && !bfd_is_abs_section (htab->elf.splt->output_section))
+       htab->plt_eh_frame->size
+         = get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_size;
+
+      if (htab->plt_got_eh_frame != NULL
+         && htab->plt_got != NULL
+         && htab->plt_got->size != 0
+         && !bfd_is_abs_section (htab->plt_got->output_section))
+       htab->plt_got_eh_frame->size
+         = get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_got_size;
+    }
 
   /* We now have determined the sizes of the various dynamic sections.
      Allocate memory for them.  */
@@ -3415,6 +3474,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
               || s == htab->elf.igotplt
               || s == htab->plt_got
               || s == htab->plt_eh_frame
+              || s == htab->plt_got_eh_frame
               || s == htab->elf.sdynbss
               || s == htab->elf.sdynrelro)
        {
@@ -3476,6 +3536,17 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
                  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
     }
 
+  if (htab->plt_got_eh_frame != NULL
+      && htab->plt_got_eh_frame->contents != NULL)
+    {
+      memcpy (htab->plt_got_eh_frame->contents,
+             get_elf_i386_backend_data (output_bfd)->plt->eh_frame_plt_got,
+             htab->plt_got_eh_frame->size);
+      bfd_put_32 (dynobj, htab->plt_got->size,
+                 (htab->plt_got_eh_frame->contents
+                  + PLT_FDE_LEN_OFFSET));
+    }
+
   if (htab->elf.dynamic_sections_created)
     {
       /* Add some entries to the .dynamic section.  We fill in the
@@ -5885,6 +5956,33 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
        }
     }
 
+  /* Adjust .eh_frame for .plt.got section.  */
+  if (htab->plt_got_eh_frame != NULL
+      && htab->plt_got_eh_frame->contents != NULL)
+    {
+      if (htab->plt_got != NULL
+         && htab->plt_got->size != 0
+         && (htab->plt_got->flags & SEC_EXCLUDE) == 0
+         && htab->plt_got->output_section != NULL
+         && htab->plt_got_eh_frame->output_section != NULL)
+       {
+         bfd_vma plt_start = htab->plt_got->output_section->vma;
+         bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma
+                                  + htab->plt_got_eh_frame->output_offset
+                                  + PLT_FDE_START_OFFSET;
+         bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+                            htab->plt_got_eh_frame->contents
+                            + PLT_FDE_START_OFFSET);
+       }
+      if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+       {
+         if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+                                                htab->plt_got_eh_frame,
+                                                htab->plt_got_eh_frame->contents))
+           return FALSE;
+       }
+    }
+
   if (htab->elf.sgot && htab->elf.sgot->size > 0)
     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
 
@@ -6428,6 +6526,8 @@ static const struct elf_i386_plt_layout elf_i386_nacl_plt =
     elf_i386_nacl_pic_plt_entry,       /* pic_plt_entry */
     elf_i386_nacl_eh_frame_plt,                /* eh_frame_plt */
     sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */
+    NULL,                              /* eh_frame_plt_got */
+    0,                                 /* eh_frame_plt_got_size */
   };
 
 static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
index 36630f88cc10c7f52255bc2e8d89208983e99f75..1edab046a1166e04010fe83848a9b15d5ad7a64c 100644 (file)
@@ -659,6 +659,33 @@ static const bfd_byte elf_x86_64_eh_frame_plt[] =
   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
 };
 
+/* .eh_frame covering the .plt.got section.  */
+
+static const bfd_byte elf_x86_64_eh_frame_plt_got[] =
+{
+#define PLT_GOT_FDE_LENGTH             20
+  PLT_CIE_LENGTH, 0, 0, 0,     /* CIE length */
+  0, 0, 0, 0,                  /* CIE ID */
+  1,                           /* CIE version */
+  'z', 'R', 0,                 /* Augmentation string */
+  1,                           /* Code alignment factor */
+  0x78,                                /* Data alignment factor */
+  16,                          /* Return address column */
+  1,                           /* Augmentation size */
+  DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+  DW_CFA_def_cfa, 7, 8,                /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
+  DW_CFA_offset + 16, 1,       /* DW_CFA_offset: r16 (rip) at cfa-8 */
+  DW_CFA_nop, DW_CFA_nop,
+
+  PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+  PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+  0, 0, 0, 0,                  /* the start of .plt.got goes here */
+  0, 0, 0, 0,                  /* .plt.got size goes here */
+  0,                           /* Augmentation size */
+  DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop,
+  DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
 /* Architecture-specific backend data for x86-64.  */
 
 struct elf_x86_64_backend_data
@@ -693,6 +720,10 @@ struct elf_x86_64_backend_data
   /* .eh_frame covering the .plt section.  */
   const bfd_byte *eh_frame_plt;
   unsigned int eh_frame_plt_size;
+
+  /* .eh_frame covering the .plt.got section.  */
+  const bfd_byte *eh_frame_plt_got;
+  unsigned int eh_frame_plt_got_size;
 };
 
 #define get_elf_x86_64_arch_data(bed) \
@@ -721,6 +752,8 @@ static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
     6,                                  /* plt_lazy_offset */
     elf_x86_64_eh_frame_plt,            /* eh_frame_plt */
     sizeof (elf_x86_64_eh_frame_plt),   /* eh_frame_plt_size */
+    elf_x86_64_eh_frame_plt_got,        /* eh_frame_plt_got */
+    sizeof (elf_x86_64_eh_frame_plt_got), /* eh_frame_plt_got_size */
   };
 
 static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed =
@@ -739,6 +772,9 @@ static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed =
     0,                                  /* plt_lazy_offset */
     elf_x86_64_eh_frame_plt,            /* eh_frame_plt */
     sizeof (elf_x86_64_eh_frame_plt),   /* eh_frame_plt_size */
+    /* FIXME: Needs .eh_frame coverage.  */
+    NULL,                               /* eh_frame_plt_got */
+    0,                                  /* eh_frame_plt_got_size */
   };
 
 #define        elf_backend_arch_data   &elf_x86_64_arch_bed
@@ -865,6 +901,7 @@ struct elf_x86_64_link_hash_table
   asection *plt_eh_frame;
   asection *plt_bnd;
   asection *plt_got;
+  asection *plt_got_eh_frame;
 
   union
   {
@@ -1135,7 +1172,8 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
       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, 3))
+         || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame,
+                                        ABI_64_P (dynobj) ? 3 : 2))
        return FALSE;
     }
 
@@ -2744,6 +2782,24 @@ do_size:
                                             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
@@ -3788,15 +3844,28 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
        htab->elf.sgotplt->size = 0;
     }
 
-  if (htab->plt_eh_frame != NULL
-      && htab->elf.splt != NULL
-      && htab->elf.splt->size != 0
-      && !bfd_is_abs_section (htab->elf.splt->output_section)
-      && _bfd_elf_eh_frame_present (info))
+  if (_bfd_elf_eh_frame_present (info))
     {
-      const struct elf_x86_64_backend_data *arch_data
-       = get_elf_x86_64_arch_data (bed);
-      htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
+      if (htab->plt_eh_frame != NULL
+         && htab->elf.splt != NULL
+         && htab->elf.splt->size != 0
+         && !bfd_is_abs_section (htab->elf.splt->output_section))
+       {
+         const struct elf_x86_64_backend_data *arch_data
+           = get_elf_x86_64_arch_data (bed);
+         htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
+       }
+
+      if (htab->plt_got_eh_frame != NULL
+         && htab->plt_got != NULL
+         && htab->plt_got->size != 0
+         && !bfd_is_abs_section (htab->plt_got->output_section))
+       {
+         const struct elf_x86_64_backend_data *arch_data
+           = get_elf_x86_64_arch_data (bed);
+         htab->plt_got_eh_frame->size
+           = arch_data->eh_frame_plt_got_size;
+       }
     }
 
   /* We now have determined the sizes of the various dynamic sections.
@@ -3815,6 +3884,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          || s == htab->plt_bnd
          || s == htab->plt_got
          || s == htab->plt_eh_frame
+         || s == htab->plt_got_eh_frame
          || s == htab->elf.sdynbss
          || s == htab->elf.sdynrelro)
        {
@@ -3878,6 +3948,20 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
                  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
     }
 
+  if (htab->plt_got_eh_frame != NULL
+      && htab->plt_got_eh_frame->contents != NULL)
+    {
+      const struct elf_x86_64_backend_data *arch_data
+       = get_elf_x86_64_arch_data (bed);
+
+      memcpy (htab->plt_got_eh_frame->contents,
+             arch_data->eh_frame_plt_got,
+             htab->plt_got_eh_frame->size);
+      bfd_put_32 (dynobj, htab->plt_got->size,
+                 (htab->plt_got_eh_frame->contents
+                  + PLT_FDE_LEN_OFFSET));
+    }
+
   if (htab->elf.dynamic_sections_created)
     {
       /* Add some entries to the .dynamic section.  We fill in the
@@ -6343,6 +6427,33 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
        }
     }
 
+  /* Adjust .eh_frame for .plt.got section.  */
+  if (htab->plt_got_eh_frame != NULL
+      && htab->plt_got_eh_frame->contents != NULL)
+    {
+      if (htab->plt_got != NULL
+         && htab->plt_got->size != 0
+         && (htab->plt_got->flags & SEC_EXCLUDE) == 0
+         && htab->plt_got->output_section != NULL
+         && htab->plt_got_eh_frame->output_section != NULL)
+       {
+         bfd_vma plt_start = htab->plt_got->output_section->vma;
+         bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma
+                                  + htab->plt_got_eh_frame->output_offset
+                                  + PLT_FDE_START_OFFSET;
+         bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+                            htab->plt_got_eh_frame->contents
+                            + PLT_FDE_START_OFFSET);
+       }
+      if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+       {
+         if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+                                                htab->plt_got_eh_frame,
+                                                htab->plt_got_eh_frame->contents))
+           return FALSE;
+       }
+    }
+
   if (htab->elf.sgot && htab->elf.sgot->size > 0)
     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
       = GOT_ENTRY_SIZE;
@@ -7007,6 +7118,8 @@ static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
     32,                                      /* plt_lazy_offset */
     elf_x86_64_nacl_eh_frame_plt,            /* eh_frame_plt */
     sizeof (elf_x86_64_nacl_eh_frame_plt),   /* eh_frame_plt_size */
+    NULL,                                    /* eh_frame_plt_got */
+    0,                                       /* eh_frame_plt_got_size */
   };
 
 #undef elf_backend_arch_data
index 6a61d61fee1bf2809d6731be3394909dd7b3ee32..03562de4291bd81ce407123e3c2827972f589b1e 100644 (file)
@@ -1,3 +1,29 @@
+2017-01-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       Backport from master
+       2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * testsuite/ld-x86-64/pr20830b.d: Updated.
+
+       2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * emulparams/elf32_x86_64.sh (TINY_READONLY_SECTION): New.
+       * testsuite/ld-x86-64/pr20830.d: Renamed to ...
+       * testsuite/ld-x86-64/pr20830a.d: This.  Updated.
+       * testsuite/ld-x86-64/pr20830b.d: New file.
+       * testsuite/ld-x86-64/x86-64.exp: Rename pr20830 to pr20830a.
+       Run pr20830b.
+
+       2017-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20830
+       * testsuite/ld-i386/i386.exp: Run pr20830.
+       * testsuite/ld-x86-64/x86-64.exp: Likewise.
+       * testsuite/ld-i386/pr20830.d: New file.
+       * testsuite/ld-i386/pr20830.s: Likewise.
+       * testsuite/ld-x86-64/pr20830.d: Likewise.
+       * testsuite/ld-x86-64/pr20830.s: Likewise.
+
 2017-01-02  Alan Modra  <amodra@gmail.com>
 
        Update year range in copyright notice of all files.
index 9050730834f4b484e2d1b472cb27a1d71461d484..9b8523947eca6c98ccc36cb4b512ff1b2596ad80 100644 (file)
@@ -21,6 +21,10 @@ LARGE_SECTIONS=yes
 LARGE_BSS_AFTER_BSS=
 SEPARATE_GOTPLT="SIZEOF (.got.plt) >= 24 ? 24 : 0"
 IREL_IN_PLT=
+# Reuse TINY_READONLY_SECTION which is placed right after .plt section.
+TINY_READONLY_SECTION="
+.plt.got      ${RELOCATING-0} : { *(.plt.got) }
+"
 
 if [ "x${host}" = "x${target}" ]; then
   case " $EMULATION_LIBPATH " in
index e748e8b2d48e2a099ca4831b895b10c922c54e20..f439411956dc91cd3023050ce460341bb4f70c64 100644 (file)
@@ -864,3 +864,4 @@ if { !([istarget "i?86-*-linux*"]
 # Linux only tests
 run_dump_test "pltgot-1"
 run_dump_test "pltgot-2"
+run_dump_test "pr20830"
diff --git a/ld/testsuite/ld-i386/pr20830.d b/ld/testsuite/ld-i386/pr20830.d
new file mode 100644 (file)
index 0000000..caaadd7
--- /dev/null
@@ -0,0 +1,60 @@
+#name: PR ld/20830 (.plt.got)
+#as: --32
+#ld: -melf_i386 -shared -z relro --ld-generated-unwind-info
+#objdump: -dw -Wf
+
+.*: +file format .*
+
+Contents of the .eh_frame section:
+
+0+ 00000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 8
+  Augmentation data:     1b
+
+  DW_CFA_def_cfa: r4 \(esp\) ofs 4
+  DW_CFA_offset: r8 \(eip\) at cfa-4
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+18 00000010 0000001c FDE cie=00000000 pc=00000188..00000193
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+2c 00000020 00000030 FDE cie=00000000 pc=00000170..00000180
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_advance_loc: 6 to 00000176
+  DW_CFA_def_cfa_offset: 12
+  DW_CFA_advance_loc: 10 to 00000180
+  DW_CFA_def_cfa_expression \(DW_OP_breg4 \(esp\): 4; DW_OP_breg8 \(eip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit2; DW_OP_shl; DW_OP_plus\)
+
+0+50 00000010 00000054 FDE cie=00000000 pc=00000180..00000188
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+
+Disassembly of section .plt:
+
+0+170 <.plt>:
+ +[a-f0-9]+:   ff b3 04 00 00 00       pushl  0x4\(%ebx\)
+ +[a-f0-9]+:   ff a3 08 00 00 00       jmp    \*0x8\(%ebx\)
+ +[a-f0-9]+:   00 00                   add    %al,\(%eax\)
+       ...
+
+Disassembly of section .plt.got:
+
+0+180 <.plt.got>:
+ +[a-f0-9]+:   ff a3 fc ff ff ff       jmp    \*-0x4\(%ebx\)
+ +[a-f0-9]+:   66 90                   xchg   %ax,%ax
+
+Disassembly of section .text:
+
+0+188 <foo>:
+ +[a-f0-9]+:   e8 f3 ff ff ff          call   180 <.plt.got>
+ +[a-f0-9]+:   8b 83 fc ff ff ff       mov    -0x4\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr20830.s b/ld/testsuite/ld-i386/pr20830.s
new file mode 100644 (file)
index 0000000..344a137
--- /dev/null
@@ -0,0 +1,8 @@
+       .text
+       .globl foo
+       .type foo, @function
+foo:
+       .cfi_startproc
+       call    func@plt
+       movl    func@GOT(%ebx), %eax
+       .cfi_endproc
diff --git a/ld/testsuite/ld-x86-64/pr20830.s b/ld/testsuite/ld-x86-64/pr20830.s
new file mode 100644 (file)
index 0000000..d9a1b4c
--- /dev/null
@@ -0,0 +1,8 @@
+       .text
+       .globl foo
+       .type foo, @function
+foo:
+       .cfi_startproc
+       call    func@plt
+       movq    func@GOTPCREL(%rip), %rax
+       .cfi_endproc
diff --git a/ld/testsuite/ld-x86-64/pr20830a.d b/ld/testsuite/ld-x86-64/pr20830a.d
new file mode 100644 (file)
index 0000000..87ea25d
--- /dev/null
@@ -0,0 +1,72 @@
+#name: PR ld/20830 (.plt.got)
+#source: pr20830.s
+#as: --64
+#ld: -melf_x86_64 -shared -z relro --ld-generated-unwind-info
+#objdump: -dw -Wf
+
+.*: +file format .*
+
+Contents of the .eh_frame section:
+
+0+ 0000000000000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     1b
+
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+18 0000000000000014 0000001c FDE cie=00000000 pc=0000000000000238..0000000000000244
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+30 0000000000000024 00000034 FDE cie=00000000 pc=0000000000000220..0000000000000230
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 6 to 0000000000000226
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 10 to 0000000000000230
+  DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus\)
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+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
+
+
+Disassembly of section .plt:
+
+0+220 <.plt>:
+ +[a-f0-9]+:   ff 35 e2 0d 20 00       pushq  0x200de2\(%rip\)        # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+:   ff 25 e4 0d 20 00       jmpq   \*0x200de4\(%rip\)        # 201010 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+:   0f 1f 40 00             nopl   0x0\(%rax\)
+
+Disassembly of section .plt.got:
+
+0+230 <.plt.got>:
+ +[a-f0-9]+:   ff 25 c2 0d 20 00       jmpq   \*0x200dc2\(%rip\)        # 200ff8 <func>
+ +[a-f0-9]+:   66 90                   xchg   %ax,%ax
+
+Disassembly of section .text:
+
+0+238 <foo>:
+ +[a-f0-9]+:   e8 f3 ff ff ff          callq  230 <.plt.got>
+ +[a-f0-9]+:   48 8b 05 b4 0d 20 00    mov    0x200db4\(%rip\),%rax        # 200ff8 <func>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr20830b.d b/ld/testsuite/ld-x86-64/pr20830b.d
new file mode 100644 (file)
index 0000000..218a56e
--- /dev/null
@@ -0,0 +1,60 @@
+#name: PR ld/20830 (.plt.got)
+#source: pr20830.s
+#as: --x32
+#ld: -melf32_x86_64 -shared -z relro --ld-generated-unwind-info
+#objdump: -dw -Wf
+
+.*: +file format .*
+
+Contents of the .eh_frame section:
+
+0+ 0000000000000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     1b
+
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+18 0000000000000010 0000001c FDE cie=00000000 pc=0000000000000188..0000000000000194
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+2c 0000000000000020 00000030 FDE cie=00000000 pc=0000000000000170..0000000000000180
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 6 to 0000000000000176
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 10 to 0000000000000180
+  DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus\)
+
+0+50 0000000000000010 00000054 FDE cie=00000000 pc=0000000000000180..0000000000000188
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+
+Disassembly of section .plt:
+
+0+170 <.plt>:
+ +[a-f0-9]+:   ff 35 92 0e 20 00       pushq  0x200e92\(%rip\)        # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+:   ff 25 94 0e 20 00       jmpq   \*0x200e94\(%rip\)        # 201010 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+:   0f 1f 40 00             nopl   0x0\(%rax\)
+
+Disassembly of section .plt.got:
+
+0+180 <.plt.got>:
+ +[a-f0-9]+:   ff 25 72 0e 20 00       jmpq   \*0x200e72\(%rip\)        # 200ff8 <func>
+ +[a-f0-9]+:   66 90                   xchg   %ax,%ax
+
+Disassembly of section .text:
+
+0+188 <foo>:
+ +[a-f0-9]+:   e8 f3 ff ff ff          callq  180 <.plt.got>
+ +[a-f0-9]+:   48 8b 05 64 0e 20 00    mov    0x200e64\(%rip\),%rax        # 200ff8 <func>
+#pass
index ac63a1de12b43073f69fcbe49ce7edc5f2f0f70d..3a7ba388ff10f2a8d099640e509d03eab9e18705 100644 (file)
@@ -1017,3 +1017,5 @@ if { ![istarget "x86_64-*-linux*"]} {
 run_dump_test "pr17618"
 run_dump_test "pltgot-1"
 run_dump_test "pltgot-2"
+run_dump_test "pr20830a"
+run_dump_test "pr20830b"