Index: test/wasm/undefined-weak-call.test =================================================================== --- /dev/null +++ test/wasm/undefined-weak-call.test @@ -0,0 +1,47 @@ +# RUN: yaml2obj %s > %t.o +# RUN: not lld -flavor wasm --no-entry %t.o -o %t.wasm 2>&1 | FileCheck %s + +# Check linking fails when the input file contains weak symbols, and relocations +# which reference those symbols and cannot be resolved. + +# CHECK: Cannot generate relocation against undefined function: weakFunc + +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: TYPE + Signatures: + - Index: 0 + ReturnType: NORESULT + ParamTypes: + - Type: IMPORT + Imports: + - Module: env + Field: weakFunc + Kind: FUNCTION + SigIndex: 0 + - Type: FUNCTION + FunctionTypes: [ 0 ] + - Type: CODE + Relocations: + - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB + Index: 0 + Offset: 0x00000004 + Functions: + - Index: 1 + Locals: + Body: 1080808080000F0B + - Type: CUSTOM + Name: linking + SymbolTable: + - Index: 0 + Kind: FUNCTION + Name: weakFunc + Flags: [ UNDEFINED, BINDING_WEAK ] + Function: 0 + - Index: 1 + Kind: FUNCTION + Name: callWeakFunc + Flags: [ ] + Function: 1 Index: test/wasm/undefined-weak-getglobal.test =================================================================== --- /dev/null +++ test/wasm/undefined-weak-getglobal.test @@ -0,0 +1,48 @@ +# RUN: yaml2obj %s > %t.o +# RUN: not lld -flavor wasm --no-entry %t.o -o %t.wasm 2>&1 | FileCheck %s + +# Check linking fails when the input file contains weak symbols, and relocations +# which reference those symbols and cannot be resolved. + +# CHECK: Cannot generate relocation against undefined global: weakGlobal + +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: TYPE + Signatures: + - Index: 0 + ReturnType: NORESULT + ParamTypes: + - Type: IMPORT + Imports: + - Module: env + Field: weakGlobal + Kind: GLOBAL + GlobalType: I32 + GlobalMutable: true + - Type: FUNCTION + FunctionTypes: [ 0 ] + - Type: CODE + Relocations: + - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB + Index: 0 + Offset: 0x00000004 + Functions: + - Index: 0 + Locals: + Body: 2380808080001A0F0B + - Type: CUSTOM + Name: linking + SymbolTable: + - Index: 0 + Kind: GLOBAL + Name: weakGlobal + Flags: [ UNDEFINED, BINDING_WEAK ] + Global: 0 + - Index: 1 + Kind: FUNCTION + Name: getWeakGlobal + Flags: [ ] + Function: 0 Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -81,10 +81,28 @@ return Reloc.Addend; case R_WEBASSEMBLY_TYPE_INDEX_LEB: return TypeMap[Reloc.Index]; - case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: - return getFunctionSymbol(Reloc.Index)->getOutputIndex(); - case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: - return getGlobalSymbol(Reloc.Index)->getOutputIndex(); + case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: { + Symbol *Sym = getFunctionSymbol(Reloc.Index); + if (!Sym->hasOutputIndex()) { + // This happens if someone tries to use a `call` instruction to invoke a + // weak undefined function: if it's not found in the final link, then we + // must fail because there's nothing for the `call` to target. + fatal("Cannot generate relocation against undefined function: " + + toString(*Sym)); + } + return Sym->getOutputIndex(); + } + case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: { + Symbol *Sym = getGlobalSymbol(Reloc.Index); + if (!Sym->hasOutputIndex()) { + // This happens if someone tries to use a `get/set_global` instruction to + // use a weak undefined global: if it's not found in the final link, then + // we must fail because there's nothing for the instruction to target. + fatal("Cannot generate relocation against undefined global: " + + toString(*Sym)); + } + return Sym->getOutputIndex(); + } default: llvm_unreachable("unknown relocation type"); }