Index: lld/trunk/test/wasm/undefined-weak-call.ll =================================================================== --- lld/trunk/test/wasm/undefined-weak-call.ll +++ lld/trunk/test/wasm/undefined-weak-call.ll @@ -1,5 +1,6 @@ ; RUN: llc -filetype=obj %s -o %t.o -; RUN: wasm-ld --check-signatures --no-entry %t.o -o %t.wasm +; RUN: wasm-ld --check-signatures --no-entry --print-gc-sections %t.o \ +; RUN: -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s ; RUN: obj2yaml %t.wasm | FileCheck %s ; Check that calling an undefined weak function generates an appropriate stub @@ -12,6 +13,8 @@ declare extern_weak void @weakFunc3(i32 %arg) ; different declare extern_weak void @weakFunc4() ; should be GC'd as not called +; CHECK-GC: removing unused section {{.*}}:(weakFunc4) + define i32 @callWeakFuncs() { call void @weakFunc1() call void @weakFunc2() Index: lld/trunk/wasm/Driver.cpp =================================================================== --- lld/trunk/wasm/Driver.cpp +++ lld/trunk/wasm/Driver.cpp @@ -240,10 +240,11 @@ // Add a synthetic dummy for weak undefined functions. These dummies will // be GC'd if not used as the target of any "call" instructions. Optional SymName = demangleItanium(Sym->getName()); - StringRef StubName = + StringRef DebugName = Saver.save("undefined function " + (SymName ? StringRef(*SymName) : Sym->getName())); - SyntheticFunction *Func = make(Sig, StubName); + SyntheticFunction *Func = + make(Sig, Sym->getName(), DebugName); Func->setBody(UnreachableFn); // Ensure it compares equal to the null pointer, and so that table relocs // don't pull in the stub body (only call-operand relocs should do that). Index: lld/trunk/wasm/InputChunks.h =================================================================== --- lld/trunk/wasm/InputChunks.h +++ lld/trunk/wasm/InputChunks.h @@ -57,6 +57,7 @@ ArrayRef getRelocations() const { return Relocations; } virtual StringRef getName() const = 0; + virtual StringRef getDebugName() const = 0; virtual uint32_t getComdat() const = 0; StringRef getComdatName() const; @@ -99,6 +100,7 @@ uint32_t getAlignment() const { return Segment.Data.Alignment; } StringRef getName() const override { return Segment.Data.Name; } + StringRef getDebugName() const override { return StringRef(); } uint32_t getComdat() const override { return Segment.Data.Comdat; } const OutputSegment *OutputSeg = nullptr; @@ -125,7 +127,8 @@ C->kind() == InputChunk::SyntheticFunction; } - StringRef getName() const override { return Function->Name; } + StringRef getName() const override { return Function->SymbolName; } + StringRef getDebugName() const override { return Function->DebugName; } uint32_t getComdat() const override { return Function->Comdat; } uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); } bool hasFunctionIndex() const { return FunctionIndex.hasValue(); } @@ -152,8 +155,9 @@ class SyntheticFunction : public InputFunction { public: - SyntheticFunction(const WasmSignature &S, StringRef Name) - : InputFunction(S, nullptr, nullptr), Name(Name) { + SyntheticFunction(const WasmSignature &S, StringRef Name, + StringRef DebugName = {}) + : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) { SectionKind = InputChunk::SyntheticFunction; } @@ -162,6 +166,7 @@ } StringRef getName() const override { return Name; } + StringRef getDebugName() const override { return DebugName; } uint32_t getComdat() const override { return UINT32_MAX; } void setBody(ArrayRef Body_) { Body = Body_; } @@ -170,6 +175,7 @@ ArrayRef data() const override { return Body; } StringRef Name; + StringRef DebugName; ArrayRef Body; }; @@ -182,6 +188,7 @@ } StringRef getName() const override { return Section.Name; } + StringRef getDebugName() const override { return StringRef(); } uint32_t getComdat() const override { return UINT32_MAX; } protected: Index: lld/trunk/wasm/MarkLive.cpp =================================================================== --- lld/trunk/wasm/MarkLive.cpp +++ lld/trunk/wasm/MarkLive.cpp @@ -105,5 +105,8 @@ if (!C->Live) message("removing unused section " + toString(C)); } + for (InputChunk *C : Symtab->SyntheticFunctions) + if (!C->Live) + message("removing unused section " + toString(C)); } } Index: lld/trunk/wasm/Writer.cpp =================================================================== --- lld/trunk/wasm/Writer.cpp +++ lld/trunk/wasm/Writer.cpp @@ -534,7 +534,7 @@ void Writer::createNameSection() { unsigned NumNames = NumImportedFunctions; for (const InputFunction *F : InputFunctions) - if (!F->getName().empty()) + if (!F->getName().empty() || !F->getDebugName().empty()) ++NumNames; if (NumNames == 0) @@ -558,8 +558,12 @@ for (const InputFunction *F : InputFunctions) { if (!F->getName().empty()) { writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); - Optional Name = demangleItanium(F->getName()); - writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name"); + if (!F->getDebugName().empty()) { + writeStr(Sub.OS, F->getDebugName(), "symbol name"); + } else { + Optional Name = demangleItanium(F->getName()); + writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name"); + } } }