[PATCH] D76668: [lld][ELF] Ignore __start/__stop symbols in section groups during GC

Petr Hosek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 23 21:45:38 PDT 2020


phosek created this revision.
phosek added a reviewer: ruiu.
Herald added subscribers: llvm-commits, MaskRay, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

The GC algorithm implementation in lld marks all sections for which
there are __start_<section> and __stop_<section> references as live.
This leads to an issue where the section with the same name could be
in multiple groups, and while only some of these groups are referenced,
the current implementation will keep all of them.

Concrete example of this issue is LLVM profile instrumentation where for
every function symbol we create a section (assuming -ffunction-sections)
and corresponding __llvm_prf_data section that contains associated
metadata, both of which are in a group. When there aren't any references
to the function section, we'd expect the entire group to be collected,
but that won't be the case because of __start___llvm_prf_data and
__stop___llvm_prf_data symbol references in profile runtime.

This patch changes the behavior to ignore __start/__stop symbols in section
groups which allows for these groups to be collected. This also matches
the behavior of BFD linker.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76668

Files:
  lld/ELF/MarkLive.cpp
  lld/test/ELF/comdat-gc-startstop.s


Index: lld/test/ELF/comdat-gc-startstop.s
===================================================================
--- /dev/null
+++ lld/test/ELF/comdat-gc-startstop.s
@@ -0,0 +1,36 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld --gc-sections %t.o -o %t
+// RUN: llvm-readelf --symbols %t | FileCheck %s
+
+.weak __start___llvm_prf_data
+.weak __stop___llvm_prf_data
+
+.section .text,"ax", at progbits
+.global _start
+_start:
+  .quad __start___llvm_prf_data - .
+  .quad __stop___llvm_prf_data - .
+  call f
+
+.section __llvm_prf_data,"axG", at progbits,f,comdat,unique,0
+.quad 0
+
+.section .text.f,"axG", at progbits,f,comdat,unique,0
+.global f
+f:
+  nop
+
+.section __llvm_prf_data,"axG", at progbits,g,comdat,unique,0
+.quad 0
+
+.section .text.g,"axG", at progbits,g,comdat,unique,0
+.global g
+g:
+  nop
+
+// CHECK:     0000000000201136  0 NOTYPE  GLOBAL PROTECTED   2 __start___llvm_prf_data
+// CHECK:     000000000020113e  0 NOTYPE  GLOBAL PROTECTED   2 __stop___llvm_prf_data
+// CHECK:     0000000000201120  0 NOTYPE  GLOBAL DEFAULT     1 _start
+// CHECK:     0000000000201135  0 NOTYPE  GLOBAL DEFAULT     1 f
+// CHECK-NOT: 0000000000201136  0 NOTYPE  GLOBAL DEFAULT     1 g
Index: lld/ELF/MarkLive.cpp
===================================================================
--- lld/ELF/MarkLive.cpp
+++ lld/ELF/MarkLive.cpp
@@ -261,7 +261,7 @@
 
     if (isReserved(sec) || script->shouldKeep(sec)) {
       enqueue(sec, 0);
-    } else if (isValidCIdentifier(sec->name)) {
+    } else if (isValidCIdentifier(sec->name) && !sec->nextInSectionGroup) {
       cNamedSections[saver.save("__start_" + sec->name)].push_back(sec);
       cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76668.252216.patch
Type: text/x-patch
Size: 1760 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200324/65a686d1/attachment.bin>


More information about the llvm-commits mailing list