[TTC-15] i386/x86-64: Add unwind info for .plt.got section submit/tizen_5.0_base/20181101.000001 submit/tizen_base/20180129.030705
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 19 Jan 2018 11:02:31 +0000 (14:02 +0300)
committerSlava Barinov <v.barinov@samsung.com>
Fri, 26 Jan 2018 08:07:17 +0000 (11:07 +0300)
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.

bfd/

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/

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.

Backport from upstream: fff53daefb7838b5718422c87946330e4a8288ce
Signed-off-by: Slava Barinov <v.barinov@samsung.com>
Change-Id: I15ead2a145afaf5dff5b7fbc84e3a8f676f7618e

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/ChangeLog
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.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr20830.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 4f859c5..ca7f80a 100644 (file)
@@ -1,3 +1,34 @@
+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.
+
 2016-08-03  Tristan Gingold  <gingold@adacore.com>
 
        * version.m4: Bump version to 2.27
index 4179572..9eeeb37 100644 (file)
@@ -647,6 +647,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.  */
@@ -678,6 +704,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) \
@@ -700,6 +730,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
 
@@ -851,6 +883,7 @@ struct elf_i386_link_hash_table
   asection *srelbss;
   asection *plt_eh_frame;
   asection *plt_got;
+  asection *plt_got_eh_frame;
 
   union
   {
@@ -2351,6 +2384,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,
+                                                3))
+               goto error_return;
+           }
        }
 
       if (r_type == R_386_GOT32X
@@ -3373,13 +3424,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 = sizeof (elf_i386_eh_frame_plt);
+  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.  */
@@ -3408,6 +3468,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->sdynbss)
        {
          /* Strip these too.  */
@@ -3467,6 +3528,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
@@ -5888,6 +5960,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;
 
@@ -6429,6 +6528,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 f920208..1b80c31 100644 (file)
@@ -658,6 +658,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
@@ -692,6 +719,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) \
@@ -720,6 +751,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 =
@@ -738,6 +771,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
@@ -866,6 +902,7 @@ struct elf_x86_64_link_hash_table
   asection *plt_eh_frame;
   asection *plt_bnd;
   asection *plt_got;
+  asection *plt_got_eh_frame;
 
   union
   {
@@ -2751,6 +2788,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,
+                                                3))
+               goto error_return;
+           }
        }
 
       if ((r_type == R_X86_64_GOTPCREL
@@ -3785,15 +3840,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.
@@ -3812,6 +3880,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->sdynbss)
        {
          /* Strip this section if we don't need it; see the
@@ -3874,6 +3943,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
@@ -6327,6 +6410,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;
@@ -6989,6 +7099,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 a57cd66..21305c3 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
+
 2016-08-03  Tristan Gingold  <gingold@adacore.com>
 
        * configure: Regenerate.
index 9efe406..7f72c6c 100644 (file)
@@ -863,3 +863,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..05a543f
--- /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 <foo-0x8>
+ +[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.d b/ld/testsuite/ld-x86-64/pr20830.d
new file mode 100644 (file)
index 0000000..7a784ad
--- /dev/null
@@ -0,0 +1,71 @@
+#name: PR ld/20830 (.plt.got)
+#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 <_DYNAMIC\+0xf0>
+ +[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 <foo-0x8>
+ +[a-f0-9]+:   48 8b 05 b4 0d 20 00    mov    0x200db4\(%rip\),%rax        # 200ff8 <_DYNAMIC\+0xf0>
+#pass
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
index f6f89e2..729a52d 100644 (file)
@@ -956,3 +956,4 @@ if { ![istarget "x86_64-*-linux*"]} {
 run_dump_test "pr17618"
 run_dump_test "pltgot-1"
 run_dump_test "pltgot-2"
+run_dump_test "pr20830"