diff --git a/lld/test/wasm/pie.ll b/lld/test/wasm/pie.ll --- a/lld/test/wasm/pie.ll +++ b/lld/test/wasm/pie.ll @@ -38,7 +38,7 @@ ; CHECK-NEXT: Table: ; CHECK-NEXT: ElemType: FUNCREF ; CHECK-NEXT: Limits: -; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Initial: 0x00000000 ; CHECK-NEXT: - Module: env ; CHECK-NEXT: Field: __memory_base ; CHECK-NEXT: Kind: GLOBAL 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 @@ -54,7 +54,7 @@ ; CHECK-NEXT: Name: dylink ; CHECK-NEXT: MemorySize: 24 ; CHECK-NEXT: MemoryAlignment: 2 -; CHECK-NEXT: TableSize: 3 +; CHECK-NEXT: TableSize: 1 ; CHECK-NEXT: TableAlignment: 0 ; CHECK-NEXT: Needed: [] ; CHECK-NEXT: - Type: TYPE @@ -74,7 +74,7 @@ ; CHECK-NEXT: Table: ; CHECK-NEXT: ElemType: FUNCREF ; CHECK-NEXT: Limits: -; CHECK-NEXT: Initial: 0x00000003 +; CHECK-NEXT: Initial: 0x00000001 ; CHECK-NEXT: - Module: env ; CHECK-NEXT: Field: __stack_pointer ; CHECK-NEXT: Kind: GLOBAL @@ -124,7 +124,7 @@ ; CHECK-NEXT: - Offset: ; CHECK-NEXT: Opcode: GLOBAL_GET ; CHECK-NEXT: Index: 2 -; CHECK-NEXT: Functions: [ 5, 3, 0 ] +; CHECK-NEXT: Functions: [ 5 ] ; check the generated code in __wasm_call_ctors and __wasm_apply_relocs functions ; TODO(sbc): Disassemble and verify instructions. @@ -136,7 +136,7 @@ ; CHECK-NEXT: Body: 10020B ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 230141046A230241016A360200230141086A23043602002301410C6A230141006A360200230141106A2303360200230141146A230541046A3602000B +; CHECK-NEXT: Body: 230141046A230241006A360200230141086A23043602002301410C6A230141006A360200230141106A2303360200230141146A230541046A3602000B ; check the data segment initialized with __memory_base global as offset @@ -147,4 +147,4 @@ ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: GLOBAL_GET ; CHECK-NEXT: Index: 1 -; CHECK-NEXT: Content: '020000000100000002000000000000000000000000000000' +; CHECK-NEXT: Content: '020000000000000000000000000000000000000000000000' diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -171,6 +171,8 @@ case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: + if (Config->Pic && !getFunctionSymbol(Reloc.Index)->hasTableIndex()) + return 0; return getFunctionSymbol(Reloc.Index)->getTableIndex(); case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -1148,35 +1148,40 @@ ObjFile *File = Chunk->File; ArrayRef Types = File->getWasmObj()->types(); for (const WasmRelocation &Reloc : Chunk->getRelocations()) { + if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) { + // Mark target type as live + File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]); + File->TypeIsUsed[Reloc.Index] = true; + continue; + } + + // Other relocation types all have a corresponding symbol + auto* Sym = File->getSymbols()[Reloc.Index]; switch (Reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: case R_WASM_TABLE_INDEX_REL_SLEB: { - FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index); - if (Sym->hasTableIndex() || !Sym->hasFunctionIndex()) - continue; - Sym->setTableIndex(TableBase + IndirectFunctions.size()); - IndirectFunctions.emplace_back(Sym); + if (Config->Pic && Reloc.Type != R_WASM_TABLE_INDEX_REL_SLEB) + break; + auto *F = cast(Sym); + if (F->hasTableIndex() || !F->hasFunctionIndex()) + break; + F->setTableIndex(TableBase + IndirectFunctions.size()); + IndirectFunctions.emplace_back(F); break; } case R_WASM_TYPE_INDEX_LEB: - // Mark target type as live - File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]); - File->TypeIsUsed[Reloc.Index] = true; break; - case R_WASM_GLOBAL_INDEX_LEB: { - auto* Sym = File->getSymbols()[Reloc.Index]; + case R_WASM_GLOBAL_INDEX_LEB: if (!isa(Sym) && !Sym->isInGOT()) { Sym->setGOTIndex(NumImportedGlobals++); GOTSymbols.push_back(Sym); } break; - } case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_LEB: - case R_WASM_MEMORY_ADDR_REL_SLEB: { + case R_WASM_MEMORY_ADDR_REL_SLEB: if (!Config->Relocatable) { - auto* Sym = File->getSymbols()[Reloc.Index]; if (Sym->isUndefined() && !Sym->isWeak()) { error(toString(File) + ": cannot resolve relocation of type " + relocTypeToString(Reloc.Type) + @@ -1185,34 +1190,29 @@ } break; } - } if (Config->Pic) { switch (Reloc.Type) { case R_WASM_TABLE_INDEX_SLEB: case R_WASM_MEMORY_ADDR_SLEB: - case R_WASM_MEMORY_ADDR_LEB: { + 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: { + 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; } - } } } }