Index: test/wasm/lto/Inputs/archive.ll =================================================================== --- /dev/null +++ test/wasm/lto/Inputs/archive.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define void @f() { + ret void +} Index: test/wasm/lto/archive.ll =================================================================== --- /dev/null +++ test/wasm/lto/archive.ll @@ -0,0 +1,25 @@ +; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o +; RUN: rm -f %t.a +; RUN: llvm-ar rcs %t.a %t1.o +; RUN: llvm-as %s -o %t2.o +; RUN: wasm-ld %t2.o %t.a -o %t3 +; RUN: obj2yaml %t3 | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define void @_start() { + call void @f() + ret void +} + +declare void @f() + +; CHECK: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __wasm_call_ctors +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: f Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -360,12 +360,18 @@ "could not get the buffer for the member defining symbol " + Sym->getName()); - if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) { + InputFile *Obj; + + file_magic Magic = identify_magic(MB.getBuffer()); + if (Magic == file_magic::wasm_object) { + Obj = make(MB); + } else if (Magic == file_magic::bitcode) { + Obj = make(MB); + } else { error("unknown file type: " + MB.getBufferIdentifier()); return; } - InputFile *Obj = make(MB); Obj->ParentName = ParentName; Symtab->addFile(Obj); } Index: wasm/LTO.cpp =================================================================== --- wasm/LTO.cpp +++ wasm/LTO.cpp @@ -95,7 +95,8 @@ // Once IRObjectFile is fixed to report only one symbol this hack can // be removed. R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F; - R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj; + R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || + (R.Prevailing && Sym->includeInExports()); if (R.Prevailing) undefine(Sym); } Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -90,6 +90,7 @@ void setOutputSymbolIndex(uint32_t Index); WasmSymbolType getWasmType() const; + bool includeInExports() const; // True if this symbol was referenced by a regular (non-bitcode) object. unsigned IsUsedInRegularObj : 1; Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -98,6 +98,16 @@ Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; } +bool Symbol::includeInExports() const { + if (!isDefined()) + return false; + if (isHidden() && !Config->ExportAll) + return false; + if (isLocal()) + return false; + return true; +} + uint32_t FunctionSymbol::getFunctionIndex() const { if (auto *F = dyn_cast(this)) return F->Function->getFunctionIndex(); Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -740,11 +740,7 @@ unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isDefined()) - continue; - if (Sym->isHidden() && !Config->ExportAll) - continue; - if (Sym->isLocal()) + if (!Sym->includeInExports()) continue; if (!Sym->isLive()) continue;