Always define referenced __start_SECNAME/__stop_SECNAME
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 13 Jun 2017 15:53:22 +0000 (08:53 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 13 Jun 2017 15:53:22 +0000 (08:53 -0700)
Currently, linker will define __start_SECNAME and __stop_SECNAME symbols
only for orphaned sections.

However, during garbage collection, ELF linker marks all sections with
references to __start_SECNAME and __stop_SECNAME symbols as used even
when section SECNAME isn't an orphaned section and linker won't define
__start_SECNAME nor __stop_SECNAME.  And ELF linker stores the first
input section whose name matches __start_SECNAME or __stop_SECNAME in
u.undef.section for garbage collection.  If these symbols are provided
in linker script, u.undef.section is set to the section where they will
defined by linker script, which leads to the incorrect output.

This patch changes linker to always define referenced __start_SECNAME and
__stop_SECNAME if the input section name is the same as the output section
name, which is always true for orphaned sections, and SECNAME is a C
identifier.  Also __start_SECNAME and __stop_SECNAME symbols are marked
as hidden by ELF linker so that __start_SECNAME and __stop_SECNAME symbols
for section SECNAME in different modules are unique.  For garbage
collection, ELF linker stores the first matched input section in the
unused vtable field.

bfd/

PR ld/20022
PR ld/21557
PR ld/21562
PR ld/21571
* elf-bfd.h (elf_link_hash_entry): Add start_stop.  Change the
vtable field to a union.
(_bfd_elf_is_start_stop): Removed.
* elf32-i386.c (elf_i386_convert_load_reloc): Also check for
__start_SECNAME and __stop_SECNAME symbols.
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
* elflink.c (_bfd_elf_is_start_stop): Removed.
(_bfd_elf_gc_mark_rsec): Check start_stop instead of calling
_bfd_elf_is_start_stop.
(elf_gc_propagate_vtable_entries_used): Skip __start_SECNAME and
__stop_SECNAME symbols.  Updated.
(elf_gc_smash_unused_vtentry_relocs): Likewise.
(bfd_elf_gc_record_vtinherit): Likewise.
(bfd_elf_gc_record_vtentry): Likewise.

ld/

PR ld/20022
PR ld/21557
PR ld/21562
PR ld/21571
* ld.texinfo: Update __start_SECNAME/__stop_SECNAME symbols.
* ldlang.c (lang_insert_orphan): Move handling of __start_SECNAME
and __stop_SECNAME symbols to ...
(lang_set_startof): Here.  Also define __start_SECNAME and
__stop_SECNAME for -Ur.
* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Mark
referenced __start_SECNAME and __stop_SECNAME symbols as hidden
and set start_stop for garbage collection.
* testsuite/ld-elf/pr21562a.d: New file.
* testsuite/ld-elf/pr21562a.s: Likewise.
* testsuite/ld-elf/pr21562a.t: Likewise.
* testsuite/ld-elf/pr21562b.d: Likewise.
* testsuite/ld-elf/pr21562b.s: Likewise.
* testsuite/ld-elf/pr21562b.t: Likewise.
* testsuite/ld-elf/pr21562c.d: Likewise.
* testsuite/ld-elf/pr21562c.t: Likewise.
* testsuite/ld-elf/pr21562d.d: Likewise.
* testsuite/ld-elf/pr21562d.t: Likewise.
* testsuite/ld-elf/pr21562e.d: Likewise.
* testsuite/ld-elf/pr21562f.d: Likewise.
* testsuite/ld-elf/pr21562g.d: Likewise.
* testsuite/ld-elf/pr21562h.d: Likewise.
* testsuite/ld-elf/pr21562i.d: Likewise.
* testsuite/ld-elf/pr21562j.d: Likewise.
* testsuite/ld-elf/pr21562k.d: Likewise.
* testsuite/ld-elf/pr21562l.d: Likewise.
* testsuite/ld-elf/pr21562m.d: Likewise.
* testsuite/ld-elf/pr21562n.d: Likewise.
* testsuite/ld-gc/pr20022.d: Likewise.
* testsuite/ld-gc/pr20022a.s: Likewise.
* testsuite/ld-gc/pr20022b.s: Likewise.
* testsuite/ld-gc/gc.exp: Run PR ld/20022 tests.
* testsuite/ld-gc/pr19161.d: Also accept local __start_SECNAME
symbol.
* testsuite/ld-gc/start.d: Likewise.
* testsuite/ld-x86-64/lea1a.d: Updated.
* testsuite/ld-x86-64/lea1b.d: Updated.
* testsuite/ld-x86-64/lea1d.d: Updated.
* testsuite/ld-x86-64/lea1e.d: Likewise.

39 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elflink.c
ld/ChangeLog
ld/emultempl/elf32.em
ld/ld.texinfo
ld/ldlang.c
ld/testsuite/ld-elf/pr21562a.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562a.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562a.t [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562b.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562b.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562b.t [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562c.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562c.t [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562d.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562d.t [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562e.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562f.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562g.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562h.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562i.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562j.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562k.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562l.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562m.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21562n.d [new file with mode: 0644]
ld/testsuite/ld-gc/gc.exp
ld/testsuite/ld-gc/pr19161.d
ld/testsuite/ld-gc/pr20022.d [new file with mode: 0644]
ld/testsuite/ld-gc/pr20022a.s [new file with mode: 0644]
ld/testsuite/ld-gc/pr20022b.s [new file with mode: 0644]
ld/testsuite/ld-gc/start.d
ld/testsuite/ld-x86-64/lea1a.d
ld/testsuite/ld-x86-64/lea1b.d
ld/testsuite/ld-x86-64/lea1d.d
ld/testsuite/ld-x86-64/lea1e.d

index acddb3a2eec2346149a3bd2d50f88a2e38a932d5..edff887d20e8ba07fd68bfc373f1479dcc7e07f5 100644 (file)
@@ -1,3 +1,24 @@
+2017-06-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20022
+       PR ld/21557
+       PR ld/21562
+       PR ld/21571
+       * elf-bfd.h (elf_link_hash_entry): Add start_stop.  Change the
+       vtable field to a union.
+       (_bfd_elf_is_start_stop): Removed.
+       * elf32-i386.c (elf_i386_convert_load_reloc): Also check for
+       __start_SECNAME and __stop_SECNAME symbols.
+       * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
+       * elflink.c (_bfd_elf_is_start_stop): Removed.
+       (_bfd_elf_gc_mark_rsec): Check start_stop instead of calling
+       _bfd_elf_is_start_stop.
+       (elf_gc_propagate_vtable_entries_used): Skip __start_SECNAME and
+       __stop_SECNAME symbols.  Updated.
+       (elf_gc_smash_unused_vtentry_relocs): Likewise.
+       (bfd_elf_gc_record_vtinherit): Likewise.
+       (bfd_elf_gc_record_vtentry): Likewise.
+
 2017-06-13  Nick Clifton  <nickc@redhat.com>
 
        PR ld/21524
index 567b63a2de7c84796c5687587b367f85f99c880a..fe15b93342ac7aa507b06744a28a314c051fd2a9 100644 (file)
@@ -213,6 +213,9 @@ struct elf_link_hash_entry
   /* Symbol is defined by a shared library with non-default visibility
      in a read/write section.  */
   unsigned int protected_def : 1;
+  /* Symbol is __start_SECNAME or __stop_SECNAME to mark section
+     SECNAME.  */
+  unsigned int start_stop : 1;
 
   /* String table index in .dynstr if this is a dynamic symbol.  */
   unsigned long dynstr_index;
@@ -243,7 +246,15 @@ struct elf_link_hash_entry
     struct bfd_elf_version_tree *vertree;
   } verinfo;
 
-  struct elf_link_virtual_table_entry *vtable;
+  union
+  {
+    /* For __start_SECNAME and __stop_SECNAME symbols, record the first
+       input section whose section name is SECNAME.  */
+    asection *start_stop_section;
+
+    /* Vtable information. */
+    struct elf_link_virtual_table_entry *vtable;
+  } u2;
 };
 
 /* Will references to this symbol always reference the symbol
@@ -2445,9 +2456,6 @@ extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
 extern bfd_boolean bfd_elf_gc_common_final_link
   (bfd *, struct bfd_link_info *);
 
-extern asection *_bfd_elf_is_start_stop
-  (const struct bfd_link_info *, struct elf_link_hash_entry *);
-
 extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
   (bfd_vma, void *);
 
index f9142a98d5fa13ee06eda08b03c10c41c8224698..6636551fb014a15ddda81332f7fd42f8853d49e7 100644 (file)
@@ -1787,11 +1787,13 @@ convert_branch:
        return TRUE;
 
       /* def_regular is set by an assignment in a linker script in
-        bfd_elf_record_link_assignment.  */
-      if ((h->def_regular
-          || h->root.type == bfd_link_hash_defined
-          || h->root.type == bfd_link_hash_defweak)
-         && SYMBOL_REFERENCES_LOCAL (link_info, h))
+        bfd_elf_record_link_assignment.  start_stop is set on
+        __start_SECNAME/__stop_SECNAME which mark section SECNAME.  */
+      if (h->start_stop
+         || ((h->def_regular
+              || h->root.type == bfd_link_hash_defined
+              || h->root.type == bfd_link_hash_defweak)
+             && SYMBOL_REFERENCES_LOCAL (link_info, h)))
        {
 convert_load:
          if (opcode == 0x8b)
index 53060197fe66136222f75f38c5c24e785121fc37..ab6f06887e0bd23f9d44182518cb5fdf7f4b8fc3 100644 (file)
@@ -1920,21 +1920,25 @@ elf_x86_64_convert_load_reloc (bfd *abfd, asection *sec,
        }
       /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
         ld.so may use its link-time address.  */
-      else if ((h->def_regular
-               || h->root.type == bfd_link_hash_defined
-               || h->root.type == bfd_link_hash_defweak)
-              && h != htab->elf.hdynamic
-              && SYMBOL_REFERENCES_LOCAL (link_info, h))
+      else if (h->start_stop
+              || ((h->def_regular
+                   || h->root.type == bfd_link_hash_defined
+                   || h->root.type == bfd_link_hash_defweak)
+                  && h != htab->elf.hdynamic
+                  && SYMBOL_REFERENCES_LOCAL (link_info, h)))
        {
          /* bfd_link_hash_new or bfd_link_hash_undefined is
             set by an assignment in a linker script in
-            bfd_elf_record_link_assignment.   */
-         if (h->def_regular
-             && (h->root.type == bfd_link_hash_new
-                 || h->root.type == bfd_link_hash_undefined
-                 || ((h->root.type == bfd_link_hash_defined
-                      || h->root.type == bfd_link_hash_defweak)
-                     && h->root.u.def.section == bfd_und_section_ptr)))
+            bfd_elf_record_link_assignment.  start_stop is set
+            on __start_SECNAME/__stop_SECNAME which mark section
+            SECNAME.  */
+         if (h->start_stop
+             || (h->def_regular
+                 && (h->root.type == bfd_link_hash_new
+                     || h->root.type == bfd_link_hash_undefined
+                     || ((h->root.type == bfd_link_hash_defined
+                          || h->root.type == bfd_link_hash_defweak)
+                         && h->root.u.def.section == bfd_und_section_ptr))))
            {
              /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
              if (require_reloc_pc32)
index f0ca33f155b071a82c51a36071a5a28974895223..9b0f54435201df5fdaab792490883957282a09bb 100644 (file)
@@ -12698,55 +12698,6 @@ elf_gc_mark_debug_section (asection *sec ATTRIBUTE_UNUSED,
   return NULL;
 }
 
-/* For undefined __start_<name> and __stop_<name> symbols, return the
-   first input section matching <name>.  Return NULL otherwise.  */
-
-asection *
-_bfd_elf_is_start_stop (const struct bfd_link_info *info,
-                       struct elf_link_hash_entry *h)
-{
-  asection *s;
-  const char *sec_name;
-
-  if (h->root.type != bfd_link_hash_undefined
-      && h->root.type != bfd_link_hash_undefweak)
-    return NULL;
-
-  s = h->root.u.undef.section;
-  if (s != NULL)
-    {
-      if (s == (asection *) 0 - 1)
-       return NULL;
-      return s;
-    }
-
-  sec_name = NULL;
-  if (strncmp (h->root.root.string, "__start_", 8) == 0)
-    sec_name = h->root.root.string + 8;
-  else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
-    sec_name = h->root.root.string + 7;
-
-  if (sec_name != NULL && *sec_name != '\0')
-    {
-      bfd *i;
-
-      for (i = info->input_bfds; i != NULL; i = i->link.next)
-       {
-         s = bfd_get_section_by_name (i, sec_name);
-         if (s != NULL)
-           {
-             h->root.u.undef.section = s;
-             break;
-           }
-       }
-    }
-
-  if (s == NULL)
-    h->root.u.undef.section = (asection *) 0 - 1;
-
-  return s;
-}
-
 /* COOKIE->rel describes a relocation against section SEC, which is
    a section we've decided to keep.  Return the section that contains
    the relocation symbol, or NULL if no section contains it.  */
@@ -12792,10 +12743,9 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
             or __stop_XXX symbols.  The linker will later define such
             symbols for orphan input sections that have a name
             representable as a C identifier.  */
-         asection *s = _bfd_elf_is_start_stop (info, h);
-
-         if (s != NULL)
+         if (h->start_stop)
            {
+             asection *s = h->u2.start_stop_section;
              *start_stop = !s->gc_mark;
              return s;
            }
@@ -13136,26 +13086,28 @@ static bfd_boolean
 elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
 {
   /* Those that are not vtables.  */
-  if (h->vtable == NULL || h->vtable->parent == NULL)
+  if (h->start_stop
+      || h->u2.vtable == NULL
+      || h->u2.vtable->parent == NULL)
     return TRUE;
 
   /* Those vtables that do not have parents, we cannot merge.  */
-  if (h->vtable->parent == (struct elf_link_hash_entry *) -1)
+  if (h->u2.vtable->parent == (struct elf_link_hash_entry *) -1)
     return TRUE;
 
   /* If we've already been done, exit.  */
-  if (h->vtable->used && h->vtable->used[-1])
+  if (h->u2.vtable->used && h->u2.vtable->used[-1])
     return TRUE;
 
   /* Make sure the parent's table is up to date.  */
-  elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp);
+  elf_gc_propagate_vtable_entries_used (h->u2.vtable->parent, okp);
 
-  if (h->vtable->used == NULL)
+  if (h->u2.vtable->used == NULL)
     {
       /* None of this table's entries were referenced.  Re-use the
         parent's table.  */
-      h->vtable->used = h->vtable->parent->vtable->used;
-      h->vtable->size = h->vtable->parent->vtable->size;
+      h->u2.vtable->used = h->u2.vtable->parent->u2.vtable->used;
+      h->u2.vtable->size = h->u2.vtable->parent->u2.vtable->size;
     }
   else
     {
@@ -13163,9 +13115,9 @@ elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
       bfd_boolean *cu, *pu;
 
       /* Or the parent's entries into ours.  */
-      cu = h->vtable->used;
+      cu = h->u2.vtable->used;
       cu[-1] = TRUE;
-      pu = h->vtable->parent->vtable->used;
+      pu = h->u2.vtable->parent->u2.vtable->used;
       if (pu != NULL)
        {
          const struct elf_backend_data *bed;
@@ -13173,7 +13125,7 @@ elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
 
          bed = get_elf_backend_data (h->root.u.def.section->owner);
          log_file_align = bed->s->log_file_align;
-         n = h->vtable->parent->vtable->size >> log_file_align;
+         n = h->u2.vtable->parent->u2.vtable->size >> log_file_align;
          while (n--)
            {
              if (*pu)
@@ -13198,7 +13150,9 @@ elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
 
   /* Take care of both those symbols that do not describe vtables as
      well as those that are not loaded.  */
-  if (h->vtable == NULL || h->vtable->parent == NULL)
+  if (h->start_stop
+      || h->u2.vtable == NULL
+      || h->u2.vtable->parent == NULL)
     return TRUE;
 
   BFD_ASSERT (h->root.type == bfd_link_hash_defined
@@ -13220,11 +13174,11 @@ elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
     if (rel->r_offset >= hstart && rel->r_offset < hend)
       {
        /* If the entry is in use, do nothing.  */
-       if (h->vtable->used
-           && (rel->r_offset - hstart) < h->vtable->size)
+       if (h->u2.vtable->used
+           && (rel->r_offset - hstart) < h->u2.vtable->size)
          {
            bfd_vma entry = (rel->r_offset - hstart) >> log_file_align;
-           if (h->vtable->used[entry])
+           if (h->u2.vtable->used[entry])
              continue;
          }
        /* Otherwise, kill it.  */
@@ -13448,11 +13402,11 @@ bfd_elf_gc_record_vtinherit (bfd *abfd,
   return FALSE;
 
  win:
-  if (!child->vtable)
+  if (!child->u2.vtable)
     {
-      child->vtable = ((struct elf_link_virtual_table_entry *)
-                      bfd_zalloc (abfd, sizeof (*child->vtable)));
-      if (!child->vtable)
+      child->u2.vtable = ((struct elf_link_virtual_table_entry *)
+                         bfd_zalloc (abfd, sizeof (*child->u2.vtable)));
+      if (!child->u2.vtable)
        return FALSE;
     }
   if (!h)
@@ -13462,10 +13416,10 @@ bfd_elf_gc_record_vtinherit (bfd *abfd,
         would be bad.  It isn't worth paging in the local symbols to be
         sure though; that case should simply be handled by the assembler.  */
 
-      child->vtable->parent = (struct elf_link_hash_entry *) -1;
+      child->u2.vtable->parent = (struct elf_link_hash_entry *) -1;
     }
   else
-    child->vtable->parent = h;
+    child->u2.vtable->parent = h;
 
   return TRUE;
 }
@@ -13481,18 +13435,18 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   unsigned int log_file_align = bed->s->log_file_align;
 
-  if (!h->vtable)
+  if (!h->u2.vtable)
     {
-      h->vtable = ((struct elf_link_virtual_table_entry *)
-                  bfd_zalloc (abfd, sizeof (*h->vtable)));
-      if (!h->vtable)
+      h->u2.vtable = ((struct elf_link_virtual_table_entry *)
+                     bfd_zalloc (abfd, sizeof (*h->u2.vtable)));
+      if (!h->u2.vtable)
        return FALSE;
     }
 
-  if (addend >= h->vtable->size)
+  if (addend >= h->u2.vtable->size)
     {
       size_t size, bytes, file_align;
-      bfd_boolean *ptr = h->vtable->used;
+      bfd_boolean *ptr = h->u2.vtable->used;
 
       /* While the symbol is undefined, we have to be prepared to handle
         a zero size.  */
@@ -13523,7 +13477,7 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
            {
              size_t oldbytes;
 
-             oldbytes = (((h->vtable->size >> log_file_align) + 1)
+             oldbytes = (((h->u2.vtable->size >> log_file_align) + 1)
                          * sizeof (bfd_boolean));
              memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes);
            }
@@ -13535,11 +13489,11 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
        return FALSE;
 
       /* And arrange for that done flag to be at index -1.  */
-      h->vtable->used = ptr + 1;
-      h->vtable->size = size;
+      h->u2.vtable->used = ptr + 1;
+      h->u2.vtable->size = size;
     }
 
-  h->vtable->used[addend >> log_file_align] = TRUE;
+  h->u2.vtable->used[addend >> log_file_align] = TRUE;
 
   return TRUE;
 }
index 309bb3a49f14012d61573c15f7f0a90791e666a3..dcfc602263096847572ae2794fe3c12a85533632 100644 (file)
@@ -1,3 +1,49 @@
+2017-06-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20022
+       PR ld/21557
+       PR ld/21562
+       PR ld/21571
+       * ld.texinfo: Update __start_SECNAME/__stop_SECNAME symbols.
+       * ldlang.c (lang_insert_orphan): Move handling of __start_SECNAME
+       and __stop_SECNAME symbols to ...
+       (lang_set_startof): Here.  Also define __start_SECNAME and
+       __stop_SECNAME for -Ur.
+       * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Mark
+       referenced __start_SECNAME and __stop_SECNAME symbols as hidden
+       and set start_stop for garbage collection.
+       * testsuite/ld-elf/pr21562a.d: New file.
+       * testsuite/ld-elf/pr21562a.s: Likewise.
+       * testsuite/ld-elf/pr21562a.t: Likewise.
+       * testsuite/ld-elf/pr21562b.d: Likewise.
+       * testsuite/ld-elf/pr21562b.s: Likewise.
+       * testsuite/ld-elf/pr21562b.t: Likewise.
+       * testsuite/ld-elf/pr21562c.d: Likewise.
+       * testsuite/ld-elf/pr21562c.t: Likewise.
+       * testsuite/ld-elf/pr21562d.d: Likewise.
+       * testsuite/ld-elf/pr21562d.t: Likewise.
+       * testsuite/ld-elf/pr21562e.d: Likewise.
+       * testsuite/ld-elf/pr21562f.d: Likewise.
+       * testsuite/ld-elf/pr21562g.d: Likewise.
+       * testsuite/ld-elf/pr21562h.d: Likewise.
+       * testsuite/ld-elf/pr21562i.d: Likewise.
+       * testsuite/ld-elf/pr21562j.d: Likewise.
+       * testsuite/ld-elf/pr21562k.d: Likewise.
+       * testsuite/ld-elf/pr21562l.d: Likewise.
+       * testsuite/ld-elf/pr21562m.d: Likewise.
+       * testsuite/ld-elf/pr21562n.d: Likewise.
+       * testsuite/ld-gc/pr20022.d: Likewise.
+       * testsuite/ld-gc/pr20022a.s: Likewise.
+       * testsuite/ld-gc/pr20022b.s: Likewise.
+       * testsuite/ld-gc/gc.exp: Run PR ld/20022 tests.
+       * testsuite/ld-gc/pr19161.d: Also accept local __start_SECNAME
+       symbol.
+       * testsuite/ld-gc/start.d: Likewise.
+       * testsuite/ld-x86-64/lea1a.d: Updated.
+       * testsuite/ld-x86-64/lea1b.d: Updated.
+       * testsuite/ld-x86-64/lea1d.d: Updated.
+       * testsuite/ld-x86-64/lea1e.d: Likewise.
+
 2017-06-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/ld-elf/sizeof.d: New file.
index 0260b7ac44c211de2260fb2838dffe59a4ca0de0..9468f7d29f2b221c0446e25f3a39872f25dd37d2 100644 (file)
@@ -1216,6 +1216,9 @@ gld${EMULATION_NAME}_after_open (void)
 {
   struct bfd_link_needed_list *needed, *l;
   struct elf_link_hash_table *htab;
+  asection *s;
+  bfd *abfd;
+  char leading_char;
 
   after_open_default ();
 
@@ -1239,8 +1242,6 @@ gld${EMULATION_NAME}_after_open (void)
 
   if (emit_note_gnu_build_id != NULL)
     {
-      bfd *abfd;
-
       /* Find an ELF input.  */
       for (abfd = link_info.input_bfds;
           abfd != (bfd *) NULL; abfd = abfd->link.next)
@@ -1276,11 +1277,66 @@ gld${EMULATION_NAME}_after_open (void)
       return;
     }
 
+  leading_char = bfd_get_symbol_leading_char (link_info.output_bfd);
+
+  /* Check for input sections whose names match references to
+     __start_SECNAME or __stop_SECNAME symbols.  Mark the matched
+     symbols as hidden and set start_stop for garbage collection.  */
+  for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
+    for (s = abfd->sections; s; s = s->next)
+      {
+       const char *name = bfd_get_section_name (abfd, s);
+       const char *ps;
+
+       for (ps = name; *ps != '\0'; ps++)
+         if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
+           break;
+       if (*ps == '\0')
+         {
+           struct elf_link_hash_entry *h;
+           char *symbol = (char *) xmalloc (ps - name
+                                            + sizeof "__start_" + 1);
+
+           symbol[0] = leading_char;
+           sprintf (symbol + (leading_char != 0), "__start_%s", name);
+           h = elf_link_hash_lookup (elf_hash_table (&link_info),
+                                     symbol, FALSE, FALSE, TRUE);
+           if (h != NULL
+               && (h->root.type == bfd_link_hash_undefined
+                   || h->root.type == bfd_link_hash_undefweak)
+               && h->u2.start_stop_section == NULL)
+             {
+               h->start_stop = 1;
+               h->u2.start_stop_section = s;
+               _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
+               if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+                 h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
+                             | STV_HIDDEN);
+             }
+
+           symbol[0] = leading_char;
+           sprintf (symbol + (leading_char != 0), "__stop_%s", name);
+           h = elf_link_hash_lookup (elf_hash_table (&link_info),
+                                     symbol, FALSE, FALSE, TRUE);
+           if (h != NULL
+               && (h->root.type == bfd_link_hash_undefined
+                   || h->root.type == bfd_link_hash_undefweak)
+               && h->u2.start_stop_section == NULL)
+             {
+               h->start_stop = 1;
+               h->u2.start_stop_section = s;
+               _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
+               if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+                 h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
+                             | STV_HIDDEN);
+             }
+         }
+      }
+
   if (!link_info.traditional_format)
     {
-      bfd *abfd, *elfbfd = NULL;
+      bfd *elfbfd = NULL;
       bfd_boolean warn_eh_frame = FALSE;
-      asection *s;
       int seen_type = 0;
 
       for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
index 790b52f0251f2558d67273e2879d75754ea34341..44ad84b351726f98a562f68addf555cf517b70db 100644 (file)
@@ -4657,6 +4657,14 @@ SECTIONS @{
 @end group
 @end smallexample
 
+If an output section's name is the same as the input section's name
+and is representable as a C identifier, then the linker will
+automatically @pxref{PROVIDE} two symbols: __start_SECNAME and
+__stop_SECNAME, where SECNAME is the name of the section.  These
+indicate the start address and end address of the output section
+respectively.  Note: most section names are not representable as
+C identifiers because they contain a @samp{.} character.
+
 @node Output Section Data
 @subsection Output Section Data
 @cindex data
@@ -5841,14 +5849,6 @@ The command line options @samp{--orphan-handling} and @samp{--unique}
 (@pxref{Options,,Command Line Options}) can be used to control which
 output sections an orphan is placed in.
 
-If an orphaned section's name is representable as a C identifier then
-the linker will automatically @pxref{PROVIDE} two symbols:
-__start_SECNAME and __stop_SECNAME, where SECNAME is the name of the
-section.  These indicate the start address and end address of the
-orphaned section respectively.  Note: most section names are not
-representable as C identifiers because they contain a @samp{.}
-character.
-
 @node Location Counter
 @subsection The Location Counter
 @kindex .
index 252400bd510d8924c9ea343490d9bdc86f842ac5..f8e4f528799a327a415c84d5f99f1f2b6e723447 100644 (file)
@@ -1829,8 +1829,6 @@ lang_insert_orphan (asection *s,
                    lang_statement_list_type *add_child)
 {
   lang_statement_list_type add;
-  const char *ps;
-  lang_assignment_statement_type *start_assign;
   lang_output_section_statement_type *os;
   lang_output_section_statement_type **os_tail;
 
@@ -1852,29 +1850,6 @@ lang_insert_orphan (asection *s,
   os = lang_enter_output_section_statement (secname, address, normal_section,
                                            NULL, NULL, NULL, constraint, 0);
 
-  ps = NULL;
-  start_assign = NULL;
-  if (config.build_constructors && *os_tail == os)
-    {
-      /* If the name of the section is representable in C, then create
-        symbols to mark the start and the end of the section.  */
-      for (ps = secname; *ps != '\0'; ps++)
-       if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
-         break;
-      if (*ps == '\0')
-       {
-         char *symname;
-
-         symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
-         symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
-         sprintf (symname + (symname[0] != 0), "__start_%s", secname);
-         start_assign
-           = lang_add_assignment (exp_provide (symname,
-                                               exp_nameop (NAME, "."),
-                                               FALSE));
-       }
-    }
-
   if (add_child == NULL)
     add_child = &os->children;
   lang_add_section (add_child, s, NULL, os);
@@ -1894,27 +1869,6 @@ lang_insert_orphan (asection *s,
     lang_leave_output_section_statement (NULL, DEFAULT_MEMORY_REGION, NULL,
                                         NULL);
 
-  if (start_assign != NULL)
-    {
-      char *symname;
-      lang_assignment_statement_type *stop_assign;
-      bfd_vma dot;
-
-      symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
-      symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
-      sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
-      stop_assign
-       = lang_add_assignment (exp_provide (symname,
-                                           exp_nameop (NAME, "."),
-                                           FALSE));
-      /* Evaluate the expression to define the symbol if referenced,
-        before sizing dynamic sections.  */
-      dot = os->bfd_section->vma;
-      exp_fold_tree (start_assign->exp, os->bfd_section, &dot);
-      dot += TO_ADDR (s->size);
-      exp_fold_tree (stop_assign->exp, os->bfd_section, &dot);
-    }
-
   /* Restore the global list pointer.  */
   if (after != NULL)
     pop_stat_ptr ();
@@ -5924,20 +5878,25 @@ section_for_dot (void)
   return bfd_abs_section_ptr;
 }
 
-/* Fix any .startof. or .sizeof. symbols.  When the assemblers see the
-   operator .startof. (section_name), it produces an undefined symbol
-   .startof.section_name.  Similarly, when it sees
+/* Fix any .startof., .sizeof., __start or __stop symbols.  When the
+   assemblers see the operator .startof. (section_name), it produces
+   an undefined symbol .startof.section_name.  Similarly, when it sees
    .sizeof. (section_name), it produces an undefined symbol
-   .sizeof.section_name.  For all the output sections, we look for
-   such symbols, and set them to the correct value.  */
+   .sizeof.section_name.  Also for ELF linker, __start_XXX or __stop_XXX
+   symbols should be resolved to the start and end of section XXX.  For
+   all the output sections, we look for such symbols, and set them to
+   the correct value.  */
 
 static void
 lang_set_startof (void)
 {
   asection *s;
+  char leading_char;
+  bfd_boolean is_elf = (bfd_get_flavour (link_info.output_bfd)
+                       == bfd_target_elf_flavour);
+  bfd_boolean is_elocatable = bfd_link_relocatable (&link_info);
 
-  if (bfd_link_relocatable (&link_info))
-    return;
+  leading_char = bfd_get_symbol_leading_char (link_info.output_bfd);
 
   for (s = link_info.output_bfd->sections; s != NULL; s = s->next)
     {
@@ -5948,24 +5907,58 @@ lang_set_startof (void)
       secname = bfd_get_section_name (link_info.output_bfd, s);
       buf = (char *) xmalloc (10 + strlen (secname));
 
-      sprintf (buf, ".startof.%s", secname);
-      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
-      if (h != NULL && h->type == bfd_link_hash_undefined)
+      if (!is_elocatable)
+       {
+         sprintf (buf, ".startof.%s", secname);
+         h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+                                   TRUE);
+         if (h != NULL && h->type == bfd_link_hash_undefined)
+           {
+             h->type = bfd_link_hash_defined;
+             h->u.def.value = 0;
+             h->u.def.section = s;
+           }
+
+         sprintf (buf, ".sizeof.%s", secname);
+         h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+                                   TRUE);
+         if (h != NULL && h->type == bfd_link_hash_undefined)
+           {
+             h->type = bfd_link_hash_defined;
+             h->u.def.value = TO_ADDR (s->size);
+             h->u.def.section = bfd_abs_section_ptr;
+           }
+       }
+
+      buf[0] = leading_char;
+      sprintf (buf + (buf[0] != 0), "__start_%s", secname);
+      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+                               TRUE);
+      if (h != NULL
+         && (h->type == bfd_link_hash_undefined
+             || h->type == bfd_link_hash_undefweak))
        {
          h->type = bfd_link_hash_defined;
          h->u.def.value = 0;
          h->u.def.section = s;
+         if (is_elf)
+           ((struct elf_link_hash_entry *) h)->def_regular = 1;
        }
 
-      sprintf (buf, ".sizeof.%s", secname);
-      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
-      if (h != NULL && h->type == bfd_link_hash_undefined)
+      buf[0] = leading_char;
+      sprintf (buf + (buf[0] != 0), "__stop_%s", secname);
+      h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+                               TRUE);
+      if (h != NULL
+         && (h->type == bfd_link_hash_undefined
+             || h->type == bfd_link_hash_undefweak))
        {
          h->type = bfd_link_hash_defined;
          h->u.def.value = TO_ADDR (s->size);
-         h->u.def.section = bfd_abs_section_ptr;
+         h->u.def.section = s;
+         if (is_elf)
+           ((struct elf_link_hash_entry *) h)->def_regular = 1;
        }
-
       free (buf);
     }
 }
diff --git a/ld/testsuite/ld-elf/pr21562a.d b/ld/testsuite/ld-elf/pr21562a.d
new file mode 100644 (file)
index 0000000..009dcfc
--- /dev/null
@@ -0,0 +1,9 @@
+#ld: -shared -z defs --gc-sections
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562a.s b/ld/testsuite/ld-elf/pr21562a.s
new file mode 100644 (file)
index 0000000..ec36da4
--- /dev/null
@@ -0,0 +1,8 @@
+        .section        scnfoo,"aw",%progbits
+        .zero 0x10
+
+        .globl  bar
+        .data
+        .type   bar, %object
+bar:
+        .dc.a   __start_scnfoo
diff --git a/ld/testsuite/ld-elf/pr21562a.t b/ld/testsuite/ld-elf/pr21562a.t
new file mode 100644 (file)
index 0000000..5e05ab3
--- /dev/null
@@ -0,0 +1,3 @@
+SECTIONS {
+       scnfoo : { *(scnfoo) }
+}
diff --git a/ld/testsuite/ld-elf/pr21562b.d b/ld/testsuite/ld-elf/pr21562b.d
new file mode 100644 (file)
index 0000000..a03dbad
--- /dev/null
@@ -0,0 +1,9 @@
+#ld: -shared -z defs --gc-sections
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562b.s b/ld/testsuite/ld-elf/pr21562b.s
new file mode 100644 (file)
index 0000000..1732ee2
--- /dev/null
@@ -0,0 +1,8 @@
+        .section        scnfoo,"aw",%progbits
+        .zero 0x10
+
+        .globl  bar
+        .data
+        .type   bar, %object
+bar:
+        .dc.a   __stop_scnfoo
diff --git a/ld/testsuite/ld-elf/pr21562b.t b/ld/testsuite/ld-elf/pr21562b.t
new file mode 100644 (file)
index 0000000..b30b521
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS {
+       PROVIDE (__start_scnfoo = .);
+       scnfoo : { *(scnfoo) }
+       PROVIDE (__stop_scnfoo = .);
+}
diff --git a/ld/testsuite/ld-elf/pr21562c.d b/ld/testsuite/ld-elf/pr21562c.d
new file mode 100644 (file)
index 0000000..9de035f
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562c.t b/ld/testsuite/ld-elf/pr21562c.t
new file mode 100644 (file)
index 0000000..f9cb901
--- /dev/null
@@ -0,0 +1,7 @@
+SECTIONS {
+    .foo : {
+       PROVIDE (__start_scnfoo = .);
+       *(scnfoo)
+       PROVIDE (__stop_scnfoo = .);
+    }
+}
diff --git a/ld/testsuite/ld-elf/pr21562d.d b/ld/testsuite/ld-elf/pr21562d.d
new file mode 100644 (file)
index 0000000..e5344ef
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562d.t b/ld/testsuite/ld-elf/pr21562d.t
new file mode 100644 (file)
index 0000000..c0cea61
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS {
+       PROVIDE (__start_scnfoo = .);
+       .foo : { *(scnfoo) }
+       PROVIDE (__stop_scnfoo = .);
+}
diff --git a/ld/testsuite/ld-elf/pr21562e.d b/ld/testsuite/ld-elf/pr21562e.d
new file mode 100644 (file)
index 0000000..afaf7e5
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562a.s
+#ld: -shared -z defs
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562f.d b/ld/testsuite/ld-elf/pr21562f.d
new file mode 100644 (file)
index 0000000..b9c324a
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562b.s
+#ld: -shared -z defs
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562g.d b/ld/testsuite/ld-elf/pr21562g.d
new file mode 100644 (file)
index 0000000..a813594
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562a.s
+#ld: -shared -z defs -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562h.d b/ld/testsuite/ld-elf/pr21562h.d
new file mode 100644 (file)
index 0000000..6adabd7
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562b.s
+#ld: -shared -z defs -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562i.d b/ld/testsuite/ld-elf/pr21562i.d
new file mode 100644 (file)
index 0000000..49eb2ec
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562b.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562j.d b/ld/testsuite/ld-elf/pr21562j.d
new file mode 100644 (file)
index 0000000..14bb035
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562b.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562k.d b/ld/testsuite/ld-elf/pr21562k.d
new file mode 100644 (file)
index 0000000..1bf1e93
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562c.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562l.d b/ld/testsuite/ld-elf/pr21562l.d
new file mode 100644 (file)
index 0000000..8297ec2
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562c.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562m.d b/ld/testsuite/ld-elf/pr21562m.d
new file mode 100644 (file)
index 0000000..34f8df0
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562d.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
diff --git a/ld/testsuite/ld-elf/pr21562n.d b/ld/testsuite/ld-elf/pr21562n.d
new file mode 100644 (file)
index 0000000..e4b1919
--- /dev/null
@@ -0,0 +1,10 @@
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562d.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+  \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
index ba5c46b64f82f3752c8e116b9a69e2ddcdd9dda8..364c73bf5d4941120416427f2f060113adfdeea8 100644 (file)
@@ -119,6 +119,12 @@ if { [is_elf_format] && [check_shared_lib_support] } then {
        run_dump_test "personality"
     }
     run_dump_test "pr18223"
+    if {![ld_assemble_flags $as $gasopt $srcdir/$subdir/pr20022a.s tmpdir/pr20022a.o]
+       || ![ld_link $ld tmpdir/pr20022.so "-shared --gc-sections tmpdir/pr20022a.o"] } then {
+       fail pr20022
+    } else {
+       run_dump_test "pr20022"
+    }
 }
 
 if { [is_remote host] || [which $CC] != 0 } {
index c36e6638cd0d3da559ce6bcf6a43428575477f44..baee8da3af953b13b255d93d373fa1f0077242ad 100644 (file)
@@ -6,5 +6,5 @@
 #xfail: mips64vr-*-* msp430-*-* powerpc*-*-eabivle rl78-*-* rx-*-* sh*-*-*
 
 #...
-0*[1-9a-f]+[0-9a-f]*[  ](D)[   ]_*__start_my_section
+0*[1-9a-f]+[0-9a-f]*[  ](d|D)[         ]_*__start_my_section
 #...
diff --git a/ld/testsuite/ld-gc/pr20022.d b/ld/testsuite/ld-gc/pr20022.d
new file mode 100644 (file)
index 0000000..b51ec19
--- /dev/null
@@ -0,0 +1,11 @@
+#source: pr20022b.s
+#ld: --gc-sections -e _start tmpdir/pr20022.so
+#readelf: -SsW
+#target: *-*-linux* *-*-gnu*
+#notarget: *-*-*aout *-*-*oldld frv-*-linux* metag-*-linux*
+
+#...
+  \[[ 0-9]+\] _foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start__foo
+#pass
diff --git a/ld/testsuite/ld-gc/pr20022a.s b/ld/testsuite/ld-gc/pr20022a.s
new file mode 100644 (file)
index 0000000..6bd346f
--- /dev/null
@@ -0,0 +1,8 @@
+       .data
+       .globl bar
+       .type bar,%object
+bar:
+       .dc.a   __start__foo
+       .section _foo,"aw",%progbits
+foo:
+       .ascii "This is bar"
diff --git a/ld/testsuite/ld-gc/pr20022b.s b/ld/testsuite/ld-gc/pr20022b.s
new file mode 100644 (file)
index 0000000..2306c59
--- /dev/null
@@ -0,0 +1,8 @@
+       .text
+       .globl _start
+_start:
+       .dc.a   __start__foo
+       .dc.a   bar
+       .section _foo,"aw",%progbits
+foo:
+       .ascii "This is foo"
index 18e74c109c08dbce747f2b4cda09d3faabf996ab..9113b482043d574a88e76dd7095dff21846da185 100644 (file)
@@ -5,5 +5,5 @@
 #notarget: *-*-*aout *-*-*oldld frv-*-linux* metag-*-linux*
 
 #...
-[0-9a-f]+ D +__start__foo
+[0-9a-f]+ d +__start__foo
 #...
index 9b662cb839fc12d551836adf8ab1b3824d5a9098..28ea4b93fccd127b23f03eb14bfda9cbf01796c6 100644 (file)
@@ -15,5 +15,5 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    -0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <foo>
 [      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <bar>
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <__start_my_section>
-[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <__stop_my_section>
+[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <.*>
 #pass
index 9108149b3a3842f78f1aed193797af10aa260b07..c7873cd97bd67ccb3755f92c0883fe17e15bf3c0 100644 (file)
@@ -15,5 +15,5 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    -0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <foo>
 [      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <bar>
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <__start_my_section>
-[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <__stop_my_section>
+[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <.*>
 #pass
index 4d708d22c3a082d41e789fed6984535fade45a9e..70fc603894d19c1a22f216bbc1aafda0c1dbd5a6 100644 (file)
@@ -15,5 +15,5 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    -0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <foo>
 [      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <bar>
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <__start_my_section>
-[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <__stop_my_section>
+[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <.*>
 #pass
index da6013791810bc492872300453764b2ca2cfe22c..123fcd243c92215c8bbc7b27780838731a122c9d 100644 (file)
@@ -15,5 +15,5 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    -0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <foo>
 [      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <bar>
 [      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <__start_my_section>
-[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <__stop_my_section>
+[      ]*[a-f0-9]+:    4c 8d 1d ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%r11        # [a-f0-9]+ <.*>
 #pass