Index: test/wasm/alias.ll =================================================================== --- /dev/null +++ test/wasm/alias.ll @@ -0,0 +1,66 @@ +; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s +; RUN: lld -flavor wasm %t.o -o %t.wasm +; RUN: obj2yaml %t.wasm | FileCheck %s + +@start_alias = alias i32 (), i32 ()* @_start + +; Function Attrs: nounwind uwtable +define i32 @_start() local_unnamed_addr #1 { +entry: + ret i32 0 +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Maximum: 0x00000001 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: start_alias +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Locals: +; CHECK-NEXT: Body: 41000B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: start_alias +; CHECK-NEXT: ... Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -39,7 +39,7 @@ }; Symbol(StringRef Name, uint32_t Flags) - : WrittenToSymtab(0), WrittenToNameSec(0), Flags(Flags), Name(Name) {} + : WrittenToSymtab(0), Flags(Flags), Name(Name) {} Kind getKind() const { return SymbolKind; } @@ -99,10 +99,9 @@ void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; } const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } - // This bit is used by Writer::writeNameSection() to prevent - // symbols from being written to the symbol table more than once. + // This bit is used to prevent symbols from being written to the symbol + // table more than once. unsigned WrittenToSymtab : 1; - unsigned WrittenToNameSec : 1; protected: uint32_t Flags; Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -18,6 +18,7 @@ #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" #include "lld/Common/Threads.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" @@ -436,13 +437,15 @@ void Writer::createNameSection() { // Create an array of all function sorted by function index space std::vector Names; + llvm::DenseSet Seen; for (ObjFile *File : Symtab->ObjectFiles) { Names.reserve(Names.size() + File->getSymbols().size()); for (Symbol *S : File->getSymbols()) { - if (!S->isFunction() || S->isWeak() || S->WrittenToNameSec) + if (!S->isFunction() || S->isWeak()) + continue; + if (!Seen.insert(S->getOutputIndex()).second) continue; - S->WrittenToNameSec = true; Names.emplace_back(S); } }