Index: test/wasm/lto/relocatable-undefined.ll =================================================================== --- /dev/null +++ test/wasm/lto/relocatable-undefined.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as %s -o %t.o +; RUN: wasm-ld -r -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +@missing_data = external global i32 +declare i32 @missing_func() local_unnamed_addr + +define i32 @foo() { +entry: + %0 = call i32 @missing_func() + %1 = load i32, i32* @missing_data, align 4 + ret i32 %1 +} + + +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: Version: 2 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Function: 1 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: missing_func +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 0 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: missing_data +; CHECK-NEXT: Flags: [ UNDEFINED ] Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -70,6 +70,7 @@ assert(TypeIsUsed[Reloc.Index]); return TypeMap[Reloc.Index]; } + LLVM_DEBUG(dbgs() << "calcNewIndex: " << toString(*Symbols[Reloc.Index]) << "\n"); return Symbols[Reloc.Index]->getOutputSymbolIndex(); } Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -935,6 +935,25 @@ } } + // Undefined symbols from bitcode input files can still exist in the final + // output. For defined symbols these get replaces with the symbols in the LTO + // object itself. + for (BitcodeFile *File : Symtab->BitcodeFiles) { + LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n"); + for (Symbol *Sym : File->getSymbols()) { + if (Sym->getFile() != File) + continue; + + assert(Sym->isUndefined()); + + // (Since this is relocatable output, GC is not performed so symbols must + // be live.) + assert(Sym->isLive()); + Sym->setOutputSymbolIndex(SymbolIndex++); + SymtabEntries.emplace_back(Sym); + } + } + // For the moment, relocatable output doesn't contain any synthetic functions, // so no need to look through the Symtab for symbols not referenced by // Symtab->ObjectFiles.