This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] x86: Keep __patchable_function_entries sections with --gc-sections


After all text sections have been garbage collected, if a
__patchable_function_entries section references a section which
wasn't marked, mark it with SEC_EXCLUDE and return NULL.  Otherwise,
keep it.

Should it be handled in _bfd_elf_gc_mark_extra_sections?

H.J.
---
bfd/

	PR ld/25490
	* elfxx-x86.c (_bfd_x86_elf_gc_mark_hook): Handle
	__patchable_function_entries sections.
	(_bfd_x86_elf_gc_mark_extra_sections): New function.
	* elfxx-x86.h (_bfd_x86_elf_gc_mark_extra_sections): New.
	(elf_backend_gc_mark_extra_sections): Likewise.

ld/

	PR ld/25490
	* testsuite/ld-i386/i386.exp: Run PR ld/25490 tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-i386/pr25490-1.d: Likewise.
	* testsuite/ld-i386/pr25490-2a.d: Likewise.
	* testsuite/ld-i386/pr25490-2b.d: Likewise.
	* testsuite/ld-x86-64/pr25490-1-x32.d: Likewise.
	* testsuite/ld-x86-64/pr25490-1.d: Likewise.
	* testsuite/ld-x86-64/pr25490-1.s: Likewise.
	* testsuite/ld-x86-64/pr25490-2.s: Likewise.
	* testsuite/ld-x86-64/pr25490-2a-x32.d: Likewise.
	* testsuite/ld-x86-64/pr25490-2a.d: Likewise.
	* testsuite/ld-x86-64/pr25490-2b-x32.d: Likewise.
	* testsuite/ld-x86-64/pr25490-2b.d: Likewise.
---
 bfd/elfxx-x86.c                         | 44 +++++++++++++++++++++++++
 bfd/elfxx-x86.h                         |  5 +++
 ld/testsuite/ld-i386/i386.exp           |  3 ++
 ld/testsuite/ld-i386/pr25490-1.d        |  8 +++++
 ld/testsuite/ld-i386/pr25490-2a.d       |  8 +++++
 ld/testsuite/ld-i386/pr25490-2b.d       |  9 +++++
 ld/testsuite/ld-x86-64/pr25490-1-x32.d  |  8 +++++
 ld/testsuite/ld-x86-64/pr25490-1.d      |  7 ++++
 ld/testsuite/ld-x86-64/pr25490-1.s      | 13 ++++++++
 ld/testsuite/ld-x86-64/pr25490-2.s      | 26 +++++++++++++++
 ld/testsuite/ld-x86-64/pr25490-2a-x32.d |  8 +++++
 ld/testsuite/ld-x86-64/pr25490-2a.d     |  8 +++++
 ld/testsuite/ld-x86-64/pr25490-2b-x32.d |  9 +++++
 ld/testsuite/ld-x86-64/pr25490-2b.d     |  9 +++++
 ld/testsuite/ld-x86-64/x86-64.exp       |  6 ++++
 15 files changed, 171 insertions(+)
 create mode 100644 ld/testsuite/ld-i386/pr25490-1.d
 create mode 100644 ld/testsuite/ld-i386/pr25490-2a.d
 create mode 100644 ld/testsuite/ld-i386/pr25490-2b.d
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-1-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-1.d
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-1.s
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-2.s
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-2a-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-2a.d
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-2b-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/pr25490-2b.d

diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index fc783b0e988..ec2ab0ce72b 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2110,10 +2110,54 @@ _bfd_x86_elf_gc_mark_hook (asection *sec,
       case R_X86_64_GNU_VTENTRY:
 	return NULL;
       }
+  else if (CONST_STRNEQ (bfd_section_name (sec),
+			 "__patchable_function_entries"))
+    {
+      /* After all text sections have been garbage collected, if a
+	 __patchable_function_entries section references a section
+	 which wasn't marked, mark it with SEC_EXCLUDE and return
+	 NULL.  */
+      asection *tsec = bfd_section_from_elf_index (sec->owner,
+						   sym->st_shndx);
+      if (!tsec->gc_mark)
+	{
+	  sec->flags |= SEC_EXCLUDE;
+	  return NULL;
+	}
+    }
 
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
+/* Prevent __patchable_function_entries sections from being discarded
+   with --gc-sections.  */
+
+bfd_boolean
+_bfd_x86_elf_gc_mark_extra_sections (struct bfd_link_info *info,
+				     elf_gc_mark_hook_fn gc_mark_hook)
+{
+  bfd *sub;
+
+  _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+    {
+      asection *o;
+
+      for (o = sub->sections; o != NULL; o = o->next)
+	if (!o->gc_mark
+	    && (o->flags & SEC_EXCLUDE) == 0
+	    && CONST_STRNEQ (bfd_section_name (o),
+			     "__patchable_function_entries"))
+	  {
+	    if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	      return FALSE;
+	  }
+    }
+
+  return TRUE;
+}
+
 static bfd_vma
 elf_i386_get_plt_got_vma (struct elf_x86_plt *plt_p ATTRIBUTE_UNUSED,
 			  bfd_vma off,
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index bef17dc2bac..1e43f1d786c 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -688,6 +688,9 @@ extern asection * _bfd_x86_elf_gc_mark_hook
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
+extern bfd_boolean _bfd_x86_elf_gc_mark_extra_sections
+  (struct bfd_link_info *, elf_gc_mark_hook_fn);
+
 extern long _bfd_x86_elf_get_synthetic_symtab
   (bfd *, long, long, bfd_vma, struct elf_x86_plt [], asymbol **,
    asymbol **);
@@ -737,6 +740,8 @@ extern void _bfd_x86_elf_link_fixup_ifunc_symbol
   _bfd_x86_elf_adjust_dynamic_symbol
 #define elf_backend_gc_mark_hook \
   _bfd_x86_elf_gc_mark_hook
+#define elf_backend_gc_mark_extra_sections \
+  _bfd_x86_elf_gc_mark_extra_sections
 #define elf_backend_omit_section_dynsym \
   _bfd_elf_omit_section_dynsym_all
 #define elf_backend_parse_gnu_properties \
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 7bb3636d3b0..68a43e3c35d 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -496,6 +496,9 @@ run_dump_test "pr23930"
 run_dump_test "pr24322a"
 run_dump_test "pr24322b"
 run_dump_test "align-branch-1"
+run_dump_test "pr25490-1"
+run_dump_test "pr25490-2a"
+run_dump_test "pr25490-2b"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr25490-1.d b/ld/testsuite/ld-i386/pr25490-1.d
new file mode 100644
index 00000000000..67cc5e86ec2
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr25490-1.d
@@ -0,0 +1,8 @@
+#source: ../ld-x86-64/pr25490-1.s
+#as: --32
+#ld: --gc-sections -melf_i386
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] __patchable_function_entries +PROGBITS +[0-9a-f]+ +[0-9a-f]+000 +0+4 +00 +WA +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-i386/pr25490-2a.d b/ld/testsuite/ld-i386/pr25490-2a.d
new file mode 100644
index 00000000000..5096252829f
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr25490-2a.d
@@ -0,0 +1,8 @@
+#source: ../ld-x86-64/pr25490-2.s
+#as: --32
+#ld: --gc-sections -melf_i386
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] __patchable_function_entries._start +PROGBITS +[0-9a-f]+ +[0-9a-f]+000 +0+4 +00 +WA +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-i386/pr25490-2b.d b/ld/testsuite/ld-i386/pr25490-2b.d
new file mode 100644
index 00000000000..3f9cab548be
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr25490-2b.d
@@ -0,0 +1,9 @@
+#source: ../ld-x86-64/pr25490-2.s
+#as: --32
+#ld: --gc-sections -melf_i386
+#readelf: -SW
+
+#failif
+#...
+ +\[ *[0-9]+\] __patchable_function_entries.bar +PROGBITS +.*
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr25490-1-x32.d b/ld/testsuite/ld-x86-64/pr25490-1-x32.d
new file mode 100644
index 00000000000..65bc2bee28c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-1-x32.d
@@ -0,0 +1,8 @@
+#source: pr25490-1.s
+#as: --x32
+#ld: --gc-sections -melf32_x86_64
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] __patchable_function_entries +PROGBITS +[0-9a-f]+ +[0-9a-f]+000 +0+4 +00 +WA +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr25490-1.d b/ld/testsuite/ld-x86-64/pr25490-1.d
new file mode 100644
index 00000000000..dc1d912076b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-1.d
@@ -0,0 +1,7 @@
+#as: --64
+#ld: --gc-sections -melf_x86_64
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] __patchable_function_entries +PROGBITS +[0-9a-f]+ +[0-9a-f]+000 +0+8 +00 +WA +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr25490-1.s b/ld/testsuite/ld-x86-64/pr25490-1.s
new file mode 100644
index 00000000000..21123ad8aa0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-1.s
@@ -0,0 +1,13 @@
+	.text
+	.p2align 4
+	.globl	_start
+	.type	_start, %function
+_start:
+	.section	__patchable_function_entries,"aw",%progbits
+	.dc.a	.LPFE1
+	.text
+.LPFE1:
+	nop
+	ret
+	.size	_start, .-_start
+	.section	.note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-x86-64/pr25490-2.s b/ld/testsuite/ld-x86-64/pr25490-2.s
new file mode 100644
index 00000000000..1f8df870316
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-2.s
@@ -0,0 +1,26 @@
+	.text
+	.p2align 4
+	.section	.text.bar,"ax",%progbits
+	.globl	bar
+	.type	bar, %function
+bar:
+	.section __patchable_function_entries.bar,"aw",%progbits
+	.dc.a	.LPFE1
+	.section	.text.bar,"ax",%progbits
+.LPFE1:
+	nop
+	ret
+	.size	bar, .-bar
+	.p2align 4
+	.section	.text._start,"ax",%progbits
+	.globl	_start
+	.type	_start, %function
+_start:
+	.section __patchable_function_entries._start,"aw",%progbits
+	.dc.a	.LPFE2
+	.section	.text._start,"ax",%progbits
+.LPFE2:
+	nop
+	ret
+	.size	_start, .-_start
+	.section	.note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-x86-64/pr25490-2a-x32.d b/ld/testsuite/ld-x86-64/pr25490-2a-x32.d
new file mode 100644
index 00000000000..2029029a0f3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-2a-x32.d
@@ -0,0 +1,8 @@
+#source: pr25490-2.s
+#as: --x32
+#ld: --gc-sections -melf32_x86_64
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] __patchable_function_entries._start +PROGBITS +[0-9a-f]+ +[0-9a-f]+000 +0+4 +00 +WA +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr25490-2a.d b/ld/testsuite/ld-x86-64/pr25490-2a.d
new file mode 100644
index 00000000000..a5f0b141c87
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-2a.d
@@ -0,0 +1,8 @@
+#source: pr25490-2.s
+#as: --64
+#ld: --gc-sections -melf_x86_64
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] __patchable_function_entries._start +PROGBITS +[0-9a-f]+ +[0-9a-f]+000 +0+8 +00 +WA +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr25490-2b-x32.d b/ld/testsuite/ld-x86-64/pr25490-2b-x32.d
new file mode 100644
index 00000000000..a9fe6ba6b3c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-2b-x32.d
@@ -0,0 +1,9 @@
+#source: pr25490-2.s
+#as: --x32
+#ld: --gc-sections -melf32_x86_64
+#readelf: -SW
+
+#failif
+#...
+ +\[ *[0-9]+\] __patchable_function_entries.bar +PROGBITS +.*
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr25490-2b.d b/ld/testsuite/ld-x86-64/pr25490-2b.d
new file mode 100644
index 00000000000..5eb933f5b36
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-2b.d
@@ -0,0 +1,9 @@
+#source: pr25490-2.s
+#as: --64
+#ld: --gc-sections -melf_x86_64
+#readelf: -SW
+
+#failif
+#...
+ +\[ *[0-9]+\] __patchable_function_entries.bar +PROGBITS +.*
+#pass
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index c78b0fd7576..e30b21d53d4 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -467,6 +467,12 @@ run_dump_test "pr25416-2a"
 run_dump_test "pr25416-2b"
 run_dump_test "pr25416-3"
 run_dump_test "pr25416-4"
+run_dump_test "pr25490-1"
+run_dump_test "pr25490-1-x32"
+run_dump_test "pr25490-2a"
+run_dump_test "pr25490-2a-x32"
+run_dump_test "pr25490-2b"
+run_dump_test "pr25490-2b-x32"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return
-- 
2.24.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]