diff options
Diffstat (limited to 'wasm')
-rw-r--r-- | wasm/Driver.cpp | 4 | ||||
-rw-r--r-- | wasm/InputChunks.cpp | 6 | ||||
-rw-r--r-- | wasm/InputFiles.cpp | 11 | ||||
-rw-r--r-- | wasm/LTO.cpp | 5 | ||||
-rw-r--r-- | wasm/LTO.h | 1 | ||||
-rw-r--r-- | wasm/MarkLive.cpp | 2 | ||||
-rw-r--r-- | wasm/SymbolTable.cpp | 14 | ||||
-rw-r--r-- | wasm/SymbolTable.h | 10 | ||||
-rw-r--r-- | wasm/Symbols.h | 19 | ||||
-rw-r--r-- | wasm/Writer.cpp | 106 | ||||
-rw-r--r-- | wasm/Writer.h | 2 |
11 files changed, 115 insertions, 65 deletions
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp index fab4c0c4ed8b..ade15a19f66e 100644 --- a/wasm/Driver.cpp +++ b/wasm/Driver.cpp @@ -434,7 +434,9 @@ static Symbol *handleUndefined(StringRef Name) { static UndefinedGlobal * createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) { auto *Sym = - cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, 0, nullptr, Type)); + cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, Name, + DefaultModule, 0, + nullptr, Type)); Config->AllowUndefinedSymbols.insert(Sym->getName()); Sym->IsUsedInRegularObj = true; return Sym; diff --git a/wasm/InputChunks.cpp b/wasm/InputChunks.cpp index 1145c670253c..f5884a1beea4 100644 --- a/wasm/InputChunks.cpp +++ b/wasm/InputChunks.cpp @@ -23,7 +23,7 @@ using namespace llvm::support::endian; using namespace lld; using namespace lld::wasm; -static StringRef ReloctTypeToString(uint8_t RelocType) { +static StringRef reloctTypeToString(uint8_t RelocType) { switch (RelocType) { #define WASM_RELOC(NAME, REL) \ case REL: \ @@ -77,7 +77,7 @@ void InputChunk::verifyRelocTargets() const { warn("expected LEB at relocation site be 5-byte padded"); uint32_t ExpectedValue = File->calcExpectedValue(Rel); if (ExpectedValue != ExistingValue) - warn("unexpected existing value for " + ReloctTypeToString(Rel.Type) + + warn("unexpected existing value for " + reloctTypeToString(Rel.Type) + ": existing=" + Twine(ExistingValue) + " expected=" + Twine(ExpectedValue)); } @@ -103,7 +103,7 @@ void InputChunk::writeTo(uint8_t *Buf) const { for (const WasmRelocation &Rel : Relocations) { uint8_t *Loc = Buf + Rel.Offset + Off; uint32_t Value = File->calcNewValue(Rel); - LLVM_DEBUG(dbgs() << "apply reloc: type=" << ReloctTypeToString(Rel.Type) + LLVM_DEBUG(dbgs() << "apply reloc: type=" << reloctTypeToString(Rel.Type) << " addend=" << Rel.Addend << " index=" << Rel.Index << " value=" << Value << " offset=" << Rel.Offset << "\n"); diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp index e5da23db3773..1e5427216354 100644 --- a/wasm/InputFiles.cpp +++ b/wasm/InputFiles.cpp @@ -377,11 +377,15 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) { switch (Sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: - return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature); + return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName, + Sym.Info.ImportModule, Flags, this, + Sym.Signature); case WASM_SYMBOL_TYPE_DATA: return Symtab->addUndefinedData(Name, Flags, this); case WASM_SYMBOL_TYPE_GLOBAL: - return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType); + return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName, + Sym.Info.ImportModule, Flags, this, + Sym.GlobalType); case WASM_SYMBOL_TYPE_SECTION: llvm_unreachable("section symbols cannot be undefined"); } @@ -445,7 +449,8 @@ static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym, if (ObjSym.isUndefined()) { if (ObjSym.isExecutable()) - return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr); + return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F, + nullptr); return Symtab->addUndefinedData(Name, Flags, &F); } diff --git a/wasm/LTO.cpp b/wasm/LTO.cpp index 96a947e29d41..e994691cceb2 100644 --- a/wasm/LTO.cpp +++ b/wasm/LTO.cpp @@ -79,8 +79,9 @@ BitcodeCompiler::~BitcodeCompiler() = default; static void undefine(Symbol *S) { if (auto F = dyn_cast<DefinedFunction>(S)) - replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(), - F->Signature); + replaceSymbol<UndefinedFunction>(F, F->getName(), F->getName(), + DefaultModule, 0, + F->getFile(), F->Signature); else if (isa<DefinedData>(S)) replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile()); else diff --git a/wasm/LTO.h b/wasm/LTO.h index cf726de5643a..d771301f224d 100644 --- a/wasm/LTO.h +++ b/wasm/LTO.h @@ -23,6 +23,7 @@ #include "lld/Common/LLVM.h" #include "llvm/ADT/SmallString.h" +#include "Writer.h" #include <memory> #include <vector> diff --git a/wasm/MarkLive.cpp b/wasm/MarkLive.cpp index 3bbd1148f6ad..723ac4e3c6ba 100644 --- a/wasm/MarkLive.cpp +++ b/wasm/MarkLive.cpp @@ -85,7 +85,7 @@ void lld::wasm::markLive() { // equal to null pointer, only reachable via direct call). if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB || Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32) { - FunctionSymbol *FuncSym = cast<FunctionSymbol>(Sym); + auto *FuncSym = cast<FunctionSymbol>(Sym); if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0) continue; } diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp index c7983196db36..65441d293b50 100644 --- a/wasm/SymbolTable.cpp +++ b/wasm/SymbolTable.cpp @@ -314,8 +314,9 @@ Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, return S; } -Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, - InputFile *File, +Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName, + StringRef ImportModule, + uint32_t Flags, InputFile *File, const WasmSignature *Sig) { LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " [" << (Sig ? toString(*Sig) : "none") << "]\n"); @@ -325,7 +326,8 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) - replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); + replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags, + File, Sig); else if (auto *Lazy = dyn_cast<LazySymbol>(S)) Lazy->fetch(); else @@ -351,7 +353,8 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, return S; } -Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, +Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, InputFile *File, const WasmGlobalType *Type) { LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); @@ -361,7 +364,8 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) - replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); + replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags, + File, Type); else if (auto *Lazy = dyn_cast<LazySymbol>(S)) Lazy->fetch(); else if (S->isDefined()) diff --git a/wasm/SymbolTable.h b/wasm/SymbolTable.h index 5e38e30692ab..64678aee5005 100644 --- a/wasm/SymbolTable.h +++ b/wasm/SymbolTable.h @@ -59,11 +59,13 @@ public: Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, InputEvent *E); - Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, - const WasmSignature *Signature); + Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, + InputFile *File, const WasmSignature *Signature); Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File); - Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - const WasmGlobalType *Type); + Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, + InputFile *File, const WasmGlobalType *Type); void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym); diff --git a/wasm/Symbols.h b/wasm/Symbols.h index 11ee66550cdc..a065338ac1e4 100644 --- a/wasm/Symbols.h +++ b/wasm/Symbols.h @@ -149,13 +149,19 @@ public: class UndefinedFunction : public FunctionSymbol { public: - UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr, + UndefinedFunction(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, + InputFile *File = nullptr, const WasmSignature *Type = nullptr) - : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {} + : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type), + ImportName(ImportName), ImportModule(ImportModule) {} static bool classof(const Symbol *S) { return S->kind() == UndefinedFunctionKind; } + + StringRef ImportName; + StringRef ImportModule; }; class SectionSymbol : public Symbol { @@ -261,13 +267,18 @@ public: class UndefinedGlobal : public GlobalSymbol { public: - UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr, + UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule, + uint32_t Flags, InputFile *File = nullptr, const WasmGlobalType *Type = nullptr) - : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {} + : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type), + ImportName(ImportName), ImportModule(ImportModule) {} static bool classof(const Symbol *S) { return S->kind() == UndefinedGlobalKind; } + + StringRef ImportName; + StringRef ImportModule; }; // Wasm events are features that suspend the current execution and transfer the diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp index 819d4298fef2..902ca61ca19b 100644 --- a/wasm/Writer.cpp +++ b/wasm/Writer.cpp @@ -39,8 +39,9 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static constexpr int kStackAlignment = 16; -static constexpr const char *kFunctionTableName = "__indirect_function_table"; +static constexpr int StackAlignment = 16; +static constexpr const char *FunctionTableName = "__indirect_function_table"; +const char *lld::wasm::DefaultModule = "env"; namespace { @@ -155,7 +156,7 @@ void Writer::createImportSection() { if (Config->ImportMemory) { WasmImport Import; - Import.Module = "env"; + Import.Module = DefaultModule; Import.Field = "memory"; Import.Kind = WASM_EXTERNAL_MEMORY; Import.Memory.Flags = 0; @@ -172,8 +173,8 @@ void Writer::createImportSection() { if (Config->ImportTable) { uint32_t TableSize = TableBase + IndirectFunctions.size(); WasmImport Import; - Import.Module = "env"; - Import.Field = kFunctionTableName; + Import.Module = DefaultModule; + Import.Field = FunctionTableName; Import.Kind = WASM_EXTERNAL_TABLE; Import.Table.ElemType = WASM_TYPE_FUNCREF; Import.Table.Limits = {0, TableSize, 0}; @@ -182,8 +183,17 @@ void Writer::createImportSection() { for (const Symbol *Sym : ImportedSymbols) { WasmImport Import; - Import.Module = "env"; - Import.Field = Sym->getName(); + if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { + Import.Field = F->ImportName; + Import.Module = F->ImportModule; + } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { + Import.Field = G->ImportName; + Import.Module = G->ImportModule; + } else { + Import.Field = Sym->getName(); + Import.Module = DefaultModule; + } + if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) { Import.Kind = WASM_EXTERNAL_FUNCTION; Import.SigIndex = lookupType(*FunctionSym->Signature); @@ -441,6 +451,13 @@ static uint32_t getWasmFlags(const Symbol *Sym) { Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; if (Sym->isUndefined()) Flags |= WASM_SYMBOL_UNDEFINED; + if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { + if (F->getName() != F->ImportName) + Flags |= WASM_SYMBOL_EXPLICIT_NAME; + } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { + if (G->getName() != G->ImportName) + Flags |= WASM_SYMBOL_EXPLICIT_NAME; + } return Flags; } @@ -506,15 +523,18 @@ void Writer::createLinkingSection() { if (auto *F = dyn_cast<FunctionSymbol>(Sym)) { writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); - if (Sym->isDefined()) + if (Sym->isDefined() || + (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStr(Sub.OS, Sym->getName(), "sym name"); } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) { writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); - if (Sym->isDefined()) + if (Sym->isDefined() || + (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStr(Sub.OS, Sym->getName(), "sym name"); } else if (auto *E = dyn_cast<EventSymbol>(Sym)) { writeUleb128(Sub.OS, E->getEventIndex(), "index"); - if (Sym->isDefined()) + if (Sym->isDefined() || + (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStr(Sub.OS, Sym->getName(), "sym name"); } else if (isa<DataSymbol>(Sym)) { writeStr(Sub.OS, Sym->getName(), "sym name"); @@ -663,9 +683,9 @@ void Writer::layoutMemory() { auto PlaceStack = [&]() { if (Config->Relocatable || Config->Shared) return; - MemoryPtr = alignTo(MemoryPtr, kStackAlignment); - if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) - error("stack size must be " + Twine(kStackAlignment) + "-byte aligned"); + MemoryPtr = alignTo(MemoryPtr, StackAlignment); + if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) + error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); log("mem: stack size = " + Twine(Config->ZStackSize)); log("mem: stack base = " + Twine(MemoryPtr)); MemoryPtr += Config->ZStackSize; @@ -814,7 +834,7 @@ void Writer::calculateExports() { Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); if (!Config->Relocatable && Config->ExportTable) - Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0}); + Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); @@ -858,40 +878,42 @@ void Writer::assignSymtab() { StringMap<uint32_t> SectionSymbolIndices; unsigned SymbolIndex = SymtabEntries.size(); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n"); - for (Symbol *Sym : File->getSymbols()) { - if (Sym->getFile() != File) - continue; - - if (auto *S = dyn_cast<SectionSymbol>(Sym)) { - StringRef Name = S->getName(); - if (CustomSectionMapping.count(Name) == 0) - continue; - - auto SSI = SectionSymbolIndices.find(Name); - if (SSI != SectionSymbolIndices.end()) { - Sym->setOutputSymbolIndex(SSI->second); - continue; - } - SectionSymbolIndices[Name] = SymbolIndex; - CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym); + auto AddSymbol = [&](Symbol *Sym) { + if (auto *S = dyn_cast<SectionSymbol>(Sym)) { + StringRef Name = S->getName(); + if (CustomSectionMapping.count(Name) == 0) + return; - Sym->markLive(); + auto SSI = SectionSymbolIndices.find(Name); + if (SSI != SectionSymbolIndices.end()) { + Sym->setOutputSymbolIndex(SSI->second); + return; } - // (Since this is relocatable output, GC is not performed so symbols must - // be live.) - assert(Sym->isLive()); - Sym->setOutputSymbolIndex(SymbolIndex++); - SymtabEntries.emplace_back(Sym); + SectionSymbolIndices[Name] = SymbolIndex; + CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym); + + Sym->markLive(); } - } - // For the moment, relocatable output doesn't contain any synthetic functions, - // so no need to look through the Symtab for symbols not referenced by - // Symtab->ObjectFiles. + // (Since this is relocatable output, GC is not performed so symbols must + // be live.) + assert(Sym->isLive()); + Sym->setOutputSymbolIndex(SymbolIndex++); + SymtabEntries.emplace_back(Sym); + }; + + for (Symbol *Sym : Symtab->getSymbols()) + if (!Sym->isLazy()) + AddSymbol(Sym); + + for (ObjFile *File : Symtab->ObjectFiles) { + LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); + for (Symbol *Sym : File->getSymbols()) + if (Sym->isLocal()) + AddSymbol(Sym); + } } uint32_t Writer::lookupType(const WasmSignature &Sig) { diff --git a/wasm/Writer.h b/wasm/Writer.h index a931ba9c29a8..e62f47064228 100644 --- a/wasm/Writer.h +++ b/wasm/Writer.h @@ -15,6 +15,8 @@ namespace wasm { void writeResult(); +extern const char *DefaultModule; + } // namespace wasm } // namespace lld |