[lld] c579a5b - [COFF] Don't treat DWARF sections as GC roots

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 27 12:37:51 PDT 2020


Author: Reid Kleckner
Date: 2020-03-27T12:37:43-07:00
New Revision: c579a5b1d92a9bc2046d00ee2d427832e0f5ddec

URL: https://github.com/llvm/llvm-project/commit/c579a5b1d92a9bc2046d00ee2d427832e0f5ddec
DIFF: https://github.com/llvm/llvm-project/commit/c579a5b1d92a9bc2046d00ee2d427832e0f5ddec.diff

LOG: [COFF] Don't treat DWARF sections as GC roots

DWARF sections are typically live and not COMDAT, so they would be
treated as GC roots. Enabling DWARF would essentially keep all code with
debug info alive, preventing any section GC.

Fixes PR45273

Reviewed By: mstorsjo, MaskRay

Differential Revision: https://reviews.llvm.org/D76935

Added: 
    lld/test/COFF/gc-dwarf.s

Modified: 
    lld/COFF/MarkLive.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/MarkLive.cpp b/lld/COFF/MarkLive.cpp
index 6d34cb864e3c..0afa615a1933 100644
--- a/lld/COFF/MarkLive.cpp
+++ b/lld/COFF/MarkLive.cpp
@@ -28,10 +28,12 @@ void markLive(ArrayRef<Chunk *> chunks) {
   // as we push, so sections never appear twice in the list.
   SmallVector<SectionChunk *, 256> worklist;
 
-  // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
+  // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not
+  // traverse DWARF sections. They are live, but they should not keep other
+  // sections alive.
   for (Chunk *c : chunks)
     if (auto *sc = dyn_cast<SectionChunk>(c))
-      if (sc->live)
+      if (sc->live && !sc->isDWARF())
         worklist.push_back(sc);
 
   auto enqueue = [&](SectionChunk *c) {

diff  --git a/lld/test/COFF/gc-dwarf.s b/lld/test/COFF/gc-dwarf.s
new file mode 100644
index 000000000000..56b866f4a4ac
--- /dev/null
+++ b/lld/test/COFF/gc-dwarf.s
@@ -0,0 +1,60 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmap:%t.map -out:%t.exe -opt:ref -entry:main %t.obj -verbose 2>&1 | FileCheck %s
+# RUN: FileCheck %s --check-prefix=MAP --input-file=%t.map
+
+# CHECK:      Discarded unused1
+# CHECK-NEXT: Discarded unused2
+# CHECK-NOT: Discarded
+
+# MAP: In Symbol
+# MAP: gc-dwarf.s.tmp.obj:(.text)
+# MAP: {{ main$}}
+# MAP: gc-dwarf.s.tmp.obj:(.text)
+# MAP: {{ used$}}
+
+	.def	 @feat.00; .scl	3; .type	0; .endef
+	.globl	@feat.00
+.set @feat.00, 0
+
+	.def	 main; .scl	2; .type	32; .endef
+	.section	.text,"xr",one_only,main
+	.globl	main
+main:
+	callq used
+	xorl	%eax, %eax
+	retq
+
+	.def	 used; .scl	2; .type	32; .endef
+	.section	.text,"xr",one_only,used
+	.globl	used
+used:
+	retq
+
+
+	.def	 unused1; .scl	2; .type	32; .endef
+	.section	.text,"xr",one_only,unused1
+	.globl	unused1
+unused1:
+	retq
+
+	.def	 unused2; .scl	2; .type	32; .endef
+	.section	.text,"xr",one_only,unused2
+	.globl	unused2
+unused2:
+	retq
+
+# This isn't valid DWARF, but LLD doesn't care. Make up some data that
+# references the functions above.
+.section .debug_info,"r"
+.long main at IMGREL
+.long unused1 at IMGREL
+.long unused2 at IMGREL
+
+# Similarly, .eh_frame unwind info should not keep functions alive. Again, this
+# is not valid unwind info, but it doesn't matter for testing purposes.
+.section .eh_frame,"r"
+.long main at IMGREL
+.long unused1 at IMGREL
+.long unused2 at IMGREL


        


More information about the llvm-commits mailing list