mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-16 07:49:43 +00:00
[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
This commit is contained in:
parent
37713073d6
commit
f0d433d0c6
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user