Index: test/wasm/undefined.ll =================================================================== --- test/wasm/undefined.ll +++ test/wasm/undefined.ll @@ -2,25 +2,44 @@ ; RUN: wasm-ld --check-signatures --allow-undefined -o %t.wasm %t.o ; Fails due to undefined 'foo' and also 'baz' -; RUN: not wasm-ld --check-signatures --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s -; CHECK: error: {{.*}}.o: undefined symbol: foo -; CHECK: error: undefined symbol: baz +; RUN: not wasm-ld --check-signatures --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR +; CHECK-ERROR: error: {{.*}}.o: undefined symbol: foo +; CHECK-ERROR: error: {{.*}}.o: undefined symbol: bar +; CHECK-ERROR: error: undefined symbol: baz ; Succeeds if we pass a file containing 'foo' as --allow-undefined-file. ; RUN: echo 'foo' > %t.txt +; RUN: echo 'bar' >> %t.txt ; RUN: wasm-ld --check-signatures --allow-undefined-file=%t.txt -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s ; Succeeds even if a missing symbol is added via --export ; RUN: wasm-ld --check-signatures --allow-undefined --export=xxx -o %t.wasm %t.o target triple = "wasm32-unknown-unknown-wasm" -; Takes the address of the external foo() resulting in undefined external -@bar = hidden local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4 +; Takes the address of the external function foo() +@addr_func = local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4 + +; Take the address of the external_data +@addr_data = local_unnamed_addr global i32* @bar, align 4 declare i32 @foo() #0 +@bar = external global i32 -define hidden void @_start() local_unnamed_addr #0 { +define void @_start() local_unnamed_addr #0 { entry: ret void } + +; CHECK: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: bar +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: GlobalType: I32 +; CHECK-NEXT: GlobalMutable: false Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -91,7 +91,6 @@ void Symbol::setOutputIndex(uint32_t Index) { DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); - assert(!isa(this)); assert(OutputIndex == INVALID_INDEX); OutputIndex = Index; } Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -183,10 +183,13 @@ if (auto *FunctionSym = dyn_cast(Sym)) { Import.Kind = WASM_EXTERNAL_FUNCTION; Import.SigIndex = lookupType(*FunctionSym->getFunctionType()); - } else { - auto *GlobalSym = cast(Sym); + } else if (auto *GlobalSym = dyn_cast(Sym)) { Import.Kind = WASM_EXTERNAL_GLOBAL; Import.Global = *GlobalSym->getGlobalType(); + } else { + assert(isa(Sym)); + Import.Kind = WASM_EXTERNAL_GLOBAL; + Import.Global = {WASM_TYPE_I32, false}; } writeImport(OS, Import); } @@ -651,7 +654,9 @@ for (Symbol *Sym : Symtab->getSymbols()) { if (!Sym->isUndefined()) continue; - if (isa(Sym)) + // For data symbols we don't use imports in the relocatable output, instead + // these are in the explict symbol table. + if (isa(Sym) && Config->Relocatable) continue; if (Sym->isWeak() && !Config->Relocatable) continue;