Index: test/wasm/alias.ll =================================================================== --- test/wasm/alias.ll +++ test/wasm/alias.ll @@ -68,7 +68,7 @@ ; CHECK-NEXT: Name: name ; CHECK-NEXT: FunctionNames: ; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Name: start_alias +; CHECK-NEXT: Name: _start ; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Name: __wasm_call_ctors ; CHECK-NEXT: ... Index: test/wasm/archive.ll =================================================================== --- test/wasm/archive.ll +++ test/wasm/archive.ll @@ -27,10 +27,7 @@ ; correctly. ; CHECK: 00000003 T _start -; CHECK-NEXT: 00000003 T _start ; CHECK-NEXT: 00000001 T bar -; CHECK-NEXT: 00000001 T bar -; CHECK-NEXT: 00000002 T foo ; CHECK-NEXT: 00000002 T foo ; Verify that symbols from unused objects don't appear in the symbol table Index: test/wasm/relocatable.ll =================================================================== --- test/wasm/relocatable.ll +++ test/wasm/relocatable.ll @@ -239,4 +239,6 @@ ; CHECK-NEXT: Name: hello ; CHECK-NEXT: - Index: 3 ; CHECK-NEXT: Name: my_func +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Name: func_comdat ; CHECK-NEXT: ... Index: test/wasm/weak-symbols.ll =================================================================== --- test/wasm/weak-symbols.ll +++ test/wasm/weak-symbols.ll @@ -105,8 +105,12 @@ ; CHECK-NEXT: FunctionNames: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: weakFn ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Name: exportWeak1 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Name: weakFn ; CHECK-NEXT: - Index: 4 ; CHECK-NEXT: Name: exportWeak2 ; CHECK-NEXT: - Index: 5 Index: wasm/InputChunks.h =================================================================== --- wasm/InputChunks.h +++ wasm/InputChunks.h @@ -34,10 +34,13 @@ class InputChunk { public: - virtual uint32_t getSize() const = 0; + virtual StringRef getName() const = 0; + virtual ArrayRef data() const = 0; + virtual StringRef getComdat() const = 0; void copyRelocations(const WasmSection &Section); + uint32_t getSize() const { return data().size(); } void writeTo(uint8_t *SectionStart) const; void setOutputOffset(uint32_t Offset) { @@ -47,7 +50,6 @@ uint32_t getOutputOffset() const { return OutputOffset; } - virtual StringRef getComdat() const = 0; bool Discarded = false; std::vector OutRelocations; @@ -56,7 +58,6 @@ InputChunk(const ObjFile *F) : File(F) {} virtual ~InputChunk() = default; void calcRelocations(); - virtual ArrayRef data() const = 0; virtual uint32_t getInputSectionOffset() const = 0; std::vector Relocations; @@ -77,6 +78,10 @@ InputSegment(const WasmSegment &Seg, const ObjFile *F) : InputChunk(F), Segment(Seg) {} + StringRef getName() const override { return Segment.Data.Name; } + ArrayRef data() const override { return Segment.Data.Content; } + StringRef getComdat() const override { return Segment.Data.Comdat; } + // Translate an offset in the input segment to an offset in the output // segment. uint32_t translateVA(uint32_t Address) const; @@ -88,17 +93,13 @@ OutputSegmentOffset = Offset; } - uint32_t getSize() const override { return Segment.Data.Content.size(); } uint32_t getAlignment() const { return Segment.Data.Alignment; } uint32_t startVA() const { return Segment.Data.Offset.Value.Int32; } uint32_t endVA() const { return startVA() + getSize(); } - StringRef getName() const { return Segment.Data.Name; } - StringRef getComdat() const override { return Segment.Data.Comdat; } int32_t OutputSegmentOffset = 0; protected: - ArrayRef data() const override { return Segment.Data.Content; } uint32_t getInputSectionOffset() const override { return Segment.SectionOffset; } @@ -113,22 +114,21 @@ public: InputFunction(const WasmSignature &S, const WasmFunction *Func, const ObjFile *F) - : InputChunk(F), Signature(S), WrittenToNameSec(false), Function(Func) {} + : InputChunk(F), Signature(S), Function(Func) {} - uint32_t getSize() const override { return Function->Size; } + StringRef getName() const override { return Function->Name; } + ArrayRef data() const override { + return File->CodeSection->Content.slice(getInputSectionOffset(), Function->Size); + } StringRef getComdat() const override { return Function->Comdat; } - uint32_t getOutputIndex() const { return OutputIndex.getValue(); }; - bool hasOutputIndex() const { return OutputIndex.hasValue(); }; + + uint32_t getOutputIndex() const { return OutputIndex.getValue(); } + bool hasOutputIndex() const { return OutputIndex.hasValue(); } void setOutputIndex(uint32_t Index); const WasmSignature &Signature; - unsigned WrittenToNameSec : 1; - protected: - ArrayRef data() const override { - return File->CodeSection->Content.slice(getInputSectionOffset(), getSize()); - } uint32_t getInputSectionOffset() const override { return Function->CodeSectionOffset; } @@ -139,14 +139,15 @@ class SyntheticFunction : public InputFunction { public: - SyntheticFunction(const WasmSignature &S, ArrayRef Body) - : InputFunction(S, nullptr, nullptr), Body(Body) {} + SyntheticFunction(const WasmSignature &S, ArrayRef Body, + StringRef Name) + : InputFunction(S, nullptr, nullptr), Name(Name), Body(Body) {} - uint32_t getSize() const override { return Body.size(); } - -protected: + StringRef getName() const override { return Name; } ArrayRef data() const override { return Body; } +protected: + StringRef Name; ArrayRef Body; }; Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -252,9 +252,6 @@ case WasmSymbol::SymbolType::GLOBAL_IMPORT: S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind); break; - case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME: - // These are for debugging only, no need to create linker symbols for them - continue; } Symbols.push_back(S); 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) {} + : Flags(Flags), Name(Name) {} Kind getKind() const { return SymbolKind; } @@ -100,11 +100,6 @@ const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } InputFunction *getFunction() { return Function; } - // This bit is used by Writer::writeNameSection() to prevent - // symbols from being written to the symbol table more than once. - unsigned WrittenToSymtab : 1; - unsigned WrittenToNameSec : 1; - protected: uint32_t Flags; uint32_t VirtualAddress = 0; Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -76,7 +76,6 @@ void calculateInitFunctions(); void assignIndexes(); void calculateImports(); - void calculateOffsets(); void calculateTypes(); void createOutputSegments(); void layoutMemory(); @@ -420,7 +419,7 @@ if (!InitFunctions.empty()) { SubSection SubSection(WASM_INIT_FUNCS); writeUleb128(SubSection.getStream(), InitFunctions.size(), - "num init functionsw"); + "num init functions"); for (const WasmInitFunc &F : InitFunctions) { writeUleb128(SubSection.getStream(), F.Priority, "priority"); writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index"); @@ -470,59 +469,30 @@ // Create the custom "name" section containing debug symbol names. void Writer::createNameSection() { - // Create an array of all function sorted by function index space - std::vector Names; + unsigned Names = ImportedFunctions.size(); + for (const InputFunction *F : DefinedFunctions) + if (!F->getName().empty()) + ++Names; - auto AddToNames = [&](Symbol* S) { - if (!S->isFunction() || S->WrittenToNameSec) - return; - // We also need to guard against two different symbols (two different - // names) for the same wasm function. While this is possible (aliases) - // it is not legal in the "name" section. - InputFunction *Function = S->getFunction(); - if (Function) { - if (Function->WrittenToNameSec) - return; - Function->WrittenToNameSec = true; - } - S->WrittenToNameSec = true; - Names.emplace_back(S); - }; - - for (ObjFile *File : Symtab->ObjectFiles) { - Names.reserve(Names.size() + File->getSymbols().size()); - DEBUG(dbgs() << "adding names from: " << File->getName() << "\n"); - for (Symbol *S : File->getSymbols()) { - if (S->isWeak()) - continue; - AddToNames(S); - } - } - - DEBUG(dbgs() << "adding symtab names\n"); - for (Symbol *S : Symtab->getSymbols()) { - DEBUG(dbgs() << "sym: " << S->getName() << "\n"); - if (S->getFile()) - continue; - AddToNames(S); - } + if (Names == 0) + return; SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); - std::sort(Names.begin(), Names.end(), [](const Symbol *A, const Symbol *B) { - return A->getOutputIndex() < B->getOutputIndex(); - }); - SubSection FunctionSubsection(WASM_NAMES_FUNCTION); raw_ostream &OS = FunctionSubsection.getStream(); - writeUleb128(OS, Names.size(), "name count"); + writeUleb128(OS, Names, "name count"); - // We have to iterate through the inputs twice so that all the imports - // appear first before any of the local function names. - for (const Symbol *S : Names) { - writeUleb128(OS, S->getOutputIndex(), "func index"); + for (const Symbol *S : ImportedFunctions) { + writeUleb128(OS, S->getOutputIndex(), "import index"); writeStr(OS, S->getName(), "symbol name"); } + for (const InputFunction *F : DefinedFunctions) { + if (!F->getName().empty()) { + writeUleb128(OS, F->getOutputIndex(), "func index"); + writeStr(OS, F->getName(), "symbol name"); + } + } FunctionSubsection.finalizeContents(); FunctionSubsection.writeToStream(Section->getStream()); @@ -775,7 +745,9 @@ ArrayRef BodyArray( reinterpret_cast(CtorFunctionBody.data()), CtorFunctionBody.size()); - CtorFunction = llvm::make_unique(Signature, BodyArray); + CtorFunction = llvm::make_unique( + Signature, BodyArray, Config->CtorSymbol->getName()); + CtorFunction->setOutputIndex(FunctionIndex); DefinedFunctions.emplace_back(CtorFunction.get()); }