summaryrefslogtreecommitdiff
path: root/COFF/SymbolTable.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:19:15 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:19:15 +0000
commitd93e1dfac8711cfed1a9d9cd1876a788b83945cd (patch)
tree5896fa6c02a262a6148b215487e545d937de58b7 /COFF/SymbolTable.cpp
parent8d43286d630f9224de07809ea253e83ebb9cdee6 (diff)
Notes
Diffstat (limited to 'COFF/SymbolTable.cpp')
-rw-r--r--COFF/SymbolTable.cpp494
1 files changed, 233 insertions, 261 deletions
diff --git a/COFF/SymbolTable.cpp b/COFF/SymbolTable.cpp
index df9da4c36650..9cc0b75c1510 100644
--- a/COFF/SymbolTable.cpp
+++ b/COFF/SymbolTable.cpp
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
+#include "SymbolTable.h"
#include "Config.h"
#include "Driver.h"
#include "Error.h"
-#include "SymbolTable.h"
+#include "Memory.h"
#include "Symbols.h"
-#include "lld/Core/Parallel.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/LTO/legacy/LTOCodeGenerator.h"
#include "llvm/Support/Debug.h"
@@ -24,222 +24,265 @@ using namespace llvm;
namespace lld {
namespace coff {
-void SymbolTable::addFile(std::unique_ptr<InputFile> FileP) {
-#if LLVM_ENABLE_THREADS
- std::launch Policy = std::launch::async;
-#else
- std::launch Policy = std::launch::deferred;
-#endif
+SymbolTable *Symtab;
- InputFile *File = FileP.get();
- Files.push_back(std::move(FileP));
- if (auto *F = dyn_cast<ArchiveFile>(File)) {
- ArchiveQueue.push_back(
- std::async(Policy, [=]() { F->parse(); return F; }));
- return;
+void SymbolTable::addFile(InputFile *File) {
+ if (Config->Verbose)
+ outs() << "Reading " << toString(File) << "\n";
+ File->parse();
+
+ MachineTypes MT = File->getMachineType();
+ if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
+ Config->Machine = MT;
+ } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) {
+ fatal(toString(File) + ": machine type " + machineToStr(MT) +
+ " conflicts with " + machineToStr(Config->Machine));
}
- ObjectQueue.push_back(
- std::async(Policy, [=]() { File->parse(); return File; }));
+
if (auto *F = dyn_cast<ObjectFile>(File)) {
ObjectFiles.push_back(F);
} else if (auto *F = dyn_cast<BitcodeFile>(File)) {
BitcodeFiles.push_back(F);
- } else {
- ImportFiles.push_back(cast<ImportFile>(File));
+ } else if (auto *F = dyn_cast<ImportFile>(File)) {
+ ImportFiles.push_back(F);
}
-}
-void SymbolTable::step() {
- if (queueEmpty())
+ StringRef S = File->getDirectives();
+ if (S.empty())
return;
- readObjects();
- readArchives();
-}
-void SymbolTable::run() {
- while (!queueEmpty())
- step();
-}
-
-void SymbolTable::readArchives() {
- if (ArchiveQueue.empty())
- return;
-
- // Add lazy symbols to the symbol table. Lazy symbols that conflict
- // with existing undefined symbols are accumulated in LazySyms.
- std::vector<Symbol *> LazySyms;
- for (std::future<ArchiveFile *> &Future : ArchiveQueue) {
- ArchiveFile *File = Future.get();
- if (Config->Verbose)
- llvm::outs() << "Reading " << File->getShortName() << "\n";
- for (Lazy &Sym : File->getLazySymbols())
- addLazy(&Sym, &LazySyms);
- }
- ArchiveQueue.clear();
-
- // Add archive member files to ObjectQueue that should resolve
- // existing undefined symbols.
- for (Symbol *Sym : LazySyms)
- addMemberFile(cast<Lazy>(Sym->Body));
-}
-
-void SymbolTable::readObjects() {
- if (ObjectQueue.empty())
- return;
-
- // Add defined and undefined symbols to the symbol table.
- std::vector<StringRef> Directives;
- for (size_t I = 0; I < ObjectQueue.size(); ++I) {
- InputFile *File = ObjectQueue[I].get();
- if (Config->Verbose)
- llvm::outs() << "Reading " << File->getShortName() << "\n";
- // Adding symbols may add more files to ObjectQueue
- // (but not to ArchiveQueue).
- for (SymbolBody *Sym : File->getSymbols())
- if (Sym->isExternal())
- addSymbol(Sym);
- StringRef S = File->getDirectives();
- if (!S.empty()) {
- Directives.push_back(S);
- if (Config->Verbose)
- llvm::outs() << "Directives: " << File->getShortName()
- << ": " << S << "\n";
- }
- }
- ObjectQueue.clear();
-
- // Parse directive sections. This may add files to
- // ArchiveQueue and ObjectQueue.
- for (StringRef S : Directives)
- Driver->parseDirectives(S);
-}
-
-bool SymbolTable::queueEmpty() {
- return ArchiveQueue.empty() && ObjectQueue.empty();
+ if (Config->Verbose)
+ outs() << "Directives: " << toString(File) << ": " << S << "\n";
+ Driver->parseDirectives(S);
}
-void SymbolTable::reportRemainingUndefines(bool Resolve) {
- llvm::SmallPtrSet<SymbolBody *, 8> Undefs;
+void SymbolTable::reportRemainingUndefines() {
+ SmallPtrSet<SymbolBody *, 8> Undefs;
for (auto &I : Symtab) {
Symbol *Sym = I.second;
- auto *Undef = dyn_cast<Undefined>(Sym->Body);
+ auto *Undef = dyn_cast<Undefined>(Sym->body());
if (!Undef)
continue;
+ if (!Sym->IsUsedInRegularObj)
+ continue;
StringRef Name = Undef->getName();
// A weak alias may have been resolved, so check for that.
if (Defined *D = Undef->getWeakAlias()) {
- if (Resolve)
- Sym->Body = D;
+ // We resolve weak aliases by replacing the alias's SymbolBody with the
+ // target's SymbolBody. This causes all SymbolBody pointers referring to
+ // the old symbol to instead refer to the new symbol. However, we can't
+ // just blindly copy sizeof(Symbol::Body) bytes from D to Sym->Body
+ // because D may be an internal symbol, and internal symbols are stored as
+ // "unparented" SymbolBodies. For that reason we need to check which type
+ // of symbol we are dealing with and copy the correct number of bytes.
+ if (isa<DefinedRegular>(D))
+ memcpy(Sym->Body.buffer, D, sizeof(DefinedRegular));
+ else if (isa<DefinedAbsolute>(D))
+ memcpy(Sym->Body.buffer, D, sizeof(DefinedAbsolute));
+ else
+ // No other internal symbols are possible.
+ Sym->Body = D->symbol()->Body;
continue;
}
// If we can resolve a symbol by removing __imp_ prefix, do that.
// This odd rule is for compatibility with MSVC linker.
if (Name.startswith("__imp_")) {
Symbol *Imp = find(Name.substr(strlen("__imp_")));
- if (Imp && isa<Defined>(Imp->Body)) {
- if (!Resolve)
- continue;
- auto *D = cast<Defined>(Imp->Body);
- auto *S = new (Alloc) DefinedLocalImport(Name, D);
- LocalImportChunks.push_back(S->getChunk());
- Sym->Body = S;
+ if (Imp && isa<Defined>(Imp->body())) {
+ auto *D = cast<Defined>(Imp->body());
+ replaceBody<DefinedLocalImport>(Sym, Name, D);
+ LocalImportChunks.push_back(
+ cast<DefinedLocalImport>(Sym->body())->getChunk());
continue;
}
}
// Remaining undefined symbols are not fatal if /force is specified.
// They are replaced with dummy defined symbols.
- if (Config->Force && Resolve)
- Sym->Body = new (Alloc) DefinedAbsolute(Name, 0);
- Undefs.insert(Sym->Body);
+ if (Config->Force)
+ replaceBody<DefinedAbsolute>(Sym, Name, 0);
+ Undefs.insert(Sym->body());
}
if (Undefs.empty())
return;
- for (Undefined *U : Config->GCRoot)
- if (Undefs.count(U->repl()))
- llvm::errs() << "<root>: undefined symbol: " << U->getName() << "\n";
- for (std::unique_ptr<InputFile> &File : Files)
- if (!isa<ArchiveFile>(File.get()))
- for (SymbolBody *Sym : File->getSymbols())
- if (Undefs.count(Sym->repl()))
- llvm::errs() << File->getShortName() << ": undefined symbol: "
- << Sym->getName() << "\n";
+ for (SymbolBody *B : Config->GCRoot)
+ if (Undefs.count(B))
+ errs() << "<root>: undefined symbol: " << B->getName() << "\n";
+ for (ObjectFile *File : ObjectFiles)
+ for (SymbolBody *Sym : File->getSymbols())
+ if (Undefs.count(Sym))
+ errs() << toString(File) << ": undefined symbol: " << Sym->getName()
+ << "\n";
if (!Config->Force)
fatal("link failed");
}
-void SymbolTable::addLazy(Lazy *New, std::vector<Symbol *> *Accum) {
- Symbol *Sym = insert(New);
- if (Sym->Body == New)
- return;
- SymbolBody *Existing = Sym->Body;
- if (isa<Defined>(Existing))
- return;
- if (Lazy *L = dyn_cast<Lazy>(Existing))
- if (L->getFileIndex() < New->getFileIndex())
- return;
- Sym->Body = New;
- New->setBackref(Sym);
- if (isa<Undefined>(Existing))
- Accum->push_back(Sym);
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
+ Symbol *&Sym = Symtab[CachedHashStringRef(Name)];
+ if (Sym)
+ return {Sym, false};
+ Sym = make<Symbol>();
+ Sym->IsUsedInRegularObj = false;
+ Sym->PendingArchiveLoad = false;
+ return {Sym, true};
}
-void SymbolTable::addSymbol(SymbolBody *New) {
- // Find an existing symbol or create and insert a new one.
- assert(isa<Defined>(New) || isa<Undefined>(New));
- Symbol *Sym = insert(New);
- if (Sym->Body == New)
- return;
- SymbolBody *Existing = Sym->Body;
-
- // If we have an undefined symbol and a lazy symbol,
- // let the lazy symbol to read a member file.
- if (auto *L = dyn_cast<Lazy>(Existing)) {
- // Undefined symbols with weak aliases need not to be resolved,
- // since they would be replaced with weak aliases if they remain
- // undefined.
- if (auto *U = dyn_cast<Undefined>(New)) {
- if (!U->WeakAlias) {
- addMemberFile(L);
- return;
- }
+Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
+ bool IsWeakAlias) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(Name);
+ if (!F || !isa<BitcodeFile>(F))
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || (isa<Lazy>(S->body()) && IsWeakAlias)) {
+ replaceBody<Undefined>(S, Name);
+ return S;
+ }
+ if (auto *L = dyn_cast<Lazy>(S->body())) {
+ if (!S->PendingArchiveLoad) {
+ S->PendingArchiveLoad = true;
+ L->File->addMember(&L->Sym);
}
- Sym->Body = New;
+ }
+ return S;
+}
+
+void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
+ StringRef Name = Sym.getName();
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(Name);
+ if (WasInserted) {
+ replaceBody<Lazy>(S, F, Sym);
return;
}
+ auto *U = dyn_cast<Undefined>(S->body());
+ if (!U || U->WeakAlias || S->PendingArchiveLoad)
+ return;
+ S->PendingArchiveLoad = true;
+ F->addMember(&Sym);
+}
+
+void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
+ fatal("duplicate symbol: " + toString(*Existing->body()) + " in " +
+ toString(Existing->body()->getFile()) + " and in " +
+ (NewFile ? toString(NewFile) : "(internal)"));
+}
- // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
- // equivalent (conflicting), or more preferable, respectively.
- int Comp = Existing->compare(New);
- if (Comp == 0)
- fatal("duplicate symbol: " + Existing->getDebugName() + " and " +
- New->getDebugName());
- if (Comp < 0)
- Sym->Body = New;
+Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(N);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ replaceBody<DefinedAbsolute>(S, N, Sym);
+ else if (!isa<DefinedCOFF>(S->body()))
+ reportDuplicate(S, nullptr);
+ return S;
}
-Symbol *SymbolTable::insert(SymbolBody *New) {
- Symbol *&Sym = Symtab[New->getName()];
- if (Sym) {
- New->setBackref(Sym);
- return Sym;
+Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(N);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ replaceBody<DefinedAbsolute>(S, N, VA);
+ else if (!isa<DefinedCOFF>(S->body()))
+ reportDuplicate(S, nullptr);
+ return S;
+}
+
+Symbol *SymbolTable::addRelative(StringRef N, uint64_t VA) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(N);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ replaceBody<DefinedRelative>(S, N, VA);
+ else if (!isa<DefinedCOFF>(S->body()))
+ reportDuplicate(S, nullptr);
+ return S;
+}
+
+Symbol *SymbolTable::addRegular(ObjectFile *F, COFFSymbolRef Sym,
+ SectionChunk *C) {
+ StringRef Name;
+ F->getCOFFObj()->getSymbolName(Sym, Name);
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(Name);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ replaceBody<DefinedRegular>(S, F, Sym, C);
+ else if (auto *R = dyn_cast<DefinedRegular>(S->body())) {
+ if (!C->isCOMDAT() || !R->isCOMDAT())
+ reportDuplicate(S, F);
+ } else if (auto *B = dyn_cast<DefinedBitcode>(S->body())) {
+ if (B->IsReplaceable)
+ replaceBody<DefinedRegular>(S, F, Sym, C);
+ else if (!C->isCOMDAT())
+ reportDuplicate(S, F);
+ } else
+ replaceBody<DefinedRegular>(S, F, Sym, C);
+ return S;
+}
+
+Symbol *SymbolTable::addBitcode(BitcodeFile *F, StringRef N, bool IsReplaceable) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(N);
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) {
+ replaceBody<DefinedBitcode>(S, F, N, IsReplaceable);
+ return S;
}
- Sym = new (Alloc) Symbol(New);
- New->setBackref(Sym);
- return Sym;
+ if (isa<DefinedCommon>(S->body()))
+ return S;
+ if (IsReplaceable)
+ if (isa<DefinedRegular>(S->body()) || isa<DefinedBitcode>(S->body()))
+ return S;
+ reportDuplicate(S, F);
+ return S;
}
-// Reads an archive member file pointed by a given symbol.
-void SymbolTable::addMemberFile(Lazy *Body) {
- std::unique_ptr<InputFile> File = Body->getMember();
+Symbol *SymbolTable::addCommon(ObjectFile *F, COFFSymbolRef Sym,
+ CommonChunk *C) {
+ StringRef Name;
+ F->getCOFFObj()->getSymbolName(Sym, Name);
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(Name);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || !isa<DefinedCOFF>(S->body()))
+ replaceBody<DefinedCommon>(S, F, Sym, C);
+ else if (auto *DC = dyn_cast<DefinedCommon>(S->body()))
+ if (Sym.getValue() > DC->getSize())
+ replaceBody<DefinedCommon>(S, F, Sym, C);
+ return S;
+}
- // getMember returns an empty buffer if the member was already
- // read from the library.
- if (!File)
- return;
- if (Config->Verbose)
- llvm::outs() << "Loaded " << File->getShortName() << " for "
- << Body->getName() << "\n";
- addFile(std::move(File));
+Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(N);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ replaceBody<DefinedImportData>(S, N, F);
+ else if (!isa<DefinedCOFF>(S->body()))
+ reportDuplicate(S, nullptr);
+ return S;
+}
+
+Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
+ uint16_t Machine) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insert(Name);
+ S->IsUsedInRegularObj = true;
+ if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ replaceBody<DefinedImportThunk>(S, Name, ID, Machine);
+ else if (!isa<DefinedCOFF>(S->body()))
+ reportDuplicate(S, nullptr);
+ return S;
}
std::vector<Chunk *> SymbolTable::getChunks() {
@@ -252,7 +295,7 @@ std::vector<Chunk *> SymbolTable::getChunks() {
}
Symbol *SymbolTable::find(StringRef Name) {
- auto It = Symtab.find(Name);
+ auto It = Symtab.find(CachedHashStringRef(Name));
if (It == Symtab.end())
return nullptr;
return It->second;
@@ -266,7 +309,7 @@ Symbol *SymbolTable::findUnderscore(StringRef Name) {
StringRef SymbolTable::findByPrefix(StringRef Prefix) {
for (auto Pair : Symtab) {
- StringRef Name = Pair.first;
+ StringRef Name = Pair.first.val();
if (Name.startswith(Prefix))
return Name;
}
@@ -275,7 +318,7 @@ StringRef SymbolTable::findByPrefix(StringRef Prefix) {
StringRef SymbolTable::findMangle(StringRef Name) {
if (Symbol *Sym = find(Name))
- if (!isa<Undefined>(Sym->Body))
+ if (!isa<Undefined>(Sym->body()))
return Name;
if (Config->Machine != I386)
return findByPrefix(("?" + Name + "@@Y").str());
@@ -289,39 +332,22 @@ StringRef SymbolTable::findMangle(StringRef Name) {
return findByPrefix(("?" + Name.substr(1) + "@@Y").str());
}
-void SymbolTable::mangleMaybe(Undefined *U) {
- if (U->WeakAlias)
- return;
- if (!isa<Undefined>(U->repl()))
+void SymbolTable::mangleMaybe(SymbolBody *B) {
+ auto *U = dyn_cast<Undefined>(B);
+ if (!U || U->WeakAlias)
return;
StringRef Alias = findMangle(U->getName());
if (!Alias.empty())
U->WeakAlias = addUndefined(Alias);
}
-Undefined *SymbolTable::addUndefined(StringRef Name) {
- auto *New = new (Alloc) Undefined(Name);
- addSymbol(New);
- if (auto *U = dyn_cast<Undefined>(New->repl()))
- return U;
- return New;
-}
-
-DefinedRelative *SymbolTable::addRelative(StringRef Name, uint64_t VA) {
- auto *New = new (Alloc) DefinedRelative(Name, VA);
- addSymbol(New);
- return New;
-}
-
-DefinedAbsolute *SymbolTable::addAbsolute(StringRef Name, uint64_t VA) {
- auto *New = new (Alloc) DefinedAbsolute(Name, VA);
- addSymbol(New);
- return New;
+SymbolBody *SymbolTable::addUndefined(StringRef Name) {
+ return addUndefined(Name, nullptr, false)->body();
}
void SymbolTable::printMap(llvm::raw_ostream &OS) {
for (ObjectFile *File : ObjectFiles) {
- OS << File->getShortName() << ":\n";
+ OS << toString(File) << ":\n";
for (SymbolBody *Body : File->getSymbols())
if (auto *R = dyn_cast<DefinedRegular>(Body))
if (R->getChunk()->isLive())
@@ -330,84 +356,32 @@ void SymbolTable::printMap(llvm::raw_ostream &OS) {
}
}
-void SymbolTable::addCombinedLTOObject(ObjectFile *Obj) {
- for (SymbolBody *Body : Obj->getSymbols()) {
- if (!Body->isExternal())
- continue;
- // We should not see any new undefined symbols at this point, but we'll
- // diagnose them later in reportRemainingUndefines().
- StringRef Name = Body->getName();
- Symbol *Sym = insert(Body);
- SymbolBody *Existing = Sym->Body;
-
- if (Existing == Body)
- continue;
-
- if (isa<DefinedBitcode>(Existing)) {
- Sym->Body = Body;
- continue;
- }
- if (auto *L = dyn_cast<Lazy>(Existing)) {
- // We may see new references to runtime library symbols such as __chkstk
- // here. These symbols must be wholly defined in non-bitcode files.
- addMemberFile(L);
- continue;
- }
-
- int Comp = Existing->compare(Body);
- if (Comp == 0)
- fatal("LTO: unexpected duplicate symbol: " + Name);
- if (Comp < 0)
- Sym->Body = Body;
- }
-}
-
void SymbolTable::addCombinedLTOObjects() {
if (BitcodeFiles.empty())
return;
- // Diagnose any undefined symbols early, but do not resolve weak externals,
- // as resolution breaks the invariant that each Symbol points to a unique
- // SymbolBody, which we rely on to replace DefinedBitcode symbols correctly.
- reportRemainingUndefines(/*Resolve=*/false);
-
// Create an object file and add it to the symbol table by replacing any
// DefinedBitcode symbols with the definitions in the object file.
LTOCodeGenerator CG(BitcodeFile::Context);
CG.setOptLevel(Config->LTOOptLevel);
- std::vector<ObjectFile *> Objs = createLTOObjects(&CG);
-
- for (ObjectFile *Obj : Objs)
- addCombinedLTOObject(Obj);
-
- size_t NumBitcodeFiles = BitcodeFiles.size();
- run();
- if (BitcodeFiles.size() != NumBitcodeFiles)
- fatal("LTO: late loaded symbol created new bitcode reference");
+ for (ObjectFile *Obj : createLTOObjects(&CG))
+ Obj->parse();
}
// Combine and compile bitcode files and then return the result
// as a vector of regular COFF object files.
std::vector<ObjectFile *> SymbolTable::createLTOObjects(LTOCodeGenerator *CG) {
- // All symbols referenced by non-bitcode objects must be preserved.
- for (ObjectFile *File : ObjectFiles)
- for (SymbolBody *Body : File->getSymbols())
- if (auto *S = dyn_cast<DefinedBitcode>(Body->repl()))
- CG->addMustPreserveSymbol(S->getName());
-
- // Likewise for bitcode symbols which we initially resolved to non-bitcode.
+ // All symbols referenced by non-bitcode objects, including GC roots, must be
+ // preserved. We must also replace bitcode symbols with undefined symbols so
+ // that they may be replaced with real definitions without conflicting.
for (BitcodeFile *File : BitcodeFiles)
- for (SymbolBody *Body : File->getSymbols())
- if (isa<DefinedBitcode>(Body) && !isa<DefinedBitcode>(Body->repl()))
+ for (SymbolBody *Body : File->getSymbols()) {
+ if (!isa<DefinedBitcode>(Body))
+ continue;
+ if (Body->symbol()->IsUsedInRegularObj)
CG->addMustPreserveSymbol(Body->getName());
-
- // Likewise for other symbols that must be preserved.
- for (Undefined *U : Config->GCRoot) {
- if (auto *S = dyn_cast<DefinedBitcode>(U->repl()))
- CG->addMustPreserveSymbol(S->getName());
- else if (auto *S = dyn_cast_or_null<DefinedBitcode>(U->getWeakAlias()))
- CG->addMustPreserveSymbol(S->getName());
- }
+ replaceBody<Undefined>(Body->symbol(), Body->getName());
+ }
CG->setModule(BitcodeFiles[0]->takeModule());
for (unsigned I = 1, E = BitcodeFiles.size(); I != E; ++I)
@@ -434,10 +408,8 @@ std::vector<ObjectFile *> SymbolTable::createLTOObjects(LTOCodeGenerator *CG) {
std::vector<ObjectFile *> ObjFiles;
for (SmallString<0> &Obj : Objs) {
- auto *ObjFile = new ObjectFile(MemoryBufferRef(Obj, "<LTO object>"));
- Files.emplace_back(ObjFile);
+ auto *ObjFile = make<ObjectFile>(MemoryBufferRef(Obj, "<LTO object>"));
ObjectFiles.push_back(ObjFile);
- ObjFile->parse();
ObjFiles.push_back(ObjFile);
}