summaryrefslogtreecommitdiffstats
path: root/lld/COFF/Writer.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-09-16 21:40:47 +0000
committerRui Ueyama <ruiu@google.com>2015-09-16 21:40:47 +0000
commit4dbff20c91aa5cf5bed789b229222aa9d2eecf6b (patch)
tree644be80c4424b1aedcb48fca975f2784c880d446 /lld/COFF/Writer.cpp
parentf59497dc92146c4f988bd26f171594f5595911ff (diff)
downloadbcm5719-llvm-4dbff20c91aa5cf5bed789b229222aa9d2eecf6b.tar.gz
bcm5719-llvm-4dbff20c91aa5cf5bed789b229222aa9d2eecf6b.zip
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. llvm-svn: 247856
Diffstat (limited to 'lld/COFF/Writer.cpp')
-rw-r--r--lld/COFF/Writer.cpp27
1 files changed, 13 insertions, 14 deletions
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 8cc48b57adf..b133d1c5701 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -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);
}
OpenPOWER on IntegriCloud