aboutsummaryrefslogtreecommitdiff
path: root/tools/obj2yaml/wasm2yaml.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
commit71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch)
tree5343938942df402b49ec7300a1c25a2d4ccd5821 /tools/obj2yaml/wasm2yaml.cpp
parent31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff)
Diffstat (limited to 'tools/obj2yaml/wasm2yaml.cpp')
-rw-r--r--tools/obj2yaml/wasm2yaml.cpp219
1 files changed, 219 insertions, 0 deletions
diff --git a/tools/obj2yaml/wasm2yaml.cpp b/tools/obj2yaml/wasm2yaml.cpp
new file mode 100644
index 000000000000..f6b530c41969
--- /dev/null
+++ b/tools/obj2yaml/wasm2yaml.cpp
@@ -0,0 +1,219 @@
+//===------ utils/wasm2yaml.cpp - obj2yaml conversion tool ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "obj2yaml.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/ObjectYAML/WasmYAML.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace llvm;
+
+namespace {
+
+class WasmDumper {
+ const object::WasmObjectFile &Obj;
+
+public:
+ WasmDumper(const object::WasmObjectFile &O) : Obj(O) {}
+ ErrorOr<WasmYAML::Object *> dump();
+};
+
+ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
+ auto Y = make_unique<WasmYAML::Object>();
+
+ // Dump header
+ Y->Header.Version = Obj.getHeader().Version;
+
+ // Dump sections
+ for (const auto &Sec : Obj.sections()) {
+ const object::WasmSection &WasmSec = Obj.getWasmSection(Sec);
+ std::unique_ptr<WasmYAML::Section> S;
+ switch (WasmSec.Type) {
+ case wasm::WASM_SEC_CUSTOM: {
+ if (WasmSec.Name.startswith("reloc.")) {
+ // Relocations are attached the sections they apply to rather than
+ // being represented as a custom section in the YAML output.
+ continue;
+ }
+ auto CustomSec = make_unique<WasmYAML::CustomSection>();
+ CustomSec->Name = WasmSec.Name;
+ CustomSec->Payload = yaml::BinaryRef(WasmSec.Content);
+ S = std::move(CustomSec);
+ break;
+ }
+ case wasm::WASM_SEC_TYPE: {
+ auto TypeSec = make_unique<WasmYAML::TypeSection>();
+ uint32_t Index = 0;
+ for (const auto &FunctionSig : Obj.types()) {
+ WasmYAML::Signature Sig;
+ Sig.Index = Index++;
+ Sig.ReturnType = FunctionSig.ReturnType;
+ for (const auto &ParamType : FunctionSig.ParamTypes)
+ Sig.ParamTypes.push_back(ParamType);
+ TypeSec->Signatures.push_back(Sig);
+ }
+ S = std::move(TypeSec);
+ break;
+ }
+ case wasm::WASM_SEC_IMPORT: {
+ auto ImportSec = make_unique<WasmYAML::ImportSection>();
+ for (auto &Import : Obj.imports()) {
+ WasmYAML::Import Ex;
+ Ex.Module = Import.Module;
+ Ex.Field = Import.Field;
+ Ex.Kind = Import.Kind;
+ if (Ex.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
+ Ex.SigIndex = Import.SigIndex;
+ } else if (Ex.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
+ Ex.GlobalType = Import.GlobalType;
+ Ex.GlobalMutable = Import.GlobalMutable;
+ }
+ ImportSec->Imports.push_back(Ex);
+ }
+ S = std::move(ImportSec);
+ break;
+ }
+ case wasm::WASM_SEC_FUNCTION: {
+ auto FuncSec = make_unique<WasmYAML::FunctionSection>();
+ for (const auto &Func : Obj.functionTypes()) {
+ FuncSec->FunctionTypes.push_back(Func);
+ }
+ S = std::move(FuncSec);
+ break;
+ }
+ case wasm::WASM_SEC_TABLE: {
+ auto TableSec = make_unique<WasmYAML::TableSection>();
+ for (auto &Table : Obj.tables()) {
+ WasmYAML::Table T;
+ T.ElemType = Table.ElemType;
+ T.TableLimits.Flags = Table.Limits.Flags;
+ T.TableLimits.Initial = Table.Limits.Initial;
+ T.TableLimits.Maximum = Table.Limits.Maximum;
+ TableSec->Tables.push_back(T);
+ }
+ S = std::move(TableSec);
+ break;
+ }
+ case wasm::WASM_SEC_MEMORY: {
+ auto MemorySec = make_unique<WasmYAML::MemorySection>();
+ for (auto &Memory : Obj.memories()) {
+ WasmYAML::Limits L;
+ L.Flags = Memory.Flags;
+ L.Initial = Memory.Initial;
+ L.Maximum = Memory.Maximum;
+ MemorySec->Memories.push_back(L);
+ }
+ S = std::move(MemorySec);
+ break;
+ }
+ case wasm::WASM_SEC_GLOBAL: {
+ auto GlobalSec = make_unique<WasmYAML::GlobalSection>();
+ for (auto &Global : Obj.globals()) {
+ WasmYAML::Global G;
+ G.Type = Global.Type;
+ G.Mutable = Global.Mutable;
+ G.InitExpr = Global.InitExpr;
+ GlobalSec->Globals.push_back(G);
+ }
+ S = std::move(GlobalSec);
+ break;
+ }
+ case wasm::WASM_SEC_START: {
+ auto StartSec = make_unique<WasmYAML::StartSection>();
+ StartSec->StartFunction = Obj.startFunction();
+ S = std::move(StartSec);
+ break;
+ }
+ case wasm::WASM_SEC_EXPORT: {
+ auto ExportSec = make_unique<WasmYAML::ExportSection>();
+ for (auto &Export : Obj.exports()) {
+ WasmYAML::Export Ex;
+ Ex.Name = Export.Name;
+ Ex.Kind = Export.Kind;
+ Ex.Index = Export.Index;
+ ExportSec->Exports.push_back(Ex);
+ }
+ S = std::move(ExportSec);
+ break;
+ }
+ case wasm::WASM_SEC_ELEM: {
+ auto ElemSec = make_unique<WasmYAML::ElemSection>();
+ for (auto &Segment : Obj.elements()) {
+ WasmYAML::ElemSegment Seg;
+ Seg.TableIndex = Segment.TableIndex;
+ Seg.Offset = Segment.Offset;
+ for (auto &Func : Segment.Functions) {
+ Seg.Functions.push_back(Func);
+ }
+ ElemSec->Segments.push_back(Seg);
+ }
+ S = std::move(ElemSec);
+ break;
+ }
+ case wasm::WASM_SEC_CODE: {
+ auto CodeSec = make_unique<WasmYAML::CodeSection>();
+ for (auto &Func : Obj.functions()) {
+ WasmYAML::Function Function;
+ for (auto &Local : Func.Locals) {
+ WasmYAML::LocalDecl LocalDecl;
+ LocalDecl.Type = Local.Type;
+ LocalDecl.Count = Local.Count;
+ Function.Locals.push_back(LocalDecl);
+ }
+ Function.Body = yaml::BinaryRef(Func.Body);
+ CodeSec->Functions.push_back(Function);
+ }
+ S = std::move(CodeSec);
+ break;
+ }
+ case wasm::WASM_SEC_DATA: {
+ auto DataSec = make_unique<WasmYAML::DataSection>();
+ for (auto &Segment : Obj.dataSegments()) {
+ WasmYAML::DataSegment Seg;
+ Seg.Index = Segment.Index;
+ Seg.Offset = Segment.Offset;
+ Seg.Content = yaml::BinaryRef(Segment.Content);
+ DataSec->Segments.push_back(Seg);
+ }
+ S = std::move(DataSec);
+ break;
+ }
+ default:
+ llvm_unreachable("Unknown section type");
+ break;
+ }
+ for (const wasm::WasmRelocation &Reloc: WasmSec.Relocations) {
+ WasmYAML::Relocation R;
+ R.Type = Reloc.Type;
+ R.Index = Reloc.Index;
+ R.Offset = Reloc.Offset;
+ R.Addend = Reloc.Addend;
+ S->Relocations.push_back(R);
+ }
+ Y->Sections.push_back(std::move(S));
+ }
+
+ return Y.release();
+}
+
+} // namespace
+
+std::error_code wasm2yaml(raw_ostream &Out, const object::WasmObjectFile &Obj) {
+ WasmDumper Dumper(Obj);
+ ErrorOr<WasmYAML::Object *> YAMLOrErr = Dumper.dump();
+ if (std::error_code EC = YAMLOrErr.getError())
+ return EC;
+
+ std::unique_ptr<WasmYAML::Object> YAML(YAMLOrErr.get());
+ yaml::Output Yout(Out);
+ Yout << *YAML;
+
+ return std::error_code();
+}