diff --git a/recipes/recipes_emscripten/llvm/build.sh b/recipes/recipes_emscripten/llvm/build.sh index d70124facff..af6fb832f6e 100644 --- a/recipes/recipes_emscripten/llvm/build.sh +++ b/recipes/recipes_emscripten/llvm/build.sh @@ -25,16 +25,12 @@ emcmake cmake ${CMAKE_ARGS} -S ../llvm -B . \ -DLLVM_ENABLE_THREADS=OFF \ -DLLVM_ENABLE_ZSTD=OFF \ -DLLVM_ENABLE_LIBXML2=OFF \ + -DLLVM_BUILD_TOOLS=OFF \ -DCLANG_ENABLE_STATIC_ANALYZER=OFF \ -DCLANG_ENABLE_ARCMT=OFF \ -DCLANG_ENABLE_BOOTSTRAP=OFF \ + -DCLANG_BUILD_TOOLS=OFF \ -DCMAKE_CXX_FLAGS="-Dwait4=__syscall_wait4 -fexceptions" -# Build step -emmake make -j4 - -# Install step -emmake make install - -# Copy all files with ".wasm" extension to $PREFIX/bin -cp $SRC_DIR/build/bin/*.wasm $PREFIX/bin +# Build and Install step +emmake make clangInterpreter lldWasm -j16 install diff --git a/recipes/recipes_emscripten/llvm/patches/define_LLVM_ABI.patch b/recipes/recipes_emscripten/llvm/patches/define_LLVM_ABI.patch deleted file mode 100644 index 0c77283c8da..00000000000 --- a/recipes/recipes_emscripten/llvm/patches/define_LLVM_ABI.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/clang/include/clang/Support/Compiler.h b/clang/include/clang/Support/Compiler.h -index 13582b899dc2..5a74f8e3b672 100644 ---- a/clang/include/clang/Support/Compiler.h -+++ b/clang/include/clang/Support/Compiler.h -@@ -54,7 +54,7 @@ - #define CLANG_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT - #define CLANG_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT - #define CLANG_EXPORT_TEMPLATE --#elif defined(__MACH__) || defined(__WASM__) -+#elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__) - #define CLANG_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT - #define CLANG_TEMPLATE_ABI - #define CLANG_EXPORT_TEMPLATE -diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index f9c57b89f1f0..dc8b5389069e 100644 ---- a/llvm/include/llvm/Support/Compiler.h -+++ b/llvm/include/llvm/Support/Compiler.h -@@ -203,7 +203,7 @@ - #define LLVM_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT - #define LLVM_EXPORT_TEMPLATE - #define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT --#elif defined(__MACH__) || defined(__WASM__) -+#elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__) - #define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT - #define LLVM_TEMPLATE_ABI - #define LLVM_EXPORT_TEMPLATE diff --git a/recipes/recipes_emscripten/llvm/patches/enable_exception_handling.patch b/recipes/recipes_emscripten/llvm/patches/enable_exception_handling.patch new file mode 100644 index 00000000000..2ba229bc643 --- /dev/null +++ b/recipes/recipes_emscripten/llvm/patches/enable_exception_handling.patch @@ -0,0 +1,67 @@ +diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp +index f91563dd0378..37cf3b62e6ec 100644 +--- a/clang/lib/Interpreter/Interpreter.cpp ++++ b/clang/lib/Interpreter/Interpreter.cpp +@@ -142,6 +142,48 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { + return std::move(Clang); + } + ++static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { ++ const auto &FrontendOpts = CI.getFrontendOpts(); ++ ++ if (FrontendOpts.ShowHelp) { ++ driver::getDriverOptTable().printHelp( ++ llvm::outs(), "clang -cc1 [options] file...", ++ "LLVM 'Clang' Compiler: http://clang.llvm.org", ++ /*ShowHidden=*/false, /*ShowAllAliases=*/false, ++ llvm::opt::Visibility(driver::options::CC1Option)); ++ return llvm::createStringError(llvm::errc::not_supported, "Help displayed"); ++ } ++ ++ if (FrontendOpts.ShowVersion) { ++ llvm::cl::PrintVersionMessage(); ++ return llvm::createStringError(llvm::errc::not_supported, ++ "Version displayed"); ++ } ++ ++ if (!FrontendOpts.LLVMArgs.empty()) { ++ unsigned NumArgs = FrontendOpts.LLVMArgs.size(); ++ auto Args = std::make_unique(NumArgs + 2); ++ Args[0] = "clang-repl (LLVM option parsing)"; ++ for (unsigned i = 0; i != NumArgs; ++i) { ++ Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); ++ // remove the leading '-' from the option name ++ if (Args[i + 1][0] == '-') { ++ auto *option = static_cast *>( ++ llvm::cl::getRegisteredOptions()[Args[i + 1] + 1]); ++ if (option) { ++ option->setInitialValue(true); ++ } else { ++ llvm::errs() << "Unknown LLVM option: " << Args[i + 1] << "\n"; ++ } ++ } ++ } ++ Args[NumArgs + 1] = nullptr; ++ llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); ++ } ++ ++ return llvm::Error::success(); ++} ++ + } // anonymous namespace + + namespace clang { +@@ -452,7 +494,12 @@ const char *const Runtimes = R"( + + llvm::Expected> + Interpreter::create(std::unique_ptr CI) { +- llvm::Error Err = llvm::Error::success(); ++ ++ llvm::Error Err = HandleFrontendOptions(*CI); ++ if (Err) { ++ return std::move(Err); ++ } ++ + auto Interp = + std::unique_ptr(new Interpreter(std::move(CI), Err)); + if (Err) diff --git a/recipes/recipes_emscripten/llvm/patches/wasm-ld.patch b/recipes/recipes_emscripten/llvm/patches/wasm-ld.patch new file mode 100644 index 00000000000..084c5b4fbed --- /dev/null +++ b/recipes/recipes_emscripten/llvm/patches/wasm-ld.patch @@ -0,0 +1,1090 @@ +diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h +index 1fa6c42d9cd8..527edc11c48e 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,107 @@ struct Ctx { + llvm::SmallVector syntheticGlobals; + llvm::SmallVector 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_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 c3a74dde6480..467c49e9981b 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(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( +- is64 ? i64ArgSignature : i32ArgSignature, +- "__wasm_init_tls")); ++ make(is64 ? i64ArgSignature : i32ArgSignature, ++ "__wasm_init_tls")); + } + } + +@@ -984,19 +984,19 @@ 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"); + } + + // For non-shared memory programs we still need to define __tls_base since we +@@ -1009,7 +1009,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 +1384,9 @@ void LinkerDriver::linkerMain(ArrayRef 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", "")) { + if (auto *callDtorsFunc = dyn_cast(callDtors)) { +@@ -1395,7 +1395,7 @@ void LinkerDriver::linkerMain(ArrayRef 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 +1488,7 @@ void LinkerDriver::linkerMain(ArrayRef 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 ccdc92f5c8d7..0e6c4e691be1 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 13c7a3d894fe..2b2cf19f14b3 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 95f7ecc29de6..4142a913c8cb 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 a687fd6d6c4e..92a933ecbb02 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(this)) +diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h +index b409fffc50a6..55ee21939ce0 100644 +--- a/lld/wasm/Symbols.h ++++ b/lld/wasm/Symbols.h +@@ -537,105 +537,6 @@ public: + 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 7fb44b9f0c00..0e2aa57e9048 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(WasmSym::indirectFunctionTable) && +- cast(WasmSym::indirectFunctionTable)->table == table) { ++ isa(ctx.sym.indirectFunctionTable) && ++ cast(ctx.sym.indirectFunctionTable)->table == table) { + if (out.importSec->getNumImportedTables()) { + // Alack! Some other input imported a table, meaning that we are unable + // to assign table number 0 to the indirect function table. +@@ -395,8 +395,8 @@ void GlobalSection::assignIndexes() { + } + + static void ensureIndirectFunctionTable() { +- if (!WasmSym::indirectFunctionTable) +- WasmSym::indirectFunctionTable = ++ if (!ctx.sym.indirectFunctionTable) ++ ctx.sym.indirectFunctionTable = + symtab->resolveIndirectFunctionTable(/*required =*/true); + } + +@@ -430,10 +430,9 @@ void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const { + // Get __memory_base + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + if (sym->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"); + + // Add the virtual address of the data symbol + writeU8(os, opcode_ptr_const, "CONST"); +@@ -443,7 +442,7 @@ void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const { + continue; + // Get __table_base + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); +- writeUleb128(os, WasmSym::tableBase->getGlobalIndex(), "__table_base"); ++ writeUleb128(os, ctx.sym.tableBase->getGlobalIndex(), "__table_base"); + + // Add the table index to __table_base + writeU8(os, opcode_ptr_const, "CONST"); +@@ -490,13 +489,13 @@ void GlobalSection::writeBody() { + if (ctx.arg.extendedConst && ctx.isPic) { + if (auto *d = dyn_cast(sym)) { + if (!sym->isTLS()) { +- globalIdx = WasmSym::memoryBase->getGlobalIndex(); ++ globalIdx = ctx.sym.memoryBase->getGlobalIndex(); + offset = d->getVA(); + useExtendedConst = true; + } + } else if (auto *f = dyn_cast(sym)) { + if (!sym->isStub) { +- globalIdx = WasmSym::tableBase->getGlobalIndex(); ++ globalIdx = ctx.sym.tableBase->getGlobalIndex(); + offset = f->getTableIndex(); + useExtendedConst = true; + } +@@ -550,14 +549,11 @@ void ExportSection::writeBody() { + writeExport(os, export_); + } + +-bool StartSection::isNeeded() const { +- return WasmSym::startFunction != nullptr; +-} ++bool StartSection::isNeeded() const { return ctx.sym.startFunction != nullptr; } + + void StartSection::writeBody() { + raw_ostream &os = bodyOutputStream; +- writeUleb128(os, WasmSym::startFunction->getFunctionIndex(), +- "function index"); ++ writeUleb128(os, ctx.sym.startFunction->getFunctionIndex(), "function index"); + } + + void ElemSection::addEntry(FunctionSymbol *sym) { +@@ -573,9 +569,9 @@ void ElemSection::addEntry(FunctionSymbol *sym) { + void ElemSection::writeBody() { + raw_ostream &os = bodyOutputStream; + +- assert(WasmSym::indirectFunctionTable); ++ assert(ctx.sym.indirectFunctionTable); + writeUleb128(os, 1, "segment count"); +- uint32_t tableNumber = WasmSym::indirectFunctionTable->getTableNumber(); ++ uint32_t tableNumber = ctx.sym.indirectFunctionTable->getTableNumber(); + uint32_t flags = 0; + if (tableNumber) + flags |= WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER; +@@ -587,7 +583,7 @@ void ElemSection::writeBody() { + initExpr.Extended = false; + if (ctx.isPic) { + initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET; +- initExpr.Inst.Value.Global = WasmSym::tableBase->getGlobalIndex(); ++ initExpr.Inst.Value.Global = ctx.sym.tableBase->getGlobalIndex(); + } else { + bool is64 = ctx.arg.is64.value_or(false); + initExpr = intConst(ctx.arg.tableBase, is64); +diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp +index 76e38f548157..2bf4b370a7db 100644 +--- a/lld/wasm/Writer.cpp ++++ b/lld/wasm/Writer.cpp +@@ -340,16 +340,16 @@ void Writer::layoutMemory() { + if (ctx.arg.relocatable || ctx.isPic) + return; + memoryPtr = alignTo(memoryPtr, stackAlignment); +- if (WasmSym::stackLow) +- WasmSym::stackLow->setVA(memoryPtr); ++ if (ctx.sym.stackLow) ++ ctx.sym.stackLow->setVA(memoryPtr); + if (ctx.arg.zStackSize != alignTo(ctx.arg.zStackSize, stackAlignment)) + error("stack size must be " + Twine(stackAlignment) + "-byte aligned"); + log("mem: stack size = " + Twine(ctx.arg.zStackSize)); + log("mem: stack base = " + Twine(memoryPtr)); + memoryPtr += ctx.arg.zStackSize; +- setGlobalPtr(cast(WasmSym::stackPointer), memoryPtr); +- if (WasmSym::stackHigh) +- WasmSym::stackHigh->setVA(memoryPtr); ++ setGlobalPtr(cast(ctx.sym.stackPointer), memoryPtr); ++ if (ctx.sym.stackHigh) ++ ctx.sym.stackHigh->setVA(memoryPtr); + log("mem: stack top = " + Twine(memoryPtr)); + }; + +@@ -367,15 +367,15 @@ void Writer::layoutMemory() { + } + + log("mem: global base = " + Twine(memoryPtr)); +- if (WasmSym::globalBase) +- WasmSym::globalBase->setVA(memoryPtr); ++ if (ctx.sym.globalBase) ++ ctx.sym.globalBase->setVA(memoryPtr); + + uint64_t dataStart = memoryPtr; + + // Arbitrarily set __dso_handle handle to point to the start of the data + // segments. +- if (WasmSym::dsoHandle) +- WasmSym::dsoHandle->setVA(dataStart); ++ if (ctx.sym.dsoHandle) ++ ctx.sym.dsoHandle->setVA(dataStart); + + out.dylinkSec->memAlign = 0; + for (OutputSegment *seg : segments) { +@@ -386,16 +386,16 @@ void Writer::layoutMemory() { + memoryPtr, seg->size, seg->alignment)); + + if (!ctx.arg.relocatable && seg->isTLS()) { +- if (WasmSym::tlsSize) { +- auto *tlsSize = cast(WasmSym::tlsSize); ++ if (ctx.sym.tlsSize) { ++ auto *tlsSize = cast(ctx.sym.tlsSize); + setGlobalPtr(tlsSize, seg->size); + } +- if (WasmSym::tlsAlign) { +- auto *tlsAlign = cast(WasmSym::tlsAlign); ++ if (ctx.sym.tlsAlign) { ++ auto *tlsAlign = cast(ctx.sym.tlsAlign); + setGlobalPtr(tlsAlign, int64_t{1} << seg->alignment); + } +- if (!ctx.arg.sharedMemory && WasmSym::tlsBase) { +- auto *tlsBase = cast(WasmSym::tlsBase); ++ if (!ctx.arg.sharedMemory && ctx.sym.tlsBase) { ++ auto *tlsBase = cast(ctx.sym.tlsBase); + setGlobalPtr(tlsBase, memoryPtr); + } + } +@@ -406,17 +406,17 @@ void Writer::layoutMemory() { + // Make space for the memory initialization flag + if (ctx.arg.sharedMemory && hasPassiveInitializedSegments()) { + memoryPtr = alignTo(memoryPtr, 4); +- WasmSym::initMemoryFlag = symtab->addSyntheticDataSymbol( ++ ctx.sym.initMemoryFlag = symtab->addSyntheticDataSymbol( + "__wasm_init_memory_flag", WASM_SYMBOL_VISIBILITY_HIDDEN); +- WasmSym::initMemoryFlag->markLive(); +- WasmSym::initMemoryFlag->setVA(memoryPtr); ++ ctx.sym.initMemoryFlag->markLive(); ++ ctx.sym.initMemoryFlag->setVA(memoryPtr); + log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", + "__wasm_init_memory_flag", memoryPtr, 4, 4)); + memoryPtr += 4; + } + +- if (WasmSym::dataEnd) +- WasmSym::dataEnd->setVA(memoryPtr); ++ if (ctx.sym.dataEnd) ++ ctx.sym.dataEnd->setVA(memoryPtr); + + uint64_t staticDataSize = memoryPtr - dataStart; + log("mem: static data = " + Twine(staticDataSize)); +@@ -426,7 +426,7 @@ void Writer::layoutMemory() { + if (!ctx.arg.stackFirst) + placeStack(); + +- if (WasmSym::heapBase) { ++ if (ctx.sym.heapBase) { + // Set `__heap_base` to follow the end of the stack or global data. The + // fact that this comes last means that a malloc/brk implementation can + // grow the heap at runtime. +@@ -434,7 +434,7 @@ void Writer::layoutMemory() { + // __heap_base to be aligned already. + memoryPtr = alignTo(memoryPtr, heapAlignment); + log("mem: heap base = " + Twine(memoryPtr)); +- WasmSym::heapBase->setVA(memoryPtr); ++ ctx.sym.heapBase->setVA(memoryPtr); + } + + uint64_t maxMemorySetting = 1ULL << 32; +@@ -470,12 +470,12 @@ void Writer::layoutMemory() { + out.memorySec->numMemoryPages = memoryPtr / WasmPageSize; + log("mem: total pages = " + Twine(out.memorySec->numMemoryPages)); + +- if (WasmSym::heapEnd) { ++ if (ctx.sym.heapEnd) { + // Set `__heap_end` to follow the end of the statically allocated linear + // memory. The fact that this comes last means that a malloc/brk + // implementation can grow the heap at runtime. + log("mem: heap end = " + Twine(memoryPtr)); +- WasmSym::heapEnd->setVA(memoryPtr); ++ ctx.sym.heapEnd->setVA(memoryPtr); + } + + uint64_t maxMemory = 0; +@@ -758,14 +758,14 @@ void Writer::calculateImports() { + // Some inputs require that the indirect function table be assigned to table + // number 0, so if it is present and is an import, allocate it before any + // other tables. +- if (WasmSym::indirectFunctionTable && +- shouldImport(WasmSym::indirectFunctionTable)) +- out.importSec->addImport(WasmSym::indirectFunctionTable); ++ if (ctx.sym.indirectFunctionTable && ++ shouldImport(ctx.sym.indirectFunctionTable)) ++ out.importSec->addImport(ctx.sym.indirectFunctionTable); + + for (Symbol *sym : symtab->symbols()) { + if (!shouldImport(sym)) + continue; +- if (sym == WasmSym::indirectFunctionTable) ++ if (sym == ctx.sym.indirectFunctionTable) + continue; + LLVM_DEBUG(dbgs() << "import: " << sym->getName() << "\n"); + out.importSec->addImport(sym); +@@ -879,7 +879,7 @@ void Writer::createCommandExportWrappers() { + + // If there are no ctors and there's no libc `__wasm_call_dtors` to + // call, don't wrap the exports. +- if (initFunctions.empty() && WasmSym::callDtors == nullptr) ++ if (initFunctions.empty() && ctx.sym.callDtors == nullptr) + return; + + std::vector toWrap; +@@ -919,27 +919,27 @@ void Writer::createCommandExportWrappers() { + } + + static void finalizeIndirectFunctionTable() { +- if (!WasmSym::indirectFunctionTable) ++ if (!ctx.sym.indirectFunctionTable) + return; + +- if (shouldImport(WasmSym::indirectFunctionTable) && +- !WasmSym::indirectFunctionTable->hasTableNumber()) { ++ if (shouldImport(ctx.sym.indirectFunctionTable) && ++ !ctx.sym.indirectFunctionTable->hasTableNumber()) { + // Processing -Bsymbolic relocations resulted in a late requirement that the + // indirect function table be present, and we are running in --import-table + // mode. Add the table now to the imports section. Otherwise it will be + // added to the tables section later in assignIndexes. +- out.importSec->addImport(WasmSym::indirectFunctionTable); ++ out.importSec->addImport(ctx.sym.indirectFunctionTable); + } + + uint32_t tableSize = ctx.arg.tableBase + out.elemSec->numEntries(); + WasmLimits limits = {0, tableSize, 0}; +- if (WasmSym::indirectFunctionTable->isDefined() && !ctx.arg.growableTable) { ++ if (ctx.sym.indirectFunctionTable->isDefined() && !ctx.arg.growableTable) { + limits.Flags |= WASM_LIMITS_FLAG_HAS_MAX; + limits.Maximum = limits.Minimum; + } + if (ctx.arg.is64.value_or(false)) + limits.Flags |= WASM_LIMITS_FLAG_IS_64; +- WasmSym::indirectFunctionTable->setLimits(limits); ++ ctx.sym.indirectFunctionTable->setLimits(limits); + } + + static void scanRelocations() { +@@ -1142,26 +1142,26 @@ void Writer::createSyntheticInitFunctions() { + // We also initialize bss segments (using memory.fill) as part of this + // function. + if (hasPassiveInitializedSegments()) { +- WasmSym::initMemory = symtab->addSyntheticFunction( ++ ctx.sym.initMemory = symtab->addSyntheticFunction( + "__wasm_init_memory", WASM_SYMBOL_VISIBILITY_HIDDEN, + make(nullSignature, "__wasm_init_memory")); +- WasmSym::initMemory->markLive(); ++ ctx.sym.initMemory->markLive(); + if (ctx.arg.sharedMemory) { + // This global is assigned during __wasm_init_memory in the shared memory + // case. +- WasmSym::tlsBase->markLive(); ++ ctx.sym.tlsBase->markLive(); + } + } + + if (ctx.arg.sharedMemory) { + if (out.globalSec->needsTLSRelocations()) { +- WasmSym::applyGlobalTLSRelocs = symtab->addSyntheticFunction( ++ ctx.sym.applyGlobalTLSRelocs = symtab->addSyntheticFunction( + "__wasm_apply_global_tls_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN, + make(nullSignature, + "__wasm_apply_global_tls_relocs")); +- WasmSym::applyGlobalTLSRelocs->markLive(); ++ ctx.sym.applyGlobalTLSRelocs->markLive(); + // TLS relocations depend on the __tls_base symbols +- WasmSym::tlsBase->markLive(); ++ ctx.sym.tlsBase->markLive(); + } + + auto hasTLSRelocs = [](const OutputSegment *segment) { +@@ -1172,40 +1172,39 @@ void Writer::createSyntheticInitFunctions() { + return false; + }; + if (llvm::any_of(segments, hasTLSRelocs)) { +- WasmSym::applyTLSRelocs = symtab->addSyntheticFunction( ++ ctx.sym.applyTLSRelocs = symtab->addSyntheticFunction( + "__wasm_apply_tls_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN, +- make(nullSignature, +- "__wasm_apply_tls_relocs")); +- WasmSym::applyTLSRelocs->markLive(); ++ make(nullSignature, "__wasm_apply_tls_relocs")); ++ ctx.sym.applyTLSRelocs->markLive(); + } + } + + if (ctx.isPic && out.globalSec->needsRelocations()) { +- WasmSym::applyGlobalRelocs = symtab->addSyntheticFunction( ++ ctx.sym.applyGlobalRelocs = symtab->addSyntheticFunction( + "__wasm_apply_global_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN, + make(nullSignature, "__wasm_apply_global_relocs")); +- WasmSym::applyGlobalRelocs->markLive(); ++ ctx.sym.applyGlobalRelocs->markLive(); + } + + // If there is only one start function we can just use that function + // itself as the Wasm start function, otherwise we need to synthesize + // a new function to call them in sequence. +- if (WasmSym::applyGlobalRelocs && WasmSym::initMemory) { +- WasmSym::startFunction = symtab->addSyntheticFunction( ++ if (ctx.sym.applyGlobalRelocs && ctx.sym.initMemory) { ++ ctx.sym.startFunction = symtab->addSyntheticFunction( + "__wasm_start", WASM_SYMBOL_VISIBILITY_HIDDEN, + make(nullSignature, "__wasm_start")); +- WasmSym::startFunction->markLive(); ++ ctx.sym.startFunction->markLive(); + } + } + + void Writer::createInitMemoryFunction() { + LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); +- assert(WasmSym::initMemory); ++ assert(ctx.sym.initMemory); + assert(hasPassiveInitializedSegments()); + uint64_t flagAddress; + if (ctx.arg.sharedMemory) { +- assert(WasmSym::initMemoryFlag); +- flagAddress = WasmSym::initMemoryFlag->getVA(); ++ assert(ctx.sym.initMemoryFlag); ++ flagAddress = ctx.sym.initMemoryFlag->getVA(); + } + bool is64 = ctx.arg.is64.value_or(false); + std::string bodyContent; +@@ -1278,7 +1277,7 @@ void Writer::createInitMemoryFunction() { + writeUleb128(os, 2, "local count"); + writeU8(os, is64 ? WASM_TYPE_I64 : WASM_TYPE_I32, "address type"); + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); +- writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base"); ++ writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(), "memory_base"); + writePtrConst(os, flagAddress, is64, "flag address"); + writeU8(os, is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD, "add"); + writeU8(os, WASM_OPCODE_LOCAL_SET, "local.set"); +@@ -1325,7 +1324,7 @@ void Writer::createInitMemoryFunction() { + writePtrConst(os, s->startVA, is64, "destination address"); + if (ctx.isPic) { + writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); +- writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), ++ writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(), + "__memory_base"); + writeU8(os, is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD, + "i32.add"); +@@ -1343,8 +1342,7 @@ void Writer::createInitMemoryFunction() { + writePtrConst(os, s->startVA, is64, "destination address"); + } + writeU8(os, WASM_OPCODE_GLOBAL_SET, "GLOBAL_SET"); +- writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), +- "__tls_base"); ++ writeUleb128(os, ctx.sym.tlsBase->getGlobalIndex(), "__tls_base"); + if (ctx.isPic) { + writeU8(os, WASM_OPCODE_LOCAL_GET, "local.tee"); + writeUleb128(os, 1, "local 1"); +@@ -1420,30 +1418,30 @@ void Writer::createInitMemoryFunction() { + writeU8(os, WASM_OPCODE_END, "END"); + } + +- createFunction(WasmSym::initMemory, bodyContent); ++ createFunction(ctx.sym.initMemory, bodyContent); + } + + void Writer::createStartFunction() { + // If the start function exists when we have more than one function to call. +- if (WasmSym::initMemory && WasmSym::applyGlobalRelocs) { +- assert(WasmSym::startFunction); ++ if (ctx.sym.initMemory && ctx.sym.applyGlobalRelocs) { ++ assert(ctx.sym.startFunction); + std::string bodyContent; + { + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); + writeU8(os, WASM_OPCODE_CALL, "CALL"); +- writeUleb128(os, WasmSym::applyGlobalRelocs->getFunctionIndex(), ++ writeUleb128(os, ctx.sym.applyGlobalRelocs->getFunctionIndex(), + "function index"); + writeU8(os, WASM_OPCODE_CALL, "CALL"); +- writeUleb128(os, WasmSym::initMemory->getFunctionIndex(), ++ writeUleb128(os, ctx.sym.initMemory->getFunctionIndex(), + "function index"); + writeU8(os, WASM_OPCODE_END, "END"); + } +- createFunction(WasmSym::startFunction, bodyContent); +- } else if (WasmSym::initMemory) { +- WasmSym::startFunction = WasmSym::initMemory; +- } else if (WasmSym::applyGlobalRelocs) { +- WasmSym::startFunction = WasmSym::applyGlobalRelocs; ++ createFunction(ctx.sym.startFunction, bodyContent); ++ } else if (ctx.sym.initMemory) { ++ ctx.sym.startFunction = ctx.sym.initMemory; ++ } else if (ctx.sym.applyGlobalRelocs) { ++ ctx.sym.startFunction = ctx.sym.applyGlobalRelocs; + } + } + +@@ -1497,7 +1495,7 @@ void Writer::createApplyTLSRelocationsFunction() { + writeU8(os, WASM_OPCODE_END, "END"); + } + +- createFunction(WasmSym::applyTLSRelocs, bodyContent); ++ createFunction(ctx.sym.applyTLSRelocs, bodyContent); + } + + // Similar to createApplyDataRelocationsFunction but generates relocation code +@@ -1513,7 +1511,7 @@ void Writer::createApplyGlobalRelocationsFunction() { + writeU8(os, WASM_OPCODE_END, "END"); + } + +- createFunction(WasmSym::applyGlobalRelocs, bodyContent); ++ createFunction(ctx.sym.applyGlobalRelocs, bodyContent); + } + + // Similar to createApplyGlobalRelocationsFunction but for +@@ -1529,7 +1527,7 @@ void Writer::createApplyGlobalTLSRelocationsFunction() { + writeU8(os, WASM_OPCODE_END, "END"); + } + +- createFunction(WasmSym::applyGlobalTLSRelocs, bodyContent); ++ createFunction(ctx.sym.applyGlobalTLSRelocs, bodyContent); + } + + // Create synthetic "__wasm_call_ctors" function based on ctor functions +@@ -1537,7 +1535,7 @@ void Writer::createApplyGlobalTLSRelocationsFunction() { + void Writer::createCallCtorsFunction() { + // If __wasm_call_ctors isn't referenced, there aren't any ctors, don't + // define the `__wasm_call_ctors` function. +- if (!WasmSym::callCtors->isLive() && initFunctions.empty()) ++ if (!ctx.sym.callCtors->isLive() && initFunctions.empty()) + return; + + // First write the body's contents to a string. +@@ -1558,7 +1556,7 @@ void Writer::createCallCtorsFunction() { + writeU8(os, WASM_OPCODE_END, "END"); + } + +- createFunction(WasmSym::callCtors, bodyContent); ++ createFunction(ctx.sym.callCtors, bodyContent); + } + + // Create a wrapper around a function export which calls the +@@ -1573,10 +1571,9 @@ void Writer::createCommandExportWrapper(uint32_t functionIndex, + + // Call `__wasm_call_ctors` which call static constructors (and + // applies any runtime relocations in Emscripten-style PIC mode) +- if (WasmSym::callCtors->isLive()) { ++ if (ctx.sym.callCtors->isLive()) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); +- writeUleb128(os, WasmSym::callCtors->getFunctionIndex(), +- "function index"); ++ writeUleb128(os, ctx.sym.callCtors->getFunctionIndex(), "function index"); + } + + // Call the user's code, leaving any return values on the operand stack. +@@ -1588,7 +1585,7 @@ void Writer::createCommandExportWrapper(uint32_t functionIndex, + writeUleb128(os, functionIndex, "function index"); + + // Call the function that calls the destructors. +- if (DefinedFunction *callDtors = WasmSym::callDtors) { ++ if (DefinedFunction *callDtors = ctx.sym.callDtors) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, callDtors->getFunctionIndex(), "function index"); + } +@@ -1619,7 +1616,7 @@ void Writer::createInitTLSFunction() { + writeUleb128(os, 0, "local index"); + + writeU8(os, WASM_OPCODE_GLOBAL_SET, "global.set"); +- writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "global index"); ++ writeUleb128(os, ctx.sym.tlsBase->getGlobalIndex(), "global index"); + + // FIXME(wvo): this local needs to be I64 in wasm64, or we need an extend op. + writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get"); +@@ -1635,28 +1632,28 @@ void Writer::createInitTLSFunction() { + writeU8(os, 0, "memory index immediate"); + } + +- if (WasmSym::applyTLSRelocs) { ++ if (ctx.sym.applyTLSRelocs) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); +- writeUleb128(os, WasmSym::applyTLSRelocs->getFunctionIndex(), ++ writeUleb128(os, ctx.sym.applyTLSRelocs->getFunctionIndex(), + "function index"); + } + +- if (WasmSym::applyGlobalTLSRelocs) { ++ if (ctx.sym.applyGlobalTLSRelocs) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); +- writeUleb128(os, WasmSym::applyGlobalTLSRelocs->getFunctionIndex(), ++ writeUleb128(os, ctx.sym.applyGlobalTLSRelocs->getFunctionIndex(), + "function index"); + } + writeU8(os, WASM_OPCODE_END, "end function"); + } + +- createFunction(WasmSym::initTLS, bodyContent); ++ createFunction(ctx.sym.initTLS, bodyContent); + } + + // Populate InitFunctions vector with init functions from all input objects. + // This is then used either when creating the output linking section or to + // synthesize the "__wasm_call_ctors" function. + void Writer::calculateInitFunctions() { +- if (!ctx.arg.relocatable && !WasmSym::callCtors->isLive()) ++ if (!ctx.arg.relocatable && !ctx.sym.callCtors->isLive()) + return; + + for (ObjFile *file : ctx.objectFiles) { +@@ -1707,8 +1704,8 @@ void Writer::createSyntheticSectionsPostLayout() { + void Writer::run() { + // For PIC code the table base is assigned dynamically by the loader. + // For non-PIC, we start at 1 so that accessing table index 0 always traps. +- if (!ctx.isPic && WasmSym::definedTableBase) +- WasmSym::definedTableBase->setVA(ctx.arg.tableBase); ++ if (!ctx.isPic && ctx.sym.definedTableBase) ++ ctx.sym.definedTableBase->setVA(ctx.arg.tableBase); + + log("-- createOutputSegments"); + createOutputSegments(); +@@ -1776,14 +1773,18 @@ void Writer::run() { + + if (!ctx.arg.relocatable) { + // Create linker synthesized functions +- if (WasmSym::applyGlobalRelocs) ++ if (ctx.sym.applyGlobalRelocs) { + createApplyGlobalRelocationsFunction(); +- if (WasmSym::applyTLSRelocs) ++ } ++ if (ctx.sym.applyTLSRelocs) { + createApplyTLSRelocationsFunction(); +- if (WasmSym::applyGlobalTLSRelocs) ++ } ++ if (ctx.sym.applyGlobalTLSRelocs) { + createApplyGlobalTLSRelocationsFunction(); +- if (WasmSym::initMemory) ++ } ++ if (ctx.sym.initMemory) { + createInitMemoryFunction(); ++ } + createStartFunction(); + + createCallCtorsFunction(); +@@ -1794,14 +1795,14 @@ void Writer::run() { + // the input objects or an explicit export from the command-line, we + // assume ctors and dtors are taken care of already. + if (!ctx.arg.relocatable && !ctx.isPic && +- !WasmSym::callCtors->isUsedInRegularObj && +- !WasmSym::callCtors->isExported()) { ++ !ctx.sym.callCtors->isUsedInRegularObj && ++ !ctx.sym.callCtors->isExported()) { + log("-- createCommandExportWrappers"); + createCommandExportWrappers(); + } + } + +- if (WasmSym::initTLS && WasmSym::initTLS->isLive()) { ++ if (ctx.sym.initTLS && ctx.sym.initTLS->isLive()) { + log("-- createInitTLSFunction"); + createInitTLSFunction(); + } diff --git a/recipes/recipes_emscripten/llvm/recipe.yaml b/recipes/recipes_emscripten/llvm/recipe.yaml index b83a2524f7c..d99b6a1daff 100644 --- a/recipes/recipes_emscripten/llvm/recipe.yaml +++ b/recipes/recipes_emscripten/llvm/recipe.yaml @@ -1,5 +1,5 @@ context: - version: 20.1.1 + version: 20.1.4 package: name: llvm @@ -8,11 +8,12 @@ package: source: url: https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-${{ version }}.tar.gz - sha256: edde69aa3e48a3892a8f01332ff79cfb6179151b42503c4ba77d2cd408b013bf + sha256: 65e3a582c4c684fa707a56ff643427bce3633eceaceae3295d81c0e830f44b89 patches: - patches/cross_compile.patch - patches/shift_temporary_files_to_tmp_dir.patch - - patches/define_LLVM_ABI.patch + - patches/wasm-ld.patch + - patches/enable_exception_handling.patch build: number: 0