diff options
| author | Sam Clegg <sbc@chromium.org> | 2018-02-02 22:59:56 +0000 |
|---|---|---|
| committer | Sam Clegg <sbc@chromium.org> | 2018-02-02 22:59:56 +0000 |
| commit | f0d433d0c6da4b48ae2d70ee30c910bef630c69f (patch) | |
| tree | 399d637754d037ab46fb105b88b903e9ebf5d792 /lld/wasm | |
| parent | 37713073d65e473b6306b347a3f6e892128e27ca (diff) | |
| download | bcm5719-llvm-f0d433d0c6da4b48ae2d70ee30c910bef630c69f.tar.gz bcm5719-llvm-f0d433d0c6da4b48ae2d70ee30c910bef630c69f.zip | |
[WebAssembly] Refactor linker-generated symbols. NFC.
Group all synthetic symbols in the in single struct to match
the ELF linker.
This change is part of a larger change to add more linker
symbols such as `_end` and `_edata`.
Differential Revision: https://reviews.llvm.org/D42866
llvm-svn: 324157
Diffstat (limited to 'lld/wasm')
| -rw-r--r-- | lld/wasm/Config.h | 3 | ||||
| -rw-r--r-- | lld/wasm/Driver.cpp | 17 | ||||
| -rw-r--r-- | lld/wasm/MarkLive.cpp | 2 | ||||
| -rw-r--r-- | lld/wasm/Symbols.cpp | 5 | ||||
| -rw-r--r-- | lld/wasm/Symbols.h | 19 | ||||
| -rw-r--r-- | lld/wasm/Writer.cpp | 56 |
6 files changed, 62 insertions, 40 deletions
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h index 3ac2297076e..89f31c83377 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -38,9 +38,6 @@ struct Configuration { llvm::StringSet<> AllowUndefinedSymbols; std::vector<llvm::StringRef> SearchPaths; - Symbol *StackPointerSymbol = nullptr; - Symbol *HeapBaseSymbol = nullptr; - Symbol *CtorSymbol = nullptr; }; // The only instance of Configuration struct. diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 24079d004bf..c3884381089 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -299,20 +299,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { // Handle the `--undefined <sym>` options. for (auto* Arg : Args.filtered(OPT_undefined)) Symtab->addUndefinedFunction(Arg->getValue(), nullptr); - - // Create linker-synthetic symbols - // __wasm_call_ctors: - // Function that directly calls all ctors in priority order. - // __stack_pointer: - // Wasm global that holds the address of the top of the explict - // value stack in linear memory. - // __dso_handle; - // Global in calls to __cxa_atexit to determine current DLL - Config->CtorSymbol = Symtab->addDefinedFunction( + WasmSym::CallCtors = Symtab->addDefinedFunction( "__wasm_call_ctors", &Signature, WASM_SYMBOL_VISIBILITY_HIDDEN); - Config->StackPointerSymbol = Symtab->addDefinedGlobal("__stack_pointer"); - Config->HeapBaseSymbol = Symtab->addDefinedGlobal("__heap_base"); - Symtab->addDefinedGlobal("__dso_handle")->setVirtualAddress(0); + WasmSym::StackPointer = Symtab->addDefinedGlobal("__stack_pointer"); + WasmSym::HeapBase = Symtab->addDefinedGlobal("__heap_base"); + WasmSym::DsoHandle = Symtab->addDefinedGlobal("__dso_handle"); } createFiles(Args); diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp index 9bd2a83c013..7a0a9e9724d 100644 --- a/lld/wasm/MarkLive.cpp +++ b/lld/wasm/MarkLive.cpp @@ -52,7 +52,7 @@ void lld::wasm::markLive() { // Add GC root symbols. if (!Config->Entry.empty()) Enqueue(Symtab->find(Config->Entry)); - Enqueue(Config->CtorSymbol); + Enqueue(WasmSym::CallCtors); // By default we export all non-hidden, so they are gc roots too for (Symbol *Sym : Symtab->getSymbols()) diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index 485e7d0a539..cd7b678ffc1 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -22,6 +22,11 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; +Symbol *WasmSym::CallCtors; +Symbol *WasmSym::DsoHandle; +Symbol *WasmSym::HeapBase; +Symbol *WasmSym::StackPointer; + const WasmSignature &Symbol::getFunctionType() const { if (Chunk != nullptr) return dyn_cast<InputFunction>(Chunk)->Signature; diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index 42cebef7992..efb58839a03 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -111,6 +111,25 @@ protected: const WasmSignature *FunctionType = nullptr; }; +// linker-generated symbols +struct WasmSym { + // __stack_pointer + // Global that holds the address of the top of the explict value stack + // in linear memory. + static Symbol *StackPointer; + + // __heap_base + static Symbol *HeapBase; + + // __wasm_call_ctors + // Function that directly calls all ctors in priority order. + static Symbol *CallCtors; + + // __dso_handle + // Global used in calls to __cxa_atexit to determine current DLL + static Symbol *DsoHandle; +}; + } // namespace wasm // Returns a symbol name for an error message. diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index e0680f6239c..c5d19e3acad 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -237,7 +237,7 @@ void Writer::createGlobalSection() { for (const Symbol *Sym : DefinedGlobals) { WasmGlobal Global; Global.Type.Type = WASM_TYPE_I32; - Global.Type.Mutable = Sym == Config->StackPointerSymbol; + Global.Type.Mutable = Sym == WasmSym::StackPointer; Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); writeGlobal(OS, Global); @@ -520,6 +520,11 @@ void Writer::writeSections() { // Fix the memory layout of the output binary. This assigns memory offsets // to each of the input data sections as well as the explicit stack region. +// The memory layout is as follows, from low to high. +// - initialized data (starting at Config->GlobalBase) +// - BSS data (not currently implemented in llvm) +// - explicit stack (Config->ZStackSize) +// - heap start / unallocated void Writer::layoutMemory() { uint32_t MemoryPtr = 0; if (!Config->Relocatable) { @@ -529,7 +534,11 @@ void Writer::layoutMemory() { createOutputSegments(); - // Static data comes first + // Arbitrarily set __dso_handle handle to point to the start of the data + // segments. + if (WasmSym::DsoHandle) + WasmSym::DsoHandle->setVirtualAddress(MemoryPtr); + for (OutputSegment *Seg : Segments) { MemoryPtr = alignTo(MemoryPtr, Seg->Alignment); Seg->StartVA = MemoryPtr; @@ -538,12 +547,14 @@ void Writer::layoutMemory() { MemoryPtr += Seg->Size; } + // TODO: Add .bss space here. + DataSize = MemoryPtr; if (!Config->Relocatable) DataSize -= Config->GlobalBase; debugPrint("mem: static data = %d\n", DataSize); - // Stack comes after static data + // Stack comes after static data and bss if (!Config->Relocatable) { MemoryPtr = alignTo(MemoryPtr, kStackAlignment); if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) @@ -551,12 +562,12 @@ void Writer::layoutMemory() { debugPrint("mem: stack size = %d\n", Config->ZStackSize); debugPrint("mem: stack base = %d\n", MemoryPtr); MemoryPtr += Config->ZStackSize; - Config->StackPointerSymbol->setVirtualAddress(MemoryPtr); + WasmSym::StackPointer->setVirtualAddress(MemoryPtr); debugPrint("mem: stack top = %d\n", MemoryPtr); // Set `__heap_base` to directly follow the end of the stack. We don't // allocate any heap memory up front, but instead really on the malloc/brk // implementation growing the memory at runtime. - Config->HeapBaseSymbol->setVirtualAddress(MemoryPtr); + WasmSym::HeapBase->setVirtualAddress(MemoryPtr); debugPrint("mem: heap base = %d\n", MemoryPtr); } @@ -619,6 +630,7 @@ void Writer::calculateImports() { void Writer::calculateExports() { bool ExportHidden = Config->Relocatable; StringSet<> UsedNames; + auto BudgeLocalName = [&](const Symbol *Sym) { StringRef SymName = Sym->getName(); // We can't budge non-local names. @@ -638,9 +650,9 @@ void Writer::calculateExports() { } }; - if (Config->CtorSymbol && (!Config->CtorSymbol->isHidden() || ExportHidden)) + if (WasmSym::CallCtors && (!WasmSym::CallCtors->isHidden() || ExportHidden)) ExportedSymbols.emplace_back( - WasmExportEntry{Config->CtorSymbol, Config->CtorSymbol->getName()}); + WasmExportEntry{WasmSym::CallCtors, WasmSym::CallCtors->getName()}); for (ObjFile *File : Symtab->ObjectFiles) { for (Symbol *Sym : File->getSymbols()) { @@ -664,7 +676,7 @@ void Writer::calculateExports() { // Can't export the SP right now because its mutable, and mutuable globals // are yet supported in the official binary format. // TODO(sbc): Remove this if/when the "mutable global" proposal is accepted. - if (Sym == Config->StackPointerSymbol) + if (Sym == WasmSym::StackPointer) continue; ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)}); } @@ -712,23 +724,22 @@ void Writer::assignIndexes() { uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size(); uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size(); - if (Config->StackPointerSymbol) { - DefinedGlobals.emplace_back(Config->StackPointerSymbol); - Config->StackPointerSymbol->setOutputIndex(GlobalIndex++); - } - - if (Config->HeapBaseSymbol) { - DefinedGlobals.emplace_back(Config->HeapBaseSymbol); - Config->HeapBaseSymbol->setOutputIndex(GlobalIndex++); - } + auto AddDefinedGlobal = [&](Symbol* Sym) { + if (Sym) { + DefinedGlobals.emplace_back(Sym); + Sym->setOutputIndex(GlobalIndex++); + } + }; + AddDefinedGlobal(WasmSym::StackPointer); + AddDefinedGlobal(WasmSym::HeapBase); if (Config->Relocatable) DefinedGlobals.reserve(Symtab->getSymbols().size()); uint32_t TableIndex = kInitialTableOffset; - for (ObjFile *File : Symtab->ObjectFiles) { - if (Config->Relocatable) { + if (Config->Relocatable) { + for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); for (Symbol *Sym : File->getSymbols()) { // Create wasm globals for data symbols defined in this file @@ -737,8 +748,7 @@ void Writer::assignIndexes() { if (Sym->isFunction()) continue; - DefinedGlobals.emplace_back(Sym); - Sym->setOutputIndex(GlobalIndex++); + AddDefinedGlobal(Sym); } } } @@ -822,7 +832,7 @@ static const int OPCODE_END = 0xb; // in input object. void Writer::createCtorFunction() { uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size(); - Config->CtorSymbol->setOutputIndex(FunctionIndex); + WasmSym::CallCtors->setOutputIndex(FunctionIndex); // First write the body bytes to a string. std::string FunctionBody; @@ -846,7 +856,7 @@ void Writer::createCtorFunction() { reinterpret_cast<const uint8_t *>(CtorFunctionBody.data()), CtorFunctionBody.size()); CtorFunction = llvm::make_unique<SyntheticFunction>( - Signature, BodyArray, Config->CtorSymbol->getName()); + Signature, BodyArray, WasmSym::CallCtors->getName()); CtorFunction->setOutputIndex(FunctionIndex); DefinedFunctions.emplace_back(CtorFunction.get()); } |

