[PATCH] D95749: [ELF] Make SHF_GNU_RETAIN sections GC roots

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 30 14:59:23 PST 2021


MaskRay created this revision.
MaskRay added reviewers: grimar, jhenderson, peter.smith.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

binutils 2.36 introduced the new section flag SHF_GNU_RETAIN (for ELFOSABI_GNU &
ELFOSABI_FREEBSD) to mark a sections as a GC root.

Currently GNU ld only respects SHF_GNU_RETAIN semantics for ELFOSABI_GNU &
ELFOSABI_FREEBSD object files (https://sourceware.org/bugzilla/show_bug.cgi?id=27282).
GNU ld sets EI_OSABI to ELFOSABI_GNU for relocatable output
(https://sourceware.org/bugzilla/show_bug.cgi?id=27091).

In practice the single value EI_OSABI is neither a good indicator for
object file compatibility, nor a useful mechanism marking used ELF
extensions. It is not clear ELFOSABI_GNU is the suitable value on
non-Linux platforms which adopt this section flag.

Several LLVM side toolchain folks (including me) were involved in the
design process of SHF_GNU_RETAIN and were happy with this proposal. As
of LLVM 12.0.0, the integrated assembler does not set ELFOSABI_GNU for
(mildly useful) STT_GNU_IFUNC /(used by GCC, considered misfeature by
some folks) STB_GNU_UNIQUE. LLD does not mark the output ELFOSABI_GNU
when STT_GNU_IFUNC/STB_GNU_UNIQUE features are used.  Therefore, we
don't set EI_OSABI to ELFOSABI_GNU for SHF_GNU_RETAIN.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D95749

Files:
  lld/ELF/MarkLive.cpp
  lld/test/ELF/gc-sections-retain.s


Index: lld/test/ELF/gc-sections-retain.s
===================================================================
--- /dev/null
+++ lld/test/ELF/gc-sections-retain.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+## SHF_GNU_RETAIN is a generic feature defined in the OS specific range. The
+## flag marks a section as a GC root.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: ld.lld --gc-sections --print-gc-sections %t.o -o %t | count 0
+# RUN: llvm-readobj -h %t | FileCheck %s
+# RUN: ld.lld -r -e _start --gc-sections --print-gc-sections %t.o -o %t.ro | count 0
+# RUN: llvm-readobj -h %t.ro | FileCheck %s
+
+## SHF_GNU_RETAIN has no significance in executables/shared objects. Multiple
+## OSABI values can benefit from this flag. Test that we don't change EI_OSABI,
+## even for relocatable output.
+# CHECK: OS/ABI: SystemV (0x0)
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 --defsym NONALLOC=1 %s -o %t1.o
+# RUN: not ld.lld --gc-sections %t1.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+# ERR: error: {{.*}}.o:(.nonalloc): sh_link points to discarded section {{.*}}.o:(.discard)
+
+.global _start
+_start:
+
+.section .retain,"aR", at progbits
+.quad .foo
+
+.section .foo,"a", at progbits
+.quad 0
+
+.ifdef NONALLOC
+.section .discard,"a", at progbits
+
+## With SHF_GNU_RETAIN, .nonalloc is retained while its linked-to section
+## .discard is discarded, so there will be an error.
+.section .nonalloc,"oR", at progbits,.discard
+.quad .text
+.endif
Index: lld/ELF/MarkLive.cpp
===================================================================
--- lld/ELF/MarkLive.cpp
+++ lld/ELF/MarkLive.cpp
@@ -261,6 +261,10 @@
         scanEhFrameSection(*eh, eh->template rels<ELFT>());
     }
 
+    if (sec->flags & SHF_GNU_RETAIN) {
+      enqueue(sec, 0);
+      continue;
+    }
     if (sec->flags & SHF_LINK_ORDER)
       continue;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95749.320325.patch
Type: text/x-patch
Size: 1849 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210130/78435d8b/attachment.bin>


More information about the llvm-commits mailing list