mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
[WebAssembly] Parse llvm.ident into producers section
Summary: Everything before the word "version" is the tool, and everything after the word "version" is the version. Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D56742 llvm-svn: 351399
This commit is contained in:
parent
7f4ac5dfb0
commit
30a5c9786a
@ -43,6 +43,12 @@ struct WasmDylinkInfo {
|
||||
std::vector<StringRef> Needed; // Shared library depenedencies
|
||||
};
|
||||
|
||||
struct WasmProducerInfo {
|
||||
std::vector<std::pair<std::string, std::string>> Languages;
|
||||
std::vector<std::pair<std::string, std::string>> Tools;
|
||||
std::vector<std::pair<std::string, std::string>> SDKs;
|
||||
};
|
||||
|
||||
struct WasmExport {
|
||||
StringRef Name;
|
||||
uint8_t Kind;
|
||||
|
@ -130,6 +130,7 @@ public:
|
||||
static bool classof(const Binary *v) { return v->isWasm(); }
|
||||
|
||||
const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
|
||||
const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
|
||||
ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
|
||||
ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
|
||||
ArrayRef<wasm::WasmImport> imports() const { return Imports; }
|
||||
@ -149,7 +150,6 @@ public:
|
||||
uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
|
||||
uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
|
||||
uint32_t getNumImportedEvents() const { return NumImportedEvents; }
|
||||
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override;
|
||||
|
||||
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
|
||||
@ -252,11 +252,13 @@ private:
|
||||
Error parseLinkingSection(ReadContext &Ctx);
|
||||
Error parseLinkingSectionSymtab(ReadContext &Ctx);
|
||||
Error parseLinkingSectionComdat(ReadContext &Ctx);
|
||||
Error parseProducersSection(ReadContext &Ctx);
|
||||
Error parseRelocSection(StringRef Name, ReadContext &Ctx);
|
||||
|
||||
wasm::WasmObjectHeader Header;
|
||||
std::vector<WasmSection> Sections;
|
||||
wasm::WasmDylinkInfo DylinkInfo;
|
||||
wasm::WasmProducerInfo ProducerInfo;
|
||||
std::vector<wasm::WasmSignature> Signatures;
|
||||
std::vector<uint32_t> FunctionTypes;
|
||||
std::vector<wasm::WasmTable> Tables;
|
||||
|
@ -123,6 +123,11 @@ struct NameEntry {
|
||||
StringRef Name;
|
||||
};
|
||||
|
||||
struct ProducerEntry {
|
||||
std::string Name;
|
||||
std::string Version;
|
||||
};
|
||||
|
||||
struct SegmentInfo {
|
||||
uint32_t Index;
|
||||
StringRef Name;
|
||||
@ -224,6 +229,19 @@ struct LinkingSection : CustomSection {
|
||||
std::vector<Comdat> Comdats;
|
||||
};
|
||||
|
||||
struct ProducersSection : CustomSection {
|
||||
ProducersSection() : CustomSection("producers") {}
|
||||
|
||||
static bool classof(const Section *S) {
|
||||
auto C = dyn_cast<CustomSection>(S);
|
||||
return C && C->Name == "producers";
|
||||
}
|
||||
|
||||
std::vector<ProducerEntry> Languages;
|
||||
std::vector<ProducerEntry> Tools;
|
||||
std::vector<ProducerEntry> SDKs;
|
||||
};
|
||||
|
||||
struct TypeSection : Section {
|
||||
TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
|
||||
|
||||
@ -366,6 +384,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
|
||||
@ -444,6 +463,10 @@ template <> struct MappingTraits<WasmYAML::NameEntry> {
|
||||
static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<WasmYAML::ProducerEntry> {
|
||||
static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<WasmYAML::SegmentInfo> {
|
||||
static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
|
||||
};
|
||||
|
@ -224,6 +224,7 @@ class WasmObjectWriter : public MCObjectWriter {
|
||||
// Stores output data (index, relocations, content offset) for custom
|
||||
// section.
|
||||
std::vector<WasmCustomSection> CustomSections;
|
||||
std::unique_ptr<WasmCustomSection> ProducersSection;
|
||||
// Relocations for fixing up references in the custom sections.
|
||||
DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>>
|
||||
CustomSectionsRelocations;
|
||||
@ -265,6 +266,8 @@ private:
|
||||
WasmIndices.clear();
|
||||
TableIndices.clear();
|
||||
DataLocations.clear();
|
||||
CustomSections.clear();
|
||||
ProducersSection.reset();
|
||||
CustomSectionsRelocations.clear();
|
||||
SignatureIndices.clear();
|
||||
Signatures.clear();
|
||||
@ -311,7 +314,8 @@ private:
|
||||
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
|
||||
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
|
||||
const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats);
|
||||
void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
|
||||
void writeCustomSection(WasmCustomSection &CustomSection,
|
||||
const MCAssembler &Asm, const MCAsmLayout &Layout);
|
||||
void writeCustomRelocSections();
|
||||
void
|
||||
updateCustomSectionRelocations(const SmallVector<WasmFunction, 4> &Functions,
|
||||
@ -1045,25 +1049,24 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
|
||||
endSection(Section);
|
||||
}
|
||||
|
||||
void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
|
||||
const MCAsmLayout &Layout) {
|
||||
for (auto &CustomSection : CustomSections) {
|
||||
SectionBookkeeping Section;
|
||||
auto *Sec = CustomSection.Section;
|
||||
startCustomSection(Section, CustomSection.Name);
|
||||
void WasmObjectWriter::writeCustomSection(WasmCustomSection &CustomSection,
|
||||
const MCAssembler &Asm,
|
||||
const MCAsmLayout &Layout) {
|
||||
SectionBookkeeping Section;
|
||||
auto *Sec = CustomSection.Section;
|
||||
startCustomSection(Section, CustomSection.Name);
|
||||
|
||||
Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(W.OS, Sec, Layout);
|
||||
Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
|
||||
Asm.writeSectionData(W.OS, Sec, Layout);
|
||||
|
||||
CustomSection.OutputContentsOffset = Section.ContentsOffset;
|
||||
CustomSection.OutputIndex = Section.Index;
|
||||
CustomSection.OutputContentsOffset = Section.ContentsOffset;
|
||||
CustomSection.OutputIndex = Section.Index;
|
||||
|
||||
endSection(Section);
|
||||
endSection(Section);
|
||||
|
||||
// Apply fixups.
|
||||
auto &Relocations = CustomSectionsRelocations[CustomSection.Section];
|
||||
applyRelocations(Relocations, CustomSection.OutputContentsOffset);
|
||||
}
|
||||
// Apply fixups.
|
||||
auto &Relocations = CustomSectionsRelocations[CustomSection.Section];
|
||||
applyRelocations(Relocations, CustomSection.OutputContentsOffset);
|
||||
}
|
||||
|
||||
uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) {
|
||||
@ -1282,6 +1285,13 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
report_fatal_error("section name and begin symbol should match: " +
|
||||
Twine(SectionName));
|
||||
}
|
||||
|
||||
// Separate out the producers section
|
||||
if (Name == "producers") {
|
||||
ProducersSection = llvm::make_unique<WasmCustomSection>(Name, &Section);
|
||||
continue;
|
||||
}
|
||||
|
||||
CustomSections.emplace_back(Name, &Section);
|
||||
}
|
||||
}
|
||||
@ -1570,11 +1580,14 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
writeElemSection(TableElems);
|
||||
writeCodeSection(Asm, Layout, Functions);
|
||||
writeDataSection();
|
||||
writeCustomSections(Asm, Layout);
|
||||
for (auto &CustomSection : CustomSections)
|
||||
writeCustomSection(CustomSection, Asm, Layout);
|
||||
writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
|
||||
writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
|
||||
writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
|
||||
writeCustomRelocSections();
|
||||
if (ProducersSection)
|
||||
writeCustomSection(*ProducersSection, Asm, Layout);
|
||||
|
||||
// TODO: Translate the .comment section to the output.
|
||||
return W.OS.tell() - StartOffset;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
@ -659,6 +660,47 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
|
||||
llvm::SmallSet<StringRef, 3> FieldsSeen;
|
||||
uint32_t Fields = readVaruint32(Ctx);
|
||||
for (size_t i = 0; i < Fields; ++i) {
|
||||
StringRef FieldName = readString(Ctx);
|
||||
if (!FieldsSeen.insert(FieldName).second)
|
||||
return make_error<GenericBinaryError>(
|
||||
"Producers section does not have unique fields",
|
||||
object_error::parse_failed);
|
||||
std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
|
||||
if (FieldName == "language") {
|
||||
ProducerVec = &ProducerInfo.Languages;
|
||||
} else if (FieldName == "processed-by") {
|
||||
ProducerVec = &ProducerInfo.Tools;
|
||||
} else if (FieldName == "sdk") {
|
||||
ProducerVec = &ProducerInfo.SDKs;
|
||||
} else {
|
||||
return make_error<GenericBinaryError>(
|
||||
"Producers section field is not named one of language, processed-by, "
|
||||
"or sdk",
|
||||
object_error::parse_failed);
|
||||
}
|
||||
uint32_t ValueCount = readVaruint32(Ctx);
|
||||
llvm::SmallSet<StringRef, 8> ProducersSeen;
|
||||
for (size_t j = 0; j < ValueCount; ++j) {
|
||||
StringRef Name = readString(Ctx);
|
||||
StringRef Version = readString(Ctx);
|
||||
if (!ProducersSeen.insert(Name).second) {
|
||||
return make_error<GenericBinaryError>(
|
||||
"Producers section contains repeated producer",
|
||||
object_error::parse_failed);
|
||||
}
|
||||
ProducerVec->emplace_back(Name, Version);
|
||||
}
|
||||
}
|
||||
if (Ctx.Ptr != Ctx.End)
|
||||
return make_error<GenericBinaryError>("Producers section ended prematurely",
|
||||
object_error::parse_failed);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
|
||||
uint32_t SectionIndex = readVaruint32(Ctx);
|
||||
if (SectionIndex >= Sections.size())
|
||||
@ -757,6 +799,9 @@ Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
|
||||
} else if (Sec.Name == "linking") {
|
||||
if (Error Err = parseLinkingSection(Ctx))
|
||||
return Err;
|
||||
} else if (Sec.Name == "producers") {
|
||||
if (Error Err = parseProducersSection(Ctx))
|
||||
return Err;
|
||||
} else if (Sec.Name.startswith("reloc.")) {
|
||||
if (Error Err = parseRelocSection(Sec.Name, Ctx))
|
||||
return Err;
|
||||
|
@ -74,6 +74,14 @@ static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
|
||||
IO.mapOptional("Comdats", Section.Comdats);
|
||||
}
|
||||
|
||||
static void sectionMapping(IO &IO, WasmYAML::ProducersSection &Section) {
|
||||
commonSectionMapping(IO, Section);
|
||||
IO.mapRequired("Name", Section.Name);
|
||||
IO.mapOptional("Languages", Section.Languages);
|
||||
IO.mapOptional("Tools", Section.Tools);
|
||||
IO.mapOptional("SDKs", Section.SDKs);
|
||||
}
|
||||
|
||||
static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
|
||||
commonSectionMapping(IO, Section);
|
||||
IO.mapRequired("Name", Section.Name);
|
||||
@ -169,6 +177,10 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
|
||||
if (!IO.outputting())
|
||||
Section.reset(new WasmYAML::NameSection());
|
||||
sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
|
||||
} else if (SectionName == "producers") {
|
||||
if (!IO.outputting())
|
||||
Section.reset(new WasmYAML::ProducersSection());
|
||||
sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
|
||||
} else {
|
||||
if (!IO.outputting())
|
||||
Section.reset(new WasmYAML::CustomSection(SectionName));
|
||||
@ -293,6 +305,12 @@ void MappingTraits<WasmYAML::NameEntry>::mapping(
|
||||
IO.mapRequired("Name", NameEntry.Name);
|
||||
}
|
||||
|
||||
void MappingTraits<WasmYAML::ProducerEntry>::mapping(
|
||||
IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
|
||||
IO.mapRequired("Name", ProducerEntry.Name);
|
||||
IO.mapRequired("Version", ProducerEntry.Version);
|
||||
}
|
||||
|
||||
void MappingTraits<WasmYAML::SegmentInfo>::mapping(
|
||||
IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
|
||||
IO.mapRequired("Index", SegmentInfo.Index);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "WebAssemblyMCInstLower.h"
|
||||
#include "WebAssemblyMachineFunctionInfo.h"
|
||||
#include "WebAssemblyRegisterInfo.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
@ -146,6 +147,35 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||
OutStreamer->PopSection();
|
||||
}
|
||||
}
|
||||
|
||||
if (const NamedMDNode *Ident = M.getNamedMetadata("llvm.ident")) {
|
||||
llvm::SmallSet<StringRef, 4> SeenTools;
|
||||
llvm::SmallVector<std::pair<StringRef, StringRef>, 4> Tools;
|
||||
for (size_t i = 0, e = Ident->getNumOperands(); i < e; ++i) {
|
||||
const auto *S = cast<MDString>(Ident->getOperand(i)->getOperand(0));
|
||||
std::pair<StringRef, StringRef> Field = S->getString().split("version");
|
||||
StringRef Name = Field.first.trim();
|
||||
StringRef Version = Field.second.trim();
|
||||
if (!SeenTools.insert(Name).second)
|
||||
continue;
|
||||
Tools.emplace_back(Name, Version);
|
||||
}
|
||||
MCSectionWasm *Producers = OutContext.getWasmSection(
|
||||
".custom_section.producers", SectionKind::getMetadata());
|
||||
OutStreamer->PushSection();
|
||||
OutStreamer->SwitchSection(Producers);
|
||||
OutStreamer->EmitULEB128IntValue(1);
|
||||
OutStreamer->EmitULEB128IntValue(strlen("processed-by"));
|
||||
OutStreamer->EmitBytes("processed-by");
|
||||
OutStreamer->EmitULEB128IntValue(Tools.size());
|
||||
for (auto &Tool : Tools) {
|
||||
OutStreamer->EmitULEB128IntValue(Tool.first.size());
|
||||
OutStreamer->EmitBytes(Tool.first);
|
||||
OutStreamer->EmitULEB128IntValue(Tool.second.size());
|
||||
OutStreamer->EmitBytes(Tool.second);
|
||||
}
|
||||
OutStreamer->PopSection();
|
||||
}
|
||||
}
|
||||
|
||||
void WebAssemblyAsmPrinter::EmitConstantPool() {
|
||||
|
@ -10,6 +10,9 @@ target triple = "wasm32-unknown-unknown"
|
||||
!2 = !{ !"green", !"qux" }
|
||||
!wasm.custom_sections = !{ !0, !1, !2 }
|
||||
|
||||
!llvm.ident = !{!3}
|
||||
!3 = !{!"clang version 123"}
|
||||
|
||||
; CHECK: .section .custom_section.red,"",@
|
||||
; CHECK-NEXT: .ascii "foo"
|
||||
|
||||
@ -18,3 +21,13 @@ target triple = "wasm32-unknown-unknown"
|
||||
|
||||
; CHECK: .section .custom_section.green,"",@
|
||||
; CHECK-NEXT: .ascii "qux"
|
||||
|
||||
; CHECK: .section .custom_section.producers,"",@
|
||||
; CHECK-NEXT: .int8 1
|
||||
; CHECK-NEXT: .int8 12
|
||||
; CHECK-NEXT: .ascii "processed-by"
|
||||
; CHECK-NEXT: .int8 1
|
||||
; CHECK-NEXT: .int8 5
|
||||
; CHECK-NEXT: .ascii "clang"
|
||||
; CHECK-NEXT: .int8 3
|
||||
; CHECK-NEXT: .ascii "123"
|
||||
|
@ -9,6 +9,9 @@ target triple = "wasm32-unknown-unknown"
|
||||
!2 = !{ !"green", !"qux" }
|
||||
!wasm.custom_sections = !{ !0, !1, !2 }
|
||||
|
||||
!3 = !{ !"clang version 123"}
|
||||
!llvm.ident = !{!3}
|
||||
|
||||
; CHECK: Section {
|
||||
; CHECK: Type: CUSTOM (0x0)
|
||||
; CHECK: Size: 3
|
||||
@ -21,3 +24,9 @@ target triple = "wasm32-unknown-unknown"
|
||||
; CHECK: Offset: 85
|
||||
; CHECK: Name: green
|
||||
; CHECK: }
|
||||
; CHECK: Section {
|
||||
; CHECK: Type: CUSTOM (0x0)
|
||||
; CHECK: Size: 25
|
||||
; CHECK: Offset: 118
|
||||
; CHECK: Name: producers
|
||||
; CHECK: }
|
||||
|
@ -124,6 +124,12 @@
|
||||
; CHECK-NEXT: Offset: 991
|
||||
; CHECK-NEXT: Name: reloc..debug_line
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Section {
|
||||
; CHECK-NEXT: Type: CUSTOM (0x0)
|
||||
; CHECK-NEXT: Size: 62
|
||||
; CHECK-NEXT: Offset: 1021
|
||||
; CHECK-NEXT: Name: producers
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT:]
|
||||
; CHECK-NEXT:Relocations [
|
||||
; CHECK-NEXT: Section (6) DATA {
|
||||
|
29
test/ObjectYAML/wasm/producers_section.yaml
Normal file
29
test/ObjectYAML/wasm/producers_section.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x00000001
|
||||
Sections:
|
||||
- Type: CUSTOM
|
||||
Name: producers
|
||||
Languages:
|
||||
- Name: C++
|
||||
Version: C++11
|
||||
Tools:
|
||||
- Name: clang
|
||||
Version: 123
|
||||
SDKs:
|
||||
- Name: emscripten
|
||||
Version: 9001
|
||||
...
|
||||
# CHECK: Sections:
|
||||
# CHECK: - Type: CUSTOM
|
||||
# CHECK: Name: producers
|
||||
# CHECK: Languages:
|
||||
# CHECK: - Name: 'C++'
|
||||
# CHECK: Version: 'C++11'
|
||||
# CHECK: Tools:
|
||||
# CHECK: - Name: clang
|
||||
# CHECK: Version: '123'
|
||||
# CHECK: SDKs:
|
||||
# CHECK: - Name: emscripten
|
||||
# CHECK: Version: '9001'
|
14
test/ObjectYAML/wasm/producers_section_repeat.yaml
Normal file
14
test/ObjectYAML/wasm/producers_section_repeat.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
# RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x00000001
|
||||
Sections:
|
||||
- Type: CUSTOM
|
||||
Name: producers
|
||||
Languages:
|
||||
- Name: C++
|
||||
Version: C++11
|
||||
- Name: C++
|
||||
Version: C++17
|
||||
...
|
||||
# CHECK: Producers section contains repeated producer
|
@ -133,6 +133,29 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
|
||||
}
|
||||
|
||||
CustomSec = std::move(LinkingSec);
|
||||
} else if (WasmSec.Name == "producers") {
|
||||
std::unique_ptr<WasmYAML::ProducersSection> ProducersSec =
|
||||
make_unique<WasmYAML::ProducersSection>();
|
||||
const llvm::wasm::WasmProducerInfo &Info = Obj.getProducerInfo();
|
||||
for (auto &E : Info.Languages) {
|
||||
WasmYAML::ProducerEntry Producer;
|
||||
Producer.Name = E.first;
|
||||
Producer.Version = E.second;
|
||||
ProducersSec->Languages.push_back(Producer);
|
||||
}
|
||||
for (auto &E : Info.Tools) {
|
||||
WasmYAML::ProducerEntry Producer;
|
||||
Producer.Name = E.first;
|
||||
Producer.Version = E.second;
|
||||
ProducersSec->Tools.push_back(Producer);
|
||||
}
|
||||
for (auto &E : Info.SDKs) {
|
||||
WasmYAML::ProducerEntry Producer;
|
||||
Producer.Name = E.first;
|
||||
Producer.Version = E.second;
|
||||
ProducersSec->SDKs.push_back(Producer);
|
||||
}
|
||||
CustomSec = std::move(ProducersSec);
|
||||
} else {
|
||||
CustomSec = make_unique<WasmYAML::CustomSection>(WasmSec.Name);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ private:
|
||||
int writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section);
|
||||
int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
|
||||
int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
|
||||
int writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section);
|
||||
WasmYAML::Object &Obj;
|
||||
uint32_t NumImportedFunctions = 0;
|
||||
uint32_t NumImportedGlobals = 0;
|
||||
@ -255,6 +256,29 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
WasmYAML::ProducersSection &Section) {
|
||||
writeStringRef(Section.Name, OS);
|
||||
int Fields = int(!Section.Languages.empty()) + int(!Section.Tools.empty()) +
|
||||
int(!Section.SDKs.empty());
|
||||
if (Fields == 0)
|
||||
return 0;
|
||||
encodeULEB128(Fields, OS);
|
||||
for (auto &Field : {std::make_pair(StringRef("language"), &Section.Languages),
|
||||
std::make_pair(StringRef("processed-by"), &Section.Tools),
|
||||
std::make_pair(StringRef("sdk"), &Section.SDKs)}) {
|
||||
if (Field.second->empty())
|
||||
continue;
|
||||
writeStringRef(Field.first, OS);
|
||||
encodeULEB128(Field.second->size(), OS);
|
||||
for (auto &Entry : *Field.second) {
|
||||
writeStringRef(Entry.Name, OS);
|
||||
writeStringRef(Entry.Version, OS);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
WasmYAML::CustomSection &Section) {
|
||||
if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) {
|
||||
@ -266,6 +290,9 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
} else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {
|
||||
if (auto Err = writeSectionContent(OS, *S))
|
||||
return Err;
|
||||
} else if (auto S = dyn_cast<WasmYAML::ProducersSection>(&Section)) {
|
||||
if (auto Err = writeSectionContent(OS, *S))
|
||||
return Err;
|
||||
} else {
|
||||
writeStringRef(Section.Name, OS);
|
||||
Section.Payload.writeAsBinary(OS);
|
||||
|
Loading…
Reference in New Issue
Block a user