Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ 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; Index: include/llvm/Object/Wasm.h =================================================================== --- include/llvm/Object/Wasm.h +++ include/llvm/Object/Wasm.h @@ -124,6 +124,7 @@ static bool classof(const Binary *v) { return v->isWasm(); } + const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; } ArrayRef types() const { return Signatures; } ArrayRef functionTypes() const { return FunctionTypes; } ArrayRef imports() const { return Imports; } @@ -233,6 +234,7 @@ Error parseDataSection(ReadContext &Ctx); // Custom section types + Error parseDylinkSection(ReadContext &Ctx); Error parseNameSection(ReadContext &Ctx); Error parseLinkingSection(ReadContext &Ctx); Error parseLinkingSectionSymtab(ReadContext &Ctx); @@ -241,6 +243,7 @@ wasm::WasmObjectHeader Header; std::vector Sections; + wasm::WasmDylinkInfo DylinkInfo; std::vector Signatures; std::vector FunctionTypes; std::vector Tables; Index: include/llvm/ObjectYAML/WasmYAML.h =================================================================== --- include/llvm/ObjectYAML/WasmYAML.h +++ include/llvm/ObjectYAML/WasmYAML.h @@ -176,6 +176,20 @@ yaml::BinaryRef Payload; }; +struct DylinkSection : CustomSection { + DylinkSection() : CustomSection("dylink") {} + + static bool classof(const Section *S) { + auto C = dyn_cast(S); + return C && C->Name == "dylink"; + } + + uint32_t MemorySize; + uint32_t MemoryAlignment; + uint32_t TableSize; + uint32_t TableAlignment; +}; + struct NameSection : CustomSection { NameSection() : CustomSection("name") {} Index: lib/Object/WasmObjectFile.cpp =================================================================== --- lib/Object/WasmObjectFile.cpp +++ lib/Object/WasmObjectFile.cpp @@ -311,6 +311,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("dylink section ended prematurely", + object_error::parse_failed); + return Error::success(); +} + Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { llvm::DenseSet Seen; if (Functions.size() != FunctionTypes.size()) { @@ -683,7 +695,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") { Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ 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); @@ -142,7 +151,11 @@ } else { IO.mapRequired("Name", SectionName); } - if (SectionName == "linking") { + if (SectionName == "dylink") { + if (!IO.outputting()) + Section.reset(new WasmYAML::DylinkSection()); + sectionMapping(IO, *cast(Section.get())); + } else if (SectionName == "linking") { if (!IO.outputting()) Section.reset(new WasmYAML::LinkingSection()); sectionMapping(IO, *cast(Section.get())); Index: test/ObjectYAML/wasm/dylink_section.yaml =================================================================== --- /dev/null +++ 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: ... Index: tools/obj2yaml/wasm2yaml.cpp =================================================================== --- tools/obj2yaml/wasm2yaml.cpp +++ tools/obj2yaml/wasm2yaml.cpp @@ -52,7 +52,16 @@ std::unique_ptr WasmDumper::dumpCustomSection(const WasmSection &WasmSec) { std::unique_ptr CustomSec; - if (WasmSec.Name == "name") { + if (WasmSec.Name == "dylink") { + std::unique_ptr DylinkSec = + make_unique(); + 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 NameSec = make_unique(); for (const llvm::wasm::WasmFunctionName &Func : Obj.debugNames()) { Index: tools/yaml2obj/yaml2wasm.cpp =================================================================== --- tools/yaml2obj/yaml2wasm.cpp +++ tools/yaml2obj/yaml2wasm.cpp @@ -44,6 +44,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; @@ -130,6 +131,16 @@ raw_ostream &GetStream() { return StringStream; } }; +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); @@ -238,7 +249,10 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section) { - if (auto S = dyn_cast(&Section)) { + if (auto S = dyn_cast(&Section)) { + if (auto Err = writeSectionContent(OS, *S)) + return Err; + } else if (auto S = dyn_cast(&Section)) { if (auto Err = writeSectionContent(OS, *S)) return Err; } else if (auto S = dyn_cast(&Section)) {