summaryrefslogtreecommitdiffstats
path: root/lld/wasm
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2018-02-02 22:59:56 +0000
committerSam Clegg <sbc@chromium.org>2018-02-02 22:59:56 +0000
commitf0d433d0c6da4b48ae2d70ee30c910bef630c69f (patch)
tree399d637754d037ab46fb105b88b903e9ebf5d792 /lld/wasm
parent37713073d65e473b6306b347a3f6e892128e27ca (diff)
downloadbcm5719-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.h3
-rw-r--r--lld/wasm/Driver.cpp17
-rw-r--r--lld/wasm/MarkLive.cpp2
-rw-r--r--lld/wasm/Symbols.cpp5
-rw-r--r--lld/wasm/Symbols.h19
-rw-r--r--lld/wasm/Writer.cpp56
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());
}
OpenPOWER on IntegriCloud