[PATCH] x86: Skip __[start|stop]_SECNAME for --gc-sections -z start-stop-gc
H.J. Lu
hjl.tools@gmail.com
Thu Dec 2 11:54:43 GMT 2021
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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v3-0001-x86-Skip-__-start-stop-_SECNAME-for-gc-sections-z.patch
Type: text/x-patch
Size: 19899 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20211202/e7d0af70/attachment-0001.bin>
More information about the Binutils
mailing list