From 03cdd1241fc256bc3daf22da33e76f3afd249c5b Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 5 May 2017 18:12:34 +0000 Subject: [PATCH] [WebAssembly] Add ObjectYAML support for wasm name section Differential Revision: https://reviews.llvm.org/D32841 llvm-svn: 302266 --- llvm/include/llvm/ObjectYAML/WasmYAML.h | 15 ++++++++++ llvm/lib/ObjectYAML/WasmYAML.cpp | 12 +++++++- llvm/test/ObjectYAML/wasm/name_section.yaml | 40 +++++++++++++++++++++++++ llvm/tools/obj2yaml/wasm2yaml.cpp | 19 +++++++++++- llvm/tools/yaml2obj/yaml2wasm.cpp | 46 ++++++++++++++++++++++------- 5 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 llvm/test/ObjectYAML/wasm/name_section.yaml diff --git a/llvm/include/llvm/ObjectYAML/WasmYAML.h b/llvm/include/llvm/ObjectYAML/WasmYAML.h index dfeeb85..bd7d72b 100644 --- a/llvm/include/llvm/ObjectYAML/WasmYAML.h +++ b/llvm/include/llvm/ObjectYAML/WasmYAML.h @@ -97,6 +97,11 @@ struct DataSegment { yaml::BinaryRef Content; }; +struct NameEntry { + uint32_t Index; + StringRef Name; +}; + struct Signature { Signature() : Form(wasm::WASM_TYPE_FUNC) {} @@ -122,6 +127,11 @@ struct CustomSection : Section { StringRef Name; yaml::BinaryRef Payload; + + // The follow is used by the "name" custom section. + // TODO(sbc): Add support for more then just functions names. The wasm + // name section can support multiple sub-sections. + std::vector FunctionNames; }; struct TypeSection : Section { @@ -244,6 +254,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global) 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_FLOW_SEQUENCE_VECTOR(uint32_t) namespace llvm { @@ -297,6 +308,10 @@ template <> struct MappingTraits { static void mapping(IO &IO, WasmYAML::Relocation &Relocation); }; +template <> struct MappingTraits { + static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); +}; + template <> struct MappingTraits { static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); }; diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp index 9b1ff7e..c5d1b43 100644 --- a/llvm/lib/ObjectYAML/WasmYAML.cpp +++ b/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -50,7 +50,11 @@ static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) { static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { commonSectionMapping(IO, Section); IO.mapRequired("Name", Section.Name); - IO.mapRequired("Payload", Section.Payload); + if (Section.Name == "name") { + IO.mapOptional("FunctionNames", Section.FunctionNames); + } else { + IO.mapRequired("Payload", Section.Payload); + } } static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { @@ -226,6 +230,12 @@ void MappingTraits::mapping( IO.mapOptional("Addend", Relocation.Addend, 0); } +void MappingTraits::mapping( + IO &IO, WasmYAML::NameEntry &NameEntry) { + IO.mapRequired("Index", NameEntry.Index); + IO.mapRequired("Name", NameEntry.Name); +} + void MappingTraits::mapping( IO &IO, WasmYAML::LocalDecl &LocalDecl) { IO.mapRequired("Type", LocalDecl.Type); diff --git a/llvm/test/ObjectYAML/wasm/name_section.yaml b/llvm/test/ObjectYAML/wasm/name_section.yaml new file mode 100644 index 0000000..0a4191d --- /dev/null +++ b/llvm/test/ObjectYAML/wasm/name_section.yaml @@ -0,0 +1,40 @@ +# RUN: yaml2obj %s | obj2yaml | FileCheck %s +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: TYPE + Signatures: + - ReturnType: I32 + ParamTypes: + - I32 + - Type: IMPORT + Imports: + - Module: foo + Field: a + Kind: FUNCTION + SigIndex: 0 + - Module: foo + Field: b + Kind: FUNCTION + SigIndex: 0 + - Module: foo + Field: c + Kind: FUNCTION + SigIndex: 0 + - Type: CUSTOM + Name: name + FunctionNames: + - Index: 1 + Name: foo + - Index: 0 + Name: bar +... +# CHECK: - Type: CUSTOM +# CHECK-NEXT: Name: name +# CHECK-NEXT: FunctionNames: +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Name: foo +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: bar +# CHECK: ... diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp index f6b530c..cc04b99 100644 --- a/llvm/tools/obj2yaml/wasm2yaml.cpp +++ b/llvm/tools/obj2yaml/wasm2yaml.cpp @@ -44,7 +44,24 @@ ErrorOr WasmDumper::dump() { } auto CustomSec = make_unique(); CustomSec->Name = WasmSec.Name; - CustomSec->Payload = yaml::BinaryRef(WasmSec.Content); + if (CustomSec->Name == "name") { + for (const object::SymbolRef& Sym: Obj.symbols()) { + uint32_t Flags = Sym.getFlags(); + // Skip over symbols that come from imports or exports + if (Flags & + (object::SymbolRef::SF_Global | object::SymbolRef::SF_Undefined)) + continue; + Expected NameOrError = Sym.getName(); + if (!NameOrError) + continue; + WasmYAML::NameEntry NameEntry; + NameEntry.Name = *NameOrError; + NameEntry.Index = Sym.getValue(); + CustomSec->FunctionNames.push_back(NameEntry); + } + } else { + CustomSec->Payload = yaml::BinaryRef(WasmSec.Content); + } S = std::move(CustomSec); break; } diff --git a/llvm/tools/yaml2obj/yaml2wasm.cpp b/llvm/tools/yaml2obj/yaml2wasm.cpp index 55267ce..eed9f2c 100644 --- a/llvm/tools/yaml2obj/yaml2wasm.cpp +++ b/llvm/tools/yaml2obj/yaml2wasm.cpp @@ -27,6 +27,8 @@ public: WasmWriter(WasmYAML::Object &Obj) : Obj(Obj) {} int writeWasm(raw_ostream &OS); int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec); + int writeNameSection(raw_ostream &OS, WasmYAML::CustomSection &Section); + int writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section); int writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section); int writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section); @@ -65,13 +67,13 @@ static int writeUint8(raw_ostream &OS, uint8_t Value) { return 0; } -static int writeStringRef(StringRef &Str, raw_ostream &OS) { +static int writeStringRef(const StringRef &Str, raw_ostream &OS) { encodeULEB128(Str.size(), OS); OS << Str; return 0; } -static int writeLimits(WasmYAML::Limits Lim, raw_ostream &OS) { +static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) { encodeULEB128(Lim.Flags, OS); encodeULEB128(Lim.Initial, OS); if (Lim.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) @@ -79,7 +81,7 @@ static int writeLimits(WasmYAML::Limits Lim, raw_ostream &OS) { return 0; } -static int writeInitExpr(wasm::WasmInitExpr InitExpr, raw_ostream &OS) { +static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) { writeUint8(OS, InitExpr.Opcode); switch (InitExpr.Opcode) { case wasm::WASM_OPCODE_I32_CONST: @@ -105,18 +107,42 @@ static int writeInitExpr(wasm::WasmInitExpr InitExpr, raw_ostream &OS) { return 0; } +int WasmWriter::writeNameSection(raw_ostream &OS, + WasmYAML::CustomSection &Section) { + writeStringRef(Section.Name, OS); + if (Section.FunctionNames.size()) { + encodeULEB128(wasm::WASM_NAMES_FUNCTION, OS); + + std::string OutString; + raw_string_ostream StringStream(OutString); + + encodeULEB128(Section.FunctionNames.size(), StringStream); + for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) { + encodeULEB128(NameEntry.Index, StringStream); + writeStringRef(NameEntry.Name, StringStream); + } + + StringStream.flush(); + encodeULEB128(OutString.size(), OS); + OS << OutString; + } + return 0; +} + int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section) { - // writeStringRef(Section.Name, OS); - // encodeULEB128(Section.Payload.binary_size(), OS); - Section.Payload.writeAsBinary(OS); + if (Section.Name == "name") { + writeNameSection(OS, Section); + } else { + Section.Payload.writeAsBinary(OS); + } return 0; } int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section) { encodeULEB128(Section.Signatures.size(), OS); - for (auto &Sig : Section.Signatures) { + for (const WasmYAML::Signature &Sig : Section.Signatures) { encodeSLEB128(Sig.Form, OS); encodeULEB128(Sig.ParamTypes.size(), OS); for (auto ParamType : Sig.ParamTypes) @@ -134,7 +160,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section) { encodeULEB128(Section.Imports.size(), OS); - for (auto &Import : Section.Imports) { + for (const WasmYAML::Import &Import : Section.Imports) { writeStringRef(Import.Module, OS); writeStringRef(Import.Field, OS); encodeULEB128(Import.Kind, OS); @@ -166,7 +192,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section) { encodeULEB128(Section.Exports.size(), OS); - for (auto &Export : Section.Exports) { + for (const WasmYAML::Export &Export : Section.Exports) { writeStringRef(Export.Name, OS); encodeULEB128(Export.Kind, OS); encodeULEB128(Export.Index, OS); @@ -193,7 +219,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section) { encodeULEB128(Section.Memories.size(), OS); - for (auto &Mem : Section.Memories) { + for (const WasmYAML::Limits &Mem : Section.Memories) { writeLimits(Mem, OS); } return 0; -- 2.7.4