[WebAssembly] Add support for dylink section in object format
See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md.
Differential Revision: https://reviews.llvm.org/D54490
llvm-svn: 346880
diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index fbca8df..c22d366 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -35,6 +35,13 @@
uint32_t Version;
};
+struct WasmDylinkInfo {
+ uint32_t MemorySize; // Memory size in bytes
+ uint32_t MemoryAlignment; // P2 alignment of memory
+ uint32_t TableSize; // Table size in elements
+ uint32_t TableAlignment; // P2 alignment of table
+};
+
struct WasmExport {
StringRef Name;
uint8_t Kind;
diff --git a/llvm/include/llvm/Object/Wasm.h b/llvm/include/llvm/Object/Wasm.h
index 03273a8..3f3ad92 100644
--- a/llvm/include/llvm/Object/Wasm.h
+++ b/llvm/include/llvm/Object/Wasm.h
@@ -129,6 +129,7 @@
static bool classof(const Binary *v) { return v->isWasm(); }
+ const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
ArrayRef<wasm::WasmImport> imports() const { return Imports; }
@@ -245,6 +246,7 @@
Error parseDataSection(ReadContext &Ctx);
// Custom section types
+ Error parseDylinkSection(ReadContext &Ctx);
Error parseNameSection(ReadContext &Ctx);
Error parseLinkingSection(ReadContext &Ctx);
Error parseLinkingSectionSymtab(ReadContext &Ctx);
@@ -253,6 +255,7 @@
wasm::WasmObjectHeader Header;
std::vector<WasmSection> Sections;
+ wasm::WasmDylinkInfo DylinkInfo;
std::vector<wasm::WasmSignature> Signatures;
std::vector<uint32_t> FunctionTypes;
std::vector<wasm::WasmTable> Tables;
diff --git a/llvm/include/llvm/ObjectYAML/WasmYAML.h b/llvm/include/llvm/ObjectYAML/WasmYAML.h
index 694fe9a..e3fc030 100644
--- a/llvm/include/llvm/ObjectYAML/WasmYAML.h
+++ b/llvm/include/llvm/ObjectYAML/WasmYAML.h
@@ -183,6 +183,20 @@
yaml::BinaryRef Payload;
};
+struct DylinkSection : CustomSection {
+ DylinkSection() : CustomSection("dylink") {}
+
+ static bool classof(const Section *S) {
+ auto C = dyn_cast<CustomSection>(S);
+ return C && C->Name == "dylink";
+ }
+
+ uint32_t MemorySize;
+ uint32_t MemoryAlignment;
+ uint32_t TableSize;
+ uint32_t TableAlignment;
+};
+
struct NameSection : CustomSection {
NameSection() : CustomSection("name") {}
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 794f869..e756007 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -313,6 +313,18 @@
}
}
+Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
+ // See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+ DylinkInfo.MemorySize = readVaruint32(Ctx);
+ DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
+ DylinkInfo.TableSize = readVaruint32(Ctx);
+ DylinkInfo.TableAlignment = readVaruint32(Ctx);
+ if (Ctx.Ptr != Ctx.End)
+ return make_error<GenericBinaryError>("dylink section ended prematurely",
+ object_error::parse_failed);
+ return Error::success();
+}
+
Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
llvm::DenseSet<uint64_t> Seen;
if (Functions.size() != FunctionTypes.size()) {
@@ -721,7 +733,10 @@
}
Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
- if (Sec.Name == "name") {
+ if (Sec.Name == "dylink") {
+ if (Error Err = parseDylinkSection(Ctx))
+ return Err;
+ } else if (Sec.Name == "name") {
if (Error Err = parseNameSection(Ctx))
return Err;
} else if (Sec.Name == "linking") {
diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index 610507c..2bc971a 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -48,6 +48,15 @@
IO.mapOptional("Relocations", Section.Relocations);
}
+static void sectionMapping(IO &IO, WasmYAML::DylinkSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapRequired("MemorySize", Section.MemorySize);
+ IO.mapRequired("MemoryAlignment", Section.MemoryAlignment);
+ IO.mapRequired("TableSize", Section.TableSize);
+ IO.mapRequired("TableAlignment", Section.TableAlignment);
+}
+
static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Name", Section.Name);
@@ -147,7 +156,11 @@
} else {
IO.mapRequired("Name", SectionName);
}
- if (SectionName == "linking") {
+ if (SectionName == "dylink") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::DylinkSection());
+ sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get()));
+ } else if (SectionName == "linking") {
if (!IO.outputting())
Section.reset(new WasmYAML::LinkingSection());
sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get()));
diff --git a/llvm/test/ObjectYAML/wasm/dylink_section.yaml b/llvm/test/ObjectYAML/wasm/dylink_section.yaml
new file mode 100644
index 0000000..ea9d03f
--- /dev/null
+++ b/llvm/test/ObjectYAML/wasm/dylink_section.yaml
@@ -0,0 +1,24 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+--- !WASM
+FileHeader:
+ Version: 0x00000001
+
+Sections:
+ - Type: CUSTOM
+ Name: dylink
+ MemorySize: 4
+ MemoryAlignment: 2
+ TableSize: 1
+ TableAlignment: 0
+...
+# CHECK: --- !WASM
+# CHECK: FileHeader:
+# CHECK: Version: 0x00000001
+# CHECK: Sections:
+# CHECK: - Type: CUSTOM
+# CHECK: Name: dylink
+# CHECK: MemorySize: 4
+# CHECK: MemoryAlignment: 2
+# CHECK: TableSize: 1
+# CHECK: TableAlignment: 0
+# CHECK: ...
diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index 8bbc9fb..ebfe078 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -52,7 +52,16 @@
std::unique_ptr<WasmYAML::CustomSection>
WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
std::unique_ptr<WasmYAML::CustomSection> CustomSec;
- if (WasmSec.Name == "name") {
+ if (WasmSec.Name == "dylink") {
+ std::unique_ptr<WasmYAML::DylinkSection> DylinkSec =
+ make_unique<WasmYAML::DylinkSection>();
+ const wasm::WasmDylinkInfo& Info = Obj.dylinkInfo();
+ DylinkSec->MemorySize = Info.MemorySize;
+ DylinkSec->MemoryAlignment = Info.MemoryAlignment;
+ DylinkSec->TableSize = Info.TableSize;
+ DylinkSec->TableAlignment = Info.TableAlignment;
+ CustomSec = std::move(DylinkSec);
+ } else if (WasmSec.Name == "name") {
std::unique_ptr<WasmYAML::NameSection> NameSec =
make_unique<WasmYAML::NameSection>();
for (const llvm::wasm::WasmFunctionName &Func : Obj.debugNames()) {
diff --git a/llvm/tools/yaml2obj/yaml2wasm.cpp b/llvm/tools/yaml2obj/yaml2wasm.cpp
index 4a9269d..0809cc4 100644
--- a/llvm/tools/yaml2obj/yaml2wasm.cpp
+++ b/llvm/tools/yaml2obj/yaml2wasm.cpp
@@ -45,6 +45,7 @@
int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
// Custom section types
+ int writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
WasmYAML::Object &Obj;
@@ -133,6 +134,16 @@
};
int WasmWriter::writeSectionContent(raw_ostream &OS,
+ WasmYAML::DylinkSection &Section) {
+ writeStringRef(Section.Name, OS);
+ encodeULEB128(Section.MemorySize, OS);
+ encodeULEB128(Section.MemoryAlignment, OS);
+ encodeULEB128(Section.TableSize, OS);
+ encodeULEB128(Section.TableAlignment, OS);
+ return 0;
+}
+
+int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::LinkingSection &Section) {
writeStringRef(Section.Name, OS);
encodeULEB128(Section.Version, OS);
@@ -241,7 +252,10 @@
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::CustomSection &Section) {
- if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
+ if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) {
+ if (auto Err = writeSectionContent(OS, *S))
+ return Err;
+ } else if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
if (auto Err = writeSectionContent(OS, *S))
return Err;
} else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {