aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-06-13 08:53:22 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-06-13 08:53:22 -0700
commitcbd0eecf261c2447781f8c89b0d955ee66fae7e9 (patch)
tree1a8139f0a7989d71079057f6000877af275b546d /ld
parent6490dc678bc35f2204afb38449de5127ef8bcca0 (diff)
Always define referenced __start_SECNAME/__stop_SECNAME
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog46
-rw-r--r--ld/emultempl/elf32.em64
-rw-r--r--ld/ld.texinfo16
-rw-r--r--ld/ldlang.c115
-rw-r--r--ld/testsuite/ld-elf/pr21562a.d9
-rw-r--r--ld/testsuite/ld-elf/pr21562a.s8
-rw-r--r--ld/testsuite/ld-elf/pr21562a.t3
-rw-r--r--ld/testsuite/ld-elf/pr21562b.d9
-rw-r--r--ld/testsuite/ld-elf/pr21562b.s8
-rw-r--r--ld/testsuite/ld-elf/pr21562b.t5
-rw-r--r--ld/testsuite/ld-elf/pr21562c.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562c.t7
-rw-r--r--ld/testsuite/ld-elf/pr21562d.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562d.t5
-rw-r--r--ld/testsuite/ld-elf/pr21562e.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562f.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562g.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562h.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562i.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562j.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562k.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562l.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562m.d10
-rw-r--r--ld/testsuite/ld-elf/pr21562n.d10
-rw-r--r--ld/testsuite/ld-gc/gc.exp6
-rw-r--r--ld/testsuite/ld-gc/pr19161.d2
-rw-r--r--ld/testsuite/ld-gc/pr20022.d11
-rw-r--r--ld/testsuite/ld-gc/pr20022a.s8
-rw-r--r--ld/testsuite/ld-gc/pr20022b.s8
-rw-r--r--ld/testsuite/ld-gc/start.d2
-rw-r--r--ld/testsuite/ld-x86-64/lea1a.d2
-rw-r--r--ld/testsuite/ld-x86-64/lea1b.d2
-rw-r--r--ld/testsuite/ld-x86-64/lea1d.d2
-rw-r--r--ld/testsuite/ld-x86-64/lea1e.d2
34 files changed, 381 insertions, 79 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 309bb3a49f..dcfc602263 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,51 @@
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.
* testsuite/ld-elf/sizeof.s: Likewise.
* testsuite/ld-elf/startof.d: Likewise.
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 0260b7ac44..9468f7d29f 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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)
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 790b52f025..44ad84b351 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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 .
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 252400bd51..f8e4f52879 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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
index 0000000000..009dcfc05c
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562a.d
@@ -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
index 0000000000..ec36da4b8e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562a.s
@@ -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
index 0000000000..5e05ab3302
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562a.t
@@ -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
index 0000000000..a03dbad6a0
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562b.d
@@ -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
index 0000000000..1732ee24b2
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562b.s
@@ -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
index 0000000000..b30b521d40
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562b.t
@@ -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
index 0000000000..9de035faac
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562c.d
@@ -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
index 0000000000..f9cb901afb
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562c.t
@@ -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
index 0000000000..e5344eff80
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562d.d
@@ -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
index 0000000000..c0cea61f06
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562d.t
@@ -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
index 0000000000..afaf7e56a6
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562e.d
@@ -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
index 0000000000..b9c324a47d
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562f.d
@@ -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
index 0000000000..a813594d27
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562g.d
@@ -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
index 0000000000..6adabd7ba4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562h.d
@@ -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
index 0000000000..49eb2ecb64
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562i.d
@@ -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
index 0000000000..14bb03587d
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562j.d
@@ -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
index 0000000000..1bf1e93177
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562k.d
@@ -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
index 0000000000..8297ec2b8e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562l.d
@@ -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
index 0000000000..34f8df09aa
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562m.d
@@ -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
index 0000000000..e4b1919c67
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21562n.d
@@ -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
diff --git a/ld/testsuite/ld-gc/gc.exp b/ld/testsuite/ld-gc/gc.exp
index ba5c46b64f..364c73bf5d 100644
--- a/ld/testsuite/ld-gc/gc.exp
+++ b/ld/testsuite/ld-gc/gc.exp
@@ -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 } {
diff --git a/ld/testsuite/ld-gc/pr19161.d b/ld/testsuite/ld-gc/pr19161.d
index c36e6638cd..baee8da3af 100644
--- a/ld/testsuite/ld-gc/pr19161.d
+++ b/ld/testsuite/ld-gc/pr19161.d
@@ -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
index 0000000000..b51ec1903f
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20022.d
@@ -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
index 0000000000..6bd346fe21
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20022a.s
@@ -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
index 0000000000..2306c59d76
--- /dev/null
+++ b/ld/testsuite/ld-gc/pr20022b.s
@@ -0,0 +1,8 @@
+ .text
+ .globl _start
+_start:
+ .dc.a __start__foo
+ .dc.a bar
+ .section _foo,"aw",%progbits
+foo:
+ .ascii "This is foo"
diff --git a/ld/testsuite/ld-gc/start.d b/ld/testsuite/ld-gc/start.d
index 18e74c109c..9113b48204 100644
--- a/ld/testsuite/ld-gc/start.d
+++ b/ld/testsuite/ld-gc/start.d
@@ -5,5 +5,5 @@
#notarget: *-*-*aout *-*-*oldld frv-*-linux* metag-*-linux*
#...
-[0-9a-f]+ D +__start__foo
+[0-9a-f]+ d +__start__foo
#...
diff --git a/ld/testsuite/ld-x86-64/lea1a.d b/ld/testsuite/ld-x86-64/lea1a.d
index 9b662cb839..28ea4b93fc 100644
--- a/ld/testsuite/ld-x86-64/lea1a.d
+++ b/ld/testsuite/ld-x86-64/lea1a.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/lea1b.d b/ld/testsuite/ld-x86-64/lea1b.d
index 9108149b3a..c7873cd97b 100644
--- a/ld/testsuite/ld-x86-64/lea1b.d
+++ b/ld/testsuite/ld-x86-64/lea1b.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/lea1d.d b/ld/testsuite/ld-x86-64/lea1d.d
index 4d708d22c3..70fc603894 100644
--- a/ld/testsuite/ld-x86-64/lea1d.d
+++ b/ld/testsuite/ld-x86-64/lea1d.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/lea1e.d b/ld/testsuite/ld-x86-64/lea1e.d
index da60137918..123fcd243c 100644
--- a/ld/testsuite/ld-x86-64/lea1e.d
+++ b/ld/testsuite/ld-x86-64/lea1e.d
@@ -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