public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc
@ 2021-12-02  0:00 H.J. Lu
  2021-12-02  2:24 ` Fangrui Song
  0 siblings, 1 reply; 3+ messages in thread
From: H.J. Lu @ 2021-12-02  0:00 UTC (permalink / raw)
  To: binutils; +Cc: Fangrui Song

Don't convert memory load to immediate load on __start_SECNAME and
__stop_SECNAME for --gc-sections -z start-stop-gc if all SECNAME
sections been garbage collected.

bfd/

	PR ld/27491
	* elf32-i386.c (elf_i386_convert_load_reloc): Skip __start_SECNAME
	and __stop_SECNAME for --gc-sections -z start-stop-gc if the input
	section been garbage collected.
	* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
	* elfxx-x86.h (elf_x86_start_stop_gc_p): New function.

ld/
	PR ld/27491
	* testsuite/ld-i386/i386.exp: Run PR ld/27491 tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-i386/pr27491-1.s: New file.
	* testsuite/ld-i386/pr27491-1a.d: Likewise.
	* testsuite/ld-i386/pr27491-1b.d: Likewise.
	* testsuite/ld-i386/pr27491-2.d: Likewise.
	* testsuite/ld-i386/pr27491-2.s: Likewise.
	* testsuite/ld-i386/pr27491-3.d: Likewise.
	* testsuite/ld-i386/pr27491-3.s: Likewise.
	* testsuite/ld-i386/pr27491-4.d: Likewise.
	* testsuite/ld-i386/pr27491-4a.s: Likewise.
	* testsuite/ld-i386/pr27491-4b.s: Likewise.
	* testsuite/ld-x86-64/pr27491-1.s: Likewise.
	* testsuite/ld-x86-64/pr27491-1a.d: Likewise.
	* testsuite/ld-x86-64/pr27491-1b.d: Likewise.
	* testsuite/ld-x86-64/pr27491-2.d: Likewise.
	* testsuite/ld-x86-64/pr27491-2.s: Likewise.
	* testsuite/ld-x86-64/pr27491-3.d: Likewise.
	* testsuite/ld-x86-64/pr27491-3.s: Likewise.
	* testsuite/ld-x86-64/pr27491-4.d: Likewise.
	* testsuite/ld-x86-64/pr27491-4a.s: Likewise.
	* testsuite/ld-x86-64/pr27491-4b.s: Likewise.
---
 bfd/elf32-i386.c                    |  5 +++++
 bfd/elf64-x86-64.c                  |  5 +++++
 bfd/elfxx-x86.h                     | 35 +++++++++++++++++++++++++++++
 ld/testsuite/ld-i386/i386.exp       |  5 +++++
 ld/testsuite/ld-i386/pr27491-1.s    | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-1a.d   | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-1b.d   | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-2.d    | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-2.s    | 16 +++++++++++++
 ld/testsuite/ld-i386/pr27491-3.d    | 13 +++++++++++
 ld/testsuite/ld-i386/pr27491-3.s    | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-4.d    | 15 +++++++++++++
 ld/testsuite/ld-i386/pr27491-4a.s   | 11 +++++++++
 ld/testsuite/ld-i386/pr27491-4b.s   |  2 ++
 ld/testsuite/ld-x86-64/pr27491-1.s  | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-1a.d | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-1b.d | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-2.d  | 15 +++++++++++++
 ld/testsuite/ld-x86-64/pr27491-2.s  | 20 +++++++++++++++++
 ld/testsuite/ld-x86-64/pr27491-3.d  | 13 +++++++++++
 ld/testsuite/ld-x86-64/pr27491-3.s  | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-4.d  | 15 +++++++++++++
 ld/testsuite/ld-x86-64/pr27491-4a.s | 11 +++++++++
 ld/testsuite/ld-x86-64/pr27491-4b.s |  2 ++
 ld/testsuite/ld-x86-64/x86-64.exp   |  5 +++++
 25 files changed, 314 insertions(+)
 create mode 100644 ld/testsuite/ld-i386/pr27491-1.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-1a.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-1b.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-2.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-2.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-3.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-3.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-4.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-4a.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-4b.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1a.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1b.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-4.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-4a.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-4b.s

diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 0d7f29097e4..db6d1accdbc 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1393,6 +1393,11 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
 	       || h->root.type == bfd_link_hash_defweak)
 	      && local_ref))
 	{
+	  /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
+	     -z start-stop-gc are used.  */
+	  if (elf_x86_start_stop_gc_p (link_info, h))
+	    return true;
+
 	convert_load:
 	  if (opcode == 0x8b)
 	    {
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 25e2bb156e8..bb6df798d7b 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1643,6 +1643,11 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
 			   || h->root.type == bfd_link_hash_defweak)
 			  && h->root.u.def.section == bfd_und_section_ptr))))
 	    {
+	      /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
+	         -z start-stop-gc are used.  */
+	      if (elf_x86_start_stop_gc_p (link_info, h))
+		return true;
+
 	      /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
 	      if (no_overflow)
 		return true;
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 8251f641a77..15bdec6b5de 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -731,3 +731,38 @@ extern void _bfd_x86_elf_link_report_relative_reloc
   _bfd_x86_elf_merge_gnu_properties
 #define elf_backend_fixup_gnu_properties \
   _bfd_x86_elf_link_fixup_gnu_properties
+
+/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the
+   SECNAME section which has been garbage collected by --gc-sections
+   -z start-stop-gc.  */
+
+static inline bool
+elf_x86_start_stop_gc_p (struct bfd_link_info *link_info,
+			 struct elf_link_hash_entry *h)
+{
+  if (h->start_stop
+      && link_info->gc_sections
+      && link_info->start_stop_gc)
+    {
+      asection *first = h->root.u.def.section;
+      asection *s = first;
+
+      while (s != NULL)
+	{
+	  /* Return false if any SECNAME section is kept.  */
+	  if (s->gc_mark)
+	    return false;
+	  s = bfd_get_next_section_by_name (s->owner, s);
+	  if (s == first)
+	    break;
+	}
+
+      /* Return true only if all SECNAME sections have been garbage
+	 collected.  */
+      return true;
+    }
+
+  /* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or
+     --gc-sections or -z start-stop-gc isn't used.  */
+  return false;
+}
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index ceb60002d13..72aa41dab7c 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -493,6 +493,11 @@ run_dump_test "property-x86-isa3"
 run_dump_test "property-x86-isa4"
 run_dump_test "pr26869"
 run_dump_test "code16"
+run_dump_test "pr27491-1a"
+run_dump_test "pr27491-1b"
+run_dump_test "pr27491-2"
+run_dump_test "pr27491-3"
+run_dump_test "pr27491-4"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr27491-1.s b/ld/testsuite/ld-i386/pr27491-1.s
new file mode 100644
index 00000000000..89155aee5f4
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-i386/pr27491-1a.d b/ld/testsuite/ld-i386/pr27491-1a.d
new file mode 100644
index 00000000000..006c17695c1
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1a.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-1b.d b/ld/testsuite/ld-i386/pr27491-1b.d
new file mode 100644
index 00000000000..730e975d179
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1b.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --32
+#ld: --gc-sections -melf_i386 -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-2.d b/ld/testsuite/ld-i386/pr27491-2.d
new file mode 100644
index 00000000000..ea379465a11
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-2.d
@@ -0,0 +1,14 @@
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-2.s b/ld/testsuite/ld-i386/pr27491-2.s
new file mode 100644
index 00000000000..17871dddd76
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-2.s
@@ -0,0 +1,16 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+	leal	bar1@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+bar1:
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-i386/pr27491-3.d b/ld/testsuite/ld-i386/pr27491-3.d
new file mode 100644
index 00000000000..7719f2d2e75
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-3.d
@@ -0,0 +1,13 @@
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-3.s b/ld/testsuite/ld-i386/pr27491-3.s
new file mode 100644
index 00000000000..85fc3ddfffd
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-3.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+	.byte 0
+
+	.section xx,"aR",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-i386/pr27491-4.d b/ld/testsuite/ld-i386/pr27491-4.d
new file mode 100644
index 00000000000..d2d08571915
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-4.d
@@ -0,0 +1,15 @@
+#source: pr27491-4a.s
+#source: pr27491-4b.s
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-4a.s b/ld/testsuite/ld-i386/pr27491-4a.s
new file mode 100644
index 00000000000..a183b2f820b
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-4a.s
@@ -0,0 +1,11 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+	.byte 0
diff --git a/ld/testsuite/ld-i386/pr27491-4b.s b/ld/testsuite/ld-i386/pr27491-4b.s
new file mode 100644
index 00000000000..d0b83e92b64
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-4b.s
@@ -0,0 +1,2 @@
+	.section xx,"aR",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-1.s b/ld/testsuite/ld-x86-64/pr27491-1.s
new file mode 100644
index 00000000000..0d5b7714d87
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+
+	.section xx,"a",unique,0
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-1a.d b/ld/testsuite/ld-x86-64/pr27491-1a.d
new file mode 100644
index 00000000000..ade5c6fa4f9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1a.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf64-x86-64
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
+ +[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-1b.d b/ld/testsuite/ld-x86-64/pr27491-1b.d
new file mode 100644
index 00000000000..28cef96cf59
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1b.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -shared
+#objdump: -dw
+
+.*: +file format elf64-x86-64
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-2.d b/ld/testsuite/ld-x86-64/pr27491-2.d
new file mode 100644
index 00000000000..1c71c7decf2
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-2.d
@@ -0,0 +1,15 @@
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf64-x86-64
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar1>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar2>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-2.s b/ld/testsuite/ld-x86-64/pr27491-2.s
new file mode 100644
index 00000000000..a0975ff42c5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-2.s
@@ -0,0 +1,20 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+	leaq	bar1(%rip), %rax
+	leaq	bar2(%rip), %rax
+
+	.section xx,"a",unique,0
+	.byte 0
+bar1:
+	.byte 0
+bar2:
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-3.d b/ld/testsuite/ld-x86-64/pr27491-3.d
new file mode 100644
index 00000000000..45deae9b9b7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-3.d
@@ -0,0 +1,13 @@
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf64-x86-64
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-3.s b/ld/testsuite/ld-x86-64/pr27491-3.s
new file mode 100644
index 00000000000..efdcba401b3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-3.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+
+	.section xx,"a",unique,1
+	.byte 0
+
+	.section xx,"aR",unique,0
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-4.d b/ld/testsuite/ld-x86-64/pr27491-4.d
new file mode 100644
index 00000000000..cb044191494
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-4.d
@@ -0,0 +1,15 @@
+#source: pr27491-4a.s
+#source: pr27491-4b.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf64-x86-64
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-4a.s b/ld/testsuite/ld-x86-64/pr27491-4a.s
new file mode 100644
index 00000000000..3b17a813e84
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-4a.s
@@ -0,0 +1,11 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+
+	.section xx,"a",unique,1
+	.byte 0
diff --git a/ld/testsuite/ld-x86-64/pr27491-4b.s b/ld/testsuite/ld-x86-64/pr27491-4b.s
new file mode 100644
index 00000000000..2b46b21d3f0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-4b.s
@@ -0,0 +1,2 @@
+	.section xx,"aR",unique,0
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 064438a3f91..b9c2a33ca05 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -480,6 +480,11 @@ run_dump_test "property-x86-isa3-x32"
 run_dump_test "property-x86-isa4"
 run_dump_test "property-x86-isa4-x32"
 run_dump_test "code16"
+run_dump_test "pr27491-1a"
+run_dump_test "pr27491-1b"
+run_dump_test "pr27491-2"
+run_dump_test "pr27491-3"
+run_dump_test "pr27491-4"
 
 if ![istarget "x86_64-*-linux*"] {
     return
-- 
2.33.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc
  2021-12-02  0:00 [PATCH] x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc H.J. Lu
@ 2021-12-02  2:24 ` Fangrui Song
  2021-12-02 11:54   ` H.J. Lu
  0 siblings, 1 reply; 3+ messages in thread
From: Fangrui Song @ 2021-12-02  2:24 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

Thanks for the patch. I have applied it locally and behavior is expected.

On 2021-12-01, H.J. Lu wrote:
>Don't convert memory load to immediate load on __start_SECNAME and
>__stop_SECNAME for --gc-sections -z start-stop-gc if all SECNAME
>sections been garbage collected.
>
>bfd/
>
>	PR ld/27491
>	* elf32-i386.c (elf_i386_convert_load_reloc): Skip __start_SECNAME
>	and __stop_SECNAME for --gc-sections -z start-stop-gc if the input
>	section been garbage collected.
>	* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
>	* elfxx-x86.h (elf_x86_start_stop_gc_p): New function.
>
>ld/
>	PR ld/27491
>	* testsuite/ld-i386/i386.exp: Run PR ld/27491 tests.
>	* testsuite/ld-x86-64/x86-64.exp: Likewise.
>	* testsuite/ld-i386/pr27491-1.s: New file.
>	* testsuite/ld-i386/pr27491-1a.d: Likewise.
>	* testsuite/ld-i386/pr27491-1b.d: Likewise.
>	* testsuite/ld-i386/pr27491-2.d: Likewise.
>	* testsuite/ld-i386/pr27491-2.s: Likewise.
>	* testsuite/ld-i386/pr27491-3.d: Likewise.
>	* testsuite/ld-i386/pr27491-3.s: Likewise.
>	* testsuite/ld-i386/pr27491-4.d: Likewise.
>	* testsuite/ld-i386/pr27491-4a.s: Likewise.
>	* testsuite/ld-i386/pr27491-4b.s: Likewise.
>	* testsuite/ld-x86-64/pr27491-1.s: Likewise.
>	* testsuite/ld-x86-64/pr27491-1a.d: Likewise.
>	* testsuite/ld-x86-64/pr27491-1b.d: Likewise.
>	* testsuite/ld-x86-64/pr27491-2.d: Likewise.
>	* testsuite/ld-x86-64/pr27491-2.s: Likewise.
>	* testsuite/ld-x86-64/pr27491-3.d: Likewise.
>	* testsuite/ld-x86-64/pr27491-3.s: Likewise.
>	* testsuite/ld-x86-64/pr27491-4.d: Likewise.
>	* testsuite/ld-x86-64/pr27491-4a.s: Likewise.
>	* testsuite/ld-x86-64/pr27491-4b.s: Likewise.
>---
> bfd/elf32-i386.c                    |  5 +++++
> bfd/elf64-x86-64.c                  |  5 +++++
> bfd/elfxx-x86.h                     | 35 +++++++++++++++++++++++++++++
> ld/testsuite/ld-i386/i386.exp       |  5 +++++
> ld/testsuite/ld-i386/pr27491-1.s    | 14 ++++++++++++
> ld/testsuite/ld-i386/pr27491-1a.d   | 14 ++++++++++++
> ld/testsuite/ld-i386/pr27491-1b.d   | 14 ++++++++++++
> ld/testsuite/ld-i386/pr27491-2.d    | 14 ++++++++++++
> ld/testsuite/ld-i386/pr27491-2.s    | 16 +++++++++++++
> ld/testsuite/ld-i386/pr27491-3.d    | 13 +++++++++++
> ld/testsuite/ld-i386/pr27491-3.s    | 14 ++++++++++++
> ld/testsuite/ld-i386/pr27491-4.d    | 15 +++++++++++++
> ld/testsuite/ld-i386/pr27491-4a.s   | 11 +++++++++
> ld/testsuite/ld-i386/pr27491-4b.s   |  2 ++
> ld/testsuite/ld-x86-64/pr27491-1.s  | 14 ++++++++++++
> ld/testsuite/ld-x86-64/pr27491-1a.d | 14 ++++++++++++
> ld/testsuite/ld-x86-64/pr27491-1b.d | 14 ++++++++++++
> ld/testsuite/ld-x86-64/pr27491-2.d  | 15 +++++++++++++
> ld/testsuite/ld-x86-64/pr27491-2.s  | 20 +++++++++++++++++
> ld/testsuite/ld-x86-64/pr27491-3.d  | 13 +++++++++++
> ld/testsuite/ld-x86-64/pr27491-3.s  | 14 ++++++++++++
> ld/testsuite/ld-x86-64/pr27491-4.d  | 15 +++++++++++++
> ld/testsuite/ld-x86-64/pr27491-4a.s | 11 +++++++++
> ld/testsuite/ld-x86-64/pr27491-4b.s |  2 ++
> ld/testsuite/ld-x86-64/x86-64.exp   |  5 +++++
> 25 files changed, 314 insertions(+)
> create mode 100644 ld/testsuite/ld-i386/pr27491-1.s
> create mode 100644 ld/testsuite/ld-i386/pr27491-1a.d
> create mode 100644 ld/testsuite/ld-i386/pr27491-1b.d
> create mode 100644 ld/testsuite/ld-i386/pr27491-2.d
> create mode 100644 ld/testsuite/ld-i386/pr27491-2.s
> create mode 100644 ld/testsuite/ld-i386/pr27491-3.d
> create mode 100644 ld/testsuite/ld-i386/pr27491-3.s
> create mode 100644 ld/testsuite/ld-i386/pr27491-4.d
> create mode 100644 ld/testsuite/ld-i386/pr27491-4a.s
> create mode 100644 ld/testsuite/ld-i386/pr27491-4b.s
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-1.s
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-1a.d
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-1b.d
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.d
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.s
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.d
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.s
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-4.d
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-4a.s
> create mode 100644 ld/testsuite/ld-x86-64/pr27491-4b.s
>
>diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>index 0d7f29097e4..db6d1accdbc 100644
>--- a/bfd/elf32-i386.c
>+++ b/bfd/elf32-i386.c
>@@ -1393,6 +1393,11 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
> 	       || h->root.type == bfd_link_hash_defweak)
> 	      && local_ref))
> 	{
>+	  /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
>+	     -z start-stop-gc are used.  */
>+	  if (elf_x86_start_stop_gc_p (link_info, h))
>+	    return true;
>+
> 	convert_load:
> 	  if (opcode == 0x8b)
> 	    {
>diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>index 25e2bb156e8..bb6df798d7b 100644
>--- a/bfd/elf64-x86-64.c
>+++ b/bfd/elf64-x86-64.c
>@@ -1643,6 +1643,11 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
> 			   || h->root.type == bfd_link_hash_defweak)
> 			  && h->root.u.def.section == bfd_und_section_ptr))))
> 	    {
>+	      /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
>+	         -z start-stop-gc are used.  */
>+	      if (elf_x86_start_stop_gc_p (link_info, h))
>+		return true;
>+
> 	      /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
> 	      if (no_overflow)
> 		return true;
>diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
>index 8251f641a77..15bdec6b5de 100644
>--- a/bfd/elfxx-x86.h
>+++ b/bfd/elfxx-x86.h
>@@ -731,3 +731,38 @@ extern void _bfd_x86_elf_link_report_relative_reloc
>   _bfd_x86_elf_merge_gnu_properties
> #define elf_backend_fixup_gnu_properties \
>   _bfd_x86_elf_link_fixup_gnu_properties
>+
>+/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the
>+   SECNAME section which has been garbage collected by --gc-sections
>+   -z start-stop-gc.  */
>+
>+static inline bool
>+elf_x86_start_stop_gc_p (struct bfd_link_info *link_info,
>+			 struct elf_link_hash_entry *h)
>+{
>+  if (h->start_stop
>+      && link_info->gc_sections
>+      && link_info->start_stop_gc)
>+    {
>+      asection *first = h->root.u.def.section;
>+      asection *s = first;
>+
>+      while (s != NULL)
>+	{
>+	  /* Return false if any SECNAME section is kept.  */
>+	  if (s->gc_mark)
>+	    return false;
>+	  s = bfd_get_next_section_by_name (s->owner, s);
>+	  if (s == first)
>+	    break;
>+	}
>+
>+      /* Return true only if all SECNAME sections have been garbage
>+	 collected.  */
>+      return true;
>+    }
>+
>+  /* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or
>+     --gc-sections or -z start-stop-gc isn't used.  */
>+  return false;
>+}
>diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
>index ceb60002d13..72aa41dab7c 100644
>--- a/ld/testsuite/ld-i386/i386.exp
>+++ b/ld/testsuite/ld-i386/i386.exp
>@@ -493,6 +493,11 @@ run_dump_test "property-x86-isa3"
> run_dump_test "property-x86-isa4"
> run_dump_test "pr26869"
> run_dump_test "code16"
>+run_dump_test "pr27491-1a"
>+run_dump_test "pr27491-1b"
>+run_dump_test "pr27491-2"
>+run_dump_test "pr27491-3"
>+run_dump_test "pr27491-4"
>
> if { !([istarget "i?86-*-linux*"]
>        || [istarget "i?86-*-gnu*"]
>diff --git a/ld/testsuite/ld-i386/pr27491-1.s b/ld/testsuite/ld-i386/pr27491-1.s
>new file mode 100644
>index 00000000000..89155aee5f4
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-1.s
>@@ -0,0 +1,14 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movl	__start_xx@got(%ebx), %eax
>+	movl	__stop_xx@got(%ebx), %eax
>+
>+	.section xx,"a",unique,0
>+	.byte 0
>+
>+	.section xx,"a",unique,1
>+	.byte 1
>diff --git a/ld/testsuite/ld-i386/pr27491-1a.d b/ld/testsuite/ld-i386/pr27491-1a.d
>new file mode 100644
>index 00000000000..006c17695c1
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-1a.d
>@@ -0,0 +1,14 @@
>+#source: pr27491-1.s
>+#as: --32
>+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf32-i386
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
>+ +[a-f0-9]+:	8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
>+#pass

These tests do not show .got content or __start_xx/__stop_xx values so
they cannot catch the case if the GC behavior regresses in the future.

Can --print-gc-sections output be tested?

>diff --git a/ld/testsuite/ld-i386/pr27491-1b.d b/ld/testsuite/ld-i386/pr27491-1b.d
>new file mode 100644
>index 00000000000..730e975d179
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-1b.d
>@@ -0,0 +1,14 @@
>+#source: pr27491-1.s
>+#as: --32
>+#ld: --gc-sections -melf_i386 -shared
>+#objdump: -dw
>+
>+.*: +file format elf32-i386
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+#pass
>diff --git a/ld/testsuite/ld-i386/pr27491-2.d b/ld/testsuite/ld-i386/pr27491-2.d
>new file mode 100644
>index 00000000000..ea379465a11
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-2.d
>@@ -0,0 +1,14 @@
>+#as: --32
>+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf32-i386
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+#pass
>diff --git a/ld/testsuite/ld-i386/pr27491-2.s b/ld/testsuite/ld-i386/pr27491-2.s
>new file mode 100644
>index 00000000000..17871dddd76
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-2.s
>@@ -0,0 +1,16 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movl	__start_xx@got(%ebx), %eax
>+	movl	__stop_xx@got(%ebx), %eax
>+	leal	bar1@got(%ebx), %eax
>+
>+	.section xx,"a",unique,0
>+bar1:
>+	.byte 0
>+
>+	.section xx,"a",unique,1
>+	.byte 1
>diff --git a/ld/testsuite/ld-i386/pr27491-3.d b/ld/testsuite/ld-i386/pr27491-3.d
>new file mode 100644
>index 00000000000..7719f2d2e75
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-3.d
>@@ -0,0 +1,13 @@
>+#as: --32
>+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf32-i386
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+#pass
>diff --git a/ld/testsuite/ld-i386/pr27491-3.s b/ld/testsuite/ld-i386/pr27491-3.s
>new file mode 100644
>index 00000000000..85fc3ddfffd
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-3.s
>@@ -0,0 +1,14 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movl	__start_xx@got(%ebx), %eax
>+	movl	__stop_xx@got(%ebx), %eax
>+
>+	.section xx,"a",unique,0
>+	.byte 0
>+
>+	.section xx,"aR",unique,1
>+	.byte 1
>diff --git a/ld/testsuite/ld-i386/pr27491-4.d b/ld/testsuite/ld-i386/pr27491-4.d
>new file mode 100644
>index 00000000000..d2d08571915
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-4.d
>@@ -0,0 +1,15 @@
>+#source: pr27491-4a.s
>+#source: pr27491-4b.s
>+#as: --32
>+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf32-i386
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
>+#pass
>diff --git a/ld/testsuite/ld-i386/pr27491-4a.s b/ld/testsuite/ld-i386/pr27491-4a.s
>new file mode 100644
>index 00000000000..a183b2f820b
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-4a.s
>@@ -0,0 +1,11 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movl	__start_xx@got(%ebx), %eax
>+	movl	__stop_xx@got(%ebx), %eax
>+
>+	.section xx,"a",unique,0
>+	.byte 0
>diff --git a/ld/testsuite/ld-i386/pr27491-4b.s b/ld/testsuite/ld-i386/pr27491-4b.s
>new file mode 100644
>index 00000000000..d0b83e92b64
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr27491-4b.s
>@@ -0,0 +1,2 @@
>+	.section xx,"aR",unique,1
>+	.byte 1
>diff --git a/ld/testsuite/ld-x86-64/pr27491-1.s b/ld/testsuite/ld-x86-64/pr27491-1.s
>new file mode 100644
>index 00000000000..0d5b7714d87
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-1.s
>@@ -0,0 +1,14 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movq	__start_xx@gotpcrel(%rip), %rax
>+	movq	__stop_xx@gotpcrel(%rip), %rax
>+
>+	.section xx,"a",unique,0
>+	.byte 0
>+
>+	.section xx,"a",unique,1
>+	.byte 1
>diff --git a/ld/testsuite/ld-x86-64/pr27491-1a.d b/ld/testsuite/ld-x86-64/pr27491-1a.d
>new file mode 100644
>index 00000000000..ade5c6fa4f9
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-1a.d
>@@ -0,0 +1,14 @@
>+#source: pr27491-1.s
>+#as: --64
>+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf64-x86-64
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
>+ +[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
>+#pass
>diff --git a/ld/testsuite/ld-x86-64/pr27491-1b.d b/ld/testsuite/ld-x86-64/pr27491-1b.d
>new file mode 100644
>index 00000000000..28cef96cf59
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-1b.d
>@@ -0,0 +1,14 @@
>+#source: pr27491-1.s
>+#as: --64
>+#ld: --gc-sections -melf_x86_64 -shared
>+#objdump: -dw
>+
>+.*: +file format elf64-x86-64
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
>+#pass
>diff --git a/ld/testsuite/ld-x86-64/pr27491-2.d b/ld/testsuite/ld-x86-64/pr27491-2.d
>new file mode 100644
>index 00000000000..1c71c7decf2
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-2.d
>@@ -0,0 +1,15 @@
>+#as: --64
>+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf64-x86-64
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar1>
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar2>
>+#pass
>diff --git a/ld/testsuite/ld-x86-64/pr27491-2.s b/ld/testsuite/ld-x86-64/pr27491-2.s
>new file mode 100644
>index 00000000000..a0975ff42c5
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-2.s
>@@ -0,0 +1,20 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movq	__start_xx@gotpcrel(%rip), %rax
>+	movq	__stop_xx@gotpcrel(%rip), %rax
>+	leaq	bar1(%rip), %rax
>+	leaq	bar2(%rip), %rax
>+
>+	.section xx,"a",unique,0
>+	.byte 0
>+bar1:
>+	.byte 0
>+bar2:
>+	.byte 0
>+
>+	.section xx,"a",unique,1
>+	.byte 1
>diff --git a/ld/testsuite/ld-x86-64/pr27491-3.d b/ld/testsuite/ld-x86-64/pr27491-3.d
>new file mode 100644
>index 00000000000..45deae9b9b7
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-3.d
>@@ -0,0 +1,13 @@
>+#as: --64
>+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf64-x86-64
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
>+#pass
>diff --git a/ld/testsuite/ld-x86-64/pr27491-3.s b/ld/testsuite/ld-x86-64/pr27491-3.s
>new file mode 100644
>index 00000000000..efdcba401b3
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-3.s
>@@ -0,0 +1,14 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movq	__start_xx@gotpcrel(%rip), %rax
>+	movq	__stop_xx@gotpcrel(%rip), %rax
>+
>+	.section xx,"a",unique,1
>+	.byte 0
>+
>+	.section xx,"aR",unique,0
>+	.byte 1
>diff --git a/ld/testsuite/ld-x86-64/pr27491-4.d b/ld/testsuite/ld-x86-64/pr27491-4.d
>new file mode 100644
>index 00000000000..cb044191494
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-4.d
>@@ -0,0 +1,15 @@
>+#source: pr27491-4a.s
>+#source: pr27491-4b.s
>+#as: --64
>+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
>+#objdump: -dw
>+
>+.*: +file format elf64-x86-64
>+
>+
>+Disassembly of section .text:
>+
>+[a-f0-9]+ <foo>:
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
>+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
>+#pass
>diff --git a/ld/testsuite/ld-x86-64/pr27491-4a.s b/ld/testsuite/ld-x86-64/pr27491-4a.s
>new file mode 100644
>index 00000000000..3b17a813e84
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-4a.s
>@@ -0,0 +1,11 @@
>+	.weak __start_xx
>+	.weak __stop_xx
>+
>+	.text
>+	.global foo
>+foo:
>+	movq	__start_xx@gotpcrel(%rip), %rax
>+	movq	__stop_xx@gotpcrel(%rip), %rax
>+
>+	.section xx,"a",unique,1
>+	.byte 0
>diff --git a/ld/testsuite/ld-x86-64/pr27491-4b.s b/ld/testsuite/ld-x86-64/pr27491-4b.s
>new file mode 100644
>index 00000000000..2b46b21d3f0
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr27491-4b.s
>@@ -0,0 +1,2 @@
>+	.section xx,"aR",unique,0
>+	.byte 1
>diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>index 064438a3f91..b9c2a33ca05 100644
>--- a/ld/testsuite/ld-x86-64/x86-64.exp
>+++ b/ld/testsuite/ld-x86-64/x86-64.exp
>@@ -480,6 +480,11 @@ run_dump_test "property-x86-isa3-x32"
> run_dump_test "property-x86-isa4"
> run_dump_test "property-x86-isa4-x32"
> run_dump_test "code16"
>+run_dump_test "pr27491-1a"
>+run_dump_test "pr27491-1b"
>+run_dump_test "pr27491-2"
>+run_dump_test "pr27491-3"
>+run_dump_test "pr27491-4"
>
> if ![istarget "x86_64-*-linux*"] {
>     return
>-- 
>2.33.1
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc
  2021-12-02  2:24 ` Fangrui Song
@ 2021-12-02 11:54   ` H.J. Lu
  0 siblings, 0 replies; 3+ messages in thread
From: H.J. Lu @ 2021-12-02 11:54 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

[-- Attachment #1: Type: text/plain, Size: 9619 bytes --]

On Wed, Dec 1, 2021 at 6:24 PM Fangrui Song <maskray@google.com> wrote:
>
> Thanks for the patch. I have applied it locally and behavior is expected.
>
> On 2021-12-01, H.J. Lu wrote:
> >Don't convert memory load to immediate load on __start_SECNAME and
> >__stop_SECNAME for --gc-sections -z start-stop-gc if all SECNAME
> >sections been garbage collected.
> >
> >bfd/
> >
> >       PR ld/27491
> >       * elf32-i386.c (elf_i386_convert_load_reloc): Skip __start_SECNAME
> >       and __stop_SECNAME for --gc-sections -z start-stop-gc if the input
> >       section been garbage collected.
> >       * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
> >       * elfxx-x86.h (elf_x86_start_stop_gc_p): New function.
> >
> >ld/
> >       PR ld/27491
> >       * testsuite/ld-i386/i386.exp: Run PR ld/27491 tests.
> >       * testsuite/ld-x86-64/x86-64.exp: Likewise.
> >       * testsuite/ld-i386/pr27491-1.s: New file.
> >       * testsuite/ld-i386/pr27491-1a.d: Likewise.
> >       * testsuite/ld-i386/pr27491-1b.d: Likewise.
> >       * testsuite/ld-i386/pr27491-2.d: Likewise.
> >       * testsuite/ld-i386/pr27491-2.s: Likewise.
> >       * testsuite/ld-i386/pr27491-3.d: Likewise.
> >       * testsuite/ld-i386/pr27491-3.s: Likewise.
> >       * testsuite/ld-i386/pr27491-4.d: Likewise.
> >       * testsuite/ld-i386/pr27491-4a.s: Likewise.
> >       * testsuite/ld-i386/pr27491-4b.s: Likewise.
> >       * testsuite/ld-x86-64/pr27491-1.s: Likewise.
> >       * testsuite/ld-x86-64/pr27491-1a.d: Likewise.
> >       * testsuite/ld-x86-64/pr27491-1b.d: Likewise.
> >       * testsuite/ld-x86-64/pr27491-2.d: Likewise.
> >       * testsuite/ld-x86-64/pr27491-2.s: Likewise.
> >       * testsuite/ld-x86-64/pr27491-3.d: Likewise.
> >       * testsuite/ld-x86-64/pr27491-3.s: Likewise.
> >       * testsuite/ld-x86-64/pr27491-4.d: Likewise.
> >       * testsuite/ld-x86-64/pr27491-4a.s: Likewise.
> >       * testsuite/ld-x86-64/pr27491-4b.s: Likewise.
> >---
> > bfd/elf32-i386.c                    |  5 +++++
> > bfd/elf64-x86-64.c                  |  5 +++++
> > bfd/elfxx-x86.h                     | 35 +++++++++++++++++++++++++++++
> > ld/testsuite/ld-i386/i386.exp       |  5 +++++
> > ld/testsuite/ld-i386/pr27491-1.s    | 14 ++++++++++++
> > ld/testsuite/ld-i386/pr27491-1a.d   | 14 ++++++++++++
> > ld/testsuite/ld-i386/pr27491-1b.d   | 14 ++++++++++++
> > ld/testsuite/ld-i386/pr27491-2.d    | 14 ++++++++++++
> > ld/testsuite/ld-i386/pr27491-2.s    | 16 +++++++++++++
> > ld/testsuite/ld-i386/pr27491-3.d    | 13 +++++++++++
> > ld/testsuite/ld-i386/pr27491-3.s    | 14 ++++++++++++
> > ld/testsuite/ld-i386/pr27491-4.d    | 15 +++++++++++++
> > ld/testsuite/ld-i386/pr27491-4a.s   | 11 +++++++++
> > ld/testsuite/ld-i386/pr27491-4b.s   |  2 ++
> > ld/testsuite/ld-x86-64/pr27491-1.s  | 14 ++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-1a.d | 14 ++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-1b.d | 14 ++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-2.d  | 15 +++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-2.s  | 20 +++++++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-3.d  | 13 +++++++++++
> > ld/testsuite/ld-x86-64/pr27491-3.s  | 14 ++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-4.d  | 15 +++++++++++++
> > ld/testsuite/ld-x86-64/pr27491-4a.s | 11 +++++++++
> > ld/testsuite/ld-x86-64/pr27491-4b.s |  2 ++
> > ld/testsuite/ld-x86-64/x86-64.exp   |  5 +++++
> > 25 files changed, 314 insertions(+)
> > create mode 100644 ld/testsuite/ld-i386/pr27491-1.s
> > create mode 100644 ld/testsuite/ld-i386/pr27491-1a.d
> > create mode 100644 ld/testsuite/ld-i386/pr27491-1b.d
> > create mode 100644 ld/testsuite/ld-i386/pr27491-2.d
> > create mode 100644 ld/testsuite/ld-i386/pr27491-2.s
> > create mode 100644 ld/testsuite/ld-i386/pr27491-3.d
> > create mode 100644 ld/testsuite/ld-i386/pr27491-3.s
> > create mode 100644 ld/testsuite/ld-i386/pr27491-4.d
> > create mode 100644 ld/testsuite/ld-i386/pr27491-4a.s
> > create mode 100644 ld/testsuite/ld-i386/pr27491-4b.s
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-1.s
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-1a.d
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-1b.d
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.d
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.s
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.d
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.s
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-4.d
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-4a.s
> > create mode 100644 ld/testsuite/ld-x86-64/pr27491-4b.s
> >
> >diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >index 0d7f29097e4..db6d1accdbc 100644
> >--- a/bfd/elf32-i386.c
> >+++ b/bfd/elf32-i386.c
> >@@ -1393,6 +1393,11 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
> >              || h->root.type == bfd_link_hash_defweak)
> >             && local_ref))
> >       {
> >+        /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
> >+           -z start-stop-gc are used.  */
> >+        if (elf_x86_start_stop_gc_p (link_info, h))
> >+          return true;
> >+
> >       convert_load:
> >         if (opcode == 0x8b)
> >           {
> >diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >index 25e2bb156e8..bb6df798d7b 100644
> >--- a/bfd/elf64-x86-64.c
> >+++ b/bfd/elf64-x86-64.c
> >@@ -1643,6 +1643,11 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
> >                          || h->root.type == bfd_link_hash_defweak)
> >                         && h->root.u.def.section == bfd_und_section_ptr))))
> >           {
> >+            /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
> >+               -z start-stop-gc are used.  */
> >+            if (elf_x86_start_stop_gc_p (link_info, h))
> >+              return true;
> >+
> >             /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
> >             if (no_overflow)
> >               return true;
> >diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
> >index 8251f641a77..15bdec6b5de 100644
> >--- a/bfd/elfxx-x86.h
> >+++ b/bfd/elfxx-x86.h
> >@@ -731,3 +731,38 @@ extern void _bfd_x86_elf_link_report_relative_reloc
> >   _bfd_x86_elf_merge_gnu_properties
> > #define elf_backend_fixup_gnu_properties \
> >   _bfd_x86_elf_link_fixup_gnu_properties
> >+
> >+/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the
> >+   SECNAME section which has been garbage collected by --gc-sections
> >+   -z start-stop-gc.  */
> >+
> >+static inline bool
> >+elf_x86_start_stop_gc_p (struct bfd_link_info *link_info,
> >+                       struct elf_link_hash_entry *h)
> >+{
> >+  if (h->start_stop
> >+      && link_info->gc_sections
> >+      && link_info->start_stop_gc)
> >+    {
> >+      asection *first = h->root.u.def.section;
> >+      asection *s = first;
> >+
> >+      while (s != NULL)
> >+      {
> >+        /* Return false if any SECNAME section is kept.  */
> >+        if (s->gc_mark)
> >+          return false;
> >+        s = bfd_get_next_section_by_name (s->owner, s);
> >+        if (s == first)
> >+          break;
> >+      }
> >+
> >+      /* Return true only if all SECNAME sections have been garbage
> >+       collected.  */
> >+      return true;
> >+    }
> >+
> >+  /* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or
> >+     --gc-sections or -z start-stop-gc isn't used.  */
> >+  return false;
> >+}
> >diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
> >index ceb60002d13..72aa41dab7c 100644
> >--- a/ld/testsuite/ld-i386/i386.exp
> >+++ b/ld/testsuite/ld-i386/i386.exp
> >@@ -493,6 +493,11 @@ run_dump_test "property-x86-isa3"
> > run_dump_test "property-x86-isa4"
> > run_dump_test "pr26869"
> > run_dump_test "code16"
> >+run_dump_test "pr27491-1a"
> >+run_dump_test "pr27491-1b"
> >+run_dump_test "pr27491-2"
> >+run_dump_test "pr27491-3"
> >+run_dump_test "pr27491-4"
> >
> > if { !([istarget "i?86-*-linux*"]
> >        || [istarget "i?86-*-gnu*"]
> >diff --git a/ld/testsuite/ld-i386/pr27491-1.s b/ld/testsuite/ld-i386/pr27491-1.s
> >new file mode 100644
> >index 00000000000..89155aee5f4
> >--- /dev/null
> >+++ b/ld/testsuite/ld-i386/pr27491-1.s
> >@@ -0,0 +1,14 @@
> >+      .weak __start_xx
> >+      .weak __stop_xx
> >+
> >+      .text
> >+      .global foo
> >+foo:
> >+      movl    __start_xx@got(%ebx), %eax
> >+      movl    __stop_xx@got(%ebx), %eax
> >+
> >+      .section xx,"a",unique,0
> >+      .byte 0
> >+
> >+      .section xx,"a",unique,1
> >+      .byte 1
> >diff --git a/ld/testsuite/ld-i386/pr27491-1a.d b/ld/testsuite/ld-i386/pr27491-1a.d
> >new file mode 100644
> >index 00000000000..006c17695c1
> >--- /dev/null
> >+++ b/ld/testsuite/ld-i386/pr27491-1a.d
> >@@ -0,0 +1,14 @@
> >+#source: pr27491-1.s
> >+#as: --32
> >+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
> >+#objdump: -dw
> >+
> >+.*: +file format elf32-i386
> >+
> >+
> >+Disassembly of section .text:
> >+
> >+[a-f0-9]+ <foo>:
> >+ +[a-f0-9]+:  8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
> >+ +[a-f0-9]+:  8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
> >+#pass
>
> These tests do not show .got content or __start_xx/__stop_xx values so
> they cannot catch the case if the GC behavior regresses in the future.
>
> Can --print-gc-sections output be tested?
>

This is the patch I am checking in:

1. Add tests to verify that __start_xx and __stop_xx are removed when
xx sections are garbage collected.
2. Update tests to verify that __start_xx and __stop_xx are in the symbol
table when xx sections aren't garbage collected.

Thanks.

-- 
H.J.

[-- Attachment #2: v3-0001-x86-Skip-__-start-stop-_SECNAME-for-gc-sections-z.patch --]
[-- Type: text/x-patch, Size: 19899 bytes --]

From ea1ef53219c98a2bcfc74135c74bf56930dfb292 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 1 Dec 2021 04:55:24 -0800
Subject: [PATCH v3] x86: Skip __[start|stop]_SECNAME for --gc-sections -z
 start-stop-gc

Don't convert memory load to immediate load on __start_SECNAME and
__stop_SECNAME for --gc-sections -z start-stop-gc if all SECNAME
sections been garbage collected.

bfd/

	PR ld/27491
	* elf32-i386.c (elf_i386_convert_load_reloc): Skip __start_SECNAME
	and __stop_SECNAME for --gc-sections -z start-stop-gc if the input
	section been garbage collected.
	* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
	* elfxx-x86.h (elf_x86_start_stop_gc_p): New function.

ld/
	PR ld/27491
	* testsuite/ld-i386/i386.exp: Run PR ld/27491 tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-i386/pr27491-1.s: New file.
	* testsuite/ld-i386/pr27491-1a.d: Likewise.
	* testsuite/ld-i386/pr27491-1b.d: Likewise.
	* testsuite/ld-i386/pr27491-1c.d: Likewise.
	* testsuite/ld-i386/pr27491-2.d: Likewise.
	* testsuite/ld-i386/pr27491-2.s: Likewise.
	* testsuite/ld-i386/pr27491-3.d: Likewise.
	* testsuite/ld-i386/pr27491-3.s: Likewise.
	* testsuite/ld-i386/pr27491-4.d: Likewise.
	* testsuite/ld-i386/pr27491-4a.s: Likewise.
	* testsuite/ld-i386/pr27491-4b.s: Likewise.
	* testsuite/ld-x86-64/pr27491-1.s: Likewise.
	* testsuite/ld-x86-64/pr27491-1a.d: Likewise.
	* testsuite/ld-x86-64/pr27491-1b.d: Likewise.
	* testsuite/ld-x86-64/pr27491-1c.d: Likewise.
	* testsuite/ld-x86-64/pr27491-2.d: Likewise.
	* testsuite/ld-x86-64/pr27491-2.s: Likewise.
	* testsuite/ld-x86-64/pr27491-3.d: Likewise.
	* testsuite/ld-x86-64/pr27491-3.s: Likewise.
	* testsuite/ld-x86-64/pr27491-4.d: Likewise.
	* testsuite/ld-x86-64/pr27491-4a.s: Likewise.
	* testsuite/ld-x86-64/pr27491-4b.s: Likewise.
---
 bfd/elf32-i386.c                    |  5 +++++
 bfd/elf64-x86-64.c                  |  5 +++++
 bfd/elfxx-x86.h                     | 33 +++++++++++++++++++++++++++++
 ld/testsuite/ld-i386/i386.exp       |  6 ++++++
 ld/testsuite/ld-i386/pr27491-1.s    | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-1a.d   | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-1b.d   | 11 ++++++++++
 ld/testsuite/ld-i386/pr27491-1c.d   | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-2.d    | 22 +++++++++++++++++++
 ld/testsuite/ld-i386/pr27491-2.s    | 16 ++++++++++++++
 ld/testsuite/ld-i386/pr27491-3.d    | 21 ++++++++++++++++++
 ld/testsuite/ld-i386/pr27491-3.s    | 14 ++++++++++++
 ld/testsuite/ld-i386/pr27491-4.d    | 23 ++++++++++++++++++++
 ld/testsuite/ld-i386/pr27491-4a.s   | 11 ++++++++++
 ld/testsuite/ld-i386/pr27491-4b.s   |  2 ++
 ld/testsuite/ld-x86-64/pr27491-1.s  | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-1a.d | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-1b.d | 11 ++++++++++
 ld/testsuite/ld-x86-64/pr27491-1c.d | 21 ++++++++++++++++++
 ld/testsuite/ld-x86-64/pr27491-2.d  | 23 ++++++++++++++++++++
 ld/testsuite/ld-x86-64/pr27491-2.s  | 20 +++++++++++++++++
 ld/testsuite/ld-x86-64/pr27491-3.d  | 21 ++++++++++++++++++
 ld/testsuite/ld-x86-64/pr27491-3.s  | 14 ++++++++++++
 ld/testsuite/ld-x86-64/pr27491-4.d  | 23 ++++++++++++++++++++
 ld/testsuite/ld-x86-64/pr27491-4a.s | 11 ++++++++++
 ld/testsuite/ld-x86-64/pr27491-4b.s |  2 ++
 ld/testsuite/ld-x86-64/x86-64.exp   |  6 ++++++
 27 files changed, 391 insertions(+)
 create mode 100644 ld/testsuite/ld-i386/pr27491-1.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-1a.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-1b.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-1c.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-2.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-2.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-3.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-3.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-4.d
 create mode 100644 ld/testsuite/ld-i386/pr27491-4a.s
 create mode 100644 ld/testsuite/ld-i386/pr27491-4b.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1a.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1b.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-1c.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-2.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-3.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-4.d
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-4a.s
 create mode 100644 ld/testsuite/ld-x86-64/pr27491-4b.s

diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 0d7f29097e4..db6d1accdbc 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1393,6 +1393,11 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
 	       || h->root.type == bfd_link_hash_defweak)
 	      && local_ref))
 	{
+	  /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
+	     -z start-stop-gc are used.  */
+	  if (elf_x86_start_stop_gc_p (link_info, h))
+	    return true;
+
 	convert_load:
 	  if (opcode == 0x8b)
 	    {
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 25e2bb156e8..bb6df798d7b 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1643,6 +1643,11 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
 			   || h->root.type == bfd_link_hash_defweak)
 			  && h->root.u.def.section == bfd_und_section_ptr))))
 	    {
+	      /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections
+	         -z start-stop-gc are used.  */
+	      if (elf_x86_start_stop_gc_p (link_info, h))
+		return true;
+
 	      /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
 	      if (no_overflow)
 		return true;
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 8251f641a77..aab641ab751 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -731,3 +731,36 @@ extern void _bfd_x86_elf_link_report_relative_reloc
   _bfd_x86_elf_merge_gnu_properties
 #define elf_backend_fixup_gnu_properties \
   _bfd_x86_elf_link_fixup_gnu_properties
+
+/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the
+   SECNAME section which has been garbage collected by --gc-sections
+   -z start-stop-gc.  */
+
+static inline bool
+elf_x86_start_stop_gc_p (struct bfd_link_info *link_info,
+			 struct elf_link_hash_entry *h)
+{
+  if (h->start_stop
+      && link_info->gc_sections
+      && link_info->start_stop_gc)
+    {
+      asection *s = h->root.u.def.section;
+
+      do
+	{
+	  /* Return false if any SECNAME section is kept.  */
+	  if (s->gc_mark)
+	    return false;
+	  s = bfd_get_next_section_by_name (s->owner, s);
+	}
+      while (s != NULL);
+
+      /* Return true only if all SECNAME sections have been garbage
+	 collected.  */
+      return true;
+    }
+
+  /* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or
+     --gc-sections or -z start-stop-gc isn't used.  */
+  return false;
+}
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index ceb60002d13..23ab8544c79 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -493,6 +493,12 @@ run_dump_test "property-x86-isa3"
 run_dump_test "property-x86-isa4"
 run_dump_test "pr26869"
 run_dump_test "code16"
+run_dump_test "pr27491-1a"
+run_dump_test "pr27491-1b"
+run_dump_test "pr27491-1c"
+run_dump_test "pr27491-2"
+run_dump_test "pr27491-3"
+run_dump_test "pr27491-4"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr27491-1.s b/ld/testsuite/ld-i386/pr27491-1.s
new file mode 100644
index 00000000000..89155aee5f4
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-i386/pr27491-1a.d b/ld/testsuite/ld-i386/pr27491-1a.d
new file mode 100644
index 00000000000..006c17695c1
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1a.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-1b.d b/ld/testsuite/ld-i386/pr27491-1b.d
new file mode 100644
index 00000000000..69b9ac3b082
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1b.d
@@ -0,0 +1,11 @@
+#source: pr27491-1.s
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#nm: -n
+
+#failif
+#...
+[a-f0-9]+ R __start_xx
+#...
+[a-f0-9]+ R __stop_xx
+#...
diff --git a/ld/testsuite/ld-i386/pr27491-1c.d b/ld/testsuite/ld-i386/pr27491-1c.d
new file mode 100644
index 00000000000..730e975d179
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-1c.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --32
+#ld: --gc-sections -melf_i386 -shared
+#objdump: -dw
+
+.*: +file format elf32-i386
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-2.d b/ld/testsuite/ld-i386/pr27491-2.d
new file mode 100644
index 00000000000..02b310aab6e
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-2.d
@@ -0,0 +1,22 @@
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: --syms -dw
+
+.*: +file format elf32-i386
+
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-2.s b/ld/testsuite/ld-i386/pr27491-2.s
new file mode 100644
index 00000000000..17871dddd76
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-2.s
@@ -0,0 +1,16 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+	leal	bar1@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+bar1:
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-i386/pr27491-3.d b/ld/testsuite/ld-i386/pr27491-3.d
new file mode 100644
index 00000000000..77495701689
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-3.d
@@ -0,0 +1,21 @@
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: --syms -dw
+
+.*: +file format elf32-i386
+
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-3.s b/ld/testsuite/ld-i386/pr27491-3.s
new file mode 100644
index 00000000000..85fc3ddfffd
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-3.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+	.byte 0
+
+	.section xx,"aR",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-i386/pr27491-4.d b/ld/testsuite/ld-i386/pr27491-4.d
new file mode 100644
index 00000000000..4a305da1ead
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-4.d
@@ -0,0 +1,23 @@
+#source: pr27491-4a.s
+#source: pr27491-4b.s
+#as: --32
+#ld: --gc-sections -melf_i386 -z start-stop-gc -shared
+#objdump: --syms -dw
+
+.*: +file format elf32-i386
+
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+ +[a-f0-9]+:	8d 83 ([0-9a-f]{2} ){4}[ \t]+lea +-0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr27491-4a.s b/ld/testsuite/ld-i386/pr27491-4a.s
new file mode 100644
index 00000000000..a183b2f820b
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-4a.s
@@ -0,0 +1,11 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movl	__start_xx@got(%ebx), %eax
+	movl	__stop_xx@got(%ebx), %eax
+
+	.section xx,"a",unique,0
+	.byte 0
diff --git a/ld/testsuite/ld-i386/pr27491-4b.s b/ld/testsuite/ld-i386/pr27491-4b.s
new file mode 100644
index 00000000000..d0b83e92b64
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27491-4b.s
@@ -0,0 +1,2 @@
+	.section xx,"aR",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-1.s b/ld/testsuite/ld-x86-64/pr27491-1.s
new file mode 100644
index 00000000000..0d5b7714d87
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+
+	.section xx,"a",unique,0
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-1a.d b/ld/testsuite/ld-x86-64/pr27491-1a.d
new file mode 100644
index 00000000000..ade5c6fa4f9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1a.d
@@ -0,0 +1,14 @@
+#source: pr27491-1.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: -dw
+
+.*: +file format elf64-x86-64
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
+ +[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-1b.d b/ld/testsuite/ld-x86-64/pr27491-1b.d
new file mode 100644
index 00000000000..a6e21dac219
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1b.d
@@ -0,0 +1,11 @@
+#source: pr27491-1.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#nm: -n
+
+#failif
+#...
+[a-f0-9]+ R __start_xx
+#...
+[a-f0-9]+ R __stop_xx
+#...
diff --git a/ld/testsuite/ld-x86-64/pr27491-1c.d b/ld/testsuite/ld-x86-64/pr27491-1c.d
new file mode 100644
index 00000000000..1288361463d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-1c.d
@@ -0,0 +1,21 @@
+#source: pr27491-1.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -shared
+#objdump: --syms -dw
+
+.*: +file format elf64-x86-64
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-2.d b/ld/testsuite/ld-x86-64/pr27491-2.d
new file mode 100644
index 00000000000..753ebb64082
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-2.d
@@ -0,0 +1,23 @@
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: --syms -dw
+
+.*: +file format elf64-x86-64
+
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar1>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <bar2>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-2.s b/ld/testsuite/ld-x86-64/pr27491-2.s
new file mode 100644
index 00000000000..a0975ff42c5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-2.s
@@ -0,0 +1,20 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+	leaq	bar1(%rip), %rax
+	leaq	bar2(%rip), %rax
+
+	.section xx,"a",unique,0
+	.byte 0
+bar1:
+	.byte 0
+bar2:
+	.byte 0
+
+	.section xx,"a",unique,1
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-3.d b/ld/testsuite/ld-x86-64/pr27491-3.d
new file mode 100644
index 00000000000..6dda5424fff
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-3.d
@@ -0,0 +1,21 @@
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: --syms -dw
+
+.*: +file format elf64-x86-64
+
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-3.s b/ld/testsuite/ld-x86-64/pr27491-3.s
new file mode 100644
index 00000000000..efdcba401b3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-3.s
@@ -0,0 +1,14 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+
+	.section xx,"a",unique,1
+	.byte 0
+
+	.section xx,"aR",unique,0
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/pr27491-4.d b/ld/testsuite/ld-x86-64/pr27491-4.d
new file mode 100644
index 00000000000..54542fd2d1a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-4.d
@@ -0,0 +1,23 @@
+#source: pr27491-4a.s
+#source: pr27491-4b.s
+#as: --64
+#ld: --gc-sections -melf_x86_64 -z start-stop-gc -shared
+#objdump: --syms -dw
+
+.*: +file format elf64-x86-64
+
+
+SYMBOL TABLE:
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __stop_xx
+#...
+[a-f0-9]+ g       xx	[a-f0-9]+ \.protected __start_xx
+#...
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <foo>:
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__start_xx>
+ +[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4}[ \t]+lea +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <__stop_xx>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr27491-4a.s b/ld/testsuite/ld-x86-64/pr27491-4a.s
new file mode 100644
index 00000000000..3b17a813e84
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-4a.s
@@ -0,0 +1,11 @@
+	.weak __start_xx
+	.weak __stop_xx
+
+	.text
+	.global foo
+foo:
+	movq	__start_xx@gotpcrel(%rip), %rax
+	movq	__stop_xx@gotpcrel(%rip), %rax
+
+	.section xx,"a",unique,1
+	.byte 0
diff --git a/ld/testsuite/ld-x86-64/pr27491-4b.s b/ld/testsuite/ld-x86-64/pr27491-4b.s
new file mode 100644
index 00000000000..2b46b21d3f0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr27491-4b.s
@@ -0,0 +1,2 @@
+	.section xx,"aR",unique,0
+	.byte 1
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 064438a3f91..ba065c0fe7f 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -480,6 +480,12 @@ run_dump_test "property-x86-isa3-x32"
 run_dump_test "property-x86-isa4"
 run_dump_test "property-x86-isa4-x32"
 run_dump_test "code16"
+run_dump_test "pr27491-1a"
+run_dump_test "pr27491-1b"
+run_dump_test "pr27491-1c"
+run_dump_test "pr27491-2"
+run_dump_test "pr27491-3"
+run_dump_test "pr27491-4"
 
 if ![istarget "x86_64-*-linux*"] {
     return
-- 
2.33.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-12-02 11:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-02  0:00 [PATCH] x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc H.J. Lu
2021-12-02  2:24 ` Fangrui Song
2021-12-02 11:54   ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).