From: "H.J. Lu" <hjl.tools@gmail.com>
To: Binutils <binutils@sourceware.org>
Subject: Re: [PATCH] x86: Keep __patchable_function_entries sections with --gc-sections
Date: Sat, 01 Feb 2020 17:19:00 -0000 [thread overview]
Message-ID: <CAMe9rOqo+2qbGtsz1+qmeJYNpKE=GP8QeDmi6sAOdZBSg_Rrdg@mail.gmail.com> (raw)
In-Reply-To: <20200201162613.2023476-1-hjl.tools@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 507 bytes --]
On Sat, Feb 1, 2020 at 8:26 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> 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?
>
It should be an error if a __patchable_function_entries section
references both kept and garbage collected sections. Here
is the updated patch to do it.
--
H.J.
[-- Attachment #2: 0001-x86-Keep-__patchable_function_entries-sections-with-.patch --]
[-- Type: text/x-patch, Size: 14226 bytes --]
From 16dbc36a7ff358f82b95abe892e23575f502f1d9 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 1 Feb 2020 08:19:00 -0800
Subject: [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. Issue an error if a __patchable_function_entries section
references both kept and garbage collected sections.
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: New file.
* testsuite/ld-i386/pr25490-2a.d: Likewise.
* testsuite/ld-i386/pr25490-2b.d: Likewise.
* testsuite/ld-i386/pr25490-3.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.
* testsuite/ld-x86-64/pr25490-3-x32.d: Likewise.
* testsuite/ld-x86-64/pr25490-3.d: Likewise.
* testsuite/ld-x86-64/pr25490-3.s: Likewise.
---
bfd/elfxx-x86.c | 49 +++++++++++++++++++++++++
bfd/elfxx-x86.h | 5 +++
ld/testsuite/ld-i386/i386.exp | 4 ++
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-i386/pr25490-3.d | 4 ++
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/pr25490-3-x32.d | 4 ++
ld/testsuite/ld-x86-64/pr25490-3.d | 3 ++
ld/testsuite/ld-x86-64/pr25490-3.s | 28 ++++++++++++++
ld/testsuite/ld-x86-64/x86-64.exp | 8 ++++
19 files changed, 218 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-i386/pr25490-3.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
create mode 100644 ld/testsuite/ld-x86-64/pr25490-3-x32.d
create mode 100644 ld/testsuite/ld-x86-64/pr25490-3.d
create mode 100644 ld/testsuite/ld-x86-64/pr25490-3.s
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index fc783b0e988..758717d99ae 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2110,10 +2110,59 @@ _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);
+ /* NB: A __patchable_function_entries section may reference both
+ kept and garbage collected sections. */
+ if (tsec->gc_mark)
+ sec->flags |= SEC_KEEP;
+ else
+ sec->flags |= SEC_EXCLUDE;
+ }
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
+ && (o->flags & SEC_KEEP) == 0
+ && CONST_STRNEQ (bfd_section_name (o),
+ "__patchable_function_entries"))
+ {
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ if ((o->flags & SEC_EXCLUDE) && (o->flags & SEC_KEEP))
+ info->callbacks->einfo (_("%F%pB(%pA): reference to garbage collected section\n"),
+ o->owner, o);
+ }
+ }
+
+ 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..e13f23cdc67 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -496,6 +496,10 @@ 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"
+run_dump_test "pr25490-3"
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-i386/pr25490-3.d b/ld/testsuite/ld-i386/pr25490-3.d
new file mode 100644
index 00000000000..4da1f85d630
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr25490-3.d
@@ -0,0 +1,4 @@
+#source: ../ld-x86-64/pr25490-3.s
+#as: --32
+#ld: --gc-sections -melf_i386
+#error: .*\(__patchable_function_entries\): reference to garbage collected section
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/pr25490-3-x32.d b/ld/testsuite/ld-x86-64/pr25490-3-x32.d
new file mode 100644
index 00000000000..4979a3e7978
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-3-x32.d
@@ -0,0 +1,4 @@
+#source: pr25490-3.s
+#as: --x32
+#ld: --gc-sections -melf32_x86_64
+#error: .*\(__patchable_function_entries\): reference to garbage collected section
diff --git a/ld/testsuite/ld-x86-64/pr25490-3.d b/ld/testsuite/ld-x86-64/pr25490-3.d
new file mode 100644
index 00000000000..27a11480b60
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-3.d
@@ -0,0 +1,3 @@
+#as: --64
+#ld: --gc-sections -melf_x86_64
+#error: .*\(__patchable_function_entries\): reference to garbage collected section
diff --git a/ld/testsuite/ld-x86-64/pr25490-3.s b/ld/testsuite/ld-x86-64/pr25490-3.s
new file mode 100644
index 00000000000..c7fae78314c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr25490-3.s
@@ -0,0 +1,28 @@
+ .text
+ .section .text.bar,"ax",%progbits
+ .p2align 4
+ .globl bar
+ .type bar, %function
+bar:
+ .section __patchable_function_entries,"aw",%progbits
+ .align 8
+ .dc.a .LPFE1
+ .section .text.bar
+.LPFE1:
+ nop
+ ret
+ .size bar, .-bar
+ .section .text._start,"ax",%progbits
+ .p2align 4
+ .globl _start
+ .type _start, %function
+_start:
+ .section __patchable_function_entries
+ .align 8
+ .dc.a .LPFE2
+ .section .text._start
+.LPFE2:
+ nop
+ ret
+ .size _start, .-_start
+ .section .note.GNU-stack,"",%progbits
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index c78b0fd7576..48912ace1c1 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -467,6 +467,14 @@ 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"
+run_dump_test "pr25490-3"
+run_dump_test "pr25490-3-x32"
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
return
--
2.24.1
next prev parent reply other threads:[~2020-02-01 17:19 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-01 16:26 H.J. Lu
2020-02-01 17:19 ` H.J. Lu [this message]
2020-02-01 17:34 ` Fangrui Song
2020-02-01 17:43 ` H.J. Lu
2020-02-01 18:21 ` Fangrui Song
2020-02-02 23:44 ` [PATCH] Issue an error for GC on __patchable_function_entries section H.J. Lu
2020-02-03 0:57 ` Fangrui Song
2020-02-03 1:18 ` H.J. Lu
2020-02-07 2:23 ` [PATCH] ld: " H.J. Lu
2020-02-07 3:28 ` Alan Modra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMe9rOqo+2qbGtsz1+qmeJYNpKE=GP8QeDmi6sAOdZBSg_Rrdg@mail.gmail.com' \
--to=hjl.tools@gmail.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).