diff options
Diffstat (limited to 'wasm/SymbolTable.cpp')
-rw-r--r-- | wasm/SymbolTable.cpp | 147 |
1 files changed, 88 insertions, 59 deletions
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp index e1ba23769738..c7983196db36 100644 --- a/wasm/SymbolTable.cpp +++ b/wasm/SymbolTable.cpp @@ -10,6 +10,7 @@ #include "SymbolTable.h" #include "Config.h" #include "InputChunks.h" +#include "InputEvent.h" #include "InputGlobal.h" #include "WriterUtils.h" #include "lld/Common/ErrorHandler.h" @@ -20,6 +21,7 @@ using namespace llvm; using namespace llvm::wasm; +using namespace llvm::object; using namespace lld; using namespace lld::wasm; @@ -60,7 +62,6 @@ void SymbolTable::addCombinedLTOObject() { } void SymbolTable::reportRemainingUndefines() { - SetVector<Symbol *> Undefs; for (Symbol *Sym : SymVector) { if (!Sym->isUndefined() || Sym->isWeak()) continue; @@ -68,34 +69,26 @@ void SymbolTable::reportRemainingUndefines() { continue; if (!Sym->IsUsedInRegularObj) continue; - Undefs.insert(Sym); + error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym)); } - - if (Undefs.empty()) - return; - - for (ObjFile *File : ObjectFiles) - for (Symbol *Sym : File->getSymbols()) - if (Undefs.count(Sym)) - error(toString(File) + ": undefined symbol: " + toString(*Sym)); - - for (Symbol *Sym : Undefs) - if (!Sym->getFile()) - error("undefined symbol: " + toString(*Sym)); } Symbol *SymbolTable::find(StringRef Name) { return SymMap.lookup(CachedHashStringRef(Name)); } -std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { +std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) { + bool Inserted = false; Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; - if (Sym) - return {Sym, false}; - Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); - Sym->IsUsedInRegularObj = false; - SymVector.emplace_back(Sym); - return {Sym, true}; + if (!Sym) { + Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); + Sym->IsUsedInRegularObj = false; + SymVector.emplace_back(Sym); + Inserted = true; + } + if (!File || File->kind() == InputFile::ObjectKind) + Sym->IsUsedInRegularObj = true; + return {Sym, Inserted}; } static void reportTypeError(const Symbol *Existing, const InputFile *File, @@ -106,6 +99,8 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File, " in " + toString(File)); } +// Check the type of new symbol matches that of the symbol is replacing. +// For functions this can also involve verifying that the signatures match. static void checkFunctionType(Symbol *Existing, const InputFile *File, const WasmSignature *NewSig) { auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing); @@ -117,9 +112,9 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File, if (!NewSig) return; - const WasmSignature *OldSig = ExistingFunction->FunctionType; + const WasmSignature *OldSig = ExistingFunction->Signature; if (!OldSig) { - ExistingFunction->FunctionType = NewSig; + ExistingFunction->Signature = NewSig; return; } @@ -130,8 +125,6 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File, toString(*NewSig) + " in " + toString(File)); } -// Check the type of new symbol matches that of the symbol is replacing. -// For functions this can also involve verifying that the signatures match. static void checkGlobalType(const Symbol *Existing, const InputFile *File, const WasmGlobalType *NewType) { if (!isa<GlobalSymbol>(Existing)) { @@ -147,6 +140,28 @@ static void checkGlobalType(const Symbol *Existing, const InputFile *File, } } +static void checkEventType(const Symbol *Existing, const InputFile *File, + const WasmEventType *NewType, + const WasmSignature *NewSig) { + auto ExistingEvent = dyn_cast<EventSymbol>(Existing); + if (!isa<EventSymbol>(Existing)) { + reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT); + return; + } + + const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType(); + const WasmSignature *OldSig = ExistingEvent->Signature; + if (NewType->Attribute != OldType->Attribute) + error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " + + toString(*OldType) + " in " + toString(Existing->getFile()) + + "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); + if (*NewSig != *OldSig) + warn("Event signature mismatch: " + Existing->getName() + + "\n>>> defined as " + toString(*OldSig) + " in " + + toString(Existing->getFile()) + "\n>>> defined as " + + toString(*NewSig) + " in " + toString(File)); +} + static void checkDataType(const Symbol *Existing, const InputFile *File) { if (!isa<DataSymbol>(Existing)) reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); @@ -158,15 +173,15 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); assert(!find(Name)); SyntheticFunctions.emplace_back(Function); - return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags, - nullptr, Function); + return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name, + Flags, nullptr, Function); } DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, uint32_t Flags) { LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); assert(!find(Name)); - return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags); + return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags); } DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, @@ -175,8 +190,8 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, << "\n"); assert(!find(Name)); SyntheticGlobals.emplace_back(Global); - return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr, - Global); + return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags, + nullptr, Global); } static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, @@ -210,13 +225,12 @@ static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, InputFunction *Function) { - LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n"); + LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" + << (Function ? toString(Function->Signature) : "none") + << "]\n"); Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + std::tie(S, WasInserted) = insert(Name, File); if (WasInserted || S->isLazy()) { replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); @@ -226,8 +240,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, if (Function) checkFunctionType(S, File, &Function->Signature); - if (shouldReplace(S, File, Flags)) - replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); + if (shouldReplace(S, File, Flags)) { + // If the new defined function doesn't have signture (i.e. bitcode + // functions) but the old symbols does then preserve the old signature + const WasmSignature *OldSig = nullptr; + if (auto* F = dyn_cast<FunctionSymbol>(S)) + OldSig = F->Signature; + auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); + if (!NewSym->Signature) + NewSym->Signature = OldSig; + } return S; } @@ -238,10 +260,7 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, << "\n"); Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + std::tie(S, WasInserted) = insert(Name, File); if (WasInserted || S->isLazy()) { replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); @@ -258,12 +277,10 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, InputGlobal *Global) { LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); + Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + std::tie(S, WasInserted) = insert(Name, File); if (WasInserted || S->isLazy()) { replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); @@ -277,17 +294,35 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, return S; } +Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, + InputFile *File, InputEvent *Event) { + LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n"); + + Symbol *S; + bool WasInserted; + std::tie(S, WasInserted) = insert(Name, File); + + if (WasInserted || S->isLazy()) { + replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); + return S; + } + + checkEventType(S, File, &Event->getType(), &Event->Signature); + + if (shouldReplace(S, File, Flags)) + replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); + return S; +} + Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, const WasmSignature *Sig) { - LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n"); + LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << + " [" << (Sig ? toString(*Sig) : "none") << "]\n"); Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); @@ -305,10 +340,7 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) replaceSymbol<UndefinedData>(S, Name, Flags, File); @@ -326,10 +358,7 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - - if (!File || File->kind() == InputFile::ObjectKind) - S->IsUsedInRegularObj = true; + std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); @@ -346,7 +375,7 @@ void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); + std::tie(S, WasInserted) = insert(Name, nullptr); if (WasInserted) { replaceSymbol<LazySymbol>(S, Name, File, *Sym); |