Skip to content

Commit cbda16e

Browse files
committed
[WebAssembly] Parse llvm.ident into producers section
llvm-svn: 351413
1 parent 2a0868f commit cbda16e

File tree

14 files changed

+276
-18
lines changed

14 files changed

+276
-18
lines changed

llvm/include/llvm/BinaryFormat/Wasm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ struct WasmDylinkInfo {
4343
std::vector<StringRef> Needed; // Shared library depenedencies
4444
};
4545

46+
struct WasmProducerInfo {
47+
std::vector<std::pair<std::string, std::string>> Languages;
48+
std::vector<std::pair<std::string, std::string>> Tools;
49+
std::vector<std::pair<std::string, std::string>> SDKs;
50+
};
51+
4652
struct WasmExport {
4753
StringRef Name;
4854
uint8_t Kind;

llvm/include/llvm/Object/Wasm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class WasmObjectFile : public ObjectFile {
130130
static bool classof(const Binary *v) { return v->isWasm(); }
131131

132132
const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
133+
const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
133134
ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
134135
ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
135136
ArrayRef<wasm::WasmImport> imports() const { return Imports; }
@@ -149,7 +150,6 @@ class WasmObjectFile : public ObjectFile {
149150
uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
150151
uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
151152
uint32_t getNumImportedEvents() const { return NumImportedEvents; }
152-
153153
void moveSymbolNext(DataRefImpl &Symb) const override;
154154

155155
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
@@ -252,11 +252,13 @@ class WasmObjectFile : public ObjectFile {
252252
Error parseLinkingSection(ReadContext &Ctx);
253253
Error parseLinkingSectionSymtab(ReadContext &Ctx);
254254
Error parseLinkingSectionComdat(ReadContext &Ctx);
255+
Error parseProducersSection(ReadContext &Ctx);
255256
Error parseRelocSection(StringRef Name, ReadContext &Ctx);
256257

257258
wasm::WasmObjectHeader Header;
258259
std::vector<WasmSection> Sections;
259260
wasm::WasmDylinkInfo DylinkInfo;
261+
wasm::WasmProducerInfo ProducerInfo;
260262
std::vector<wasm::WasmSignature> Signatures;
261263
std::vector<uint32_t> FunctionTypes;
262264
std::vector<wasm::WasmTable> Tables;

llvm/include/llvm/ObjectYAML/WasmYAML.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ struct NameEntry {
123123
StringRef Name;
124124
};
125125

126+
struct ProducerEntry {
127+
std::string Name;
128+
std::string Version;
129+
};
130+
126131
struct SegmentInfo {
127132
uint32_t Index;
128133
StringRef Name;
@@ -224,6 +229,19 @@ struct LinkingSection : CustomSection {
224229
std::vector<Comdat> Comdats;
225230
};
226231

232+
struct ProducersSection : CustomSection {
233+
ProducersSection() : CustomSection("producers") {}
234+
235+
static bool classof(const Section *S) {
236+
auto C = dyn_cast<CustomSection>(S);
237+
return C && C->Name == "producers";
238+
}
239+
240+
std::vector<ProducerEntry> Languages;
241+
std::vector<ProducerEntry> Tools;
242+
std::vector<ProducerEntry> SDKs;
243+
};
244+
227245
struct TypeSection : Section {
228246
TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
229247

@@ -366,6 +384,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
366384
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
367385
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
368386
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
387+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
369388
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
370389
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
371390
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
@@ -444,6 +463,10 @@ template <> struct MappingTraits<WasmYAML::NameEntry> {
444463
static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
445464
};
446465

466+
template <> struct MappingTraits<WasmYAML::ProducerEntry> {
467+
static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
468+
};
469+
447470
template <> struct MappingTraits<WasmYAML::SegmentInfo> {
448471
static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
449472
};

llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class WasmObjectWriter : public MCObjectWriter {
224224
// Stores output data (index, relocations, content offset) for custom
225225
// section.
226226
std::vector<WasmCustomSection> CustomSections;
227+
std::unique_ptr<WasmCustomSection> ProducersSection;
227228
// Relocations for fixing up references in the custom sections.
228229
DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>>
229230
CustomSectionsRelocations;
@@ -265,6 +266,8 @@ class WasmObjectWriter : public MCObjectWriter {
265266
WasmIndices.clear();
266267
TableIndices.clear();
267268
DataLocations.clear();
269+
CustomSections.clear();
270+
ProducersSection.reset();
268271
CustomSectionsRelocations.clear();
269272
SignatureIndices.clear();
270273
Signatures.clear();
@@ -311,7 +314,8 @@ class WasmObjectWriter : public MCObjectWriter {
311314
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
312315
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
313316
const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats);
314-
void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
317+
void writeCustomSection(WasmCustomSection &CustomSection,
318+
const MCAssembler &Asm, const MCAsmLayout &Layout);
315319
void writeCustomRelocSections();
316320
void
317321
updateCustomSectionRelocations(const SmallVector<WasmFunction, 4> &Functions,
@@ -1045,25 +1049,24 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
10451049
endSection(Section);
10461050
}
10471051

1048-
void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
1049-
const MCAsmLayout &Layout) {
1050-
for (auto &CustomSection : CustomSections) {
1051-
SectionBookkeeping Section;
1052-
auto *Sec = CustomSection.Section;
1053-
startCustomSection(Section, CustomSection.Name);
1052+
void WasmObjectWriter::writeCustomSection(WasmCustomSection &CustomSection,
1053+
const MCAssembler &Asm,
1054+
const MCAsmLayout &Layout) {
1055+
SectionBookkeeping Section;
1056+
auto *Sec = CustomSection.Section;
1057+
startCustomSection(Section, CustomSection.Name);
10541058

1055-
Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
1056-
Asm.writeSectionData(W.OS, Sec, Layout);
1059+
Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
1060+
Asm.writeSectionData(W.OS, Sec, Layout);
10571061

1058-
CustomSection.OutputContentsOffset = Section.ContentsOffset;
1059-
CustomSection.OutputIndex = Section.Index;
1062+
CustomSection.OutputContentsOffset = Section.ContentsOffset;
1063+
CustomSection.OutputIndex = Section.Index;
10601064

1061-
endSection(Section);
1065+
endSection(Section);
10621066

1063-
// Apply fixups.
1064-
auto &Relocations = CustomSectionsRelocations[CustomSection.Section];
1065-
applyRelocations(Relocations, CustomSection.OutputContentsOffset);
1066-
}
1067+
// Apply fixups.
1068+
auto &Relocations = CustomSectionsRelocations[CustomSection.Section];
1069+
applyRelocations(Relocations, CustomSection.OutputContentsOffset);
10671070
}
10681071

10691072
uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) {
@@ -1282,6 +1285,13 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
12821285
report_fatal_error("section name and begin symbol should match: " +
12831286
Twine(SectionName));
12841287
}
1288+
1289+
// Separate out the producers section
1290+
if (Name == "producers") {
1291+
ProducersSection = llvm::make_unique<WasmCustomSection>(Name, &Section);
1292+
continue;
1293+
}
1294+
12851295
CustomSections.emplace_back(Name, &Section);
12861296
}
12871297
}
@@ -1570,11 +1580,14 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
15701580
writeElemSection(TableElems);
15711581
writeCodeSection(Asm, Layout, Functions);
15721582
writeDataSection();
1573-
writeCustomSections(Asm, Layout);
1583+
for (auto &CustomSection : CustomSections)
1584+
writeCustomSection(CustomSection, Asm, Layout);
15741585
writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
15751586
writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
15761587
writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
15771588
writeCustomRelocSections();
1589+
if (ProducersSection)
1590+
writeCustomSection(*ProducersSection, Asm, Layout);
15781591

15791592
// TODO: Translate the .comment section to the output.
15801593
return W.OS.tell() - StartOffset;

llvm/lib/Object/WasmObjectFile.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/ADT/ArrayRef.h"
1111
#include "llvm/ADT/DenseSet.h"
1212
#include "llvm/ADT/STLExtras.h"
13+
#include "llvm/ADT/SmallSet.h"
1314
#include "llvm/ADT/StringRef.h"
1415
#include "llvm/ADT/StringSet.h"
1516
#include "llvm/ADT/Triple.h"
@@ -659,6 +660,47 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
659660
return Error::success();
660661
}
661662

663+
Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
664+
llvm::SmallSet<StringRef, 3> FieldsSeen;
665+
uint32_t Fields = readVaruint32(Ctx);
666+
for (size_t i = 0; i < Fields; ++i) {
667+
StringRef FieldName = readString(Ctx);
668+
if (!FieldsSeen.insert(FieldName).second)
669+
return make_error<GenericBinaryError>(
670+
"Producers section does not have unique fields",
671+
object_error::parse_failed);
672+
std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
673+
if (FieldName == "language") {
674+
ProducerVec = &ProducerInfo.Languages;
675+
} else if (FieldName == "processed-by") {
676+
ProducerVec = &ProducerInfo.Tools;
677+
} else if (FieldName == "sdk") {
678+
ProducerVec = &ProducerInfo.SDKs;
679+
} else {
680+
return make_error<GenericBinaryError>(
681+
"Producers section field is not named one of language, processed-by, "
682+
"or sdk",
683+
object_error::parse_failed);
684+
}
685+
uint32_t ValueCount = readVaruint32(Ctx);
686+
llvm::SmallSet<StringRef, 8> ProducersSeen;
687+
for (size_t j = 0; j < ValueCount; ++j) {
688+
StringRef Name = readString(Ctx);
689+
StringRef Version = readString(Ctx);
690+
if (!ProducersSeen.insert(Name).second) {
691+
return make_error<GenericBinaryError>(
692+
"Producers section contains repeated producer",
693+
object_error::parse_failed);
694+
}
695+
ProducerVec->emplace_back(Name, Version);
696+
}
697+
}
698+
if (Ctx.Ptr != Ctx.End)
699+
return make_error<GenericBinaryError>("Producers section ended prematurely",
700+
object_error::parse_failed);
701+
return Error::success();
702+
}
703+
662704
Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
663705
uint32_t SectionIndex = readVaruint32(Ctx);
664706
if (SectionIndex >= Sections.size())
@@ -757,6 +799,9 @@ Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
757799
} else if (Sec.Name == "linking") {
758800
if (Error Err = parseLinkingSection(Ctx))
759801
return Err;
802+
} else if (Sec.Name == "producers") {
803+
if (Error Err = parseProducersSection(Ctx))
804+
return Err;
760805
} else if (Sec.Name.startswith("reloc.")) {
761806
if (Error Err = parseRelocSection(Sec.Name, Ctx))
762807
return Err;

llvm/lib/ObjectYAML/WasmYAML.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
7474
IO.mapOptional("Comdats", Section.Comdats);
7575
}
7676

77+
static void sectionMapping(IO &IO, WasmYAML::ProducersSection &Section) {
78+
commonSectionMapping(IO, Section);
79+
IO.mapRequired("Name", Section.Name);
80+
IO.mapOptional("Languages", Section.Languages);
81+
IO.mapOptional("Tools", Section.Tools);
82+
IO.mapOptional("SDKs", Section.SDKs);
83+
}
84+
7785
static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
7886
commonSectionMapping(IO, Section);
7987
IO.mapRequired("Name", Section.Name);
@@ -169,6 +177,10 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
169177
if (!IO.outputting())
170178
Section.reset(new WasmYAML::NameSection());
171179
sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
180+
} else if (SectionName == "producers") {
181+
if (!IO.outputting())
182+
Section.reset(new WasmYAML::ProducersSection());
183+
sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
172184
} else {
173185
if (!IO.outputting())
174186
Section.reset(new WasmYAML::CustomSection(SectionName));
@@ -293,6 +305,12 @@ void MappingTraits<WasmYAML::NameEntry>::mapping(
293305
IO.mapRequired("Name", NameEntry.Name);
294306
}
295307

308+
void MappingTraits<WasmYAML::ProducerEntry>::mapping(
309+
IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
310+
IO.mapRequired("Name", ProducerEntry.Name);
311+
IO.mapRequired("Version", ProducerEntry.Version);
312+
}
313+
296314
void MappingTraits<WasmYAML::SegmentInfo>::mapping(
297315
IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
298316
IO.mapRequired("Index", SegmentInfo.Index);

llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "WebAssemblyMCInstLower.h"
2323
#include "WebAssemblyMachineFunctionInfo.h"
2424
#include "WebAssemblyRegisterInfo.h"
25+
#include "llvm/ADT/SmallSet.h"
2526
#include "llvm/ADT/StringExtras.h"
2627
#include "llvm/CodeGen/Analysis.h"
2728
#include "llvm/CodeGen/AsmPrinter.h"
@@ -146,6 +147,35 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
146147
OutStreamer->PopSection();
147148
}
148149
}
150+
151+
if (const NamedMDNode *Ident = M.getNamedMetadata("llvm.ident")) {
152+
llvm::SmallSet<StringRef, 4> SeenTools;
153+
llvm::SmallVector<std::pair<StringRef, StringRef>, 4> Tools;
154+
for (size_t i = 0, e = Ident->getNumOperands(); i < e; ++i) {
155+
const auto *S = cast<MDString>(Ident->getOperand(i)->getOperand(0));
156+
std::pair<StringRef, StringRef> Field = S->getString().split("version");
157+
StringRef Name = Field.first.trim();
158+
StringRef Version = Field.second.trim();
159+
if (!SeenTools.insert(Name).second)
160+
continue;
161+
Tools.emplace_back(Name, Version);
162+
}
163+
MCSectionWasm *Producers = OutContext.getWasmSection(
164+
".custom_section.producers", SectionKind::getMetadata());
165+
OutStreamer->PushSection();
166+
OutStreamer->SwitchSection(Producers);
167+
OutStreamer->EmitULEB128IntValue(1);
168+
OutStreamer->EmitULEB128IntValue(strlen("processed-by"));
169+
OutStreamer->EmitBytes("processed-by");
170+
OutStreamer->EmitULEB128IntValue(Tools.size());
171+
for (auto &Tool : Tools) {
172+
OutStreamer->EmitULEB128IntValue(Tool.first.size());
173+
OutStreamer->EmitBytes(Tool.first);
174+
OutStreamer->EmitULEB128IntValue(Tool.second.size());
175+
OutStreamer->EmitBytes(Tool.second);
176+
}
177+
OutStreamer->PopSection();
178+
}
149179
}
150180

151181
void WebAssemblyAsmPrinter::EmitConstantPool() {

llvm/test/CodeGen/WebAssembly/custom-sections.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ target triple = "wasm32-unknown-unknown"
1010
!2 = !{ !"green", !"qux" }
1111
!wasm.custom_sections = !{ !0, !1, !2 }
1212

13+
!llvm.ident = !{!3}
14+
!3 = !{!"clang version 123"}
15+
1316
; CHECK: .section .custom_section.red,"",@
1417
; CHECK-NEXT: .ascii "foo"
1518

@@ -18,3 +21,13 @@ target triple = "wasm32-unknown-unknown"
1821

1922
; CHECK: .section .custom_section.green,"",@
2023
; CHECK-NEXT: .ascii "qux"
24+
25+
; CHECK: .section .custom_section.producers,"",@
26+
; CHECK-NEXT: .int8 1
27+
; CHECK-NEXT: .int8 12
28+
; CHECK-NEXT: .ascii "processed-by"
29+
; CHECK-NEXT: .int8 1
30+
; CHECK-NEXT: .int8 5
31+
; CHECK-NEXT: .ascii "clang"
32+
; CHECK-NEXT: .int8 3
33+
; CHECK-NEXT: .ascii "123"

llvm/test/MC/WebAssembly/custom-sections.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ target triple = "wasm32-unknown-unknown"
99
!2 = !{ !"green", !"qux" }
1010
!wasm.custom_sections = !{ !0, !1, !2 }
1111

12+
!3 = !{ !"clang version 123"}
13+
!llvm.ident = !{!3}
14+
1215
; CHECK: Section {
1316
; CHECK: Type: CUSTOM (0x0)
1417
; CHECK: Size: 3
@@ -21,3 +24,9 @@ target triple = "wasm32-unknown-unknown"
2124
; CHECK: Offset: 85
2225
; CHECK: Name: green
2326
; CHECK: }
27+
; CHECK: Section {
28+
; CHECK: Type: CUSTOM (0x0)
29+
; CHECK: Size: 25
30+
; CHECK: Offset: 118
31+
; CHECK: Name: producers
32+
; CHECK: }

llvm/test/MC/WebAssembly/debug-info.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@
124124
; CHECK-NEXT: Offset: 991
125125
; CHECK-NEXT: Name: reloc..debug_line
126126
; CHECK-NEXT: }
127+
; CHECK-NEXT: Section {
128+
; CHECK-NEXT: Type: CUSTOM (0x0)
129+
; CHECK-NEXT: Size: 62
130+
; CHECK-NEXT: Offset: 1021
131+
; CHECK-NEXT: Name: producers
132+
; CHECK-NEXT: }
127133
; CHECK-NEXT:]
128134
; CHECK-NEXT:Relocations [
129135
; CHECK-NEXT: Section (6) DATA {

0 commit comments

Comments
 (0)