mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[lld][WebAssembly] Perform data relocations during start function
We already perform memory initialization and apply global relocations during start. It makes sense to performs data relocations too. I think the reason we were not doing this already is solely historical. Differential Revision: https://reviews.llvm.org/D117412
This commit is contained in:
@@ -1022,7 +1022,16 @@ void Writer::createSyntheticInitFunctions() {
|
||||
}
|
||||
}
|
||||
|
||||
if (WasmSym::applyGlobalRelocs && WasmSym::initMemory) {
|
||||
int startCount = 0;
|
||||
if (WasmSym::applyGlobalRelocs)
|
||||
startCount++;
|
||||
if (WasmSym::WasmSym::initMemory || WasmSym::applyDataRelocs)
|
||||
startCount++;
|
||||
|
||||
// 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 (startCount > 1) {
|
||||
WasmSym::startFunction = symtab->addSyntheticFunction(
|
||||
"__wasm_start", WASM_SYMBOL_VISIBILITY_HIDDEN,
|
||||
make<SyntheticFunction>(nullSignature, "__wasm_start"));
|
||||
@@ -1179,6 +1188,14 @@ void Writer::createInitMemoryFunction() {
|
||||
}
|
||||
}
|
||||
|
||||
// Memory init is now complete. Apply data relocation if there
|
||||
// are any.
|
||||
if (WasmSym::applyDataRelocs) {
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::applyDataRelocs->getFunctionIndex(),
|
||||
"function index");
|
||||
}
|
||||
|
||||
if (config->sharedMemory) {
|
||||
// Set flag to 2 to mark end of initialization
|
||||
writeGetFlagAddress();
|
||||
@@ -1231,17 +1248,28 @@ void Writer::createInitMemoryFunction() {
|
||||
}
|
||||
|
||||
void Writer::createStartFunction() {
|
||||
// If the start function exists when we have more than one function to call.
|
||||
if (WasmSym::startFunction) {
|
||||
std::string bodyContent;
|
||||
{
|
||||
raw_string_ostream os(bodyContent);
|
||||
writeUleb128(os, 0, "num locals");
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::initMemory->getFunctionIndex(),
|
||||
"function index");
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::applyGlobalRelocs->getFunctionIndex(),
|
||||
"function index");
|
||||
if (WasmSym::initMemory) {
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::initMemory->getFunctionIndex(),
|
||||
"function index");
|
||||
} else if (WasmSym::applyDataRelocs) {
|
||||
// When initMemory is present it calls applyDataRelocs. If not,
|
||||
// we must call it directly.
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::applyDataRelocs->getFunctionIndex(),
|
||||
"function index");
|
||||
}
|
||||
if (WasmSym::applyGlobalRelocs) {
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::applyGlobalRelocs->getFunctionIndex(),
|
||||
"function index");
|
||||
}
|
||||
writeU8(os, WASM_OPCODE_END, "END");
|
||||
}
|
||||
createFunction(WasmSym::startFunction, bodyContent);
|
||||
@@ -1249,6 +1277,8 @@ void Writer::createStartFunction() {
|
||||
WasmSym::startFunction = WasmSym::initMemory;
|
||||
} else if (WasmSym::applyGlobalRelocs) {
|
||||
WasmSym::startFunction = WasmSym::applyGlobalRelocs;
|
||||
} else if (WasmSym::applyDataRelocs) {
|
||||
WasmSym::startFunction = WasmSym::applyDataRelocs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,8 +1341,7 @@ void Writer::createCallCtorsFunction() {
|
||||
// If __wasm_call_ctors isn't referenced, there aren't any ctors, and we
|
||||
// aren't calling `__wasm_apply_data_relocs` for Emscripten-style PIC, don't
|
||||
// define the `__wasm_call_ctors` function.
|
||||
if (!WasmSym::callCtors->isLive() && !WasmSym::applyDataRelocs &&
|
||||
initFunctions.empty())
|
||||
if (!WasmSym::callCtors->isLive() && initFunctions.empty())
|
||||
return;
|
||||
|
||||
// First write the body's contents to a string.
|
||||
@@ -1321,7 +1350,7 @@ void Writer::createCallCtorsFunction() {
|
||||
raw_string_ostream os(bodyContent);
|
||||
writeUleb128(os, 0, "num locals");
|
||||
|
||||
if (WasmSym::applyDataRelocs) {
|
||||
if (WasmSym::applyDataRelocs && !WasmSym::initMemory) {
|
||||
writeU8(os, WASM_OPCODE_CALL, "CALL");
|
||||
writeUleb128(os, WasmSym::applyDataRelocs->getFunctionIndex(),
|
||||
"function index");
|
||||
|
||||
Reference in New Issue
Block a user