diff options
-rw-r--r-- | lld/wasm/InputFiles.cpp | 2 | ||||
-rw-r--r-- | lld/wasm/InputFiles.h | 3 | ||||
-rw-r--r-- | lld/wasm/Writer.cpp | 47 |
3 files changed, 50 insertions, 2 deletions
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index e5da23db377..1c612cabdc4 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -240,6 +240,8 @@ void ObjFile::parse() { CustomSections.emplace_back(make<InputSection>(Section, this)); CustomSections.back()->setRelocations(Section.Relocations); CustomSectionsByIndex[SectionIndex] = CustomSections.back(); + if (Section.Name == "producers") + ProducersSection = &Section; } SectionIndex++; } diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h index bcda9cc8ee9..267b2e7b00a 100644 --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -99,6 +99,7 @@ public: const WasmSection *CodeSection = nullptr; const WasmSection *DataSection = nullptr; + const WasmSection *ProducersSection = nullptr; // Maps input type indices to output type indices std::vector<uint32_t> TypeMap; @@ -139,7 +140,7 @@ public: }; // Will report a fatal() error if the input buffer is not a valid bitcode -// or was object file. +// or wasm object file. InputFile *createObjectFile(MemoryBufferRef MB); // Opens a given file. diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 819d4298fef..ea65bc32599 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -21,6 +21,8 @@ #include "lld/Common/Strings.h" #include "lld/Common/Threads.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/Object/WasmTraits.h" @@ -95,6 +97,7 @@ private: void createRelocSections(); void createLinkingSection(); void createNameSection(); + void createProducersSection(); void writeHeader(); void writeSections(); @@ -327,7 +330,8 @@ void Writer::calculateCustomSections() { StringRef Name = Section->getName(); // These custom sections are known the linker and synthesized rather than // blindly copied - if (Name == "linking" || Name == "name" || Name.startswith("reloc.")) + if (Name == "linking" || Name == "name" || Name == "producers" || + Name.startswith("reloc.")) continue; // .. or it is a debug section if (StripDebug && Name.startswith(".debug_")) @@ -633,6 +637,43 @@ void Writer::createNameSection() { Sub.writeTo(Section->getStream()); } +void Writer::createProducersSection() { + SmallVector<std::pair<std::string, std::string>, 8> Languages; + SmallVector<std::pair<std::string, std::string>, 8> Tools; + SmallVector<std::pair<std::string, std::string>, 8> SDKs; + for (ObjFile *File : Symtab->ObjectFiles) { + const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo(); + for (auto &Producers : {std::make_pair(&Info.Languages, &Languages), + std::make_pair(&Info.Tools, &Tools), + std::make_pair(&Info.SDKs, &SDKs)}) { + llvm::SmallSet<StringRef, 8> SeenProducers; + for (auto &Producer : *Producers.first) + if (SeenProducers.insert(Producer.first).second) + Producers.second->push_back(Producer); + } + } + int FieldCount = + int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty()); + if (FieldCount == 0) + return; + SyntheticSection *Section = + createSyntheticSection(WASM_SEC_CUSTOM, "producers"); + auto &OS = Section->getStream(); + writeUleb128(OS, FieldCount, "field count"); + for (auto &Field : {std::make_pair(StringRef("language"), Languages), + std::make_pair(StringRef("processed-by"), Tools), + std::make_pair(StringRef("sdk"), SDKs)}) { + if (Field.second.empty()) + continue; + writeStr(OS, Field.first, "field name"); + writeUleb128(OS, Field.second.size(), "number of entries"); + for (auto &Entry : Field.second) { + writeStr(OS, Entry.first, "producer name"); + writeStr(OS, Entry.second, "producer version"); + } + } +} + void Writer::writeHeader() { memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); } @@ -772,9 +813,13 @@ void Writer::createSections() { createLinkingSection(); createRelocSections(); } + if (!Config->StripDebug && !Config->StripAll) createNameSection(); + if (!Config->StripAll) + createProducersSection(); + for (OutputSection *S : OutputSections) { S->setOffset(FileSize); S->finalizeContents(); |