Index: lld/wasm/Driver.cpp =================================================================== --- lld/wasm/Driver.cpp +++ lld/wasm/Driver.cpp @@ -503,11 +503,15 @@ make(nullSignature, "__wasm_call_ctors")); if (config->isPic) { - // For PIC code we create a synthetic function __wasm_apply_relocs which - // is called from __wasm_call_ctors before the user-level constructors. - WasmSym::applyRelocs = symtab->addSyntheticFunction( - "__wasm_apply_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN, - make(nullSignature, "__wasm_apply_relocs")); + for (auto i = 0; i < WasmSym::applyRelocFuncCount; i++) { + // For PIC code we create a synthetic function __wasm_apply_relocs which + // is called from __wasm_call_ctors before the user-level constructors. + char buff[1024]; + sprintf(buff, "__wasm__apply_relocs_%d", i); + WasmSym::applyRelocFuncs[i] = symtab->addSyntheticFunction( + buff, WASM_SYMBOL_VISIBILITY_HIDDEN, + make(nullSignature, buff)); + } } Index: lld/wasm/InputChunks.h =================================================================== --- lld/wasm/InputChunks.h +++ lld/wasm/InputChunks.h @@ -96,7 +96,8 @@ static bool classof(const InputChunk *c) { return c->kind() == DataSegment; } - void generateRelocationCode(raw_ostream &os) const; + void generateRelocationCode(raw_ostream &os, int relocFuncIdx, + int relocFuncCount) const; uint32_t getAlignment() const { return segment.Data.Alignment; } StringRef getName() const override { return segment.Data.Name; } Index: lld/wasm/InputChunks.cpp =================================================================== --- lld/wasm/InputChunks.cpp +++ lld/wasm/InputChunks.cpp @@ -295,14 +295,23 @@ // Generate code to apply relocations to the data section at runtime. // This is only called when generating shared libaries (PIC) where address are // not known at static link time. -void InputSegment::generateRelocationCode(raw_ostream &os) const { +void InputSegment::generateRelocationCode(raw_ostream &os, int relocFuncIdx, + int relocFuncCount) const { LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName() - << " count=" << relocations.size() << "\n"); + << " count=" << relocations.size() << " chunk " + << relocFuncidx << "/" << relocFuncCount << "\n"); + const auto relocsPerFunc = + static_cast(relocations.size() / relocFuncCount); + const auto startIdx = relocsPerFunc * relocFuncIdx; + const auto endIdx = relocFuncIdx + 1 < relocFuncCount + ? relocsPerFunc * (relocFuncIdx + 1) + : static_cast(relocations.size()); // TODO(sbc): Encode the relocations in the data section and write a loop // here to apply them. uint32_t segmentVA = outputSeg->startVA + outputSegmentOffset; - for (const WasmRelocation &rel : relocations) { + for (auto relIdx = startIdx; relIdx < endIdx; relIdx++) { + const WasmRelocation &rel = relocations[relIdx]; uint32_t offset = rel.Offset - getInputSectionOffset(); uint32_t outputOffset = segmentVA + offset; Index: lld/wasm/MarkLive.cpp =================================================================== --- lld/wasm/MarkLive.cpp +++ lld/wasm/MarkLive.cpp @@ -64,7 +64,8 @@ // have to manually mark the ctors as live if callCtors itself is live. if (sym == WasmSym::callCtors) { if (config->isPic) - enqueue(WasmSym::applyRelocs); + for (auto i = 0; i < WasmSym::applyRelocFuncCount; i++) + enqueue(WasmSym::applyRelocFuncs[i]); for (const ObjFile *obj : symtab->objectFiles) { const WasmLinkingData &l = obj->getWasmObj()->linkingData(); for (const WasmInitFunc &f : l.InitFunctions) { Index: lld/wasm/Symbols.h =================================================================== --- lld/wasm/Symbols.h +++ lld/wasm/Symbols.h @@ -472,7 +472,8 @@ // __wasm_apply_relocs // Function that applies relocations to data segment post-instantiation. - static DefinedFunction *applyRelocs; + static DefinedFunction *applyRelocFuncs[10]; + static int applyRelocFuncCount; // __wasm_init_tls // Function that allocates thread-local storage and initializes it. Index: lld/wasm/Symbols.cpp =================================================================== --- lld/wasm/Symbols.cpp +++ lld/wasm/Symbols.cpp @@ -67,7 +67,8 @@ namespace wasm { DefinedFunction *WasmSym::callCtors; DefinedFunction *WasmSym::initMemory; -DefinedFunction *WasmSym::applyRelocs; +DefinedFunction *WasmSym::applyRelocFuncs[10]; +int WasmSym::applyRelocFuncCount = 10; DefinedFunction *WasmSym::initTLS; DefinedData *WasmSym::dsoHandle; DefinedData *WasmSym::dataEnd; Index: lld/wasm/Writer.cpp =================================================================== --- lld/wasm/Writer.cpp +++ lld/wasm/Writer.cpp @@ -844,18 +844,20 @@ // before any of the constructors run. void Writer::createApplyRelocationsFunction() { LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n"); - // First write the body's contents to a string. - std::string bodyContent; - { - raw_string_ostream os(bodyContent); - writeUleb128(os, 0, "num locals"); - for (const OutputSegment *seg : segments) - for (const InputSegment *inSeg : seg->inputSegments) - inSeg->generateRelocationCode(os); - writeU8(os, WASM_OPCODE_END, "END"); - } + for (auto i = 0; i < WasmSym::applyRelocFuncCount; i++) { + // First write the body's contents to a string. + std::string bodyContent; + { + raw_string_ostream os(bodyContent); + writeUleb128(os, 0, "num locals"); + for (const OutputSegment *seg : segments) + for (const InputSegment *inSeg : seg->inputSegments) + inSeg->generateRelocationCode(os, i, WasmSym::applyRelocFuncCount); + writeU8(os, WASM_OPCODE_END, "END"); + } - createFunction(WasmSym::applyRelocs, bodyContent); + createFunction(WasmSym::applyRelocFuncs[i], bodyContent); + } } // Create synthetic "__wasm_call_ctors" function based on ctor functions @@ -871,9 +873,11 @@ writeUleb128(os, 0, "num locals"); if (config->isPic) { - writeU8(os, WASM_OPCODE_CALL, "CALL"); - writeUleb128(os, WasmSym::applyRelocs->getFunctionIndex(), - "function index"); + for (auto i = 0; i < WasmSym::applyRelocFuncCount; i++) { + writeU8(os, WASM_OPCODE_CALL, "CALL"); + writeUleb128(os, WasmSym::applyRelocFuncs[i]->getFunctionIndex(), + "function index"); + } } // Call constructors