Index: test/wasm/pie.ll =================================================================== --- test/wasm/pie.ll +++ test/wasm/pie.ll @@ -11,7 +11,7 @@ @data_addr = local_unnamed_addr global i32* @data, align 4 @data_addr_external = local_unnamed_addr global i32* @data_external, align 4 -define i32 @foo() { +define hidden i32 @foo() { entry: ; To ensure we use __stack_pointer %ptr = alloca i32 Index: test/wasm/shared.ll =================================================================== --- test/wasm/shared.ll +++ test/wasm/shared.ll @@ -28,12 +28,12 @@ ret i32 %0 } -define default i32* @get_data_address() { +define hidden i32* @get_data_address() { entry: ret i32* @data_external } -define default i8* @get_func_address() { +define hidden i8* @get_func_address() { entry: ret i8* bitcast (void ()* @func_external to i8*) } @@ -54,7 +54,7 @@ ; CHECK-NEXT: Name: dylink ; CHECK-NEXT: MemorySize: 24 ; CHECK-NEXT: MemoryAlignment: 2 -; CHECK-NEXT: TableSize: 3 +; CHECK-NEXT: TableSize: 2 ; 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: 0x00000002 ; CHECK-NEXT: - Module: env ; CHECK-NEXT: Field: __stack_pointer ; CHECK-NEXT: Kind: GLOBAL @@ -95,7 +95,7 @@ ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: SigIndex: 1 ; CHECK-NEXT: - Module: GOT.mem -; CHECK-NEXT: Field: data_external +; CHECK-NEXT: Field: indirect_func ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: GlobalType: I32 ; CHECK-NEXT: GlobalMutable: true @@ -105,6 +105,11 @@ ; CHECK-NEXT: GlobalType: I32 ; CHECK-NEXT: GlobalMutable: true ; CHECK-NEXT: - Module: GOT.mem +; CHECK-NEXT: Field: data_external +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: GlobalType: I32 +; CHECK-NEXT: GlobalMutable: true +; CHECK-NEXT: - Module: GOT.mem ; CHECK-NEXT: Field: extern_struct ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: GlobalType: I32 @@ -124,7 +129,7 @@ ; CHECK-NEXT: - Offset: ; CHECK-NEXT: Opcode: GLOBAL_GET ; CHECK-NEXT: Index: 2 -; CHECK-NEXT: Functions: [ 5, 3, 0 ] +; CHECK-NEXT: Functions: [ 4, 3 ] ; check the generated code in __wasm_call_ctors and __wasm_apply_relocs functions ; TODO(sbc): Disassemble and verify instructions. @@ -136,7 +141,7 @@ ; CHECK-NEXT: Body: 10020B ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Locals: [] -; CHECK-NEXT: Body: 230141046A230241016A360200230141086A23043602002301410C6A230141006A360200230141106A2303360200230141146A230541046A3602000B +; CHECK-NEXT: Body: 230141046A230241016A360200230141086A23043602002301410C6A230141006A360200230141106A2305360200230141146A230641046A3602000B ; check the data segment initialized with __memory_base global as offset @@ -147,4 +152,4 @@ ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: GLOBAL_GET ; CHECK-NEXT: Index: 1 -; CHECK-NEXT: Content: '020000000100000002000000000000000000000000000000' +; CHECK-NEXT: Content: '020000000100000000000000000000000000000000000000' Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ 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: Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -1142,6 +1142,10 @@ registerType(E->Signature); } +static bool requiresGOTAccess(const Symbol* Sym) { + return Config->Pic && !Sym->isHidden() && !Sym->isLocal(); +} + void Writer::processRelocations(InputChunk *Chunk) { if (!Chunk->Live) return; @@ -1153,8 +1157,8 @@ 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; + if (Sym->hasTableIndex() || !Sym->hasFunctionIndex() || requiresGOTAccess(Sym)) + break; Sym->setTableIndex(TableBase + IndirectFunctions.size()); IndirectFunctions.emplace_back(Sym); break; @@ -1206,7 +1210,7 @@ // 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()) { + if (requiresGOTAccess(Sym) && !Sym->isInGOT()) { Sym->setGOTIndex(NumImportedGlobals++); GOTSymbols.push_back(Sym); }