summaryrefslogtreecommitdiffstats
path: root/lld/wasm/SymbolTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/wasm/SymbolTable.cpp')
-rw-r--r--lld/wasm/SymbolTable.cpp750
1 files changed, 375 insertions, 375 deletions
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 35ceed6d2a9..b6181252340 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -24,37 +24,37 @@ using namespace llvm::object;
using namespace lld;
using namespace lld::wasm;
-SymbolTable *lld::wasm::Symtab;
+SymbolTable *lld::wasm::symtab;
-void SymbolTable::addFile(InputFile *File) {
- log("Processing: " + toString(File));
+void SymbolTable::addFile(InputFile *file) {
+ log("Processing: " + toString(file));
// .a file
- if (auto *F = dyn_cast<ArchiveFile>(File)) {
- F->parse();
+ if (auto *f = dyn_cast<ArchiveFile>(file)) {
+ f->parse();
return;
}
// .so file
- if (auto *F = dyn_cast<SharedFile>(File)) {
- SharedFiles.push_back(F);
+ if (auto *f = dyn_cast<SharedFile>(file)) {
+ sharedFiles.push_back(f);
return;
}
- if (Config->Trace)
- message(toString(File));
+ if (config->trace)
+ message(toString(file));
// LLVM bitcode file
- if (auto *F = dyn_cast<BitcodeFile>(File)) {
- F->parse();
- BitcodeFiles.push_back(F);
+ if (auto *f = dyn_cast<BitcodeFile>(file)) {
+ f->parse();
+ bitcodeFiles.push_back(f);
return;
}
// Regular object file
- auto *F = cast<ObjFile>(File);
- F->parse(false);
- ObjectFiles.push_back(F);
+ auto *f = cast<ObjFile>(file);
+ f->parse(false);
+ objectFiles.push_back(f);
}
// This function is where all the optimizations of link-time
@@ -65,512 +65,512 @@ void SymbolTable::addFile(InputFile *File) {
// Because all bitcode files that the program consists of are passed
// to the compiler at once, it can do whole-program optimization.
void SymbolTable::addCombinedLTOObject() {
- if (BitcodeFiles.empty())
+ if (bitcodeFiles.empty())
return;
// Compile bitcode files and replace bitcode symbols.
- LTO.reset(new BitcodeCompiler);
- for (BitcodeFile *F : BitcodeFiles)
- LTO->add(*F);
-
- for (StringRef Filename : LTO->compile()) {
- auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"), "");
- Obj->parse(true);
- ObjectFiles.push_back(Obj);
+ lto.reset(new BitcodeCompiler);
+ for (BitcodeFile *f : bitcodeFiles)
+ lto->add(*f);
+
+ for (StringRef filename : lto->compile()) {
+ auto *obj = make<ObjFile>(MemoryBufferRef(filename, "lto.tmp"), "");
+ obj->parse(true);
+ objectFiles.push_back(obj);
}
}
-Symbol *SymbolTable::find(StringRef Name) {
- auto It = SymMap.find(CachedHashStringRef(Name));
- if (It == SymMap.end() || It->second == -1)
+Symbol *SymbolTable::find(StringRef name) {
+ auto it = symMap.find(CachedHashStringRef(name));
+ if (it == symMap.end() || it->second == -1)
return nullptr;
- return SymVector[It->second];
+ return symVector[it->second];
}
-void SymbolTable::replace(StringRef Name, Symbol* Sym) {
- auto It = SymMap.find(CachedHashStringRef(Name));
- SymVector[It->second] = Sym;
+void SymbolTable::replace(StringRef name, Symbol* sym) {
+ auto it = symMap.find(CachedHashStringRef(name));
+ symVector[it->second] = sym;
}
-std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
- bool Trace = false;
- auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
- int &SymIndex = P.first->second;
- bool IsNew = P.second;
- if (SymIndex == -1) {
- SymIndex = SymVector.size();
- Trace = true;
- IsNew = true;
+std::pair<Symbol *, bool> SymbolTable::insertName(StringRef name) {
+ bool trace = false;
+ auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
+ int &symIndex = p.first->second;
+ bool isNew = p.second;
+ if (symIndex == -1) {
+ symIndex = symVector.size();
+ trace = true;
+ isNew = true;
}
- if (!IsNew)
- return {SymVector[SymIndex], false};
+ if (!isNew)
+ return {symVector[symIndex], false};
- Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
- Sym->IsUsedInRegularObj = false;
- Sym->CanInline = true;
- Sym->Traced = Trace;
- SymVector.emplace_back(Sym);
- return {Sym, true};
+ Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ sym->isUsedInRegularObj = false;
+ sym->canInline = true;
+ sym->traced = trace;
+ symVector.emplace_back(sym);
+ return {sym, true};
}
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
- const InputFile *File) {
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insertName(Name);
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef name,
+ const InputFile *file) {
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insertName(name);
- if (!File || File->kind() == InputFile::ObjectKind)
- S->IsUsedInRegularObj = true;
+ if (!file || file->kind() == InputFile::ObjectKind)
+ s->isUsedInRegularObj = true;
- return {S, WasInserted};
+ return {s, wasInserted};
}
-static void reportTypeError(const Symbol *Existing, const InputFile *File,
- llvm::wasm::WasmSymbolType Type) {
- error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " +
- toString(Existing->getWasmType()) + " in " +
- toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) +
- " in " + toString(File));
+static void reportTypeError(const Symbol *existing, const InputFile *file,
+ llvm::wasm::WasmSymbolType type) {
+ error("symbol type mismatch: " + toString(*existing) + "\n>>> defined as " +
+ toString(existing->getWasmType()) + " in " +
+ toString(existing->getFile()) + "\n>>> defined as " + toString(type) +
+ " in " + toString(file));
}
// Check the type of new symbol matches that of the symbol is replacing.
// Returns true if the function types match, false is there is a singature
// mismatch.
-static bool signatureMatches(FunctionSymbol *Existing,
- const WasmSignature *NewSig) {
- const WasmSignature *OldSig = Existing->Signature;
+static bool signatureMatches(FunctionSymbol *existing,
+ const WasmSignature *newSig) {
+ const WasmSignature *oldSig = existing->signature;
// If either function is missing a signature (this happend for bitcode
// symbols) then assume they match. Any mismatch will be reported later
// when the LTO objects are added.
- if (!NewSig || !OldSig)
+ if (!newSig || !oldSig)
return true;
- return *NewSig == *OldSig;
+ return *newSig == *oldSig;
}
-static void checkGlobalType(const Symbol *Existing, const InputFile *File,
- const WasmGlobalType *NewType) {
- if (!isa<GlobalSymbol>(Existing)) {
- reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL);
+static void checkGlobalType(const Symbol *existing, const InputFile *file,
+ const WasmGlobalType *newType) {
+ if (!isa<GlobalSymbol>(existing)) {
+ reportTypeError(existing, file, WASM_SYMBOL_TYPE_GLOBAL);
return;
}
- const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType();
- if (*NewType != *OldType) {
- error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " +
- toString(*OldType) + " in " + toString(Existing->getFile()) +
- "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
+ const WasmGlobalType *oldType = cast<GlobalSymbol>(existing)->getGlobalType();
+ if (*newType != *oldType) {
+ error("Global type mismatch: " + existing->getName() + "\n>>> defined as " +
+ toString(*oldType) + " in " + toString(existing->getFile()) +
+ "\n>>> defined as " + toString(*newType) + " in " + toString(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);
+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));
+ 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);
+static void checkDataType(const Symbol *existing, const InputFile *file) {
+ if (!isa<DataSymbol>(existing))
+ reportTypeError(existing, file, WASM_SYMBOL_TYPE_DATA);
}
-DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
- uint32_t Flags,
- InputFunction *Function) {
- LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
- assert(!find(Name));
- SyntheticFunctions.emplace_back(Function);
- return replaceSymbol<DefinedFunction>(insertName(Name).first, Name,
- Flags, nullptr, Function);
+DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name,
+ uint32_t flags,
+ InputFunction *function) {
+ LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << name << "\n");
+ assert(!find(name));
+ syntheticFunctions.emplace_back(function);
+ return replaceSymbol<DefinedFunction>(insertName(name).first, name,
+ flags, nullptr, function);
}
// Adds an optional, linker generated, data symbols. The symbol will only be
// added if there is an undefine reference to it, or if it is explictly exported
// via the --export flag. Otherwise we don't add the symbol and return nullptr.
-DefinedData *SymbolTable::addOptionalDataSymbol(StringRef Name, uint32_t Value,
- uint32_t Flags) {
- Symbol *S = find(Name);
- if (!S && (Config->ExportAll || Config->ExportedSymbols.count(Name) != 0))
- S = insertName(Name).first;
- else if (!S || S->isDefined())
+DefinedData *SymbolTable::addOptionalDataSymbol(StringRef name, uint32_t value,
+ uint32_t flags) {
+ Symbol *s = find(name);
+ if (!s && (config->exportAll || config->exportedSymbols.count(name) != 0))
+ s = insertName(name).first;
+ else if (!s || s->isDefined())
return nullptr;
- LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << Name << "\n");
- auto *rtn = replaceSymbol<DefinedData>(S, Name, Flags);
- rtn->setVirtualAddress(Value);
- rtn->Referenced = true;
+ LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << name << "\n");
+ auto *rtn = replaceSymbol<DefinedData>(s, name, flags);
+ rtn->setVirtualAddress(value);
+ rtn->referenced = true;
return rtn;
}
-DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
- uint32_t Flags) {
- LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
- assert(!find(Name));
- return replaceSymbol<DefinedData>(insertName(Name).first, Name, Flags);
+DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef name,
+ uint32_t flags) {
+ LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << name << "\n");
+ assert(!find(name));
+ return replaceSymbol<DefinedData>(insertName(name).first, name, flags);
}
-DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
- InputGlobal *Global) {
- LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global
+DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef name, uint32_t flags,
+ InputGlobal *global) {
+ LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << name << " -> " << global
<< "\n");
- assert(!find(Name));
- SyntheticGlobals.emplace_back(Global);
- return replaceSymbol<DefinedGlobal>(insertName(Name).first, Name, Flags,
- nullptr, Global);
+ assert(!find(name));
+ syntheticGlobals.emplace_back(global);
+ return replaceSymbol<DefinedGlobal>(insertName(name).first, name, flags,
+ nullptr, global);
}
-static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
- uint32_t NewFlags) {
+static bool shouldReplace(const Symbol *existing, InputFile *newFile,
+ uint32_t newFlags) {
// If existing symbol is undefined, replace it.
- if (!Existing->isDefined()) {
+ if (!existing->isDefined()) {
LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: "
- << Existing->getName() << "\n");
+ << existing->getName() << "\n");
return true;
}
// Now we have two defined symbols. If the new one is weak, we can ignore it.
- if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
+ if ((newFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n");
return false;
}
// If the existing symbol is weak, we should replace it.
- if (Existing->isWeak()) {
+ if (existing->isWeak()) {
LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n");
return true;
}
// Neither symbol is week. They conflict.
- error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " +
- toString(Existing->getFile()) + "\n>>> defined in " +
- toString(NewFile));
+ error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
+ toString(existing->getFile()) + "\n>>> defined in " +
+ toString(newFile));
return true;
}
-Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
- InputFile *File,
- InputFunction *Function) {
- LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
- << (Function ? toString(Function->Signature) : "none")
+Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags,
+ InputFile *file,
+ InputFunction *function) {
+ LLVM_DEBUG(dbgs() << "addDefinedFunction: " << name << " ["
+ << (function ? toString(function->signature) : "none")
<< "]\n");
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, File);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
- auto ReplaceSym = [&](Symbol *Sym) {
+ auto replaceSym = [&](Symbol *sym) {
// If the new defined function doesn't have signture (i.e. bitcode
// functions) but the old symbol does, then preserve the old signature
- const WasmSignature *OldSig = S->getSignature();
- auto* NewSym = replaceSymbol<DefinedFunction>(Sym, Name, Flags, File, Function);
- if (!NewSym->Signature)
- NewSym->Signature = OldSig;
+ const WasmSignature *oldSig = s->getSignature();
+ auto* newSym = replaceSymbol<DefinedFunction>(sym, name, flags, file, function);
+ if (!newSym->signature)
+ newSym->signature = oldSig;
};
- if (WasInserted || S->isLazy()) {
- ReplaceSym(S);
- return S;
+ if (wasInserted || s->isLazy()) {
+ replaceSym(s);
+ return s;
}
- auto ExistingFunction = dyn_cast<FunctionSymbol>(S);
- if (!ExistingFunction) {
- reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION);
- return S;
+ auto existingFunction = dyn_cast<FunctionSymbol>(s);
+ if (!existingFunction) {
+ reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
+ return s;
}
- bool CheckSig = true;
- if (auto UD = dyn_cast<UndefinedFunction>(ExistingFunction))
- CheckSig = UD->IsCalledDirectly;
+ bool checkSig = true;
+ if (auto ud = dyn_cast<UndefinedFunction>(existingFunction))
+ checkSig = ud->isCalledDirectly;
- if (CheckSig && Function && !signatureMatches(ExistingFunction, &Function->Signature)) {
- Symbol* Variant;
- if (getFunctionVariant(S, &Function->Signature, File, &Variant))
+ if (checkSig && function && !signatureMatches(existingFunction, &function->signature)) {
+ Symbol* variant;
+ if (getFunctionVariant(s, &function->signature, file, &variant))
// New variant, always replace
- ReplaceSym(Variant);
- else if (shouldReplace(S, File, Flags))
+ replaceSym(variant);
+ else if (shouldReplace(s, file, flags))
// Variant already exists, replace it after checking shouldReplace
- ReplaceSym(Variant);
+ replaceSym(variant);
// This variant we found take the place in the symbol table as the primary
// variant.
- replace(Name, Variant);
- return Variant;
+ replace(name, variant);
+ return variant;
}
// Existing function with matching signature.
- if (shouldReplace(S, File, Flags))
- ReplaceSym(S);
+ if (shouldReplace(s, file, flags))
+ replaceSym(s);
- return S;
+ return s;
}
-Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
- InputFile *File, InputSegment *Segment,
- uint32_t Address, uint32_t Size) {
- LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address
+Symbol *SymbolTable::addDefinedData(StringRef name, uint32_t flags,
+ InputFile *file, InputSegment *segment,
+ uint32_t address, uint32_t size) {
+ LLVM_DEBUG(dbgs() << "addDefinedData:" << name << " addr:" << address
<< "\n");
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, File);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
- auto ReplaceSym = [&]() {
- replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
+ auto replaceSym = [&]() {
+ replaceSymbol<DefinedData>(s, name, flags, file, segment, address, size);
};
- if (WasInserted || S->isLazy()) {
- ReplaceSym();
- return S;
+ if (wasInserted || s->isLazy()) {
+ replaceSym();
+ return s;
}
- checkDataType(S, File);
+ checkDataType(s, file);
- if (shouldReplace(S, File, Flags))
- ReplaceSym();
- return S;
+ if (shouldReplace(s, file, flags))
+ replaceSym();
+ return s;
}
-Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
- InputFile *File, InputGlobal *Global) {
- LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
+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, File);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
- auto ReplaceSym = [&]() {
- replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
+ auto replaceSym = [&]() {
+ replaceSymbol<DefinedGlobal>(s, name, flags, file, global);
};
- if (WasInserted || S->isLazy()) {
- ReplaceSym();
- return S;
+ if (wasInserted || s->isLazy()) {
+ replaceSym();
+ return s;
}
- checkGlobalType(S, File, &Global->getType());
+ checkGlobalType(s, file, &global->getType());
- if (shouldReplace(S, File, Flags))
- ReplaceSym();
- return S;
+ if (shouldReplace(s, file, flags))
+ replaceSym();
+ return s;
}
-Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
- InputFile *File, InputEvent *Event) {
- LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n");
+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);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
- auto ReplaceSym = [&]() {
- replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
+ auto replaceSym = [&]() {
+ replaceSymbol<DefinedEvent>(s, name, flags, file, event);
};
- if (WasInserted || S->isLazy()) {
- ReplaceSym();
- return S;
+ if (wasInserted || s->isLazy()) {
+ replaceSym();
+ return s;
}
- checkEventType(S, File, &Event->getType(), &Event->Signature);
+ checkEventType(s, file, &event->getType(), &event->signature);
- if (shouldReplace(S, File, Flags))
- ReplaceSym();
- return S;
+ if (shouldReplace(s, file, flags))
+ replaceSym();
+ return s;
}
-Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName,
- StringRef ImportModule,
- uint32_t Flags, InputFile *File,
- const WasmSignature *Sig,
- bool IsCalledDirectly) {
- LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " ["
- << (Sig ? toString(*Sig) : "none")
- << "] IsCalledDirectly:" << IsCalledDirectly << "\n");
+Symbol *SymbolTable::addUndefinedFunction(StringRef name, StringRef importName,
+ StringRef importModule,
+ uint32_t flags, InputFile *file,
+ const WasmSignature *sig,
+ bool isCalledDirectly) {
+ LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " ["
+ << (sig ? toString(*sig) : "none")
+ << "] IsCalledDirectly:" << isCalledDirectly << "\n");
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, File);
- if (S->Traced)
- printTraceSymbolUndefined(Name, File);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
+ if (s->traced)
+ printTraceSymbolUndefined(name, file);
- auto ReplaceSym = [&]() {
- replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags,
- File, Sig, IsCalledDirectly);
+ auto replaceSym = [&]() {
+ replaceSymbol<UndefinedFunction>(s, name, importName, importModule, flags,
+ file, sig, isCalledDirectly);
};
- if (WasInserted)
- ReplaceSym();
- else if (auto *Lazy = dyn_cast<LazySymbol>(S))
- Lazy->fetch();
+ if (wasInserted)
+ replaceSym();
+ else if (auto *lazy = dyn_cast<LazySymbol>(s))
+ lazy->fetch();
else {
- auto ExistingFunction = dyn_cast<FunctionSymbol>(S);
- if (!ExistingFunction) {
- reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION);
- return S;
+ auto existingFunction = dyn_cast<FunctionSymbol>(s);
+ if (!existingFunction) {
+ reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
+ return s;
}
- if (!ExistingFunction->Signature && Sig)
- ExistingFunction->Signature = Sig;
- if (IsCalledDirectly && !signatureMatches(ExistingFunction, Sig))
- if (getFunctionVariant(S, Sig, File, &S))
- ReplaceSym();
+ if (!existingFunction->signature && sig)
+ existingFunction->signature = sig;
+ if (isCalledDirectly && !signatureMatches(existingFunction, sig))
+ if (getFunctionVariant(s, sig, file, &s))
+ replaceSym();
}
- return S;
+ return s;
}
-Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
- InputFile *File) {
- LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n");
+Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
+ InputFile *file) {
+ LLVM_DEBUG(dbgs() << "addUndefinedData: " << name << "\n");
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, File);
- if (S->Traced)
- printTraceSymbolUndefined(Name, File);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
+ if (s->traced)
+ printTraceSymbolUndefined(name, file);
- if (WasInserted)
- replaceSymbol<UndefinedData>(S, Name, Flags, File);
- else if (auto *Lazy = dyn_cast<LazySymbol>(S))
- Lazy->fetch();
- else if (S->isDefined())
- checkDataType(S, File);
- return S;
+ if (wasInserted)
+ replaceSymbol<UndefinedData>(s, name, flags, file);
+ else if (auto *lazy = dyn_cast<LazySymbol>(s))
+ lazy->fetch();
+ else if (s->isDefined())
+ checkDataType(s, file);
+ return s;
}
-Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName,
- StringRef ImportModule, uint32_t Flags,
- InputFile *File,
- const WasmGlobalType *Type) {
- LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
+Symbol *SymbolTable::addUndefinedGlobal(StringRef name, StringRef importName,
+ StringRef importModule, uint32_t flags,
+ InputFile *file,
+ const WasmGlobalType *type) {
+ LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n");
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, File);
- if (S->Traced)
- printTraceSymbolUndefined(Name, File);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insert(name, file);
+ if (s->traced)
+ printTraceSymbolUndefined(name, file);
- if (WasInserted)
- replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags,
- File, Type);
- else if (auto *Lazy = dyn_cast<LazySymbol>(S))
- Lazy->fetch();
- else if (S->isDefined())
- checkGlobalType(S, File, Type);
- return S;
+ if (wasInserted)
+ replaceSymbol<UndefinedGlobal>(s, name, importName, importModule, flags,
+ file, type);
+ else if (auto *lazy = dyn_cast<LazySymbol>(s))
+ lazy->fetch();
+ else if (s->isDefined())
+ checkGlobalType(s, file, type);
+ return s;
}
-void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
- LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n");
- StringRef Name = Sym->getName();
+void SymbolTable::addLazy(ArchiveFile *file, const Archive::Symbol *sym) {
+ LLVM_DEBUG(dbgs() << "addLazy: " << sym->getName() << "\n");
+ StringRef name = sym->getName();
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insertName(Name);
+ Symbol *s;
+ bool wasInserted;
+ std::tie(s, wasInserted) = insertName(name);
- if (WasInserted) {
- replaceSymbol<LazySymbol>(S, Name, 0, File, *Sym);
+ if (wasInserted) {
+ replaceSymbol<LazySymbol>(s, name, 0, file, *sym);
return;
}
- if (!S->isUndefined())
+ if (!s->isUndefined())
return;
// The existing symbol is undefined, load a new one from the archive,
// unless the the existing symbol is weak in which case replace the undefined
// symbols with a LazySymbol.
- if (S->isWeak()) {
- const WasmSignature *OldSig = nullptr;
+ if (s->isWeak()) {
+ const WasmSignature *oldSig = nullptr;
// In the case of an UndefinedFunction we need to preserve the expected
// signature.
- if (auto *F = dyn_cast<UndefinedFunction>(S))
- OldSig = F->Signature;
+ if (auto *f = dyn_cast<UndefinedFunction>(s))
+ oldSig = f->signature;
LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n");
- auto NewSym = replaceSymbol<LazySymbol>(S, Name, WASM_SYMBOL_BINDING_WEAK,
- File, *Sym);
- NewSym->Signature = OldSig;
+ auto newSym = replaceSymbol<LazySymbol>(s, name, WASM_SYMBOL_BINDING_WEAK,
+ file, *sym);
+ newSym->signature = oldSig;
return;
}
LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
- File->addMember(Sym);
+ file->addMember(sym);
}
-bool SymbolTable::addComdat(StringRef Name) {
- return ComdatGroups.insert(CachedHashStringRef(Name)).second;
+bool SymbolTable::addComdat(StringRef name) {
+ return comdatGroups.insert(CachedHashStringRef(name)).second;
}
// The new signature doesn't match. Create a variant to the symbol with the
// signature encoded in the name and return that instead. These symbols are
// then unified later in handleSymbolVariants.
-bool SymbolTable::getFunctionVariant(Symbol* Sym, const WasmSignature *Sig,
- const InputFile *File, Symbol **Out) {
- LLVM_DEBUG(dbgs() << "getFunctionVariant: " << Sym->getName() << " -> "
- << " " << toString(*Sig) << "\n");
- Symbol *Variant = nullptr;
+bool SymbolTable::getFunctionVariant(Symbol* sym, const WasmSignature *sig,
+ const InputFile *file, Symbol **out) {
+ LLVM_DEBUG(dbgs() << "getFunctionVariant: " << sym->getName() << " -> "
+ << " " << toString(*sig) << "\n");
+ Symbol *variant = nullptr;
// Linear search through symbol variants. Should never be more than two
// or three entries here.
- auto &Variants = SymVariants[CachedHashStringRef(Sym->getName())];
- if (Variants.empty())
- Variants.push_back(Sym);
+ auto &variants = symVariants[CachedHashStringRef(sym->getName())];
+ if (variants.empty())
+ variants.push_back(sym);
- for (Symbol* V : Variants) {
- if (*V->getSignature() == *Sig) {
- Variant = V;
+ for (Symbol* v : variants) {
+ if (*v->getSignature() == *sig) {
+ variant = v;
break;
}
}
- bool WasAdded = !Variant;
- if (WasAdded) {
+ bool wasAdded = !variant;
+ if (wasAdded) {
// Create a new variant;
LLVM_DEBUG(dbgs() << "added new variant\n");
- Variant = reinterpret_cast<Symbol *>(make<SymbolUnion>());
- Variants.push_back(Variant);
+ variant = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ variants.push_back(variant);
} else {
- LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*Variant) << "\n");
- assert(*Variant->getSignature() == *Sig);
+ LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*variant) << "\n");
+ assert(*variant->getSignature() == *sig);
}
- *Out = Variant;
- return WasAdded;
+ *out = variant;
+ return wasAdded;
}
// Set a flag for --trace-symbol so that we can print out a log message
// if a new symbol with the same name is inserted into the symbol table.
-void SymbolTable::trace(StringRef Name) {
- SymMap.insert({CachedHashStringRef(Name), -1});
+void SymbolTable::trace(StringRef name) {
+ symMap.insert({CachedHashStringRef(name), -1});
}
-void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
+void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// Swap symbols as instructed by -wrap.
- int &OrigIdx = SymMap[CachedHashStringRef(Sym->getName())];
- int &RealIdx= SymMap[CachedHashStringRef(Real->getName())];
- int &WrapIdx = SymMap[CachedHashStringRef(Wrap->getName())];
- LLVM_DEBUG(dbgs() << "wrap: " << Sym->getName() << "\n");
+ int &origIdx = symMap[CachedHashStringRef(sym->getName())];
+ int &realIdx= symMap[CachedHashStringRef(real->getName())];
+ int &wrapIdx = symMap[CachedHashStringRef(wrap->getName())];
+ LLVM_DEBUG(dbgs() << "wrap: " << sym->getName() << "\n");
// Anyone looking up __real symbols should get the original
- RealIdx = OrigIdx;
+ realIdx = origIdx;
// Anyone looking up the original should get the __wrap symbol
- OrigIdx = WrapIdx;
+ origIdx = wrapIdx;
}
-static const uint8_t UnreachableFn[] = {
+static const uint8_t unreachableFn[] = {
0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
0x00 /* opcode unreachable */, 0x0b /* opcode end */
};
@@ -579,15 +579,15 @@ static const uint8_t UnreachableFn[] = {
// This is used by handleWeakUndefines in order to generate a callable
// equivalent of an undefined function and also handleSymbolVariants for
// undefined functions that don't match the signature of the definition.
-InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym,
- const WasmSignature &Sig,
- StringRef DebugName) {
- auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
- Func->setBody(UnreachableFn);
- SyntheticFunctions.emplace_back(Func);
- replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Sym->getFlags(), nullptr,
- Func);
- return Func;
+InputFunction *SymbolTable::replaceWithUnreachable(Symbol *sym,
+ const WasmSignature &sig,
+ StringRef debugName) {
+ auto *func = make<SyntheticFunction>(sig, sym->getName(), debugName);
+ func->setBody(unreachableFn);
+ syntheticFunctions.emplace_back(func);
+ replaceSymbol<DefinedFunction>(sym, sym->getName(), sym->getFlags(), nullptr,
+ func);
+ return func;
}
// For weak undefined functions, there may be "call" instructions that reference
@@ -595,41 +595,41 @@ InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym,
// will abort at runtime, so that relocations can still provided an operand to
// the call instruction that passes Wasm validation.
void SymbolTable::handleWeakUndefines() {
- for (Symbol *Sym : getSymbols()) {
- if (!Sym->isUndefWeak())
+ for (Symbol *sym : getSymbols()) {
+ if (!sym->isUndefWeak())
continue;
- const WasmSignature *Sig = Sym->getSignature();
- if (!Sig) {
+ const WasmSignature *sig = sym->getSignature();
+ if (!sig) {
// It is possible for undefined functions not to have a signature (eg. if
// added via "--undefined"), but weak undefined ones do have a signature.
// Lazy symbols may not be functions and therefore Sig can still be null
// in some circumstantce.
- assert(!isa<FunctionSymbol>(Sym));
+ assert(!isa<FunctionSymbol>(sym));
continue;
}
// Add a synthetic dummy for weak undefined functions. These dummies will
// be GC'd if not used as the target of any "call" instructions.
- StringRef DebugName = Saver.save("undefined:" + toString(*Sym));
- InputFunction* Func = replaceWithUnreachable(Sym, *Sig, DebugName);
+ StringRef debugName = saver.save("undefined:" + toString(*sym));
+ InputFunction* func = replaceWithUnreachable(sym, *sig, debugName);
// Ensure it compares equal to the null pointer, and so that table relocs
// don't pull in the stub body (only call-operand relocs should do that).
- Func->setTableIndex(0);
+ func->setTableIndex(0);
// Hide our dummy to prevent export.
- Sym->setHidden(true);
+ sym->setHidden(true);
}
}
-static void reportFunctionSignatureMismatch(StringRef SymName,
- FunctionSymbol *A,
- FunctionSymbol *B, bool IsError) {
- std::string msg = ("function signature mismatch: " + SymName +
- "\n>>> defined as " + toString(*A->Signature) + " in " +
- toString(A->getFile()) + "\n>>> defined as " +
- toString(*B->Signature) + " in " + toString(B->getFile()))
+static void reportFunctionSignatureMismatch(StringRef symName,
+ FunctionSymbol *a,
+ FunctionSymbol *b, bool isError) {
+ std::string msg = ("function signature mismatch: " + symName +
+ "\n>>> defined as " + toString(*a->signature) + " in " +
+ toString(a->getFile()) + "\n>>> defined as " +
+ toString(*b->signature) + " in " + toString(b->getFile()))
.str();
- if (IsError)
+ if (isError)
error(msg);
else
warn(msg);
@@ -638,26 +638,26 @@ static void reportFunctionSignatureMismatch(StringRef SymName,
// Remove any variant symbols that were created due to function signature
// mismatches.
void SymbolTable::handleSymbolVariants() {
- for (auto Pair : SymVariants) {
+ for (auto pair : symVariants) {
// Push the initial symbol onto the list of variants.
- StringRef SymName = Pair.first.val();
- std::vector<Symbol *> &Variants = Pair.second;
+ StringRef symName = pair.first.val();
+ std::vector<Symbol *> &variants = pair.second;
#ifndef NDEBUG
- LLVM_DEBUG(dbgs() << "symbol with (" << Variants.size()
- << ") variants: " << SymName << "\n");
- for (auto *S: Variants) {
- auto *F = cast<FunctionSymbol>(S);
- LLVM_DEBUG(dbgs() << " variant: " + F->getName() << " "
- << toString(*F->Signature) << "\n");
+ LLVM_DEBUG(dbgs() << "symbol with (" << variants.size()
+ << ") variants: " << symName << "\n");
+ for (auto *s: variants) {
+ auto *f = cast<FunctionSymbol>(s);
+ LLVM_DEBUG(dbgs() << " variant: " + f->getName() << " "
+ << toString(*f->signature) << "\n");
}
#endif
// Find the one definition.
- DefinedFunction *Defined = nullptr;
- for (auto *Symbol : Variants) {
- if (auto F = dyn_cast<DefinedFunction>(Symbol)) {
- Defined = F;
+ DefinedFunction *defined = nullptr;
+ for (auto *symbol : variants) {
+ if (auto f = dyn_cast<DefinedFunction>(symbol)) {
+ defined = f;
break;
}
}
@@ -665,19 +665,19 @@ void SymbolTable::handleSymbolVariants() {
// If there are no definitions, and the undefined symbols disagree on
// the signature, there is not we can do since we don't know which one
// to use as the signature on the import.
- if (!Defined) {
- reportFunctionSignatureMismatch(SymName,
- cast<FunctionSymbol>(Variants[0]),
- cast<FunctionSymbol>(Variants[1]), true);
+ if (!defined) {
+ reportFunctionSignatureMismatch(symName,
+ cast<FunctionSymbol>(variants[0]),
+ cast<FunctionSymbol>(variants[1]), true);
return;
}
- for (auto *Symbol : Variants) {
- if (Symbol != Defined) {
- auto *F = cast<FunctionSymbol>(Symbol);
- reportFunctionSignatureMismatch(SymName, F, Defined, false);
- StringRef DebugName = Saver.save("unreachable:" + toString(*F));
- replaceWithUnreachable(F, *F->Signature, DebugName);
+ for (auto *symbol : variants) {
+ if (symbol != defined) {
+ auto *f = cast<FunctionSymbol>(symbol);
+ reportFunctionSignatureMismatch(symName, f, defined, false);
+ StringRef debugName = saver.save("unreachable:" + toString(*f));
+ replaceWithUnreachable(f, *f->signature, debugName);
}
}
}
OpenPOWER on IntegriCloud