Author: Reid Kleckner
Date: 2020-04-13T13:48:04-07:00
New Revision: edbe962459da6e3b7b4168118f93a77847b54e02

URL: 
https://github.com/llvm/llvm-project/commit/edbe962459da6e3b7b4168118f93a77847b54e02
DIFF: 
https://github.com/llvm/llvm-project/commit/edbe962459da6e3b7b4168118f93a77847b54e02.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

(cherry picked from commit c579a5b1d92a9bc2046d00ee2d427832e0f5ddec)

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@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


        
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to