llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lld-wasm Author: Anutosh Bhat (anutosh491) <details> <summary>Changes</summary> Backport : https://github.com/llvm/llvm-project/commit/9cbbb74d370c09e13b8412f21dccb7d2c4afc6a4 --- Patch is 44.21 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137620.diff 9 Files Affected: - (modified) lld/wasm/Config.h (+110) - (modified) lld/wasm/Driver.cpp (+34-30) - (modified) lld/wasm/InputChunks.cpp (+5-5) - (modified) lld/wasm/MarkLive.cpp (+3-3) - (modified) lld/wasm/OutputSections.cpp (+2-2) - (modified) lld/wasm/Symbols.cpp (-25) - (modified) lld/wasm/Symbols.h (-99) - (modified) lld/wasm/SyntheticSections.cpp (+14-18) - (modified) lld/wasm/Writer.cpp (+94-93) ``````````diff diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h index 1fa6c42d9cd86..71dabaedb8a8c 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -32,6 +32,11 @@ class InputTable; class InputGlobal; class InputFunction; class Symbol; +class DefinedData; +class GlobalSymbol; +class DefinedFunction; +class UndefinedGlobal; +class TableSymbol; // For --unresolved-symbols. enum class UnresolvedPolicy { ReportError, Warn, Ignore, ImportDynamic }; @@ -139,6 +144,111 @@ struct Ctx { llvm::SmallVector<InputGlobal *, 0> syntheticGlobals; llvm::SmallVector<InputTable *, 0> syntheticTables; + // linker-generated symbols + struct WasmSym { + // __global_base + // Symbol marking the start of the global section. + DefinedData *globalBase; + + // __stack_pointer/__stack_low/__stack_high + // Global that holds current value of stack pointer and data symbols marking + // the start and end of the stack region. stackPointer is initialized to + // stackHigh and grows downwards towards stackLow + GlobalSymbol *stackPointer; + DefinedData *stackLow; + DefinedData *stackHigh; + + // __tls_base + // Global that holds the address of the base of the current thread's + // TLS block. + GlobalSymbol *tlsBase; + + // __tls_size + // Symbol whose value is the size of the TLS block. + GlobalSymbol *tlsSize; + + // __tls_size + // Symbol whose value is the alignment of the TLS block. + GlobalSymbol *tlsAlign; + + // __data_end + // Symbol marking the end of the data and bss. + DefinedData *dataEnd; + + // __heap_base/__heap_end + // Symbols marking the beginning and end of the "heap". It starts at the end + // of the data, bss and explicit stack, and extends to the end of the linear + // memory allocated by wasm-ld. This region of memory is not used by the + // linked code, so it may be used as a backing store for `sbrk` or `malloc` + // implementations. + DefinedData *heapBase; + DefinedData *heapEnd; + + // __wasm_first_page_end + // A symbol whose address is the end of the first page in memory (if any). + DefinedData *firstPageEnd; + + // __wasm_init_memory_flag + // Symbol whose contents are nonzero iff memory has already been + // initialized. + DefinedData *initMemoryFlag; + + // __wasm_init_memory + // Function that initializes passive data segments during instantiation. + DefinedFunction *initMemory; + + // __wasm_call_ctors + // Function that directly calls all ctors in priority order. + DefinedFunction *callCtors; + + // __wasm_call_dtors + // Function that calls the libc/etc. cleanup function. + DefinedFunction *callDtors; + + // __wasm_apply_global_relocs + // Function that applies relocations to wasm globals post-instantiation. + // Unlike __wasm_apply_data_relocs this needs to run on every thread. + DefinedFunction *applyGlobalRelocs; + + // __wasm_apply_tls_relocs + // Like __wasm_apply_data_relocs but for TLS section. These must be + // delayed until __wasm_init_tls. + DefinedFunction *applyTLSRelocs; + + // __wasm_apply_global_tls_relocs + // Like applyGlobalRelocs but for globals that hold TLS addresses. These + // must be delayed until __wasm_init_tls. + DefinedFunction *applyGlobalTLSRelocs; + + // __wasm_init_tls + // Function that allocates thread-local storage and initializes it. + DefinedFunction *initTLS; + + // Pointer to the function that is to be used in the start section. + // (normally an alias of initMemory, or applyGlobalRelocs). + DefinedFunction *startFunction; + + // __dso_handle + // Symbol used in calls to __cxa_atexit to determine current DLL + DefinedData *dsoHandle; + + // __table_base + // Used in PIC code for offset of indirect function table + UndefinedGlobal *tableBase; + DefinedData *definedTableBase; + + // __memory_base + // Used in PIC code for offset of global data + UndefinedGlobal *memoryBase; + DefinedData *definedMemoryBase; + + // __indirect_function_table + // Used as an address space for function pointers, with each function that + // is used as a function pointer being allocated a slot. + TableSymbol *indirectFunctionTable; + }; + WasmSym sym; + // True if we are creating position-independent code. bool isPic = false; diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index c3a74dde6480e..a6e6f90e56dc3 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -70,6 +70,7 @@ void Ctx::reset() { isPic = false; legacyFunctionTable = false; emitBssSegments = false; + sym = WasmSym{}; } namespace { @@ -941,14 +942,14 @@ static void createSyntheticSymbols() { true}; static llvm::wasm::WasmGlobalType mutableGlobalTypeI64 = {WASM_TYPE_I64, true}; - WasmSym::callCtors = symtab->addSyntheticFunction( + ctx.sym.callCtors = symtab->addSyntheticFunction( "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, make<SyntheticFunction>(nullSignature, "__wasm_call_ctors")); bool is64 = ctx.arg.is64.value_or(false); if (ctx.isPic) { - WasmSym::stackPointer = + ctx.sym.stackPointer = createUndefinedGlobal("__stack_pointer", ctx.arg.is64.value_or(false) ? &mutableGlobalTypeI64 : &mutableGlobalTypeI32); @@ -958,25 +959,24 @@ static void createSyntheticSymbols() { // See: // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md auto *globalType = is64 ? &globalTypeI64 : &globalTypeI32; - WasmSym::memoryBase = createUndefinedGlobal("__memory_base", globalType); - WasmSym::tableBase = createUndefinedGlobal("__table_base", globalType); - WasmSym::memoryBase->markLive(); - WasmSym::tableBase->markLive(); + ctx.sym.memoryBase = createUndefinedGlobal("__memory_base", globalType); + ctx.sym.tableBase = createUndefinedGlobal("__table_base", globalType); + ctx.sym.memoryBase->markLive(); + ctx.sym.tableBase->markLive(); } else { // For non-PIC code - WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true); - WasmSym::stackPointer->markLive(); + ctx.sym.stackPointer = createGlobalVariable("__stack_pointer", true); + ctx.sym.stackPointer->markLive(); } if (ctx.arg.sharedMemory) { - WasmSym::tlsBase = createGlobalVariable("__tls_base", true); - WasmSym::tlsSize = createGlobalVariable("__tls_size", false); - WasmSym::tlsAlign = createGlobalVariable("__tls_align", false); - WasmSym::initTLS = symtab->addSyntheticFunction( + ctx.sym.tlsBase = createGlobalVariable("__tls_base", true); + ctx.sym.tlsSize = createGlobalVariable("__tls_size", false); + ctx.sym.tlsAlign = createGlobalVariable("__tls_align", false); + ctx.sym.initTLS = symtab->addSyntheticFunction( "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN, - make<SyntheticFunction>( - is64 ? i64ArgSignature : i32ArgSignature, - "__wasm_init_tls")); + make<SyntheticFunction>(is64 ? i64ArgSignature : i32ArgSignature, + "__wasm_init_tls")); } } @@ -984,21 +984,25 @@ static void createOptionalSymbols() { if (ctx.arg.relocatable) return; - WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle"); + ctx.sym.dsoHandle = symtab->addOptionalDataSymbol("__dso_handle"); if (!ctx.arg.shared) - WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end"); + ctx.sym.dataEnd = symtab->addOptionalDataSymbol("__data_end"); if (!ctx.isPic) { - WasmSym::stackLow = symtab->addOptionalDataSymbol("__stack_low"); - WasmSym::stackHigh = symtab->addOptionalDataSymbol("__stack_high"); - WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base"); - WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base"); - WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end"); - WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base"); - WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base"); + ctx.sym.stackLow = symtab->addOptionalDataSymbol("__stack_low"); + ctx.sym.stackHigh = symtab->addOptionalDataSymbol("__stack_high"); + ctx.sym.globalBase = symtab->addOptionalDataSymbol("__global_base"); + ctx.sym.heapBase = symtab->addOptionalDataSymbol("__heap_base"); + ctx.sym.heapEnd = symtab->addOptionalDataSymbol("__heap_end"); + ctx.sym.definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base"); + ctx.sym.definedTableBase = symtab->addOptionalDataSymbol("__table_base"); } + ctx.sym.firstPageEnd = symtab->addOptionalDataSymbol("__wasm_first_page_end"); + if (ctx.sym.firstPageEnd) + ctx.sym.firstPageEnd->setVA(ctx.arg.pageSize); + // For non-shared memory programs we still need to define __tls_base since we // allow object files built with TLS to be linked into single threaded // programs, and such object files can contain references to this symbol. @@ -1009,7 +1013,7 @@ static void createOptionalSymbols() { // __tls_size and __tls_align are not needed in this case since they are only // needed for __wasm_init_tls (which we do not create in this case). if (!ctx.arg.sharedMemory) - WasmSym::tlsBase = createOptionalGlobal("__tls_base", false); + ctx.sym.tlsBase = createOptionalGlobal("__tls_base", false); } static void processStubLibrariesPreLTO() { @@ -1384,9 +1388,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { // by libc/etc., because destructors are registered dynamically with // `__cxa_atexit` and friends. if (!ctx.arg.relocatable && !ctx.arg.shared && - !WasmSym::callCtors->isUsedInRegularObj && - WasmSym::callCtors->getName() != ctx.arg.entry && - !ctx.arg.exportedSymbols.count(WasmSym::callCtors->getName())) { + !ctx.sym.callCtors->isUsedInRegularObj && + ctx.sym.callCtors->getName() != ctx.arg.entry && + !ctx.arg.exportedSymbols.count(ctx.sym.callCtors->getName())) { if (Symbol *callDtors = handleUndefined("__wasm_call_dtors", "<internal>")) { if (auto *callDtorsFunc = dyn_cast<DefinedFunction>(callDtors)) { @@ -1395,7 +1399,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { !callDtorsFunc->signature->Returns.empty())) { error("__wasm_call_dtors must have no argument or return values"); } - WasmSym::callDtors = callDtorsFunc; + ctx.sym.callDtors = callDtorsFunc; } else { error("__wasm_call_dtors must be a function"); } @@ -1488,7 +1492,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { markLive(); // Provide the indirect function table if needed. - WasmSym::indirectFunctionTable = + ctx.sym.indirectFunctionTable = symtab->resolveIndirectFunctionTable(/*required =*/false); if (errorCount()) diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index ccdc92f5c8d71..0e6c4e691be10 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -397,9 +397,9 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const { if (ctx.isPic) { writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); if (isTLS()) - writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "tls_base"); + writeUleb128(os, ctx.sym.tlsBase->getGlobalIndex(), "tls_base"); else - writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base"); + writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(), "memory_base"); writeU8(os, opcode_ptr_add, "ADD"); } @@ -422,12 +422,12 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const { } } else { assert(ctx.isPic); - const GlobalSymbol* baseSymbol = WasmSym::memoryBase; + const GlobalSymbol *baseSymbol = ctx.sym.memoryBase; if (rel.Type == R_WASM_TABLE_INDEX_I32 || rel.Type == R_WASM_TABLE_INDEX_I64) - baseSymbol = WasmSym::tableBase; + baseSymbol = ctx.sym.tableBase; else if (sym->isTLS()) - baseSymbol = WasmSym::tlsBase; + baseSymbol = ctx.sym.tlsBase; writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); writeUleb128(os, baseSymbol->getGlobalIndex(), "base"); writeU8(os, opcode_reloc_const, "CONST"); diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp index 13c7a3d894fe3..2b2cf19f14b30 100644 --- a/lld/wasm/MarkLive.cpp +++ b/lld/wasm/MarkLive.cpp @@ -114,8 +114,8 @@ void MarkLive::run() { if (sym->isNoStrip() || sym->isExported()) enqueue(sym); - if (WasmSym::callDtors) - enqueue(WasmSym::callDtors); + if (ctx.sym.callDtors) + enqueue(ctx.sym.callDtors); for (const ObjFile *obj : ctx.objectFiles) if (obj->isLive()) { @@ -131,7 +131,7 @@ void MarkLive::run() { // If we have any non-discarded init functions, mark `__wasm_call_ctors` as // live so that we assign it an index and call it. if (isCallCtorsLive()) - WasmSym::callCtors->markLive(); + ctx.sym.callCtors->markLive(); } void MarkLive::mark() { diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index 95f7ecc29de6b..4142a913c8cbf 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -123,7 +123,7 @@ void DataSection::finalizeContents() { if ((segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0) { if (ctx.isPic && ctx.arg.extendedConst) { writeU8(os, WASM_OPCODE_GLOBAL_GET, "global get"); - writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), + writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(), "literal (global index)"); if (segment->startVA) { writePtrConst(os, segment->startVA, is64, "offset"); @@ -136,7 +136,7 @@ void DataSection::finalizeContents() { if (ctx.isPic) { assert(segment->startVA == 0); initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET; - initExpr.Inst.Value.Global = WasmSym::memoryBase->getGlobalIndex(); + initExpr.Inst.Value.Global = ctx.sym.memoryBase->getGlobalIndex(); } else { initExpr = intConst(segment->startVA, is64); } diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index a687fd6d6c4ef..92a933ecbb024 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -77,31 +77,6 @@ std::string toString(wasm::Symbol::Kind kind) { } namespace wasm { -DefinedFunction *WasmSym::callCtors; -DefinedFunction *WasmSym::callDtors; -DefinedFunction *WasmSym::initMemory; -DefinedFunction *WasmSym::applyGlobalRelocs; -DefinedFunction *WasmSym::applyTLSRelocs; -DefinedFunction *WasmSym::applyGlobalTLSRelocs; -DefinedFunction *WasmSym::initTLS; -DefinedFunction *WasmSym::startFunction; -DefinedData *WasmSym::dsoHandle; -DefinedData *WasmSym::dataEnd; -DefinedData *WasmSym::globalBase; -DefinedData *WasmSym::heapBase; -DefinedData *WasmSym::heapEnd; -DefinedData *WasmSym::initMemoryFlag; -GlobalSymbol *WasmSym::stackPointer; -DefinedData *WasmSym::stackLow; -DefinedData *WasmSym::stackHigh; -GlobalSymbol *WasmSym::tlsBase; -GlobalSymbol *WasmSym::tlsSize; -GlobalSymbol *WasmSym::tlsAlign; -UndefinedGlobal *WasmSym::tableBase; -DefinedData *WasmSym::definedTableBase; -UndefinedGlobal *WasmSym::memoryBase; -DefinedData *WasmSym::definedMemoryBase; -TableSymbol *WasmSym::indirectFunctionTable; WasmSymbolType Symbol::getWasmType() const { if (isa<FunctionSymbol>(this)) diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index b409fffc50a6c..55ee21939ce07 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -537,105 +537,6 @@ class LazySymbol : public Symbol { const WasmSignature *signature = nullptr; }; -// linker-generated symbols -struct WasmSym { - // __global_base - // Symbol marking the start of the global section. - static DefinedData *globalBase; - - // __stack_pointer/__stack_low/__stack_high - // Global that holds current value of stack pointer and data symbols marking - // the start and end of the stack region. stackPointer is initialized to - // stackHigh and grows downwards towards stackLow - static GlobalSymbol *stackPointer; - static DefinedData *stackLow; - static DefinedData *stackHigh; - - // __tls_base - // Global that holds the address of the base of the current thread's - // TLS block. - static GlobalSymbol *tlsBase; - - // __tls_size - // Symbol whose value is the size of the TLS block. - static GlobalSymbol *tlsSize; - - // __tls_size - // Symbol whose value is the alignment of the TLS block. - static GlobalSymbol *tlsAlign; - - // __data_end - // Symbol marking the end of the data and bss. - static DefinedData *dataEnd; - - // __heap_base/__heap_end - // Symbols marking the beginning and end of the "heap". It starts at the end - // of the data, bss and explicit stack, and extends to the end of the linear - // memory allocated by wasm-ld. This region of memory is not used by the - // linked code, so it may be used as a backing store for `sbrk` or `malloc` - // implementations. - static DefinedData *heapBase; - static DefinedData *heapEnd; - - // __wasm_init_memory_flag - // Symbol whose contents are nonzero iff memory has already been initialized. - static DefinedData *initMemoryFlag; - - // __wasm_init_memory - // Function that initializes passive data segments during instantiation. - static DefinedFunction *initMemory; - - // __wasm_call_ctors - // Function that directly calls all ctors in priority order. - static DefinedFunction *callCtors; - - // __wasm_call_dtors - // Function that calls the libc/etc. cleanup function. - static DefinedFunction *callDtors; - - // __wasm_apply_global_relocs - // Function that applies relocations to wasm globals post-instantiation. - // Unlike __wasm_apply_data_relocs this needs to run on every thread. - static DefinedFunction *applyGlobalRelocs; - - // __wasm_apply_tls_relocs - // Like __wasm_apply_data_relocs but for TLS section. These must be - // delayed until __wasm_init_tls. - static DefinedFunction *applyTLSRelocs; - - // __wasm_apply_global_tls_relocs - // Like applyGlobalRelocs but for globals that hold TLS addresses. These - // must be delayed until __wasm_init_tls. - static DefinedFunction *applyGlobalTLSRelocs; - - // __wasm_init_tls - // Function that allocates thread-local storage and initializes it. - static DefinedFunction *initTLS; - - // Pointer to the function that is to be used in the start section. - // (normally an alias of initMemory, or applyGlobalRelocs). - static DefinedFunction *startFunction; - - // __dso_handle - // Symbol used in calls to __cxa_atexit to determine current DLL - static DefinedData *dsoHandle; - - // __table_base - // Used in PIC code for offset of indirect function table - static UndefinedGlobal *tableBase; - static DefinedData *definedTableBase; - - // __memory_base - // Used in PIC code for offset of global data - static UndefinedGlobal *memoryBase; - static DefinedData *definedMemoryBase; - - // __indirect_function_table - // Used as an address space for function pointers, with each function that is - // used as a function pointer being allocated a slot. - static TableSymbol *indirectFunctionTable; -}; - // A buffer class that is large enough to hold any Symbol-derived // object. We allocate memory using this class and instantiate a symbol // using the placement new. diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp index 7fb44b9f0c009..0e2aa57e9048e 100644 --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -319,8 +319,8 @@ void TableSection::addTable(InputTable *table) { // Some inputs require that the indirect function table be assigned to table // number 0. if (ctx.legacyFunctionTable && - isa<DefinedTable>(WasmSym::indirectFunctionTable) && - cast<DefinedTable>(WasmSym::indirectFunctionTable)->table == table) { + isa<DefinedTable>(ctx.sym.indirectFunctionTable) && + cast<DefinedTable>(ctx.sym.indirectFunctionTable)->table == table) { if (out.importSec->getNumImportedTables()) { // Alack! Some other i... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/137620 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits