[COFF] Don't treat DWARF sections as GC roots
authorReid Kleckner <rnk@google.com>
Fri, 27 Mar 2020 16:09:06 +0000 (09:09 -0700)
committerReid Kleckner <rnk@google.com>
Fri, 27 Mar 2020 19:37:43 +0000 (12:37 -0700)
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

lld/COFF/MarkLive.cpp
lld/test/COFF/gc-dwarf.s [new file with mode: 0644]

index 6d34cb8..0afa615 100644 (file)
@@ -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 (file)
index 0000000..56b866f
--- /dev/null
@@ -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@IMGREL
+.long unused1@IMGREL
+.long unused2@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@IMGREL
+.long unused1@IMGREL
+.long unused2@IMGREL