Index: lld/trunk/wasm/Config.h =================================================================== --- lld/trunk/wasm/Config.h +++ lld/trunk/wasm/Config.h @@ -70,6 +70,12 @@ // True if we are creating position-independent code. bool isPic; + + // The table offset at which to place function addresses. We reserve zero + // for the null function pointer. This gets set to 1 for exectuables and 0 + // for shared libraries (since they always added to a dynamic offset at + // runtime). + uint32_t tableBase = 0; }; // The only instance of Configuration struct. Index: lld/trunk/wasm/SyntheticSections.h =================================================================== --- lld/trunk/wasm/SyntheticSections.h +++ lld/trunk/wasm/SyntheticSections.h @@ -219,13 +219,12 @@ class ElemSection : public SyntheticSection { public: - ElemSection(uint32_t offset) - : SyntheticSection(llvm::wasm::WASM_SEC_ELEM), elemOffset(offset) {} + ElemSection() + : SyntheticSection(llvm::wasm::WASM_SEC_ELEM) {} bool isNeeded() const override { return indirectFunctions.size() > 0; }; void writeBody() override; void addEntry(FunctionSymbol *sym); uint32_t numEntries() const { return indirectFunctions.size(); } - uint32_t elemOffset; protected: std::vector indirectFunctions; Index: lld/trunk/wasm/SyntheticSections.cpp =================================================================== --- lld/trunk/wasm/SyntheticSections.cpp +++ lld/trunk/wasm/SyntheticSections.cpp @@ -143,7 +143,7 @@ } if (config->importTable) { - uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); + uint32_t tableSize = config->tableBase + out.elemSec->numEntries(); WasmImport import; import.Module = defaultModule; import.Field = functionTableName; @@ -212,7 +212,7 @@ } void TableSection::writeBody() { - uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); + uint32_t tableSize = config->tableBase + out.elemSec->numEntries(); raw_ostream &os = bodyOutputStream; writeUleb128(os, 1, "table count"); @@ -313,7 +313,7 @@ void ElemSection::addEntry(FunctionSymbol *sym) { if (sym->hasTableIndex()) return; - sym->setTableIndex(elemOffset + indirectFunctions.size()); + sym->setTableIndex(config->tableBase + indirectFunctions.size()); indirectFunctions.emplace_back(sym); } @@ -328,12 +328,12 @@ initExpr.Value.Global = WasmSym::tableBase->getGlobalIndex(); } else { initExpr.Opcode = WASM_OPCODE_I32_CONST; - initExpr.Value.Int32 = elemOffset; + initExpr.Value.Int32 = config->tableBase; } writeInitExpr(os, initExpr); writeUleb128(os, indirectFunctions.size(), "elem count"); - uint32_t tableIndex = elemOffset; + uint32_t tableIndex = config->tableBase; for (const FunctionSymbol *sym : indirectFunctions) { assert(sym->getTableIndex() == tableIndex); writeUleb128(os, sym->getFunctionIndex(), "function index"); Index: lld/trunk/wasm/Writer.cpp =================================================================== --- lld/trunk/wasm/Writer.cpp +++ lld/trunk/wasm/Writer.cpp @@ -87,7 +87,6 @@ void writeSections(); uint64_t fileSize = 0; - uint32_t tableBase = 0; std::vector initFunctions; llvm::StringMap> customSectionMapping; @@ -852,7 +851,7 @@ out.globalSec = make(); out.eventSec = make(); out.exportSec = make(); - out.elemSec = make(tableBase); + out.elemSec = make(); out.dataCountSec = make(segments.size()); out.linkingSec = make(initFunctions, segments); out.nameSec = make(); @@ -867,9 +866,9 @@ // 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 (!config->isPic) { - tableBase = 1; + config->tableBase = 1; if (WasmSym::definedTableBase) - WasmSym::definedTableBase->setVirtualAddress(tableBase); + WasmSym::definedTableBase->setVirtualAddress(config->tableBase); } log("-- createOutputSegments");