diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 |
commit | 71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch) | |
tree | 5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/ObjectYAML | |
parent | 31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff) |
Diffstat (limited to 'lib/ObjectYAML')
-rw-r--r-- | lib/ObjectYAML/CMakeLists.txt | 7 | ||||
-rw-r--r-- | lib/ObjectYAML/DWARFEmitter.cpp | 321 | ||||
-rw-r--r-- | lib/ObjectYAML/DWARFVisitor.cpp | 178 | ||||
-rw-r--r-- | lib/ObjectYAML/DWARFVisitor.h | 97 | ||||
-rw-r--r-- | lib/ObjectYAML/DWARFYAML.cpp | 15 | ||||
-rw-r--r-- | lib/ObjectYAML/ELFYAML.cpp | 834 | ||||
-rw-r--r-- | lib/ObjectYAML/MachOYAML.cpp | 29 | ||||
-rw-r--r-- | lib/ObjectYAML/ObjectYAML.cpp | 3 | ||||
-rw-r--r-- | lib/ObjectYAML/WasmYAML.cpp | 357 |
9 files changed, 1418 insertions, 423 deletions
diff --git a/lib/ObjectYAML/CMakeLists.txt b/lib/ObjectYAML/CMakeLists.txt index 2eee95b318db..37f8fd7bce1a 100644 --- a/lib/ObjectYAML/CMakeLists.txt +++ b/lib/ObjectYAML/CMakeLists.txt @@ -1,8 +1,11 @@ add_llvm_library(LLVMObjectYAML - YAML.cpp COFFYAML.cpp + DWARFEmitter.cpp + DWARFVisitor.cpp + DWARFYAML.cpp ELFYAML.cpp MachOYAML.cpp ObjectYAML.cpp - DWARFYAML.cpp + WasmYAML.cpp + YAML.cpp ) diff --git a/lib/ObjectYAML/DWARFEmitter.cpp b/lib/ObjectYAML/DWARFEmitter.cpp new file mode 100644 index 000000000000..1aa1519b708b --- /dev/null +++ b/lib/ObjectYAML/DWARFEmitter.cpp @@ -0,0 +1,321 @@ +//===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief The DWARF component of yaml2obj. Provided as library code for tests. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/DWARFEmitter.h" +#include "llvm/ObjectYAML/DWARFYAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/LEB128.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SwapByteOrder.h" + +#include "DWARFVisitor.h" + +#include <algorithm> + +using namespace llvm; + +template <typename T> +static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) { + if (IsLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(Integer); + OS.write(reinterpret_cast<char *>(&Integer), sizeof(T)); +} + +static void writeVariableSizedInteger(uint64_t Integer, size_t Size, + raw_ostream &OS, bool IsLittleEndian) { + if (8 == Size) + writeInteger((uint64_t)Integer, OS, IsLittleEndian); + else if (4 == Size) + writeInteger((uint32_t)Integer, OS, IsLittleEndian); + else if (2 == Size) + writeInteger((uint16_t)Integer, OS, IsLittleEndian); + else if (1 == Size) + writeInteger((uint8_t)Integer, OS, IsLittleEndian); + else + assert(false && "Invalid integer write size."); +} + +static void ZeroFillBytes(raw_ostream &OS, size_t Size) { + std::vector<uint8_t> FillData; + FillData.insert(FillData.begin(), Size, 0); + OS.write(reinterpret_cast<char *>(FillData.data()), Size); +} + +void writeInitialLength(const DWARFYAML::InitialLength &Length, raw_ostream &OS, + bool IsLittleEndian) { + writeInteger((uint32_t)Length.TotalLength, OS, IsLittleEndian); + if (Length.isDWARF64()) + writeInteger((uint64_t)Length.TotalLength64, OS, IsLittleEndian); +} + +void DWARFYAML::EmitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (auto Str : DI.DebugStrings) { + OS.write(Str.data(), Str.size()); + OS.write('\0'); + } +} + +void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (auto AbbrevDecl : DI.AbbrevDecls) { + encodeULEB128(AbbrevDecl.Code, OS); + encodeULEB128(AbbrevDecl.Tag, OS); + OS.write(AbbrevDecl.Children); + for (auto Attr : AbbrevDecl.Attributes) { + encodeULEB128(Attr.Attribute, OS); + encodeULEB128(Attr.Form, OS); + if (Attr.Form == dwarf::DW_FORM_implicit_const) + encodeSLEB128(Attr.Value, OS); + } + encodeULEB128(0, OS); + encodeULEB128(0, OS); + } +} + +void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (auto Range : DI.ARanges) { + auto HeaderStart = OS.tell(); + writeInitialLength(Range.Length, OS, DI.IsLittleEndian); + writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian); + writeInteger((uint32_t)Range.CuOffset, OS, DI.IsLittleEndian); + writeInteger((uint8_t)Range.AddrSize, OS, DI.IsLittleEndian); + writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian); + + auto HeaderSize = OS.tell() - HeaderStart; + auto FirstDescriptor = alignTo(HeaderSize, Range.AddrSize * 2); + ZeroFillBytes(OS, FirstDescriptor - HeaderSize); + + for (auto Descriptor : Range.Descriptors) { + writeVariableSizedInteger(Descriptor.Address, Range.AddrSize, OS, + DI.IsLittleEndian); + writeVariableSizedInteger(Descriptor.Length, Range.AddrSize, OS, + DI.IsLittleEndian); + } + ZeroFillBytes(OS, Range.AddrSize * 2); + } +} + +void DWARFYAML::EmitPubSection(raw_ostream &OS, + const DWARFYAML::PubSection &Sect, + bool IsLittleEndian) { + writeInitialLength(Sect.Length, OS, IsLittleEndian); + writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian); + writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian); + writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian); + for (auto Entry : Sect.Entries) { + writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian); + if (Sect.IsGNUStyle) + writeInteger((uint32_t)Entry.Descriptor, OS, IsLittleEndian); + OS.write(Entry.Name.data(), Entry.Name.size()); + OS.write('\0'); + } +} + +/// \brief An extension of the DWARFYAML::ConstVisitor which writes compile +/// units and DIEs to a stream. +class DumpVisitor : public DWARFYAML::ConstVisitor { + raw_ostream &OS; + +protected: + virtual void onStartCompileUnit(const DWARFYAML::Unit &CU) { + writeInitialLength(CU.Length, OS, DebugInfo.IsLittleEndian); + writeInteger((uint16_t)CU.Version, OS, DebugInfo.IsLittleEndian); + if(CU.Version >= 5) { + writeInteger((uint8_t)CU.Type, OS, DebugInfo.IsLittleEndian); + writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian); + writeInteger((uint32_t)CU.AbbrOffset, OS, DebugInfo.IsLittleEndian); + }else { + writeInteger((uint32_t)CU.AbbrOffset, OS, DebugInfo.IsLittleEndian); + writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian); + } + + } + + virtual void onStartDIE(const DWARFYAML::Unit &CU, + const DWARFYAML::Entry &DIE) { + encodeULEB128(DIE.AbbrCode, OS); + } + + virtual void onValue(const uint8_t U) { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + virtual void onValue(const uint16_t U) { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + virtual void onValue(const uint32_t U) { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + virtual void onValue(const uint64_t U, const bool LEB = false) { + if (LEB) + encodeULEB128(U, OS); + else + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + virtual void onValue(const int64_t S, const bool LEB = false) { + if (LEB) + encodeSLEB128(S, OS); + else + writeInteger(S, OS, DebugInfo.IsLittleEndian); + } + + virtual void onValue(const StringRef String) { + OS.write(String.data(), String.size()); + OS.write('\0'); + } + + virtual void onValue(const MemoryBufferRef MBR) { + OS.write(MBR.getBufferStart(), MBR.getBufferSize()); + } + +public: + DumpVisitor(const DWARFYAML::Data &DI, raw_ostream &Out) + : DWARFYAML::ConstVisitor(DI), OS(Out) {} +}; + +void DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { + DumpVisitor Visitor(DI, OS); + Visitor.traverseDebugInfo(); +} + +static void EmitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { + OS.write(File.Name.data(), File.Name.size()); + OS.write('\0'); + encodeULEB128(File.DirIdx, OS); + encodeULEB128(File.ModTime, OS); + encodeULEB128(File.Length, OS); +} + +void DWARFYAML::EmitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (const auto &LineTable : DI.DebugLines) { + writeInitialLength(LineTable.Length, OS, DI.IsLittleEndian); + uint64_t SizeOfPrologueLength = LineTable.Length.isDWARF64() ? 8 : 4; + writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian); + writeVariableSizedInteger(LineTable.PrologueLength, SizeOfPrologueLength, + OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian); + if (LineTable.Version >= 4) + writeInteger((uint8_t)LineTable.MaxOpsPerInst, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.DefaultIsStmt, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.LineBase, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.LineRange, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.OpcodeBase, OS, DI.IsLittleEndian); + + for (auto OpcodeLength : LineTable.StandardOpcodeLengths) + writeInteger((uint8_t)OpcodeLength, OS, DI.IsLittleEndian); + + for (auto IncludeDir : LineTable.IncludeDirs) { + OS.write(IncludeDir.data(), IncludeDir.size()); + OS.write('\0'); + } + OS.write('\0'); + + for (auto File : LineTable.Files) + EmitFileEntry(OS, File); + OS.write('\0'); + + for (auto Op : LineTable.Opcodes) { + writeInteger((uint8_t)Op.Opcode, OS, DI.IsLittleEndian); + if (Op.Opcode == 0) { + encodeULEB128(Op.ExtLen, OS); + writeInteger((uint8_t)Op.SubOpcode, OS, DI.IsLittleEndian); + switch (Op.SubOpcode) { + case dwarf::DW_LNE_set_address: + case dwarf::DW_LNE_set_discriminator: + writeVariableSizedInteger(Op.Data, DI.CompileUnits[0].AddrSize, OS, + DI.IsLittleEndian); + break; + case dwarf::DW_LNE_define_file: + EmitFileEntry(OS, Op.FileEntry); + break; + case dwarf::DW_LNE_end_sequence: + break; + default: + for (auto OpByte : Op.UnknownOpcodeData) + writeInteger((uint8_t)OpByte, OS, DI.IsLittleEndian); + } + } else if (Op.Opcode < LineTable.OpcodeBase) { + switch (Op.Opcode) { + case dwarf::DW_LNS_copy: + case dwarf::DW_LNS_negate_stmt: + case dwarf::DW_LNS_set_basic_block: + case dwarf::DW_LNS_const_add_pc: + case dwarf::DW_LNS_set_prologue_end: + case dwarf::DW_LNS_set_epilogue_begin: + break; + + case dwarf::DW_LNS_advance_pc: + case dwarf::DW_LNS_set_file: + case dwarf::DW_LNS_set_column: + case dwarf::DW_LNS_set_isa: + encodeULEB128(Op.Data, OS); + break; + + case dwarf::DW_LNS_advance_line: + encodeSLEB128(Op.SData, OS); + break; + + case dwarf::DW_LNS_fixed_advance_pc: + writeInteger((uint16_t)Op.Data, OS, DI.IsLittleEndian); + break; + + default: + for (auto OpData : Op.StandardOpcodeData) { + encodeULEB128(OpData, OS); + } + } + } + } + } +} + +typedef void (*EmitFuncType)(raw_ostream &, const DWARFYAML::Data &); + +static void +EmitDebugSectionImpl(const DWARFYAML::Data &DI, EmitFuncType EmitFunc, + StringRef Sec, + StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) { + std::string Data; + raw_string_ostream DebugInfoStream(Data); + EmitFunc(DebugInfoStream, DI); + DebugInfoStream.flush(); + if (!Data.empty()) + OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data); +} + +Expected<StringMap<std::unique_ptr<MemoryBuffer>>> +DWARFYAML::EmitDebugSections(StringRef YAMLString, + bool IsLittleEndian) { + StringMap<std::unique_ptr<MemoryBuffer>> DebugSections; + + yaml::Input YIn(YAMLString); + + DWARFYAML::Data DI; + DI.IsLittleEndian = IsLittleEndian; + YIn >> DI; + if (YIn.error()) + return errorCodeToError(YIn.error()); + + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugInfo, "debug_info", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugLine, "debug_line", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugStr, "debug_str", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAbbrev, "debug_abbrev", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAranges, "debug_aranges", + DebugSections); + return std::move(DebugSections); +} diff --git a/lib/ObjectYAML/DWARFVisitor.cpp b/lib/ObjectYAML/DWARFVisitor.cpp new file mode 100644 index 000000000000..36a9f7638bd4 --- /dev/null +++ b/lib/ObjectYAML/DWARFVisitor.cpp @@ -0,0 +1,178 @@ +//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "DWARFVisitor.h" +#include "llvm/ObjectYAML/DWARFYAML.h" + +using namespace llvm; + +template <typename T> +void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) { + switch (Size) { + case 8: + onValue((uint64_t)U); + break; + case 4: + onValue((uint32_t)U); + break; + case 2: + onValue((uint16_t)U); + break; + case 1: + onValue((uint8_t)U); + break; + default: + llvm_unreachable("Invalid integer write size."); + } +} + +unsigned getOffsetSize(const DWARFYAML::Unit &Unit) { + return Unit.Length.isDWARF64() ? 8 : 4; +} + +unsigned getRefSize(const DWARFYAML::Unit &Unit) { + if (Unit.Version == 2) + return Unit.AddrSize; + return getOffsetSize(Unit); +} + +template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() { + for (auto &Unit : DebugInfo.CompileUnits) { + onStartCompileUnit(Unit); + auto FirstAbbrevCode = Unit.Entries[0].AbbrCode; + + for (auto &Entry : Unit.Entries) { + onStartDIE(Unit, Entry); + if (Entry.AbbrCode == 0u) + continue; + auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode]; + auto FormVal = Entry.Values.begin(); + auto AbbrForm = Abbrev.Attributes.begin(); + for (; + FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); + ++FormVal, ++AbbrForm) { + onForm(*AbbrForm, *FormVal); + dwarf::Form Form = AbbrForm->Form; + bool Indirect; + do { + Indirect = false; + switch (Form) { + case dwarf::DW_FORM_addr: + onVariableSizeValue(FormVal->Value, Unit.AddrSize); + break; + case dwarf::DW_FORM_ref_addr: + onVariableSizeValue(FormVal->Value, getRefSize(Unit)); + break; + case dwarf::DW_FORM_exprloc: + case dwarf::DW_FORM_block: + onValue((uint64_t)FormVal->BlockData.size(), true); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + case dwarf::DW_FORM_block1: { + auto writeSize = FormVal->BlockData.size(); + onValue((uint8_t)writeSize); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + } + case dwarf::DW_FORM_block2: { + auto writeSize = FormVal->BlockData.size(); + onValue((uint16_t)writeSize); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + } + case dwarf::DW_FORM_block4: { + auto writeSize = FormVal->BlockData.size(); + onValue((uint32_t)writeSize); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + } + case dwarf::DW_FORM_data1: + case dwarf::DW_FORM_ref1: + case dwarf::DW_FORM_flag: + case dwarf::DW_FORM_strx1: + case dwarf::DW_FORM_addrx1: + onValue((uint8_t)FormVal->Value); + break; + case dwarf::DW_FORM_data2: + case dwarf::DW_FORM_ref2: + case dwarf::DW_FORM_strx2: + case dwarf::DW_FORM_addrx2: + onValue((uint16_t)FormVal->Value); + break; + case dwarf::DW_FORM_data4: + case dwarf::DW_FORM_ref4: + case dwarf::DW_FORM_ref_sup4: + case dwarf::DW_FORM_strx4: + case dwarf::DW_FORM_addrx4: + onValue((uint32_t)FormVal->Value); + break; + case dwarf::DW_FORM_data8: + case dwarf::DW_FORM_ref8: + case dwarf::DW_FORM_ref_sup8: + onValue((uint64_t)FormVal->Value); + break; + case dwarf::DW_FORM_sdata: + onValue((int64_t)FormVal->Value, true); + break; + case dwarf::DW_FORM_udata: + case dwarf::DW_FORM_ref_udata: + onValue((uint64_t)FormVal->Value, true); + break; + case dwarf::DW_FORM_string: + onValue(FormVal->CStr); + break; + case dwarf::DW_FORM_indirect: + onValue((uint64_t)FormVal->Value, true); + Indirect = true; + Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value); + ++FormVal; + break; + case dwarf::DW_FORM_strp: + case dwarf::DW_FORM_sec_offset: + case dwarf::DW_FORM_GNU_ref_alt: + case dwarf::DW_FORM_GNU_strp_alt: + case dwarf::DW_FORM_line_strp: + case dwarf::DW_FORM_strp_sup: + onVariableSizeValue(FormVal->Value, getOffsetSize(Unit)); + break; + case dwarf::DW_FORM_ref_sig8: + onValue((uint64_t)FormVal->Value); + break; + case dwarf::DW_FORM_GNU_addr_index: + case dwarf::DW_FORM_GNU_str_index: + onValue((uint64_t)FormVal->Value, true); + break; + default: + break; + } + } while (Indirect); + } + onEndDIE(Unit, Entry); + } + onEndCompileUnit(Unit); + } +} + +// Explicitly instantiate the two template expansions. +template class DWARFYAML::VisitorImpl<DWARFYAML::Data>; +template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>; diff --git a/lib/ObjectYAML/DWARFVisitor.h b/lib/ObjectYAML/DWARFVisitor.h new file mode 100644 index 000000000000..263e36220a05 --- /dev/null +++ b/lib/ObjectYAML/DWARFVisitor.h @@ -0,0 +1,97 @@ +//===--- DWARFVisitor.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_DWARFVISITOR_H +#define LLVM_OBJECTYAML_DWARFVISITOR_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/MemoryBuffer.h" + +namespace llvm { + +namespace DWARFYAML { + +struct Data; +struct Unit; +struct Entry; +struct FormValue; +struct AttributeAbbrev; + +/// \brief A class to visits DWARFYAML Compile Units and DIEs in preorder. +/// +/// Extensions of this class can either maintain const or non-const references +/// to the DWARFYAML::Data object. +template <typename T> class VisitorImpl { +protected: + T &DebugInfo; + + /// Visitor Functions + /// @{ + virtual void onStartCompileUnit(Unit &CU) {} + virtual void onEndCompileUnit(Unit &CU) {} + virtual void onStartDIE(Unit &CU, Entry &DIE) {} + virtual void onEndDIE(Unit &CU, Entry &DIE) {} + virtual void onForm(AttributeAbbrev &AttAbbrev, FormValue &Value) {} + /// @} + + /// Const Visitor Functions + /// @{ + virtual void onStartCompileUnit(const Unit &CU) {} + virtual void onEndCompileUnit(const Unit &CU) {} + virtual void onStartDIE(const Unit &CU, const Entry &DIE) {} + virtual void onEndDIE(const Unit &CU, const Entry &DIE) {} + virtual void onForm(const AttributeAbbrev &AttAbbrev, + const FormValue &Value) {} + /// @} + + /// Value visitors + /// @{ + virtual void onValue(const uint8_t U) {} + virtual void onValue(const uint16_t U) {} + virtual void onValue(const uint32_t U) {} + virtual void onValue(const uint64_t U, const bool LEB = false) {} + virtual void onValue(const int64_t S, const bool LEB = false) {} + virtual void onValue(const StringRef String) {} + virtual void onValue(const MemoryBufferRef MBR) {} + /// @} + +public: + VisitorImpl(T &DI) : DebugInfo(DI) {} + + virtual ~VisitorImpl() {} + + void traverseDebugInfo(); + +private: + void onVariableSizeValue(uint64_t U, unsigned Size); +}; + +// Making the visior instantiations extern and explicit in the cpp file. This +// prevents them from being instantiated in every compile unit that uses the +// visitors. +extern template class VisitorImpl<DWARFYAML::Data>; +extern template class VisitorImpl<const DWARFYAML::Data>; + +class Visitor : public VisitorImpl<Data> { +public: + Visitor(Data &DI) : VisitorImpl<Data>(DI) {} +}; + +class ConstVisitor : public VisitorImpl<const Data> { +public: + ConstVisitor(const Data &DI) : VisitorImpl<const Data>(DI) {} +}; + +} // namespace DWARFYAML +} // namespace llvm + +#endif diff --git a/lib/ObjectYAML/DWARFYAML.cpp b/lib/ObjectYAML/DWARFYAML.cpp index 014e63fe7d34..edb9545f14b1 100644 --- a/lib/ObjectYAML/DWARFYAML.cpp +++ b/lib/ObjectYAML/DWARFYAML.cpp @@ -54,6 +54,8 @@ void MappingTraits<DWARFYAML::AttributeAbbrev>::mapping( IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev) { IO.mapRequired("Attribute", AttAbbrev.Attribute); IO.mapRequired("Form", AttAbbrev.Form); + if(AttAbbrev.Form == dwarf::DW_FORM_implicit_const) + IO.mapRequired("Value", AttAbbrev.Value); } void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping( @@ -97,6 +99,8 @@ void MappingTraits<DWARFYAML::PubSection>::mapping( void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) { IO.mapRequired("Length", Unit.Length); IO.mapRequired("Version", Unit.Version); + if (Unit.Version >= 5) + IO.mapRequired("UnitType", Unit.Type); IO.mapRequired("AbbrOffset", Unit.AbbrOffset); IO.mapRequired("AddrSize", Unit.AddrSize); IO.mapOptional("Entries", Unit.Entries); @@ -144,9 +148,7 @@ void MappingTraits<DWARFYAML::LineTableOpcode>::mapping( void MappingTraits<DWARFYAML::LineTable>::mapping( IO &IO, DWARFYAML::LineTable &LineTable) { - IO.mapRequired("TotalLength", LineTable.TotalLength); - if (LineTable.TotalLength == UINT32_MAX) - IO.mapRequired("TotalLength64", LineTable.TotalLength64); + IO.mapRequired("Length", LineTable.Length); IO.mapRequired("Version", LineTable.Version); IO.mapRequired("PrologueLength", LineTable.PrologueLength); IO.mapRequired("MinInstLength", LineTable.MinInstLength); @@ -162,6 +164,13 @@ void MappingTraits<DWARFYAML::LineTable>::mapping( IO.mapRequired("Opcodes", LineTable.Opcodes); } +void MappingTraits<DWARFYAML::InitialLength>::mapping( + IO &IO, DWARFYAML::InitialLength &InitialLength) { + IO.mapRequired("TotalLength", InitialLength.TotalLength); + if (InitialLength.isDWARF64()) + IO.mapRequired("TotalLength64", InitialLength.TotalLength64); +} + } // namespace llvm::yaml } // namespace llvm diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp index fe9af9f3ac76..3052901da45c 100644 --- a/lib/ObjectYAML/ELFYAML.cpp +++ b/lib/ObjectYAML/ELFYAML.cpp @@ -21,231 +21,229 @@ ELFYAML::Section::~Section() {} namespace yaml { -void -ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(IO &IO, - ELFYAML::ELF_ET &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(ET_NONE) - ECase(ET_REL) - ECase(ET_EXEC) - ECase(ET_DYN) - ECase(ET_CORE) +void ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration( + IO &IO, ELFYAML::ELF_ET &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(ET_NONE); + ECase(ET_REL); + ECase(ET_EXEC); + ECase(ET_DYN); + ECase(ET_CORE); #undef ECase IO.enumFallback<Hex16>(Value); } -void -ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO, - ELFYAML::ELF_EM &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(EM_NONE) - ECase(EM_M32) - ECase(EM_SPARC) - ECase(EM_386) - ECase(EM_68K) - ECase(EM_88K) - ECase(EM_IAMCU) - ECase(EM_860) - ECase(EM_MIPS) - ECase(EM_S370) - ECase(EM_MIPS_RS3_LE) - ECase(EM_PARISC) - ECase(EM_VPP500) - ECase(EM_SPARC32PLUS) - ECase(EM_960) - ECase(EM_PPC) - ECase(EM_PPC64) - ECase(EM_S390) - ECase(EM_SPU) - ECase(EM_V800) - ECase(EM_FR20) - ECase(EM_RH32) - ECase(EM_RCE) - ECase(EM_ARM) - ECase(EM_ALPHA) - ECase(EM_SH) - ECase(EM_SPARCV9) - ECase(EM_TRICORE) - ECase(EM_ARC) - ECase(EM_H8_300) - ECase(EM_H8_300H) - ECase(EM_H8S) - ECase(EM_H8_500) - ECase(EM_IA_64) - ECase(EM_MIPS_X) - ECase(EM_COLDFIRE) - ECase(EM_68HC12) - ECase(EM_MMA) - ECase(EM_PCP) - ECase(EM_NCPU) - ECase(EM_NDR1) - ECase(EM_STARCORE) - ECase(EM_ME16) - ECase(EM_ST100) - ECase(EM_TINYJ) - ECase(EM_X86_64) - ECase(EM_PDSP) - ECase(EM_PDP10) - ECase(EM_PDP11) - ECase(EM_FX66) - ECase(EM_ST9PLUS) - ECase(EM_ST7) - ECase(EM_68HC16) - ECase(EM_68HC11) - ECase(EM_68HC08) - ECase(EM_68HC05) - ECase(EM_SVX) - ECase(EM_ST19) - ECase(EM_VAX) - ECase(EM_CRIS) - ECase(EM_JAVELIN) - ECase(EM_FIREPATH) - ECase(EM_ZSP) - ECase(EM_MMIX) - ECase(EM_HUANY) - ECase(EM_PRISM) - ECase(EM_AVR) - ECase(EM_FR30) - ECase(EM_D10V) - ECase(EM_D30V) - ECase(EM_V850) - ECase(EM_M32R) - ECase(EM_MN10300) - ECase(EM_MN10200) - ECase(EM_PJ) - ECase(EM_OPENRISC) - ECase(EM_ARC_COMPACT) - ECase(EM_XTENSA) - ECase(EM_VIDEOCORE) - ECase(EM_TMM_GPP) - ECase(EM_NS32K) - ECase(EM_TPC) - ECase(EM_SNP1K) - ECase(EM_ST200) - ECase(EM_IP2K) - ECase(EM_MAX) - ECase(EM_CR) - ECase(EM_F2MC16) - ECase(EM_MSP430) - ECase(EM_BLACKFIN) - ECase(EM_SE_C33) - ECase(EM_SEP) - ECase(EM_ARCA) - ECase(EM_UNICORE) - ECase(EM_EXCESS) - ECase(EM_DXP) - ECase(EM_ALTERA_NIOS2) - ECase(EM_CRX) - ECase(EM_XGATE) - ECase(EM_C166) - ECase(EM_M16C) - ECase(EM_DSPIC30F) - ECase(EM_CE) - ECase(EM_M32C) - ECase(EM_TSK3000) - ECase(EM_RS08) - ECase(EM_SHARC) - ECase(EM_ECOG2) - ECase(EM_SCORE7) - ECase(EM_DSP24) - ECase(EM_VIDEOCORE3) - ECase(EM_LATTICEMICO32) - ECase(EM_SE_C17) - ECase(EM_TI_C6000) - ECase(EM_TI_C2000) - ECase(EM_TI_C5500) - ECase(EM_MMDSP_PLUS) - ECase(EM_CYPRESS_M8C) - ECase(EM_R32C) - ECase(EM_TRIMEDIA) - ECase(EM_HEXAGON) - ECase(EM_8051) - ECase(EM_STXP7X) - ECase(EM_NDS32) - ECase(EM_ECOG1) - ECase(EM_ECOG1X) - ECase(EM_MAXQ30) - ECase(EM_XIMO16) - ECase(EM_MANIK) - ECase(EM_CRAYNV2) - ECase(EM_RX) - ECase(EM_METAG) - ECase(EM_MCST_ELBRUS) - ECase(EM_ECOG16) - ECase(EM_CR16) - ECase(EM_ETPU) - ECase(EM_SLE9X) - ECase(EM_L10M) - ECase(EM_K10M) - ECase(EM_AARCH64) - ECase(EM_AVR32) - ECase(EM_STM8) - ECase(EM_TILE64) - ECase(EM_TILEPRO) - ECase(EM_CUDA) - ECase(EM_TILEGX) - ECase(EM_CLOUDSHIELD) - ECase(EM_COREA_1ST) - ECase(EM_COREA_2ND) - ECase(EM_ARC_COMPACT2) - ECase(EM_OPEN8) - ECase(EM_RL78) - ECase(EM_VIDEOCORE5) - ECase(EM_78KOR) - ECase(EM_56800EX) - ECase(EM_AMDGPU) - ECase(EM_RISCV) - ECase(EM_LANAI) - ECase(EM_BPF) +void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration( + IO &IO, ELFYAML::ELF_EM &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(EM_NONE); + ECase(EM_M32); + ECase(EM_SPARC); + ECase(EM_386); + ECase(EM_68K); + ECase(EM_88K); + ECase(EM_IAMCU); + ECase(EM_860); + ECase(EM_MIPS); + ECase(EM_S370); + ECase(EM_MIPS_RS3_LE); + ECase(EM_PARISC); + ECase(EM_VPP500); + ECase(EM_SPARC32PLUS); + ECase(EM_960); + ECase(EM_PPC); + ECase(EM_PPC64); + ECase(EM_S390); + ECase(EM_SPU); + ECase(EM_V800); + ECase(EM_FR20); + ECase(EM_RH32); + ECase(EM_RCE); + ECase(EM_ARM); + ECase(EM_ALPHA); + ECase(EM_SH); + ECase(EM_SPARCV9); + ECase(EM_TRICORE); + ECase(EM_ARC); + ECase(EM_H8_300); + ECase(EM_H8_300H); + ECase(EM_H8S); + ECase(EM_H8_500); + ECase(EM_IA_64); + ECase(EM_MIPS_X); + ECase(EM_COLDFIRE); + ECase(EM_68HC12); + ECase(EM_MMA); + ECase(EM_PCP); + ECase(EM_NCPU); + ECase(EM_NDR1); + ECase(EM_STARCORE); + ECase(EM_ME16); + ECase(EM_ST100); + ECase(EM_TINYJ); + ECase(EM_X86_64); + ECase(EM_PDSP); + ECase(EM_PDP10); + ECase(EM_PDP11); + ECase(EM_FX66); + ECase(EM_ST9PLUS); + ECase(EM_ST7); + ECase(EM_68HC16); + ECase(EM_68HC11); + ECase(EM_68HC08); + ECase(EM_68HC05); + ECase(EM_SVX); + ECase(EM_ST19); + ECase(EM_VAX); + ECase(EM_CRIS); + ECase(EM_JAVELIN); + ECase(EM_FIREPATH); + ECase(EM_ZSP); + ECase(EM_MMIX); + ECase(EM_HUANY); + ECase(EM_PRISM); + ECase(EM_AVR); + ECase(EM_FR30); + ECase(EM_D10V); + ECase(EM_D30V); + ECase(EM_V850); + ECase(EM_M32R); + ECase(EM_MN10300); + ECase(EM_MN10200); + ECase(EM_PJ); + ECase(EM_OPENRISC); + ECase(EM_ARC_COMPACT); + ECase(EM_XTENSA); + ECase(EM_VIDEOCORE); + ECase(EM_TMM_GPP); + ECase(EM_NS32K); + ECase(EM_TPC); + ECase(EM_SNP1K); + ECase(EM_ST200); + ECase(EM_IP2K); + ECase(EM_MAX); + ECase(EM_CR); + ECase(EM_F2MC16); + ECase(EM_MSP430); + ECase(EM_BLACKFIN); + ECase(EM_SE_C33); + ECase(EM_SEP); + ECase(EM_ARCA); + ECase(EM_UNICORE); + ECase(EM_EXCESS); + ECase(EM_DXP); + ECase(EM_ALTERA_NIOS2); + ECase(EM_CRX); + ECase(EM_XGATE); + ECase(EM_C166); + ECase(EM_M16C); + ECase(EM_DSPIC30F); + ECase(EM_CE); + ECase(EM_M32C); + ECase(EM_TSK3000); + ECase(EM_RS08); + ECase(EM_SHARC); + ECase(EM_ECOG2); + ECase(EM_SCORE7); + ECase(EM_DSP24); + ECase(EM_VIDEOCORE3); + ECase(EM_LATTICEMICO32); + ECase(EM_SE_C17); + ECase(EM_TI_C6000); + ECase(EM_TI_C2000); + ECase(EM_TI_C5500); + ECase(EM_MMDSP_PLUS); + ECase(EM_CYPRESS_M8C); + ECase(EM_R32C); + ECase(EM_TRIMEDIA); + ECase(EM_HEXAGON); + ECase(EM_8051); + ECase(EM_STXP7X); + ECase(EM_NDS32); + ECase(EM_ECOG1); + ECase(EM_ECOG1X); + ECase(EM_MAXQ30); + ECase(EM_XIMO16); + ECase(EM_MANIK); + ECase(EM_CRAYNV2); + ECase(EM_RX); + ECase(EM_METAG); + ECase(EM_MCST_ELBRUS); + ECase(EM_ECOG16); + ECase(EM_CR16); + ECase(EM_ETPU); + ECase(EM_SLE9X); + ECase(EM_L10M); + ECase(EM_K10M); + ECase(EM_AARCH64); + ECase(EM_AVR32); + ECase(EM_STM8); + ECase(EM_TILE64); + ECase(EM_TILEPRO); + ECase(EM_CUDA); + ECase(EM_TILEGX); + ECase(EM_CLOUDSHIELD); + ECase(EM_COREA_1ST); + ECase(EM_COREA_2ND); + ECase(EM_ARC_COMPACT2); + ECase(EM_OPEN8); + ECase(EM_RL78); + ECase(EM_VIDEOCORE5); + ECase(EM_78KOR); + ECase(EM_56800EX); + ECase(EM_AMDGPU); + ECase(EM_RISCV); + ECase(EM_LANAI); + ECase(EM_BPF); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration( IO &IO, ELFYAML::ELF_ELFCLASS &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); +#define ECase(X) IO.enumCase(Value, #X, ELF::X) // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it // here. - ECase(ELFCLASS32) - ECase(ELFCLASS64) + ECase(ELFCLASS32); + ECase(ELFCLASS64); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration( IO &IO, ELFYAML::ELF_ELFDATA &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); +#define ECase(X) IO.enumCase(Value, #X, ELF::X) // Since the semantics of ELFDATANONE is "invalid", just don't accept it // here. - ECase(ELFDATA2LSB) - ECase(ELFDATA2MSB) + ECase(ELFDATA2LSB); + ECase(ELFDATA2MSB); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration( IO &IO, ELFYAML::ELF_ELFOSABI &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(ELFOSABI_NONE) - ECase(ELFOSABI_HPUX) - ECase(ELFOSABI_NETBSD) - ECase(ELFOSABI_GNU) - ECase(ELFOSABI_GNU) - ECase(ELFOSABI_HURD) - ECase(ELFOSABI_SOLARIS) - ECase(ELFOSABI_AIX) - ECase(ELFOSABI_IRIX) - ECase(ELFOSABI_FREEBSD) - ECase(ELFOSABI_TRU64) - ECase(ELFOSABI_MODESTO) - ECase(ELFOSABI_OPENBSD) - ECase(ELFOSABI_OPENVMS) - ECase(ELFOSABI_NSK) - ECase(ELFOSABI_AROS) - ECase(ELFOSABI_FENIXOS) - ECase(ELFOSABI_CLOUDABI) - ECase(ELFOSABI_C6000_ELFABI) - ECase(ELFOSABI_AMDGPU_HSA) - ECase(ELFOSABI_C6000_LINUX) - ECase(ELFOSABI_ARM) - ECase(ELFOSABI_STANDALONE) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(ELFOSABI_NONE); + ECase(ELFOSABI_HPUX); + ECase(ELFOSABI_NETBSD); + ECase(ELFOSABI_GNU); + ECase(ELFOSABI_GNU); + ECase(ELFOSABI_HURD); + ECase(ELFOSABI_SOLARIS); + ECase(ELFOSABI_AIX); + ECase(ELFOSABI_IRIX); + ECase(ELFOSABI_FREEBSD); + ECase(ELFOSABI_TRU64); + ECase(ELFOSABI_MODESTO); + ECase(ELFOSABI_OPENBSD); + ECase(ELFOSABI_OPENVMS); + ECase(ELFOSABI_NSK); + ECase(ELFOSABI_AROS); + ECase(ELFOSABI_FENIXOS); + ECase(ELFOSABI_CLOUDABI); + ECase(ELFOSABI_C6000_ELFABI); + ECase(ELFOSABI_AMDGPU_HSA); + ECase(ELFOSABI_C6000_LINUX); + ECase(ELFOSABI_ARM); + ECase(ELFOSABI_STANDALONE); #undef ECase } @@ -253,92 +251,92 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO, ELFYAML::ELF_EF &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); assert(Object && "The IO context is not initialized"); -#define BCase(X) IO.bitSetCase(Value, #X, ELF::X); -#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M); +#define BCase(X) IO.bitSetCase(Value, #X, ELF::X) +#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M) switch (Object->Header.Machine) { case ELF::EM_ARM: - BCase(EF_ARM_SOFT_FLOAT) - BCase(EF_ARM_VFP_FLOAT) - BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK) + BCase(EF_ARM_SOFT_FLOAT); + BCase(EF_ARM_VFP_FLOAT); + BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK); break; case ELF::EM_MIPS: - BCase(EF_MIPS_NOREORDER) - BCase(EF_MIPS_PIC) - BCase(EF_MIPS_CPIC) - BCase(EF_MIPS_ABI2) - BCase(EF_MIPS_32BITMODE) - BCase(EF_MIPS_FP64) - BCase(EF_MIPS_NAN2008) - BCase(EF_MIPS_MICROMIPS) - BCase(EF_MIPS_ARCH_ASE_M16) - BCase(EF_MIPS_ARCH_ASE_MDMX) - BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI) - BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI) - BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI) - BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI) - BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH) - BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH) + BCase(EF_MIPS_NOREORDER); + BCase(EF_MIPS_PIC); + BCase(EF_MIPS_CPIC); + BCase(EF_MIPS_ABI2); + BCase(EF_MIPS_32BITMODE); + BCase(EF_MIPS_FP64); + BCase(EF_MIPS_NAN2008); + BCase(EF_MIPS_MICROMIPS); + BCase(EF_MIPS_ARCH_ASE_M16); + BCase(EF_MIPS_ARCH_ASE_MDMX); + BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI); + BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI); + BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI); + BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI); + BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH); + BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH); break; case ELF::EM_HEXAGON: - BCase(EF_HEXAGON_MACH_V2) - BCase(EF_HEXAGON_MACH_V3) - BCase(EF_HEXAGON_MACH_V4) - BCase(EF_HEXAGON_MACH_V5) - BCase(EF_HEXAGON_ISA_V2) - BCase(EF_HEXAGON_ISA_V3) - BCase(EF_HEXAGON_ISA_V4) - BCase(EF_HEXAGON_ISA_V5) + BCase(EF_HEXAGON_MACH_V2); + BCase(EF_HEXAGON_MACH_V3); + BCase(EF_HEXAGON_MACH_V4); + BCase(EF_HEXAGON_MACH_V5); + BCase(EF_HEXAGON_ISA_V2); + BCase(EF_HEXAGON_ISA_V3); + BCase(EF_HEXAGON_ISA_V4); + BCase(EF_HEXAGON_ISA_V5); break; case ELF::EM_AVR: - BCase(EF_AVR_ARCH_AVR1) - BCase(EF_AVR_ARCH_AVR2) - BCase(EF_AVR_ARCH_AVR25) - BCase(EF_AVR_ARCH_AVR3) - BCase(EF_AVR_ARCH_AVR31) - BCase(EF_AVR_ARCH_AVR35) - BCase(EF_AVR_ARCH_AVR4) - BCase(EF_AVR_ARCH_AVR51) - BCase(EF_AVR_ARCH_AVR6) - BCase(EF_AVR_ARCH_AVRTINY) - BCase(EF_AVR_ARCH_XMEGA1) - BCase(EF_AVR_ARCH_XMEGA2) - BCase(EF_AVR_ARCH_XMEGA3) - BCase(EF_AVR_ARCH_XMEGA4) - BCase(EF_AVR_ARCH_XMEGA5) - BCase(EF_AVR_ARCH_XMEGA6) - BCase(EF_AVR_ARCH_XMEGA7) + BCase(EF_AVR_ARCH_AVR1); + BCase(EF_AVR_ARCH_AVR2); + BCase(EF_AVR_ARCH_AVR25); + BCase(EF_AVR_ARCH_AVR3); + BCase(EF_AVR_ARCH_AVR31); + BCase(EF_AVR_ARCH_AVR35); + BCase(EF_AVR_ARCH_AVR4); + BCase(EF_AVR_ARCH_AVR51); + BCase(EF_AVR_ARCH_AVR6); + BCase(EF_AVR_ARCH_AVRTINY); + BCase(EF_AVR_ARCH_XMEGA1); + BCase(EF_AVR_ARCH_XMEGA2); + BCase(EF_AVR_ARCH_XMEGA3); + BCase(EF_AVR_ARCH_XMEGA4); + BCase(EF_AVR_ARCH_XMEGA5); + BCase(EF_AVR_ARCH_XMEGA6); + BCase(EF_AVR_ARCH_XMEGA7); break; case ELF::EM_AMDGPU: case ELF::EM_X86_64: @@ -354,51 +352,51 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( IO &IO, ELFYAML::ELF_SHT &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); assert(Object && "The IO context is not initialized"); -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(SHT_NULL) - ECase(SHT_PROGBITS) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(SHT_NULL); + ECase(SHT_PROGBITS); // No SHT_SYMTAB. Use the top-level `Symbols` key instead. // FIXME: Issue a diagnostic with this information. - ECase(SHT_STRTAB) - ECase(SHT_RELA) - ECase(SHT_HASH) - ECase(SHT_DYNAMIC) - ECase(SHT_NOTE) - ECase(SHT_NOBITS) - ECase(SHT_REL) - ECase(SHT_SHLIB) - ECase(SHT_DYNSYM) - ECase(SHT_INIT_ARRAY) - ECase(SHT_FINI_ARRAY) - ECase(SHT_PREINIT_ARRAY) - ECase(SHT_GROUP) - ECase(SHT_SYMTAB_SHNDX) - ECase(SHT_LOOS) - ECase(SHT_GNU_ATTRIBUTES) - ECase(SHT_GNU_HASH) - ECase(SHT_GNU_verdef) - ECase(SHT_GNU_verneed) - ECase(SHT_GNU_versym) - ECase(SHT_HIOS) - ECase(SHT_LOPROC) + ECase(SHT_STRTAB); + ECase(SHT_RELA); + ECase(SHT_HASH); + ECase(SHT_DYNAMIC); + ECase(SHT_NOTE); + ECase(SHT_NOBITS); + ECase(SHT_REL); + ECase(SHT_SHLIB); + ECase(SHT_DYNSYM); + ECase(SHT_INIT_ARRAY); + ECase(SHT_FINI_ARRAY); + ECase(SHT_PREINIT_ARRAY); + ECase(SHT_GROUP); + ECase(SHT_SYMTAB_SHNDX); + ECase(SHT_LOOS); + ECase(SHT_GNU_ATTRIBUTES); + ECase(SHT_GNU_HASH); + ECase(SHT_GNU_verdef); + ECase(SHT_GNU_verneed); + ECase(SHT_GNU_versym); + ECase(SHT_HIOS); + ECase(SHT_LOPROC); switch (Object->Header.Machine) { case ELF::EM_ARM: - ECase(SHT_ARM_EXIDX) - ECase(SHT_ARM_PREEMPTMAP) - ECase(SHT_ARM_ATTRIBUTES) - ECase(SHT_ARM_DEBUGOVERLAY) - ECase(SHT_ARM_OVERLAYSECTION) + ECase(SHT_ARM_EXIDX); + ECase(SHT_ARM_PREEMPTMAP); + ECase(SHT_ARM_ATTRIBUTES); + ECase(SHT_ARM_DEBUGOVERLAY); + ECase(SHT_ARM_OVERLAYSECTION); break; case ELF::EM_HEXAGON: - ECase(SHT_HEX_ORDERED) + ECase(SHT_HEX_ORDERED); break; case ELF::EM_X86_64: - ECase(SHT_X86_64_UNWIND) + ECase(SHT_X86_64_UNWIND); break; case ELF::EM_MIPS: - ECase(SHT_MIPS_REGINFO) - ECase(SHT_MIPS_OPTIONS) - ECase(SHT_MIPS_ABIFLAGS) + ECase(SHT_MIPS_REGINFO); + ECase(SHT_MIPS_OPTIONS); + ECase(SHT_MIPS_ABIFLAGS); break; default: // Nothing to do. @@ -410,43 +408,43 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, ELFYAML::ELF_SHF &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); -#define BCase(X) IO.bitSetCase(Value, #X, ELF::X); - BCase(SHF_WRITE) - BCase(SHF_ALLOC) - BCase(SHF_EXCLUDE) - BCase(SHF_EXECINSTR) - BCase(SHF_MERGE) - BCase(SHF_STRINGS) - BCase(SHF_INFO_LINK) - BCase(SHF_LINK_ORDER) - BCase(SHF_OS_NONCONFORMING) - BCase(SHF_GROUP) - BCase(SHF_TLS) - switch(Object->Header.Machine) { +#define BCase(X) IO.bitSetCase(Value, #X, ELF::X) + BCase(SHF_WRITE); + BCase(SHF_ALLOC); + BCase(SHF_EXCLUDE); + BCase(SHF_EXECINSTR); + BCase(SHF_MERGE); + BCase(SHF_STRINGS); + BCase(SHF_INFO_LINK); + BCase(SHF_LINK_ORDER); + BCase(SHF_OS_NONCONFORMING); + BCase(SHF_GROUP); + BCase(SHF_TLS); + switch (Object->Header.Machine) { case ELF::EM_ARM: - BCase(SHF_ARM_PURECODE) + BCase(SHF_ARM_PURECODE); break; case ELF::EM_AMDGPU: - BCase(SHF_AMDGPU_HSA_GLOBAL) - BCase(SHF_AMDGPU_HSA_READONLY) - BCase(SHF_AMDGPU_HSA_CODE) - BCase(SHF_AMDGPU_HSA_AGENT) + BCase(SHF_AMDGPU_HSA_GLOBAL); + BCase(SHF_AMDGPU_HSA_READONLY); + BCase(SHF_AMDGPU_HSA_CODE); + BCase(SHF_AMDGPU_HSA_AGENT); break; case ELF::EM_HEXAGON: - BCase(SHF_HEX_GPREL) + BCase(SHF_HEX_GPREL); break; case ELF::EM_MIPS: - BCase(SHF_MIPS_NODUPES) - BCase(SHF_MIPS_NAMES) - BCase(SHF_MIPS_LOCAL) - BCase(SHF_MIPS_NOSTRIP) - BCase(SHF_MIPS_GPREL) - BCase(SHF_MIPS_MERGE) - BCase(SHF_MIPS_ADDR) - BCase(SHF_MIPS_STRING) + BCase(SHF_MIPS_NODUPES); + BCase(SHF_MIPS_NAMES); + BCase(SHF_MIPS_LOCAL); + BCase(SHF_MIPS_NOSTRIP); + BCase(SHF_MIPS_GPREL); + BCase(SHF_MIPS_MERGE); + BCase(SHF_MIPS_ADDR); + BCase(SHF_MIPS_STRING); break; case ELF::EM_X86_64: - BCase(SHF_X86_64_LARGE) + BCase(SHF_X86_64_LARGE); break; default: // Nothing to do. @@ -457,25 +455,25 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration( IO &IO, ELFYAML::ELF_STT &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(STT_NOTYPE) - ECase(STT_OBJECT) - ECase(STT_FUNC) - ECase(STT_SECTION) - ECase(STT_FILE) - ECase(STT_COMMON) - ECase(STT_TLS) - ECase(STT_GNU_IFUNC) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(STT_NOTYPE); + ECase(STT_OBJECT); + ECase(STT_FUNC); + ECase(STT_SECTION); + ECase(STT_FILE); + ECase(STT_COMMON); + ECase(STT_TLS); + ECase(STT_GNU_IFUNC); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration( IO &IO, ELFYAML::ELF_STV &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(STV_DEFAULT) - ECase(STV_INTERNAL) - ECase(STV_HIDDEN) - ECase(STV_PROTECTED) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(STV_DEFAULT); + ECase(STV_INTERNAL); + ECase(STV_HIDDEN); + ECase(STV_PROTECTED); #undef ECase } @@ -483,13 +481,13 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO, ELFYAML::ELF_STO &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); assert(Object && "The IO context is not initialized"); -#define BCase(X) IO.bitSetCase(Value, #X, ELF::X); +#define BCase(X) IO.bitSetCase(Value, #X, ELF::X) switch (Object->Header.Machine) { case ELF::EM_MIPS: - BCase(STO_MIPS_OPTIONAL) - BCase(STO_MIPS_PLT) - BCase(STO_MIPS_PIC) - BCase(STO_MIPS_MICROMIPS) + BCase(STO_MIPS_OPTIONAL); + BCase(STO_MIPS_PLT); + BCase(STO_MIPS_PIC); + BCase(STO_MIPS_MICROMIPS); break; default: break; // Nothing to do @@ -500,11 +498,11 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO, void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration( IO &IO, ELFYAML::ELF_RSS &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(RSS_UNDEF) - ECase(RSS_GP) - ECase(RSS_GP0) - ECase(RSS_LOC) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(RSS_UNDEF); + ECase(RSS_GP); + ECase(RSS_GP0); + ECase(RSS_LOC); #undef ECase } @@ -553,51 +551,51 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration( IO &IO, ELFYAML::MIPS_AFL_REG &Value) { -#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X); - ECase(REG_NONE) - ECase(REG_32) - ECase(REG_64) - ECase(REG_128) +#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X) + ECase(REG_NONE); + ECase(REG_32); + ECase(REG_64); + ECase(REG_128); #undef ECase } void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration( IO &IO, ELFYAML::MIPS_ABI_FP &Value) { -#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X); - ECase(FP_ANY) - ECase(FP_DOUBLE) - ECase(FP_SINGLE) - ECase(FP_SOFT) - ECase(FP_OLD_64) - ECase(FP_XX) - ECase(FP_64) - ECase(FP_64A) +#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X) + ECase(FP_ANY); + ECase(FP_DOUBLE); + ECase(FP_SINGLE); + ECase(FP_SOFT); + ECase(FP_OLD_64); + ECase(FP_XX); + ECase(FP_64); + ECase(FP_64A); #undef ECase } void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration( IO &IO, ELFYAML::MIPS_AFL_EXT &Value) { -#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X); - ECase(EXT_NONE) - ECase(EXT_XLR) - ECase(EXT_OCTEON2) - ECase(EXT_OCTEONP) - ECase(EXT_LOONGSON_3A) - ECase(EXT_OCTEON) - ECase(EXT_5900) - ECase(EXT_4650) - ECase(EXT_4010) - ECase(EXT_4100) - ECase(EXT_3900) - ECase(EXT_10000) - ECase(EXT_SB1) - ECase(EXT_4111) - ECase(EXT_4120) - ECase(EXT_5400) - ECase(EXT_5500) - ECase(EXT_LOONGSON_2E) - ECase(EXT_LOONGSON_2F) - ECase(EXT_OCTEON3) +#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X) + ECase(EXT_NONE); + ECase(EXT_XLR); + ECase(EXT_OCTEON2); + ECase(EXT_OCTEONP); + ECase(EXT_LOONGSON_3A); + ECase(EXT_OCTEON); + ECase(EXT_5900); + ECase(EXT_4650); + ECase(EXT_4010); + ECase(EXT_4100); + ECase(EXT_3900); + ECase(EXT_10000); + ECase(EXT_SB1); + ECase(EXT_4111); + ECase(EXT_4120); + ECase(EXT_5400); + ECase(EXT_5500); + ECase(EXT_LOONGSON_2E); + ECase(EXT_LOONGSON_2F); + ECase(EXT_OCTEON3); #undef ECase } @@ -614,27 +612,27 @@ void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration( void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset( IO &IO, ELFYAML::MIPS_AFL_ASE &Value) { -#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X); - BCase(DSP) - BCase(DSPR2) - BCase(EVA) - BCase(MCU) - BCase(MDMX) - BCase(MIPS3D) - BCase(MT) - BCase(SMARTMIPS) - BCase(VIRT) - BCase(MSA) - BCase(MIPS16) - BCase(MICROMIPS) - BCase(XPA) +#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X) + BCase(DSP); + BCase(DSPR2); + BCase(EVA); + BCase(MCU); + BCase(MDMX); + BCase(MIPS3D); + BCase(MT); + BCase(SMARTMIPS); + BCase(VIRT); + BCase(MSA); + BCase(MIPS16); + BCase(MICROMIPS); + BCase(XPA); #undef BCase } void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset( IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) { -#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X); - BCase(ODDSPREG) +#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X) + BCase(ODDSPREG); #undef BCase } diff --git a/lib/ObjectYAML/MachOYAML.cpp b/lib/ObjectYAML/MachOYAML.cpp index a033a79189bd..6b0e4e3762d0 100644 --- a/lib/ObjectYAML/MachOYAML.cpp +++ b/lib/ObjectYAML/MachOYAML.cpp @@ -230,6 +230,12 @@ void mapLoadCommandData<MachO::dylinker_command>( IO.mapOptional("PayloadString", LoadCommand.PayloadString); } +template <> +void mapLoadCommandData<MachO::build_version_command>( + IO &IO, MachOYAML::LoadCommand &LoadCommand) { + IO.mapOptional("Tools", LoadCommand.Tools); +} + void MappingTraits<MachOYAML::LoadCommand>::mapping( IO &IO, MachOYAML::LoadCommand &LoadCommand) { MachO::LoadCommandType TempCmd = static_cast<MachO::LoadCommandType>( @@ -282,6 +288,12 @@ void MappingTraits<MachOYAML::Section>::mapping(IO &IO, IO.mapOptional("reserved3", Section.reserved3); } +void MappingTraits<MachO::build_tool_version>::mapping( + IO &IO, MachO::build_tool_version &tool) { + IO.mapRequired("tool", tool.tool); + IO.mapRequired("version", tool.version); +} + void MappingTraits<MachO::dylib>::mapping(IO &IO, MachO::dylib &DylibStruct) { IO.mapRequired("name", DylibStruct.name); IO.mapRequired("timestamp", DylibStruct.timestamp); @@ -558,6 +570,23 @@ void MappingTraits<MachO::version_min_command>::mapping( IO.mapRequired("sdk", LoadCommand.sdk); } +void MappingTraits<MachO::note_command>::mapping( + IO &IO, MachO::note_command &LoadCommand) { + + IO.mapRequired("data_owner", LoadCommand.data_owner); + IO.mapRequired("offset", LoadCommand.offset); + IO.mapRequired("size", LoadCommand.size); +} + +void MappingTraits<MachO::build_version_command>::mapping( + IO &IO, MachO::build_version_command &LoadCommand) { + + IO.mapRequired("platform", LoadCommand.platform); + IO.mapRequired("minos", LoadCommand.minos); + IO.mapRequired("sdk", LoadCommand.sdk); + IO.mapRequired("ntools", LoadCommand.ntools); +} + } // namespace llvm::yaml } // namespace llvm diff --git a/lib/ObjectYAML/ObjectYAML.cpp b/lib/ObjectYAML/ObjectYAML.cpp index cbbaac6062a7..74581c1ecaac 100644 --- a/lib/ObjectYAML/ObjectYAML.cpp +++ b/lib/ObjectYAML/ObjectYAML.cpp @@ -43,6 +43,9 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO, ObjectFile.FatMachO.reset(new MachOYAML::UniversalBinary()); MappingTraits<MachOYAML::UniversalBinary>::mapping(IO, *ObjectFile.FatMachO); + } else if (IO.mapTag("!WASM")) { + ObjectFile.Wasm.reset(new WasmYAML::Object()); + MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm); } else { Input &In = (Input &)IO; std::string Tag = In.getCurrentNode()->getRawTag(); diff --git a/lib/ObjectYAML/WasmYAML.cpp b/lib/ObjectYAML/WasmYAML.cpp new file mode 100644 index 000000000000..3e1bed19d61f --- /dev/null +++ b/lib/ObjectYAML/WasmYAML.cpp @@ -0,0 +1,357 @@ +//===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of wasm. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/WasmYAML.h" +#include "llvm/Object/Wasm.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/MipsABIFlags.h" + +namespace llvm { + +namespace WasmYAML { + +// Declared here rather than in the header to comply with: +// http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers +Section::~Section() {} + +} // end namespace WasmYAML + +namespace yaml { + +void MappingTraits<WasmYAML::FileHeader>::mapping( + IO &IO, WasmYAML::FileHeader &FileHdr) { + IO.mapRequired("Version", FileHdr.Version); +} + +void MappingTraits<WasmYAML::Object>::mapping(IO &IO, + WasmYAML::Object &Object) { + IO.setContext(&Object); + IO.mapTag("!WASM", true); + IO.mapRequired("FileHeader", Object.Header); + IO.mapOptional("Sections", Object.Sections); + IO.setContext(nullptr); +} + +static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) { + IO.mapRequired("Type", Section.Type); + IO.mapOptional("Relocations", Section.Relocations); +} + +static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Name", Section.Name); + IO.mapRequired("Payload", Section.Payload); +} + +static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Signatures", Section.Signatures); +} + +static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Imports", Section.Imports); +} + +static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("FunctionTypes", Section.FunctionTypes); +} + +static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Tables", Section.Tables); +} + +static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Memories", Section.Memories); +} + +static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Globals", Section.Globals); +} + +static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Exports", Section.Exports); +} + +static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("StartFunction", Section.StartFunction); +} + +static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Segments", Section.Segments); +} + +static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Functions", Section.Functions); +} + +static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Segments", Section.Segments); +} + +void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping( + IO &IO, std::unique_ptr<WasmYAML::Section> &Section) { + WasmYAML::SectionType SectionType; + if (IO.outputting()) + SectionType = Section->Type; + else + IO.mapRequired("Type", SectionType); + + switch (SectionType) { + case wasm::WASM_SEC_CUSTOM: + if (!IO.outputting()) + Section.reset(new WasmYAML::CustomSection()); + sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get())); + break; + case wasm::WASM_SEC_TYPE: + if (!IO.outputting()) + Section.reset(new WasmYAML::TypeSection()); + sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get())); + break; + case wasm::WASM_SEC_IMPORT: + if (!IO.outputting()) + Section.reset(new WasmYAML::ImportSection()); + sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get())); + break; + case wasm::WASM_SEC_FUNCTION: + if (!IO.outputting()) + Section.reset(new WasmYAML::FunctionSection()); + sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get())); + break; + case wasm::WASM_SEC_TABLE: + if (!IO.outputting()) + Section.reset(new WasmYAML::TableSection()); + sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get())); + break; + case wasm::WASM_SEC_MEMORY: + if (!IO.outputting()) + Section.reset(new WasmYAML::MemorySection()); + sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get())); + break; + case wasm::WASM_SEC_GLOBAL: + if (!IO.outputting()) + Section.reset(new WasmYAML::GlobalSection()); + sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get())); + break; + case wasm::WASM_SEC_EXPORT: + if (!IO.outputting()) + Section.reset(new WasmYAML::ExportSection()); + sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get())); + break; + case wasm::WASM_SEC_START: + if (!IO.outputting()) + Section.reset(new WasmYAML::StartSection()); + sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get())); + break; + case wasm::WASM_SEC_ELEM: + if (!IO.outputting()) + Section.reset(new WasmYAML::ElemSection()); + sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get())); + break; + case wasm::WASM_SEC_CODE: + if (!IO.outputting()) + Section.reset(new WasmYAML::CodeSection()); + sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get())); + break; + case wasm::WASM_SEC_DATA: + if (!IO.outputting()) + Section.reset(new WasmYAML::DataSection()); + sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get())); + break; + default: + llvm_unreachable("Unknown section type"); + } +} + +void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration( + IO &IO, WasmYAML::SectionType &Type) { +#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X); + ECase(CUSTOM); + ECase(TYPE); + ECase(IMPORT); + ECase(FUNCTION); + ECase(TABLE); + ECase(MEMORY); + ECase(GLOBAL); + ECase(EXPORT); + ECase(START); + ECase(ELEM); + ECase(CODE); + ECase(DATA); +#undef ECase +} + +void MappingTraits<WasmYAML::Signature>::mapping( + IO &IO, WasmYAML::Signature &Signature) { + IO.mapOptional("Index", Signature.Index); + IO.mapRequired("ReturnType", Signature.ReturnType); + IO.mapRequired("ParamTypes", Signature.ParamTypes); +} + +void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) { + IO.mapRequired("ElemType", Table.ElemType); + IO.mapRequired("Limits", Table.TableLimits); +} + +void MappingTraits<WasmYAML::Function>::mapping(IO &IO, + WasmYAML::Function &Function) { + IO.mapRequired("Locals", Function.Locals); + IO.mapRequired("Body", Function.Body); +} + +void MappingTraits<WasmYAML::Relocation>::mapping( + IO &IO, WasmYAML::Relocation &Relocation) { + IO.mapRequired("Type", Relocation.Type); + IO.mapRequired("Index", Relocation.Index); + IO.mapRequired("Offset", Relocation.Offset); + IO.mapRequired("Addend", Relocation.Addend); +} + +void MappingTraits<WasmYAML::LocalDecl>::mapping( + IO &IO, WasmYAML::LocalDecl &LocalDecl) { + IO.mapRequired("Type", LocalDecl.Type); + IO.mapRequired("Count", LocalDecl.Count); +} + +void MappingTraits<WasmYAML::Limits>::mapping(IO &IO, + WasmYAML::Limits &Limits) { + if (!IO.outputting() || Limits.Flags) + IO.mapOptional("Flags", Limits.Flags); + IO.mapRequired("Initial", Limits.Initial); + if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) + IO.mapOptional("Maximum", Limits.Maximum); +} + +void MappingTraits<WasmYAML::ElemSegment>::mapping( + IO &IO, WasmYAML::ElemSegment &Segment) { + IO.mapRequired("Offset", Segment.Offset); + IO.mapRequired("Functions", Segment.Functions); +} + +void MappingTraits<WasmYAML::Import>::mapping(IO &IO, + WasmYAML::Import &Import) { + IO.mapRequired("Module", Import.Module); + IO.mapRequired("Field", Import.Field); + IO.mapRequired("Kind", Import.Kind); + if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) { + IO.mapRequired("SigIndex", Import.SigIndex); + } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) { + IO.mapRequired("GlobalType", Import.GlobalType); + IO.mapRequired("GlobalMutable", Import.GlobalMutable); + } else { + llvm_unreachable("unhandled import type"); + } +} + +void MappingTraits<WasmYAML::Export>::mapping(IO &IO, + WasmYAML::Export &Export) { + IO.mapRequired("Name", Export.Name); + IO.mapRequired("Kind", Export.Kind); + IO.mapRequired("Index", Export.Index); +} + +void MappingTraits<WasmYAML::Global>::mapping(IO &IO, + WasmYAML::Global &Global) { + IO.mapRequired("Type", Global.Type); + IO.mapRequired("Mutable", Global.Mutable); + IO.mapRequired("InitExpr", Global.InitExpr); +} + +void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO, + wasm::WasmInitExpr &Expr) { + WasmYAML::Opcode Op = Expr.Opcode; + IO.mapRequired("Opcode", Op); + Expr.Opcode = Op; + switch (Expr.Opcode) { + case wasm::WASM_OPCODE_I32_CONST: + IO.mapRequired("Value", Expr.Value.Int32); + break; + case wasm::WASM_OPCODE_I64_CONST: + IO.mapRequired("Value", Expr.Value.Int64); + break; + case wasm::WASM_OPCODE_F32_CONST: + IO.mapRequired("Value", Expr.Value.Float32); + break; + case wasm::WASM_OPCODE_F64_CONST: + IO.mapRequired("Value", Expr.Value.Float64); + break; + } +} + +void MappingTraits<WasmYAML::DataSegment>::mapping( + IO &IO, WasmYAML::DataSegment &Segment) { + IO.mapRequired("Index", Segment.Index); + IO.mapRequired("Offset", Segment.Offset); + IO.mapRequired("Content", Segment.Content); +} + +void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration( + IO &IO, WasmYAML::ValueType &Type) { +#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); + ECase(I32); + ECase(I64); + ECase(F32); + ECase(F64); + ECase(ANYFUNC); + ECase(FUNC); + ECase(NORESULT); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration( + IO &IO, WasmYAML::ExportKind &Kind) { +#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X); + ECase(FUNCTION); + ECase(TABLE); + ECase(MEMORY); + ECase(GLOBAL); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration( + IO &IO, WasmYAML::Opcode &Code) { +#define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X); + ECase(END); + ECase(I32_CONST); + ECase(I64_CONST); + ECase(F64_CONST); + ECase(F32_CONST); + ECase(GET_GLOBAL); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration( + IO &IO, WasmYAML::TableType &Type) { +#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); + ECase(ANYFUNC); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration( + IO &IO, WasmYAML::RelocType &Type) { +#define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name); +#include "llvm/Support/WasmRelocs/WebAssembly.def" +#undef WASM_RELOC +} + +} // end namespace yaml +} // end namespace llvm |