[lld] r247856 - COFF: Fix bug that not all symbols were written to symtab if /opt:noref.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 14:40:47 PDT 2015


Author: ruiu
Date: Wed Sep 16 16:40:47 2015
New Revision: 247856

URL: http://llvm.org/viewvc/llvm-project?rev=247856&view=rev
Log:
COFF: Fix bug that not all symbols were written to symtab if /opt:noref.

Only live symbols are written to the symbol table. Because isLive()
returned false if dead-stripping was disabled entirely, only
non-COMDAT sections were written to the symbol table. This patch fixes
the issue.

Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/symtab.test

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=247856&r1=247855&r2=247856&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Wed Sep 16 16:40:47 2015
@@ -38,6 +38,9 @@ SectionChunk::SectionChunk(ObjectFile *F
   unsigned Shift = (Header->Characteristics >> 20) & 0xF;
   if (Shift > 0)
     Align = uint32_t(1) << (Shift - 1);
+
+  // Only COMDAT sections are subject of dead-stripping.
+  Live = !isCOMDAT();
 }
 
 static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=247856&r1=247855&r2=247856&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Wed Sep 16 16:40:47 2015
@@ -10,6 +10,7 @@
 #ifndef LLD_COFF_CHUNKS_H
 #define LLD_COFF_CHUNKS_H
 
+#include "Config.h"
 #include "InputFiles.h"
 #include "lld/Core/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -160,9 +161,9 @@ public:
   void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; }
 
   // Used by the garbage collector.
-  bool isLive() { return Live; }
+  bool isLive() { return !Config->DoGC || Live; }
   void markLive() {
-    assert(!Live && "Cannot mark an already live section!");
+    assert(!isLive() && "Cannot mark an already live section!");
     Live = true;
   }
 
@@ -198,7 +199,7 @@ private:
   size_t NumRelocs;
 
   // Used by the garbage collector.
-  bool Live = false;
+  bool Live;
 
   // Used for ICF (Identical COMDAT Folding)
   void replaceWith(SectionChunk *Other);

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=247856&r1=247855&r2=247856&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Sep 16 16:40:47 2015
@@ -251,6 +251,13 @@ void Writer::markLive() {
   // 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.
+  for (Chunk *C : Symtab->getChunks())
+    if (auto *SC = dyn_cast<SectionChunk>(C))
+      if (SC->isLive())
+        Worklist.push_back(SC);
+
+  // Add GC root chunks.
   for (Undefined *U : Config->GCRoot) {
     auto *D = dyn_cast<DefinedRegular>(U->repl());
     if (!D || D->isLive())
@@ -258,13 +265,7 @@ void Writer::markLive() {
     D->markLive();
     Worklist.push_back(D->getChunk());
   }
-  for (Chunk *C : Symtab->getChunks()) {
-    auto *SC = dyn_cast<SectionChunk>(C);
-    if (!SC || SC->isCOMDAT() || SC->isLive())
-      continue;
-    SC->markLive();
-    Worklist.push_back(SC);
-  }
+
   while (!Worklist.empty()) {
     SectionChunk *SC = Worklist.pop_back_val();
     assert(SC->isLive() && "We mark as live when pushing onto the worklist!");
@@ -305,13 +306,11 @@ void Writer::createSections() {
   // First, bin chunks by name.
   std::map<StringRef, std::vector<Chunk *>> Map;
   for (Chunk *C : Symtab->getChunks()) {
-    if (Config->DoGC) {
-      auto *SC = dyn_cast<SectionChunk>(C);
-      if (SC && !SC->isLive()) {
-        if (Config->Verbose)
-          SC->printDiscardedMessage();
-        continue;
-      }
+    auto *SC = dyn_cast<SectionChunk>(C);
+    if (SC && !SC->isLive()) {
+      if (Config->Verbose)
+        SC->printDiscardedMessage();
+      continue;
     }
     Map[C->getSectionName()].push_back(C);
   }

Modified: lld/trunk/test/COFF/symtab.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/symtab.test?rev=247856&r1=247855&r2=247856&view=diff
==============================================================================
--- lld/trunk/test/COFF/symtab.test (original)
+++ lld/trunk/test/COFF/symtab.test Wed Sep 16 16:40:47 2015
@@ -1,6 +1,8 @@
 # RUN: yaml2obj < %s > %t.obj
 # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
 # RUN: llvm-readobj -symbols %t.exe | FileCheck %s
+# RUN: lld-link /debug /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
+# RUN: llvm-readobj -symbols %t.exe | FileCheck %s
 
 # CHECK:      Symbols [
 # CHECK-NEXT:   Symbol {




More information about the llvm-commits mailing list