aboutsummaryrefslogtreecommitdiff
path: root/wasm/SymbolTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'wasm/SymbolTable.cpp')
-rw-r--r--wasm/SymbolTable.cpp147
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);