diff --git a/lld/test/wasm/shared.ll b/lld/test/wasm/shared.ll --- a/lld/test/wasm/shared.ll +++ b/lld/test/wasm/shared.ll @@ -12,7 +12,7 @@ @data_addr = local_unnamed_addr global i32* @data, align 4 @data_addr_external = local_unnamed_addr global i32* @data_external, align 4 -define default i32 @foo() { +define hidden i32 @foo() { entry: ; To ensure we use __stack_pointer %ptr = alloca i32 diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -327,17 +327,18 @@ break; case R_WASM_MEMORY_ADDR_I32: { Symbol *Sym = File->getSymbol(Rel); - if (Sym->isUndefined()) { - // Undefined addresses are accessed via imported GOT globals - writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); - writeUleb128(OS, Sym->getGOTIndex(), "global index"); - } else { - // Defined global data is accessed via known offset from __memory_base + if (Sym->isLocal() || Sym->isHidden()) { + // Hidden/Local data symbols are accessed via known offset from + // __memory_base writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); writeUleb128(OS, WasmSym::MemoryBase->getGlobalIndex(), "memory_base"); writeU8(OS, WASM_OPCODE_I32_CONST, "CONST"); writeSleb128(OS, File->calcNewValue(Rel), "new memory offset"); writeU8(OS, WASM_OPCODE_I32_ADD, "ADD"); + } else { + // Default data symbols are accessed via imported GOT globals + writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET"); + writeUleb128(OS, Sym->getGOTIndex(), "global index"); } break; } diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -1162,22 +1162,33 @@ } if (Config->Pic) { - // Certain relocation types can't be used when building PIC output, since - // they would require absolute symbol addresses at link time. switch (Reloc.Type) { case R_WASM_TABLE_INDEX_SLEB: case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_LEB: { + // Certain relocation types can't be used when building PIC output, since + // they would require absolute symbol addresses at link time. Symbol *Sym = File->getSymbols()[Reloc.Index]; error(toString(File) + ": relocation " + relocTypeToString(Reloc.Type) + " cannot be used againt symbol " + toString(*Sym) + "; recompile with -fPIC"); break; } + case R_WASM_TABLE_INDEX_I32: + case R_WASM_MEMORY_ADDR_I32: { + // These relocation types are only present in the data section and + // will be converted into code by `generateRelocationCode`. This code + // requires the symbols to have GOT entires. + auto* Sym = File->getSymbols()[Reloc.Index]; + if (!Sym->isHidden() && !Sym->isLocal() && !Sym->isInGOT()) { + Sym->setGOTIndex(NumImportedGlobals++); + GOTSymbols.push_back(Sym); + } + break; + } } } } - } void Writer::assignIndexes() {