diff options
Diffstat (limited to 'contrib/llvm/lib/ObjectYAML')
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/COFFYAML.cpp | 73 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp | 958 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 590 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp | 806 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp | 333 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp | 178 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFVisitor.h | 97 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp | 19 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/ELFYAML.cpp | 871 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/MachOYAML.cpp | 79 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp | 12 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/WasmYAML.cpp | 411 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/YAML.cpp | 5 |
13 files changed, 3932 insertions, 500 deletions
diff --git a/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp b/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp index 7f9f4c1..1103159 100644 --- a/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp @@ -12,17 +12,25 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/COFFYAML.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <cstring> #define ECase(X) IO.enumCase(Value, #X, COFF::X); + namespace llvm { namespace COFFYAML { + Section::Section() { memset(&Header, 0, sizeof(COFF::section)); } Symbol::Symbol() { memset(&Header, 0, sizeof(COFF::symbol)); } Object::Object() { memset(&Header, 0, sizeof(COFF::header)); } -} + +} // end namespace COFFYAML namespace yaml { + void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration( IO &IO, COFFYAML::COMDATType &Value) { IO.enumCase(Value, "0", 0); @@ -172,20 +180,20 @@ void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration( void ScalarEnumerationTraits<COFF::WindowsSubsystem>::enumeration( IO &IO, COFF::WindowsSubsystem &Value) { - ECase(IMAGE_SUBSYSTEM_UNKNOWN); - ECase(IMAGE_SUBSYSTEM_NATIVE); - ECase(IMAGE_SUBSYSTEM_WINDOWS_GUI); - ECase(IMAGE_SUBSYSTEM_WINDOWS_CUI); - ECase(IMAGE_SUBSYSTEM_OS2_CUI); - ECase(IMAGE_SUBSYSTEM_POSIX_CUI); - ECase(IMAGE_SUBSYSTEM_NATIVE_WINDOWS); - ECase(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI); - ECase(IMAGE_SUBSYSTEM_EFI_APPLICATION); - ECase(IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER); - ECase(IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER); - ECase(IMAGE_SUBSYSTEM_EFI_ROM); - ECase(IMAGE_SUBSYSTEM_XBOX); - ECase(IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION); + ECase(IMAGE_SUBSYSTEM_UNKNOWN); + ECase(IMAGE_SUBSYSTEM_NATIVE); + ECase(IMAGE_SUBSYSTEM_WINDOWS_GUI); + ECase(IMAGE_SUBSYSTEM_WINDOWS_CUI); + ECase(IMAGE_SUBSYSTEM_OS2_CUI); + ECase(IMAGE_SUBSYSTEM_POSIX_CUI); + ECase(IMAGE_SUBSYSTEM_NATIVE_WINDOWS); + ECase(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI); + ECase(IMAGE_SUBSYSTEM_EFI_APPLICATION); + ECase(IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER); + ECase(IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER); + ECase(IMAGE_SUBSYSTEM_EFI_ROM); + ECase(IMAGE_SUBSYSTEM_XBOX); + ECase(IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION); } #undef ECase @@ -252,12 +260,15 @@ void ScalarBitSetTraits<COFF::DLLCharacteristics>::bitset( #undef BCase namespace { + struct NSectionSelectionType { NSectionSelectionType(IO &) : SelectionType(COFFYAML::COMDATType(0)) {} NSectionSelectionType(IO &, uint8_t C) : SelectionType(COFFYAML::COMDATType(C)) {} + uint8_t denormalize(IO &) { return SelectionType; } + COFFYAML::COMDATType SelectionType; }; @@ -266,7 +277,9 @@ struct NWeakExternalCharacteristics { : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {} NWeakExternalCharacteristics(IO &, uint32_t C) : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {} + uint32_t denormalize(IO &) { return Characteristics; } + COFFYAML::WeakExternalCharacteristics Characteristics; }; @@ -275,7 +288,9 @@ struct NSectionCharacteristics { : Characteristics(COFF::SectionCharacteristics(0)) {} NSectionCharacteristics(IO &, uint32_t C) : Characteristics(COFF::SectionCharacteristics(C)) {} + uint32_t denormalize(IO &) { return Characteristics; } + COFF::SectionCharacteristics Characteristics; }; @@ -284,13 +299,16 @@ struct NAuxTokenType { : AuxType(COFFYAML::AuxSymbolType(0)) {} NAuxTokenType(IO &, uint8_t C) : AuxType(COFFYAML::AuxSymbolType(C)) {} + uint32_t denormalize(IO &) { return AuxType; } + COFFYAML::AuxSymbolType AuxType; }; struct NStorageClass { NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {} NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {} + uint8_t denormalize(IO &) { return StorageClass; } COFF::SymbolStorageClass StorageClass; @@ -299,7 +317,9 @@ struct NStorageClass { struct NMachine { NMachine(IO &) : Machine(COFF::MachineTypes(0)) {} NMachine(IO &, uint16_t M) : Machine(COFF::MachineTypes(M)) {} + uint16_t denormalize(IO &) { return Machine; } + COFF::MachineTypes Machine; }; @@ -307,6 +327,7 @@ struct NHeaderCharacteristics { NHeaderCharacteristics(IO &) : Characteristics(COFF::Characteristics(0)) {} NHeaderCharacteristics(IO &, uint16_t C) : Characteristics(COFF::Characteristics(C)) {} + uint16_t denormalize(IO &) { return Characteristics; } COFF::Characteristics Characteristics; @@ -316,13 +337,16 @@ template <typename RelocType> struct NType { NType(IO &) : Type(RelocType(0)) {} NType(IO &, uint16_t T) : Type(RelocType(T)) {} + uint16_t denormalize(IO &) { return Type; } + RelocType Type; }; struct NWindowsSubsystem { NWindowsSubsystem(IO &) : Subsystem(COFF::WindowsSubsystem(0)) {} NWindowsSubsystem(IO &, uint16_t C) : Subsystem(COFF::WindowsSubsystem(C)) {} + uint16_t denormalize(IO &) { return Subsystem; } COFF::WindowsSubsystem Subsystem; @@ -332,12 +356,13 @@ struct NDLLCharacteristics { NDLLCharacteristics(IO &) : Characteristics(COFF::DLLCharacteristics(0)) {} NDLLCharacteristics(IO &, uint16_t C) : Characteristics(COFF::DLLCharacteristics(C)) {} + uint16_t denormalize(IO &) { return Characteristics; } COFF::DLLCharacteristics Characteristics; }; -} +} // end anonymous namespace void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO, COFFYAML::Relocation &Rel) { @@ -488,7 +513,16 @@ void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) { IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U); IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U); IO.mapOptional("Alignment", Sec.Alignment, 0U); - IO.mapRequired("SectionData", Sec.SectionData); + + // If this is a .debug$S or .debug$T section parse the semantic representation + // of the symbols/types. If it is any other kind of section, just deal in raw + // bytes. + IO.mapOptional("SectionData", Sec.SectionData); + if (Sec.Name == ".debug$S") + IO.mapOptional("Subsections", Sec.DebugS); + else if (Sec.Name == ".debug$T") + IO.mapOptional("Types", Sec.DebugT); + IO.mapOptional("Relocations", Sec.Relocations); } @@ -500,5 +534,6 @@ void MappingTraits<COFFYAML::Object>::mapping(IO &IO, COFFYAML::Object &Obj) { IO.mapRequired("symbols", Obj.Symbols); } -} -} +} // end namespace yaml + +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp new file mode 100644 index 0000000..60b0ea2 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp @@ -0,0 +1,958 @@ +//===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===// +// +// 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 CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" +#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" +#include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite) +LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport) +LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport) +LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData) + +LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false) +LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) +LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport) +LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData) +LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock) +LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite) + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct YAMLSubsectionBase { + explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {} + virtual ~YAMLSubsectionBase() = default; + + virtual void map(IO &IO) = 0; + virtual std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const = 0; + + DebugSubsectionKind Kind; +}; + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +namespace { + +struct YAMLChecksumsSubsection : public YAMLSubsectionBase { + YAMLChecksumsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLChecksumsSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &FC); + + std::vector<SourceFileChecksumEntry> Checksums; +}; + +struct YAMLLinesSubsection : public YAMLSubsectionBase { + YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLLinesSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugLinesSubsectionRef &Lines); + + SourceLineInfo Lines; +}; + +struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { + YAMLInlineeLinesSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugInlineeLinesSubsectionRef &Lines); + + InlineeInfo InlineeLines; +}; + +struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase { + YAMLCrossModuleExportsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> + fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports); + + std::vector<CrossModuleExport> Exports; +}; + +struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { + YAMLCrossModuleImportsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugCrossModuleImportsSubsectionRef &Imports); + + std::vector<YAMLCrossModuleImport> Imports; +}; + +struct YAMLSymbolsSubsection : public YAMLSubsectionBase { + YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLSymbolsSubsection>> + fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols); + + std::vector<CodeViewYAML::SymbolRecord> Symbols; +}; + +struct YAMLStringTableSubsection : public YAMLSubsectionBase { + YAMLStringTableSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLStringTableSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings); + + std::vector<StringRef> Strings; +}; + +struct YAMLFrameDataSubsection : public YAMLSubsectionBase { + YAMLFrameDataSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLFrameDataSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugFrameDataSubsectionRef &Frames); + + std::vector<YAMLFrameData> Frames; +}; + +struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase { + YAMLCoffSymbolRVASubsection() + : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> + fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs); + + std::vector<uint32_t> RVAs; +}; + +} // end anonymous namespace + +void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) { + io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); + io.enumFallback<Hex16>(Flags); +} + +void ScalarEnumerationTraits<FileChecksumKind>::enumeration( + IO &io, FileChecksumKind &Kind) { + io.enumCase(Kind, "None", FileChecksumKind::None); + io.enumCase(Kind, "MD5", FileChecksumKind::MD5); + io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1); + io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256); +} + +void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value, + void *ctx, raw_ostream &Out) { + StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()), + Value.Bytes.size()); + Out << toHex(Bytes); +} + +StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt, + HexFormattedString &Value) { + std::string H = fromHex(Scalar); + Value.Bytes.assign(H.begin(), H.end()); + return StringRef(); +} + +void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) { + IO.mapRequired("Offset", Obj.Offset); + IO.mapRequired("LineStart", Obj.LineStart); + IO.mapRequired("IsStatement", Obj.IsStatement); + IO.mapRequired("EndDelta", Obj.EndDelta); +} + +void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) { + IO.mapRequired("StartColumn", Obj.StartColumn); + IO.mapRequired("EndColumn", Obj.EndColumn); +} + +void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("Lines", Obj.Lines); + IO.mapRequired("Columns", Obj.Columns); +} + +void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) { + IO.mapRequired("LocalId", Obj.Local); + IO.mapRequired("GlobalId", Obj.Global); +} + +void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO, + YAMLCrossModuleImport &Obj) { + IO.mapRequired("Module", Obj.ModuleName); + IO.mapRequired("Imports", Obj.ImportIds); +} + +void MappingTraits<SourceFileChecksumEntry>::mapping( + IO &IO, SourceFileChecksumEntry &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("Kind", Obj.Kind); + IO.mapRequired("Checksum", Obj.ChecksumBytes); +} + +void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("LineNum", Obj.SourceLineNum); + IO.mapRequired("Inlinee", Obj.Inlinee); + IO.mapOptional("ExtraFiles", Obj.ExtraFiles); +} + +void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) { + IO.mapRequired("CodeSize", Obj.CodeSize); + IO.mapRequired("FrameFunc", Obj.FrameFunc); + IO.mapRequired("LocalSize", Obj.LocalSize); + IO.mapOptional("MaxStackSize", Obj.MaxStackSize); + IO.mapOptional("ParamsSize", Obj.ParamsSize); + IO.mapOptional("PrologSize", Obj.PrologSize); + IO.mapOptional("RvaStart", Obj.RvaStart); + IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize); +} + +void YAMLChecksumsSubsection::map(IO &IO) { + IO.mapTag("!FileChecksums", true); + IO.mapRequired("Checksums", Checksums); +} + +void YAMLLinesSubsection::map(IO &IO) { + IO.mapTag("!Lines", true); + IO.mapRequired("CodeSize", Lines.CodeSize); + + IO.mapRequired("Flags", Lines.Flags); + IO.mapRequired("RelocOffset", Lines.RelocOffset); + IO.mapRequired("RelocSegment", Lines.RelocSegment); + IO.mapRequired("Blocks", Lines.Blocks); +} + +void YAMLInlineeLinesSubsection::map(IO &IO) { + IO.mapTag("!InlineeLines", true); + IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles); + IO.mapRequired("Sites", InlineeLines.Sites); +} + +void YAMLCrossModuleExportsSubsection::map(IO &IO) { + IO.mapTag("!CrossModuleExports", true); + IO.mapOptional("Exports", Exports); +} + +void YAMLCrossModuleImportsSubsection::map(IO &IO) { + IO.mapTag("!CrossModuleImports", true); + IO.mapOptional("Imports", Imports); +} + +void YAMLSymbolsSubsection::map(IO &IO) { + IO.mapTag("!Symbols", true); + IO.mapRequired("Records", Symbols); +} + +void YAMLStringTableSubsection::map(IO &IO) { + IO.mapTag("!StringTable", true); + IO.mapRequired("Strings", Strings); +} + +void YAMLFrameDataSubsection::map(IO &IO) { + IO.mapTag("!FrameData", true); + IO.mapRequired("Frames", Frames); +} + +void YAMLCoffSymbolRVASubsection::map(IO &IO) { + IO.mapTag("!COFFSymbolRVAs", true); + IO.mapRequired("RVAs", RVAs); +} + +void MappingTraits<YAMLDebugSubsection>::mapping( + IO &IO, YAMLDebugSubsection &Subsection) { + if (!IO.outputting()) { + if (IO.mapTag("!FileChecksums")) { + auto SS = std::make_shared<YAMLChecksumsSubsection>(); + Subsection.Subsection = SS; + } else if (IO.mapTag("!Lines")) { + Subsection.Subsection = std::make_shared<YAMLLinesSubsection>(); + } else if (IO.mapTag("!InlineeLines")) { + Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>(); + } else if (IO.mapTag("!CrossModuleExports")) { + Subsection.Subsection = + std::make_shared<YAMLCrossModuleExportsSubsection>(); + } else if (IO.mapTag("!CrossModuleImports")) { + Subsection.Subsection = + std::make_shared<YAMLCrossModuleImportsSubsection>(); + } else if (IO.mapTag("!Symbols")) { + Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>(); + } else if (IO.mapTag("!StringTable")) { + Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>(); + } else if (IO.mapTag("!FrameData")) { + Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>(); + } else if (IO.mapTag("!COFFSymbolRVAs")) { + Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>(); + } else { + llvm_unreachable("Unexpected subsection tag!"); + } + } + Subsection.Subsection->map(IO); +} + +std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings()); + for (const auto &CS : Checksums) { + Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); + } + return Result; +} + +std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings() && SC.hasChecksums()); + auto Result = + std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings()); + Result->setCodeSize(Lines.CodeSize); + Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); + Result->setFlags(Lines.Flags); + for (const auto &LC : Lines.Blocks) { + Result->createBlock(LC.FileName); + if (Result->hasColumnInfo()) { + for (const auto &Item : zip(LC.Lines, LC.Columns)) { + auto &L = std::get<0>(Item); + auto &C = std::get<1>(Item); + uint32_t LE = L.LineStart + L.EndDelta; + Result->addLineAndColumnInfo(L.Offset, + LineInfo(L.LineStart, LE, L.IsStatement), + C.StartColumn, C.EndColumn); + } + } else { + for (const auto &L : LC.Lines) { + uint32_t LE = L.LineStart + L.EndDelta; + Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement)); + } + } + } + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLInlineeLinesSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasChecksums()); + auto Result = std::make_shared<DebugInlineeLinesSubsection>( + *SC.checksums(), InlineeLines.HasExtraFiles); + + for (const auto &Site : InlineeLines.Sites) { + Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, + Site.SourceLineNum); + if (!InlineeLines.HasExtraFiles) + continue; + + for (auto EF : Site.ExtraFiles) { + Result->addExtraFile(EF); + } + } + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLCrossModuleExportsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugCrossModuleExportsSubsection>(); + for (const auto &M : Exports) + Result->addMapping(M.Local, M.Global); + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLCrossModuleImportsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + + auto Result = + std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings()); + for (const auto &M : Imports) { + for (const auto Id : M.ImportIds) + Result->addImport(M.ModuleName, Id); + } + return Result; +} + +std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugSymbolsSubsection>(); + for (const auto &Sym : Symbols) + Result->addSymbol( + Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile)); + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLStringTableSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugStringTableSubsection>(); + for (const auto &Str : this->Strings) + Result->insert(Str); + return Result; +} + +std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + + auto Result = std::make_shared<DebugFrameDataSubsection>(); + for (const auto &YF : Frames) { + codeview::FrameData F; + F.CodeSize = YF.CodeSize; + F.Flags = YF.Flags; + F.LocalSize = YF.LocalSize; + F.MaxStackSize = YF.MaxStackSize; + F.ParamsSize = YF.ParamsSize; + F.PrologSize = YF.PrologSize; + F.RvaStart = YF.RvaStart; + F.SavedRegsSize = YF.SavedRegsSize; + F.FrameFunc = SC.strings()->insert(YF.FrameFunc); + Result->addFrameData(F); + } + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLCoffSymbolRVASubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugSymbolRVASubsection>(); + for (const auto &RVA : RVAs) + Result->addRVA(RVA); + return Result; +} + +static Expected<SourceFileChecksumEntry> +convertOneChecksum(const DebugStringTableSubsectionRef &Strings, + const FileChecksumEntry &CS) { + auto ExpectedString = Strings.getString(CS.FileNameOffset); + if (!ExpectedString) + return ExpectedString.takeError(); + + SourceFileChecksumEntry Result; + Result.ChecksumBytes.Bytes = CS.Checksum; + Result.Kind = CS.Kind; + Result.FileName = *ExpectedString; + return Result; +} + +static Expected<StringRef> +getFileName(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { + auto Iter = Checksums.getArray().at(FileID); + if (Iter == Checksums.getArray().end()) + return make_error<CodeViewError>(cv_error_code::no_records); + uint32_t Offset = Iter->FileNameOffset; + return Strings.getString(Offset); +} + +Expected<std::shared_ptr<YAMLChecksumsSubsection>> +YAMLChecksumsSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &FC) { + auto Result = std::make_shared<YAMLChecksumsSubsection>(); + + for (const auto &CS : FC) { + auto ConvertedCS = convertOneChecksum(Strings, CS); + if (!ConvertedCS) + return ConvertedCS.takeError(); + Result->Checksums.push_back(*ConvertedCS); + } + return Result; +} + +Expected<std::shared_ptr<YAMLLinesSubsection>> +YAMLLinesSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugLinesSubsectionRef &Lines) { + auto Result = std::make_shared<YAMLLinesSubsection>(); + Result->Lines.CodeSize = Lines.header()->CodeSize; + Result->Lines.RelocOffset = Lines.header()->RelocOffset; + Result->Lines.RelocSegment = Lines.header()->RelocSegment; + Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags)); + for (const auto &L : Lines) { + SourceLineBlock Block; + auto EF = getFileName(Strings, Checksums, L.NameIndex); + if (!EF) + return EF.takeError(); + Block.FileName = *EF; + if (Lines.hasColumnInfo()) { + for (const auto &C : L.Columns) { + SourceColumnEntry SCE; + SCE.EndColumn = C.EndColumn; + SCE.StartColumn = C.StartColumn; + Block.Columns.push_back(SCE); + } + } + for (const auto &LN : L.LineNumbers) { + SourceLineEntry SLE; + LineInfo LI(LN.Flags); + SLE.Offset = LN.Offset; + SLE.LineStart = LI.getStartLine(); + SLE.EndDelta = LI.getLineDelta(); + SLE.IsStatement = LI.isStatement(); + Block.Lines.push_back(SLE); + } + Result->Lines.Blocks.push_back(Block); + } + return Result; +} + +Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> +YAMLInlineeLinesSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugInlineeLinesSubsectionRef &Lines) { + auto Result = std::make_shared<YAMLInlineeLinesSubsection>(); + + Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles(); + for (const auto &IL : Lines) { + InlineeSite Site; + auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID); + if (!ExpF) + return ExpF.takeError(); + Site.FileName = *ExpF; + Site.Inlinee = IL.Header->Inlinee.getIndex(); + Site.SourceLineNum = IL.Header->SourceLineNum; + if (Lines.hasExtraFiles()) { + for (const auto EF : IL.ExtraFiles) { + auto ExpF2 = getFileName(Strings, Checksums, EF); + if (!ExpF2) + return ExpF2.takeError(); + Site.ExtraFiles.push_back(*ExpF2); + } + } + Result->InlineeLines.Sites.push_back(Site); + } + return Result; +} + +Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> +YAMLCrossModuleExportsSubsection::fromCodeViewSubsection( + const DebugCrossModuleExportsSubsectionRef &Exports) { + auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>(); + Result->Exports.assign(Exports.begin(), Exports.end()); + return Result; +} + +Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> +YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugCrossModuleImportsSubsectionRef &Imports) { + auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>(); + for (const auto &CMI : Imports) { + YAMLCrossModuleImport YCMI; + auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset); + if (!ExpectedStr) + return ExpectedStr.takeError(); + YCMI.ModuleName = *ExpectedStr; + YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end()); + Result->Imports.push_back(YCMI); + } + return Result; +} + +Expected<std::shared_ptr<YAMLSymbolsSubsection>> +YAMLSymbolsSubsection::fromCodeViewSubsection( + const DebugSymbolsSubsectionRef &Symbols) { + auto Result = std::make_shared<YAMLSymbolsSubsection>(); + for (const auto &Sym : Symbols) { + auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym); + if (!S) + return joinErrors(make_error<CodeViewError>( + cv_error_code::corrupt_record, + "Invalid CodeView Symbol Record in SymbolRecord " + "subsection of .debug$S while converting to YAML!"), + S.takeError()); + + Result->Symbols.push_back(*S); + } + return Result; +} + +Expected<std::shared_ptr<YAMLStringTableSubsection>> +YAMLStringTableSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings) { + auto Result = std::make_shared<YAMLStringTableSubsection>(); + BinaryStreamReader Reader(Strings.getBuffer()); + StringRef S; + // First item is a single null string, skip it. + if (auto EC = Reader.readCString(S)) + return std::move(EC); + assert(S.empty()); + while (Reader.bytesRemaining() > 0) { + if (auto EC = Reader.readCString(S)) + return std::move(EC); + Result->Strings.push_back(S); + } + return Result; +} + +Expected<std::shared_ptr<YAMLFrameDataSubsection>> +YAMLFrameDataSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugFrameDataSubsectionRef &Frames) { + auto Result = std::make_shared<YAMLFrameDataSubsection>(); + for (const auto &F : Frames) { + YAMLFrameData YF; + YF.CodeSize = F.CodeSize; + YF.Flags = F.Flags; + YF.LocalSize = F.LocalSize; + YF.MaxStackSize = F.MaxStackSize; + YF.ParamsSize = F.ParamsSize; + YF.PrologSize = F.PrologSize; + YF.RvaStart = F.RvaStart; + YF.SavedRegsSize = F.SavedRegsSize; + + auto ES = Strings.getString(F.FrameFunc); + if (!ES) + return joinErrors( + make_error<CodeViewError>( + cv_error_code::no_records, + "Could not find string for string id while mapping FrameData!"), + ES.takeError()); + YF.FrameFunc = *ES; + Result->Frames.push_back(YF); + } + return Result; +} + +Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> +YAMLCoffSymbolRVASubsection::fromCodeViewSubsection( + const DebugSymbolRVASubsectionRef &Section) { + auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>(); + for (const auto &RVA : Section) { + Result->RVAs.push_back(RVA); + } + return Result; +} + +Expected<std::vector<std::shared_ptr<DebugSubsection>>> +llvm::CodeViewYAML::toCodeViewSubsectionList( + BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections, + const codeview::StringsAndChecksums &SC) { + std::vector<std::shared_ptr<DebugSubsection>> Result; + if (Subsections.empty()) + return std::move(Result); + + for (const auto &SS : Subsections) { + std::shared_ptr<DebugSubsection> CVS; + CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC); + assert(CVS != nullptr); + Result.push_back(std::move(CVS)); + } + return std::move(Result); +} + +namespace { + +struct SubsectionConversionVisitor : public DebugSubsectionVisitor { + SubsectionConversionVisitor() = default; + + Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; + Error visitLines(DebugLinesSubsectionRef &Lines, + const StringsAndChecksumsRef &State) override; + Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) override; + Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, + const StringsAndChecksumsRef &State) override; + Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) override; + Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees, + const StringsAndChecksumsRef &State) override; + Error visitStringTable(DebugStringTableSubsectionRef &ST, + const StringsAndChecksumsRef &State) override; + Error visitSymbols(DebugSymbolsSubsectionRef &Symbols, + const StringsAndChecksumsRef &State) override; + Error visitFrameData(DebugFrameDataSubsectionRef &Symbols, + const StringsAndChecksumsRef &State) override; + Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols, + const StringsAndChecksumsRef &State) override; + + YAMLDebugSubsection Subsection; +}; + +} // end anonymous namespace + +Error SubsectionConversionVisitor::visitUnknown( + DebugUnknownSubsectionRef &Unknown) { + return make_error<CodeViewError>(cv_error_code::operation_unsupported); +} + +Error SubsectionConversionVisitor::visitLines( + DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) { + auto Result = YAMLLinesSubsection::fromCodeViewSubsection( + State.strings(), State.checksums(), Lines); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitFileChecksums( + DebugChecksumsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) { + auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(), + Checksums); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitInlineeLines( + DebugInlineeLinesSubsectionRef &Inlinees, + const StringsAndChecksumsRef &State) { + auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( + State.strings(), State.checksums(), Inlinees); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitCrossModuleExports( + DebugCrossModuleExportsSubsectionRef &Exports, + const StringsAndChecksumsRef &State) { + auto Result = + YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitCrossModuleImports( + DebugCrossModuleImportsSubsectionRef &Imports, + const StringsAndChecksumsRef &State) { + auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( + State.strings(), Imports); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitStringTable( + DebugStringTableSubsectionRef &Strings, + const StringsAndChecksumsRef &State) { + auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitSymbols( + DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) { + auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitFrameData( + DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) { + auto Result = + YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitCOFFSymbolRVAs( + DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) { + auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Expected<YAMLDebugSubsection> +YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC, + const DebugSubsectionRecord &SS) { + SubsectionConversionVisitor V; + if (auto EC = visitDebugSubsection(SS, V, SC)) + return std::move(EC); + + return V.Subsection; +} + +std::vector<YAMLDebugSubsection> +llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data, + const StringsAndChecksumsRef &SC) { + BinaryStreamReader Reader(Data, support::little); + uint32_t Magic; + + ExitOnError Err("Invalid .debug$S section!"); + Err(Reader.readInteger(Magic)); + assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!"); + + DebugSubsectionArray Subsections; + Err(Reader.readArray(Subsections, Reader.bytesRemaining())); + + std::vector<YAMLDebugSubsection> Result; + + for (const auto &SS : Subsections) { + auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS)); + Result.push_back(YamlSS); + } + return Result; +} + +void llvm::CodeViewYAML::initializeStringsAndChecksums( + ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) { + // String Table and Checksums subsections don't use the allocator. + BumpPtrAllocator Allocator; + + // It's possible for checksums and strings to even appear in different debug$S + // sections, so we have to make this a stateful function that can build up + // the strings and checksums field over multiple iterations. + + // File Checksums require the string table, but may become before it, so we + // have to scan for strings first, then scan for checksums again from the + // beginning. + if (!SC.hasStrings()) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) + continue; + + auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); + SC.setStrings( + std::static_pointer_cast<DebugStringTableSubsection>(Result)); + break; + } + } + + if (SC.hasStrings() && !SC.hasChecksums()) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums) + continue; + + auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); + SC.setChecksums( + std::static_pointer_cast<DebugChecksumsSubsection>(Result)); + break; + } + } +} diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp new file mode 100644 index 0000000..dbe4e2a --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -0,0 +1,590 @@ +//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol 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 CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/SymbolSerializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include <algorithm> +#include <cstdint> +#include <cstring> +#include <string> +#include <vector> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) + +// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp +LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) +LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) + +LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind) + +LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) +LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) +LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions) +LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType) +LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId) +LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType) +LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal) + +LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName) + +LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, true) + +StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) { + return ScalarTraits<StringRef>::input(S, V, T.value); +} + +void ScalarTraits<TypeName>::output(const TypeName &T, void *V, + raw_ostream &R) { + ScalarTraits<StringRef>::output(T.value, V, R); +} + +void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io, + SymbolKind &Value) { + auto SymbolNames = getSymbolTypeNames(); + for (const auto &E : SymbolNames) + io.enumCase(Value, E.Name.str().c_str(), E.Value); +} + +void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io, + CompileSym2Flags &Flags) { + auto FlagNames = getCompileSym2FlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<CompileSym2Flags>(E.Value)); + } +} + +void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io, + CompileSym3Flags &Flags) { + auto FlagNames = getCompileSym3FlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<CompileSym3Flags>(E.Value)); + } +} + +void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) { + auto FlagNames = getExportSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<ExportFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) { + auto FlagNames = getProcSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<PublicSymFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) { + auto FlagNames = getLocalFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<LocalSymFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) { + auto FlagNames = getProcSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<ProcSymFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<FrameProcedureOptions>::bitset( + IO &io, FrameProcedureOptions &Flags) { + auto FlagNames = getFrameProcSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<FrameProcedureOptions>(E.Value)); + } +} + +void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) { + auto CpuNames = getCPUTypeNames(); + for (const auto &E : CpuNames) { + io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value)); + } +} + +void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) { + auto RegNames = getRegisterNames(); + for (const auto &E : RegNames) { + io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); + } + io.enumFallback<Hex16>(Reg); +} + +void ScalarEnumerationTraits<TrampolineType>::enumeration( + IO &io, TrampolineType &Tramp) { + auto TrampNames = getTrampolineNames(); + for (const auto &E : TrampNames) { + io.enumCase(Tramp, E.Name.str().c_str(), + static_cast<TrampolineType>(E.Value)); + } +} + +void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, + ThunkOrdinal &Ord) { + auto ThunkNames = getThunkOrdinalNames(); + for (const auto &E : ThunkNames) { + io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); + } +} + +void ScalarEnumerationTraits<FrameCookieKind>::enumeration( + IO &io, FrameCookieKind &FC) { + auto ThunkNames = getFrameCookieKindNames(); + for (const auto &E : ThunkNames) { + io.enumCase(FC, E.Name.str().c_str(), + static_cast<FrameCookieKind>(E.Value)); + } +} + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct SymbolRecordBase { + codeview::SymbolKind Kind; + + explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} + virtual ~SymbolRecordBase() = default; + + virtual void map(yaml::IO &io) = 0; + virtual codeview::CVSymbol + toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const = 0; + virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; +}; + +template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { + explicit SymbolRecordImpl(codeview::SymbolKind K) + : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} + + void map(yaml::IO &io) override; + + codeview::CVSymbol + toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const override { + return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); + } + + Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { + return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); + } + + mutable T Symbol; +}; + +struct UnknownSymbolRecord : public SymbolRecordBase { + explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} + + void map(yaml::IO &io) override; + + CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const override { + RecordPrefix Prefix; + uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); + Prefix.RecordKind = Kind; + Prefix.RecordLen = TotalLen - 2; + uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen); + ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); + ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); + return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen)); + } + + Error fromCodeViewSymbol(CVSymbol CVS) override { + this->Kind = CVS.kind(); + Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); + return Error::success(); + } + + std::vector<uint8_t> Data; +}; + +template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} + +void UnknownSymbolRecord::map(yaml::IO &io) { + yaml::BinaryRef Binary; + if (io.outputting()) + Binary = yaml::BinaryRef(Data); + io.mapRequired("Data", Binary); + if (!io.outputting()) { + std::string Str; + raw_string_ostream OS(Str); + Binary.writeAsBinary(OS); + OS.flush(); + Data.assign(Str.begin(), Str.end()); + } +} + +template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { + IO.mapRequired("Parent", Symbol.Parent); + IO.mapRequired("End", Symbol.End); + IO.mapRequired("Next", Symbol.Next); + IO.mapRequired("Off", Symbol.Offset); + IO.mapRequired("Seg", Symbol.Segment); + IO.mapRequired("Len", Symbol.Length); + IO.mapRequired("Ordinal", Symbol.Thunk); +} + +template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Size", Symbol.Size); + IO.mapRequired("ThunkOff", Symbol.ThunkOffset); + IO.mapRequired("TargetOff", Symbol.TargetOffset); + IO.mapRequired("ThunkSection", Symbol.ThunkSection); + IO.mapRequired("TargetSection", Symbol.TargetSection); +} + +template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { + IO.mapRequired("SectionNumber", Symbol.SectionNumber); + IO.mapRequired("Alignment", Symbol.Alignment); + IO.mapRequired("Rva", Symbol.Rva); + IO.mapRequired("Length", Symbol.Length); + IO.mapRequired("Characteristics", Symbol.Characteristics); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { + IO.mapRequired("Size", Symbol.Size); + IO.mapRequired("Characteristics", Symbol.Characteristics); + IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Segment", Symbol.Segment); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { + IO.mapRequired("Ordinal", Symbol.Ordinal); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { + IO.mapOptional("PtrParent", Symbol.Parent, 0U); + IO.mapOptional("PtrEnd", Symbol.End, 0U); + IO.mapOptional("PtrNext", Symbol.Next, 0U); + IO.mapRequired("CodeSize", Symbol.CodeSize); + IO.mapRequired("DbgStart", Symbol.DbgStart); + IO.mapRequired("DbgEnd", Symbol.DbgEnd); + IO.mapRequired("FunctionType", Symbol.FunctionType); + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("DisplayName", Symbol.Name); +} + +template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Index); + IO.mapRequired("Seg", Symbol.Register); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { + IO.mapRequired("Flags", Symbol.Flags); + IO.mapOptional("Offset", Symbol.Offset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { + IO.mapRequired("SumName", Symbol.SumName); + IO.mapRequired("SymOffset", Symbol.SymOffset); + IO.mapRequired("Mod", Symbol.Module); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { + IO.mapRequired("Entries", Symbol.Fields); +} + +template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { + IO.mapOptional("PtrParent", Symbol.Parent, 0U); + IO.mapOptional("PtrEnd", Symbol.End, 0U); + IO.mapRequired("Inlinee", Symbol.Inlinee); + // TODO: The binary annotations +} + +template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Flags", Symbol.Flags); + + IO.mapRequired("VarName", Symbol.Name); +} + +template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> +void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { + IO.mapOptional("PtrParent", Symbol.Parent, 0U); + IO.mapOptional("PtrEnd", Symbol.End, 0U); + IO.mapRequired("CodeSize", Symbol.CodeSize); + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("BlockName", Symbol.Name); +} + +template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("DisplayName", Symbol.Name); +} + +template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { + IO.mapRequired("Signature", Symbol.Signature); + IO.mapRequired("ObjectName", Symbol.Name); +} + +template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Machine", Symbol.Machine); + IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); + IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); + IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); + IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); + IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); + IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); + IO.mapRequired("Version", Symbol.Version); +} + +template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Machine", Symbol.Machine); + IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); + IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); + IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); + IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); + IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); + IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); + IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); + IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); + IO.mapRequired("Version", Symbol.Version); +} + +template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { + IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); + IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); + IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); + IO.mapRequired("BytesOfCalleeSavedRegisters", + Symbol.BytesOfCalleeSavedRegisters); + IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); + IO.mapRequired("SectionIdOfExceptionHandler", + Symbol.SectionIdOfExceptionHandler); + IO.mapRequired("Flags", Symbol.Flags); +} + +template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Type", Symbol.Type); +} + +template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { + IO.mapRequired("Index", Symbol.Index); + IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); + IO.mapRequired("Type", Symbol.Type); +} + +template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { + IO.mapRequired("Register", Symbol.Register); + IO.mapRequired("CookieKind", Symbol.CookieKind); + IO.mapRequired("Flags", Symbol.Flags); +} + +template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { + IO.mapRequired("FuncID", Symbol.Indices); +} + +template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("UDTName", Symbol.Name); +} + +template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { + IO.mapRequired("BuildId", Symbol.BuildId); +} + +template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { + IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("VarName", Symbol.Name); +} + +template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { + IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Register", Symbol.Register); + IO.mapRequired("VarName", Symbol.Name); +} + +template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Value", Symbol.Value); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapOptional("Offset", Symbol.DataOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("DisplayName", Symbol.Name); +} + +template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapOptional("Offset", Symbol.DataOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("DisplayName", Symbol.Name); +} + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( + BumpPtrAllocator &Allocator, CodeViewContainer Container) const { + return Symbol->toCodeViewSymbol(Allocator, Container); +} + +namespace llvm { +namespace yaml { + +template <> struct MappingTraits<SymbolRecordBase> { + static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } +}; + +} // end namespace yaml +} // end namespace llvm + +template <typename SymbolType> +static inline Expected<CodeViewYAML::SymbolRecord> +fromCodeViewSymbolImpl(CVSymbol Symbol) { + CodeViewYAML::SymbolRecord Result; + + auto Impl = std::make_shared<SymbolType>(Symbol.kind()); + if (auto EC = Impl->fromCodeViewSymbol(Symbol)) + return std::move(EC); + Result.Symbol = Impl; + return Result; +} + +Expected<CodeViewYAML::SymbolRecord> +CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { +#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol); +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + SYMBOL_RECORD(EnumName, EnumVal, ClassName) + switch (Symbol.kind()) { +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" + default: + return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol); + } + return make_error<CodeViewError>(cv_error_code::corrupt_record); +} + +template <typename ConcreteType> +static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, + CodeViewYAML::SymbolRecord &Obj) { + if (!IO.outputting()) + Obj.Symbol = std::make_shared<ConcreteType>(Kind); + + IO.mapRequired(Class, *Obj.Symbol); +} + +void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( + IO &IO, CodeViewYAML::SymbolRecord &Obj) { + SymbolKind Kind; + if (IO.outputting()) + Kind = Obj.Symbol->Kind; + IO.mapRequired("Kind", Kind); + +#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \ + Obj); \ + break; +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + SYMBOL_RECORD(EnumName, EnumVal, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" + default: + mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); + } +} diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp new file mode 100644 index 0000000..81046b2 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -0,0 +1,806 @@ +//===- CodeViewYAMLTypes.cpp - CodeView YAMLIO types 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 CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLTypes.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <vector> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord) +LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) + +LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) +LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) + +LLVM_YAML_DECLARE_ENUM_TRAITS(TypeLeafKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(PointerToMemberRepresentation) +LLVM_YAML_DECLARE_ENUM_TRAITS(VFTableSlotKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(CallingConvention) +LLVM_YAML_DECLARE_ENUM_TRAITS(PointerKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(PointerMode) +LLVM_YAML_DECLARE_ENUM_TRAITS(HfaKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(MemberAccess) +LLVM_YAML_DECLARE_ENUM_TRAITS(MethodKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(WindowsRTClassKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(LabelType) + +LLVM_YAML_DECLARE_BITSET_TRAITS(PointerOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(ModifierOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(FunctionOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(ClassOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(MethodOptions) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(OneMethodRecord) +LLVM_YAML_DECLARE_MAPPING_TRAITS(MemberPointerInfo) + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct LeafRecordBase { + TypeLeafKind Kind; + + explicit LeafRecordBase(TypeLeafKind K) : Kind(K) {} + virtual ~LeafRecordBase() = default; + + virtual void map(yaml::IO &io) = 0; + virtual CVType toCodeViewRecord(TypeTableBuilder &TTB) const = 0; + virtual Error fromCodeViewRecord(CVType Type) = 0; +}; + +template <typename T> struct LeafRecordImpl : public LeafRecordBase { + explicit LeafRecordImpl(TypeLeafKind K) + : LeafRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {} + + void map(yaml::IO &io) override; + + Error fromCodeViewRecord(CVType Type) override { + return TypeDeserializer::deserializeAs<T>(Type, Record); + } + + CVType toCodeViewRecord(TypeTableBuilder &TTB) const override { + TTB.writeKnownType(Record); + return CVType(Kind, TTB.records().back()); + } + + mutable T Record; +}; + +template <> struct LeafRecordImpl<FieldListRecord> : public LeafRecordBase { + explicit LeafRecordImpl(TypeLeafKind K) : LeafRecordBase(K) {} + + void map(yaml::IO &io) override; + CVType toCodeViewRecord(TypeTableBuilder &TTB) const override; + Error fromCodeViewRecord(CVType Type) override; + + std::vector<MemberRecord> Members; +}; + +struct MemberRecordBase { + TypeLeafKind Kind; + + explicit MemberRecordBase(TypeLeafKind K) : Kind(K) {} + virtual ~MemberRecordBase() = default; + + virtual void map(yaml::IO &io) = 0; + virtual void writeTo(FieldListRecordBuilder &FLRB) = 0; +}; + +template <typename T> struct MemberRecordImpl : public MemberRecordBase { + explicit MemberRecordImpl(TypeLeafKind K) + : MemberRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {} + + void map(yaml::IO &io) override; + + void writeTo(FieldListRecordBuilder &FLRB) override { + FLRB.writeMemberType(Record); + } + + mutable T Record; +}; + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +void ScalarTraits<GUID>::output(const GUID &G, void *, llvm::raw_ostream &OS) { + OS << G; +} + +StringRef ScalarTraits<GUID>::input(StringRef Scalar, void *Ctx, GUID &S) { + if (Scalar.size() != 38) + return "GUID strings are 38 characters long"; + if (Scalar[0] != '{' || Scalar[37] != '}') + return "GUID is not enclosed in {}"; + if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' || + Scalar[24] != '-') + return "GUID sections are not properly delineated with dashes"; + + uint8_t *OutBuffer = S.Guid; + for (auto Iter = Scalar.begin(); Iter != Scalar.end();) { + if (*Iter == '-' || *Iter == '{' || *Iter == '}') { + ++Iter; + continue; + } + uint8_t Value = (llvm::hexDigitValue(*Iter++) << 4); + Value |= llvm::hexDigitValue(*Iter++); + *OutBuffer++ = Value; + } + + return ""; +} + +void ScalarTraits<TypeIndex>::output(const TypeIndex &S, void *, + raw_ostream &OS) { + OS << S.getIndex(); +} + +StringRef ScalarTraits<TypeIndex>::input(StringRef Scalar, void *Ctx, + TypeIndex &S) { + uint32_t I; + StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I); + S.setIndex(I); + return Result; +} + +void ScalarTraits<APSInt>::output(const APSInt &S, void *, raw_ostream &OS) { + S.print(OS, S.isSigned()); +} + +StringRef ScalarTraits<APSInt>::input(StringRef Scalar, void *Ctx, APSInt &S) { + S = APSInt(Scalar); + return ""; +} + +void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io, + TypeLeafKind &Value) { +#define CV_TYPE(name, val) io.enumCase(Value, #name, name); +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +#undef CV_TYPE +} + +void ScalarEnumerationTraits<PointerToMemberRepresentation>::enumeration( + IO &IO, PointerToMemberRepresentation &Value) { + IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown); + IO.enumCase(Value, "SingleInheritanceData", + PointerToMemberRepresentation::SingleInheritanceData); + IO.enumCase(Value, "MultipleInheritanceData", + PointerToMemberRepresentation::MultipleInheritanceData); + IO.enumCase(Value, "VirtualInheritanceData", + PointerToMemberRepresentation::VirtualInheritanceData); + IO.enumCase(Value, "GeneralData", PointerToMemberRepresentation::GeneralData); + IO.enumCase(Value, "SingleInheritanceFunction", + PointerToMemberRepresentation::SingleInheritanceFunction); + IO.enumCase(Value, "MultipleInheritanceFunction", + PointerToMemberRepresentation::MultipleInheritanceFunction); + IO.enumCase(Value, "VirtualInheritanceFunction", + PointerToMemberRepresentation::VirtualInheritanceFunction); + IO.enumCase(Value, "GeneralFunction", + PointerToMemberRepresentation::GeneralFunction); +} + +void ScalarEnumerationTraits<VFTableSlotKind>::enumeration( + IO &IO, VFTableSlotKind &Kind) { + IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16); + IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16); + IO.enumCase(Kind, "This", VFTableSlotKind::This); + IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer); + IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta); + IO.enumCase(Kind, "Near", VFTableSlotKind::Near); + IO.enumCase(Kind, "Far", VFTableSlotKind::Far); +} + +void ScalarEnumerationTraits<CallingConvention>::enumeration( + IO &IO, CallingConvention &Value) { + IO.enumCase(Value, "NearC", CallingConvention::NearC); + IO.enumCase(Value, "FarC", CallingConvention::FarC); + IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal); + IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal); + IO.enumCase(Value, "NearFast", CallingConvention::NearFast); + IO.enumCase(Value, "FarFast", CallingConvention::FarFast); + IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall); + IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall); + IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall); + IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall); + IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall); + IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall); + IO.enumCase(Value, "Generic", CallingConvention::Generic); + IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall); + IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall); + IO.enumCase(Value, "SHCall", CallingConvention::SHCall); + IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall); + IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call); + IO.enumCase(Value, "TriCall", CallingConvention::TriCall); + IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call); + IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall); + IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall); + IO.enumCase(Value, "Inline", CallingConvention::Inline); + IO.enumCase(Value, "NearVector", CallingConvention::NearVector); +} + +void ScalarEnumerationTraits<PointerKind>::enumeration(IO &IO, + PointerKind &Kind) { + IO.enumCase(Kind, "Near16", PointerKind::Near16); + IO.enumCase(Kind, "Far16", PointerKind::Far16); + IO.enumCase(Kind, "Huge16", PointerKind::Huge16); + IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment); + IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue); + IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue); + IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress); + IO.enumCase(Kind, "BasedOnSegmentAddress", + PointerKind::BasedOnSegmentAddress); + IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType); + IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf); + IO.enumCase(Kind, "Near32", PointerKind::Near32); + IO.enumCase(Kind, "Far32", PointerKind::Far32); + IO.enumCase(Kind, "Near64", PointerKind::Near64); +} + +void ScalarEnumerationTraits<PointerMode>::enumeration(IO &IO, + PointerMode &Mode) { + IO.enumCase(Mode, "Pointer", PointerMode::Pointer); + IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference); + IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember); + IO.enumCase(Mode, "PointerToMemberFunction", + PointerMode::PointerToMemberFunction); + IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference); +} + +void ScalarEnumerationTraits<HfaKind>::enumeration(IO &IO, HfaKind &Value) { + IO.enumCase(Value, "None", HfaKind::None); + IO.enumCase(Value, "Float", HfaKind::Float); + IO.enumCase(Value, "Double", HfaKind::Double); + IO.enumCase(Value, "Other", HfaKind::Other); +} + +void ScalarEnumerationTraits<MemberAccess>::enumeration(IO &IO, + MemberAccess &Access) { + IO.enumCase(Access, "None", MemberAccess::None); + IO.enumCase(Access, "Private", MemberAccess::Private); + IO.enumCase(Access, "Protected", MemberAccess::Protected); + IO.enumCase(Access, "Public", MemberAccess::Public); +} + +void ScalarEnumerationTraits<MethodKind>::enumeration(IO &IO, + MethodKind &Kind) { + IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla); + IO.enumCase(Kind, "Virtual", MethodKind::Virtual); + IO.enumCase(Kind, "Static", MethodKind::Static); + IO.enumCase(Kind, "Friend", MethodKind::Friend); + IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual); + IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual); + IO.enumCase(Kind, "PureIntroducingVirtual", + MethodKind::PureIntroducingVirtual); +} + +void ScalarEnumerationTraits<WindowsRTClassKind>::enumeration( + IO &IO, WindowsRTClassKind &Value) { + IO.enumCase(Value, "None", WindowsRTClassKind::None); + IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass); + IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass); + IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface); +} + +void ScalarEnumerationTraits<LabelType>::enumeration(IO &IO, LabelType &Value) { + IO.enumCase(Value, "Near", LabelType::Near); + IO.enumCase(Value, "Far", LabelType::Far); +} + +void ScalarBitSetTraits<PointerOptions>::bitset(IO &IO, + PointerOptions &Options) { + IO.bitSetCase(Options, "None", PointerOptions::None); + IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32); + IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile); + IO.bitSetCase(Options, "Const", PointerOptions::Const); + IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned); + IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict); + IO.bitSetCase(Options, "WinRTSmartPointer", + PointerOptions::WinRTSmartPointer); +} + +void ScalarBitSetTraits<ModifierOptions>::bitset(IO &IO, + ModifierOptions &Options) { + IO.bitSetCase(Options, "None", ModifierOptions::None); + IO.bitSetCase(Options, "Const", ModifierOptions::Const); + IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile); + IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned); +} + +void ScalarBitSetTraits<FunctionOptions>::bitset(IO &IO, + FunctionOptions &Options) { + IO.bitSetCase(Options, "None", FunctionOptions::None); + IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt); + IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor); + IO.bitSetCase(Options, "ConstructorWithVirtualBases", + FunctionOptions::ConstructorWithVirtualBases); +} + +void ScalarBitSetTraits<ClassOptions>::bitset(IO &IO, ClassOptions &Options) { + IO.bitSetCase(Options, "None", ClassOptions::None); + IO.bitSetCase(Options, "HasConstructorOrDestructor", + ClassOptions::HasConstructorOrDestructor); + IO.bitSetCase(Options, "HasOverloadedOperator", + ClassOptions::HasOverloadedOperator); + IO.bitSetCase(Options, "Nested", ClassOptions::Nested); + IO.bitSetCase(Options, "ContainsNestedClass", + ClassOptions::ContainsNestedClass); + IO.bitSetCase(Options, "HasOverloadedAssignmentOperator", + ClassOptions::HasOverloadedAssignmentOperator); + IO.bitSetCase(Options, "HasConversionOperator", + ClassOptions::HasConversionOperator); + IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference); + IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped); + IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName); + IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed); + IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic); +} + +void ScalarBitSetTraits<MethodOptions>::bitset(IO &IO, MethodOptions &Options) { + IO.bitSetCase(Options, "None", MethodOptions::None); + IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo); + IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit); + IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct); + IO.bitSetCase(Options, "CompilerGenerated", MethodOptions::CompilerGenerated); + IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed); +} + +void MappingTraits<MemberPointerInfo>::mapping(IO &IO, MemberPointerInfo &MPI) { + IO.mapRequired("ContainingType", MPI.ContainingType); + IO.mapRequired("Representation", MPI.Representation); +} + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +template <> void LeafRecordImpl<ModifierRecord>::map(IO &IO) { + IO.mapRequired("ModifiedType", Record.ModifiedType); + IO.mapRequired("Modifiers", Record.Modifiers); +} + +template <> void LeafRecordImpl<ProcedureRecord>::map(IO &IO) { + IO.mapRequired("ReturnType", Record.ReturnType); + IO.mapRequired("CallConv", Record.CallConv); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("ParameterCount", Record.ParameterCount); + IO.mapRequired("ArgumentList", Record.ArgumentList); +} + +template <> void LeafRecordImpl<MemberFunctionRecord>::map(IO &IO) { + IO.mapRequired("ReturnType", Record.ReturnType); + IO.mapRequired("ClassType", Record.ClassType); + IO.mapRequired("ThisType", Record.ThisType); + IO.mapRequired("CallConv", Record.CallConv); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("ParameterCount", Record.ParameterCount); + IO.mapRequired("ArgumentList", Record.ArgumentList); + IO.mapRequired("ThisPointerAdjustment", Record.ThisPointerAdjustment); +} + +template <> void LeafRecordImpl<LabelRecord>::map(IO &IO) { + IO.mapRequired("Mode", Record.Mode); +} + +template <> void LeafRecordImpl<MemberFuncIdRecord>::map(IO &IO) { + IO.mapRequired("ClassType", Record.ClassType); + IO.mapRequired("FunctionType", Record.FunctionType); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl<ArgListRecord>::map(IO &IO) { + IO.mapRequired("ArgIndices", Record.ArgIndices); +} + +template <> void LeafRecordImpl<StringListRecord>::map(IO &IO) { + IO.mapRequired("StringIndices", Record.StringIndices); +} + +template <> void LeafRecordImpl<PointerRecord>::map(IO &IO) { + IO.mapRequired("ReferentType", Record.ReferentType); + IO.mapRequired("Attrs", Record.Attrs); + IO.mapOptional("MemberInfo", Record.MemberInfo); +} + +template <> void LeafRecordImpl<ArrayRecord>::map(IO &IO) { + IO.mapRequired("ElementType", Record.ElementType); + IO.mapRequired("IndexType", Record.IndexType); + IO.mapRequired("Size", Record.Size); + IO.mapRequired("Name", Record.Name); +} + +void LeafRecordImpl<FieldListRecord>::map(IO &IO) { + IO.mapRequired("FieldList", Members); +} + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +namespace { + +class MemberRecordConversionVisitor : public TypeVisitorCallbacks { +public: + explicit MemberRecordConversionVisitor(std::vector<MemberRecord> &Records) + : Records(Records) {} + +#define TYPE_RECORD(EnumName, EnumVal, Name) +#define MEMBER_RECORD(EnumName, EnumVal, Name) \ + Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \ + return visitKnownMemberImpl(Record); \ + } +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +private: + template <typename T> Error visitKnownMemberImpl(T &Record) { + TypeLeafKind K = static_cast<TypeLeafKind>(Record.getKind()); + auto Impl = std::make_shared<MemberRecordImpl<T>>(K); + Impl->Record = Record; + Records.push_back(MemberRecord{Impl}); + return Error::success(); + } + + std::vector<MemberRecord> &Records; +}; + +} // end anonymous namespace + +Error LeafRecordImpl<FieldListRecord>::fromCodeViewRecord(CVType Type) { + MemberRecordConversionVisitor V(Members); + return visitMemberRecordStream(Type.content(), V); +} + +CVType +LeafRecordImpl<FieldListRecord>::toCodeViewRecord(TypeTableBuilder &TTB) const { + FieldListRecordBuilder FLRB(TTB); + FLRB.begin(); + for (const auto &Member : Members) { + Member.Member->writeTo(FLRB); + } + FLRB.end(true); + return CVType(Kind, TTB.records().back()); +} + +void MappingTraits<OneMethodRecord>::mapping(IO &io, OneMethodRecord &Record) { + io.mapRequired("Type", Record.Type); + io.mapRequired("Attrs", Record.Attrs.Attrs); + io.mapRequired("VFTableOffset", Record.VFTableOffset); + io.mapRequired("Name", Record.Name); +} + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +template <> void LeafRecordImpl<ClassRecord>::map(IO &IO) { + IO.mapRequired("MemberCount", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + IO.mapRequired("DerivationList", Record.DerivationList); + IO.mapRequired("VTableShape", Record.VTableShape); + IO.mapRequired("Size", Record.Size); +} + +template <> void LeafRecordImpl<UnionRecord>::map(IO &IO) { + IO.mapRequired("MemberCount", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + IO.mapRequired("Size", Record.Size); +} + +template <> void LeafRecordImpl<EnumRecord>::map(IO &IO) { + IO.mapRequired("NumEnumerators", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + IO.mapRequired("UnderlyingType", Record.UnderlyingType); +} + +template <> void LeafRecordImpl<BitFieldRecord>::map(IO &IO) { + IO.mapRequired("Type", Record.Type); + IO.mapRequired("BitSize", Record.BitSize); + IO.mapRequired("BitOffset", Record.BitOffset); +} + +template <> void LeafRecordImpl<VFTableShapeRecord>::map(IO &IO) { + IO.mapRequired("Slots", Record.Slots); +} + +template <> void LeafRecordImpl<TypeServer2Record>::map(IO &IO) { + IO.mapRequired("Guid", Record.Guid); + IO.mapRequired("Age", Record.Age); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl<StringIdRecord>::map(IO &IO) { + IO.mapRequired("Id", Record.Id); + IO.mapRequired("String", Record.String); +} + +template <> void LeafRecordImpl<FuncIdRecord>::map(IO &IO) { + IO.mapRequired("ParentScope", Record.ParentScope); + IO.mapRequired("FunctionType", Record.FunctionType); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl<UdtSourceLineRecord>::map(IO &IO) { + IO.mapRequired("UDT", Record.UDT); + IO.mapRequired("SourceFile", Record.SourceFile); + IO.mapRequired("LineNumber", Record.LineNumber); +} + +template <> void LeafRecordImpl<UdtModSourceLineRecord>::map(IO &IO) { + IO.mapRequired("UDT", Record.UDT); + IO.mapRequired("SourceFile", Record.SourceFile); + IO.mapRequired("LineNumber", Record.LineNumber); + IO.mapRequired("Module", Record.Module); +} + +template <> void LeafRecordImpl<BuildInfoRecord>::map(IO &IO) { + IO.mapRequired("ArgIndices", Record.ArgIndices); +} + +template <> void LeafRecordImpl<VFTableRecord>::map(IO &IO) { + IO.mapRequired("CompleteClass", Record.CompleteClass); + IO.mapRequired("OverriddenVFTable", Record.OverriddenVFTable); + IO.mapRequired("VFPtrOffset", Record.VFPtrOffset); + IO.mapRequired("MethodNames", Record.MethodNames); +} + +template <> void LeafRecordImpl<MethodOverloadListRecord>::map(IO &IO) { + IO.mapRequired("Methods", Record.Methods); +} + +template <> void MemberRecordImpl<OneMethodRecord>::map(IO &IO) { + MappingTraits<OneMethodRecord>::mapping(IO, Record); +} + +template <> void MemberRecordImpl<OverloadedMethodRecord>::map(IO &IO) { + IO.mapRequired("NumOverloads", Record.NumOverloads); + IO.mapRequired("MethodList", Record.MethodList); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<NestedTypeRecord>::map(IO &IO) { + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<DataMemberRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("FieldOffset", Record.FieldOffset); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<StaticDataMemberRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<EnumeratorRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Value", Record.Value); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<VFPtrRecord>::map(IO &IO) { + IO.mapRequired("Type", Record.Type); +} + +template <> void MemberRecordImpl<BaseClassRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Offset", Record.Offset); +} + +template <> void MemberRecordImpl<VirtualBaseClassRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("BaseType", Record.BaseType); + IO.mapRequired("VBPtrType", Record.VBPtrType); + IO.mapRequired("VBPtrOffset", Record.VBPtrOffset); + IO.mapRequired("VTableIndex", Record.VTableIndex); +} + +template <> void MemberRecordImpl<ListContinuationRecord>::map(IO &IO) { + IO.mapRequired("ContinuationIndex", Record.ContinuationIndex); +} + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +template <typename T> +static inline Expected<LeafRecord> fromCodeViewRecordImpl(CVType Type) { + LeafRecord Result; + + auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.kind()); + if (auto EC = Impl->fromCodeViewRecord(Type)) + return std::move(EC); + Result.Leaf = Impl; + return Result; +} + +Expected<LeafRecord> LeafRecord::fromCodeViewRecord(CVType Type) { +#define TYPE_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + return fromCodeViewRecordImpl<ClassName##Record>(Type); +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + TYPE_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Type.kind()) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: + llvm_unreachable("Unknown leaf kind!"); + } + return make_error<CodeViewError>(cv_error_code::corrupt_record); +} + +CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Alloc) const { + TypeTableBuilder TTB(Alloc); + return Leaf->toCodeViewRecord(TTB); +} + +CVType LeafRecord::toCodeViewRecord(TypeTableBuilder &TTB) const { + return Leaf->toCodeViewRecord(TTB); +} + +namespace llvm { +namespace yaml { + +template <> struct MappingTraits<LeafRecordBase> { + static void mapping(IO &io, LeafRecordBase &Record) { Record.map(io); } +}; + +template <> struct MappingTraits<MemberRecordBase> { + static void mapping(IO &io, MemberRecordBase &Record) { Record.map(io); } +}; + +} // end namespace yaml +} // end namespace llvm + +template <typename ConcreteType> +static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, + LeafRecord &Obj) { + if (!IO.outputting()) + Obj.Leaf = std::make_shared<LeafRecordImpl<ConcreteType>>(Kind); + + if (Kind == LF_FIELDLIST) + Obj.Leaf->map(IO); + else + IO.mapRequired(Class, *Obj.Leaf); +} + +void MappingTraits<LeafRecord>::mapping(IO &IO, LeafRecord &Obj) { + TypeLeafKind Kind; + if (IO.outputting()) + Kind = Obj.Leaf->Kind; + IO.mapRequired("Kind", Kind); + +#define TYPE_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapLeafRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \ + break; +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + TYPE_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown leaf kind!"); } + } +} + +template <typename ConcreteType> +static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, + MemberRecord &Obj) { + if (!IO.outputting()) + Obj.Member = std::make_shared<MemberRecordImpl<ConcreteType>>(Kind); + + IO.mapRequired(Class, *Obj.Member); +} + +void MappingTraits<MemberRecord>::mapping(IO &IO, MemberRecord &Obj) { + TypeLeafKind Kind; + if (IO.outputting()) + Kind = Obj.Member->Kind; + IO.mapRequired("Kind", Kind); + +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapMemberRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \ + break; +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define TYPE_RECORD(EnumName, EnumVal, ClassName) +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown member kind!"); } + } +} + +std::vector<LeafRecord> +llvm::CodeViewYAML::fromDebugT(ArrayRef<uint8_t> DebugT) { + ExitOnError Err("Invalid .debug$T section!"); + BinaryStreamReader Reader(DebugT, support::little); + CVTypeArray Types; + uint32_t Magic; + + Err(Reader.readInteger(Magic)); + assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$T section!"); + + std::vector<LeafRecord> Result; + Err(Reader.readArray(Types, Reader.bytesRemaining())); + for (const auto &T : Types) { + auto CVT = Err(LeafRecord::fromCodeViewRecord(T)); + Result.push_back(CVT); + } + return Result; +} + +ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugT(ArrayRef<LeafRecord> Leafs, + BumpPtrAllocator &Alloc) { + TypeTableBuilder TTB(Alloc, false); + uint32_t Size = sizeof(uint32_t); + for (const auto &Leaf : Leafs) { + CVType T = Leaf.toCodeViewRecord(TTB); + Size += T.length(); + assert(T.length() % 4 == 0 && "Improper type record alignment!"); + } + uint8_t *ResultBuffer = Alloc.Allocate<uint8_t>(Size); + MutableArrayRef<uint8_t> Output(ResultBuffer, Size); + BinaryStreamWriter Writer(Output, support::little); + ExitOnError Err("Error writing type record to .debug$T section"); + Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC)); + for (const auto &R : TTB.records()) { + Err(Writer.writeBytes(R)); + } + assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!"); + return Output; +} diff --git a/contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp new file mode 100644 index 0000000..89fc652 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -0,0 +1,333 @@ +//===- 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 "DWARFVisitor.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ObjectYAML/DWARFYAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/LEB128.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SwapByteOrder.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> +#include <string> +#include <vector> + +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: + void onStartCompileUnit(const DWARFYAML::Unit &CU) override { + 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); + } + + } + + void onStartDIE(const DWARFYAML::Unit &CU, + const DWARFYAML::Entry &DIE) override { + encodeULEB128(DIE.AbbrCode, OS); + } + + void onValue(const uint8_t U) override { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const uint16_t U) override { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const uint32_t U) override { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const uint64_t U, const bool LEB = false) override { + if (LEB) + encodeULEB128(U, OS); + else + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const int64_t S, const bool LEB = false) override { + if (LEB) + encodeSLEB128(S, OS); + else + writeInteger(S, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const StringRef String) override { + OS.write(String.data(), String.size()); + OS.write('\0'); + } + + void onValue(const MemoryBufferRef MBR) override { + 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); + } + } + } + } + } +} + +using EmitFuncType = void (*)(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/contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp b/contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp new file mode 100644 index 0000000..36a9f76 --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/lib/ObjectYAML/DWARFVisitor.h b/contrib/llvm/lib/ObjectYAML/DWARFVisitor.h new file mode 100644 index 0000000..81ef412 --- /dev/null +++ b/contrib/llvm/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/BinaryFormat/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/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp b/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp index 014e63f..d6c09e1 100644 --- a/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/contrib/llvm/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); } -} // namespace llvm::yaml +void MappingTraits<DWARFYAML::InitialLength>::mapping( + IO &IO, DWARFYAML::InitialLength &InitialLength) { + IO.mapRequired("TotalLength", InitialLength.TotalLength); + if (InitialLength.isDWARF64()) + IO.mapRequired("TotalLength64", InitialLength.TotalLength64); +} + +} // end namespace yaml -} // namespace llvm +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp b/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp index fe9af9f..39741da 100644 --- a/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -12,240 +12,244 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/ELFYAML.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MipsABIFlags.h" +#include "llvm/Support/YAMLTraits.h" +#include <cassert> +#include <cstdint> namespace llvm { -ELFYAML::Section::~Section() {} +ELFYAML::Section::~Section() = default; 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 +257,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 +358,52 @@ 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_LLVM_ODRTAB); + 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 +415,37 @@ 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) - 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_ARM_PURECODE); 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 +456,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 +482,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 +499,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 } @@ -515,89 +514,90 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( #define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X); switch (Object->Header.Machine) { case ELF::EM_X86_64: -#include "llvm/Support/ELFRelocs/x86_64.def" +#include "llvm/BinaryFormat/ELFRelocs/x86_64.def" break; case ELF::EM_MIPS: -#include "llvm/Support/ELFRelocs/Mips.def" +#include "llvm/BinaryFormat/ELFRelocs/Mips.def" break; case ELF::EM_HEXAGON: -#include "llvm/Support/ELFRelocs/Hexagon.def" +#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" break; case ELF::EM_386: case ELF::EM_IAMCU: -#include "llvm/Support/ELFRelocs/i386.def" +#include "llvm/BinaryFormat/ELFRelocs/i386.def" break; case ELF::EM_AARCH64: -#include "llvm/Support/ELFRelocs/AArch64.def" +#include "llvm/BinaryFormat/ELFRelocs/AArch64.def" break; case ELF::EM_ARM: -#include "llvm/Support/ELFRelocs/ARM.def" +#include "llvm/BinaryFormat/ELFRelocs/ARM.def" break; case ELF::EM_RISCV: -#include "llvm/Support/ELFRelocs/RISCV.def" +#include "llvm/BinaryFormat/ELFRelocs/RISCV.def" break; case ELF::EM_LANAI: -#include "llvm/Support/ELFRelocs/Lanai.def" +#include "llvm/BinaryFormat/ELFRelocs/Lanai.def" break; case ELF::EM_AMDGPU: -#include "llvm/Support/ELFRelocs/AMDGPU.def" +#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" break; case ELF::EM_BPF: -#include "llvm/Support/ELFRelocs/BPF.def" +#include "llvm/BinaryFormat/ELFRelocs/BPF.def" break; default: llvm_unreachable("Unsupported architecture"); } #undef ELF_RELOC + IO.enumFallback<Hex32>(Value); } 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 +614,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 } @@ -650,6 +650,7 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO, } namespace { + struct NormalizedOther { NormalizedOther(IO &) : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {} @@ -661,7 +662,8 @@ struct NormalizedOther { ELFYAML::ELF_STV Visibility; ELFYAML::ELF_STO Other; }; -} + +} // end anonymous namespace void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) { IO.mapOptional("Name", Symbol.Name, StringRef()); @@ -784,6 +786,7 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate( } namespace { + struct NormalizedMips64RelType { NormalizedMips64RelType(IO &) : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), @@ -804,7 +807,8 @@ struct NormalizedMips64RelType { ELFYAML::ELF_REL Type3; ELFYAML::ELF_RSS SpecSym; }; -} + +} // end anonymous namespace void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO, ELFYAML::Relocation &Rel) { @@ -845,4 +849,5 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) } // end namespace yaml + } // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp b/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp index a033a79..ab452a7 100644 --- a/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp @@ -12,16 +12,19 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/MachOYAML.h" -#include "llvm/Support/Casting.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/MachO.h" #include "llvm/Support/Format.h" #include "llvm/Support/Host.h" -#include "llvm/Support/MachO.h" - -#include <string.h> // For memcpy, memset and strnlen. +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <cinttypes> +#include <cstdint> +#include <cstring> namespace llvm { -MachOYAML::LoadCommand::~LoadCommand() {} +MachOYAML::LoadCommand::~LoadCommand() = default; bool MachOYAML::LinkEditData::isEmpty() const { return 0 == @@ -33,7 +36,7 @@ bool MachOYAML::LinkEditData::isEmpty() const { namespace yaml { void ScalarTraits<char_16>::output(const char_16 &Val, void *, - llvm::raw_ostream &Out) { + raw_ostream &Out) { auto Len = strnlen(&Val[0], 16); Out << StringRef(&Val[0], Len); } @@ -51,8 +54,7 @@ StringRef ScalarTraits<char_16>::input(StringRef Scalar, void *, char_16 &Val) { bool ScalarTraits<char_16>::mustQuote(StringRef S) { return needsQuotes(S); } -void ScalarTraits<uuid_t>::output(const uuid_t &Val, void *, - llvm::raw_ostream &Out) { +void ScalarTraits<uuid_t>::output(const uuid_t &Val, void *, raw_ostream &Out) { for (int Idx = 0; Idx < 16; ++Idx) { Out << format("%02" PRIX32, Val[Idx]); if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9) @@ -154,7 +156,7 @@ void MappingTraits<MachOYAML::LinkEditData>::mapping( IO.mapOptional("BindOpcodes", LinkEditData.BindOpcodes); IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes); IO.mapOptional("LazyBindOpcodes", LinkEditData.LazyBindOpcodes); - if(LinkEditData.ExportTrie.Children.size() > 0 || !IO.outputting()) + if (!LinkEditData.ExportTrie.Children.empty() || !IO.outputting()) IO.mapOptional("ExportTrie", LinkEditData.ExportTrie); IO.mapOptional("NameList", LinkEditData.NameList); IO.mapOptional("StringTable", LinkEditData.StringTable); @@ -230,6 +232,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>( @@ -246,7 +254,7 @@ void MappingTraits<MachOYAML::LoadCommand>::mapping( break; switch (LoadCommand.Data.load_command_data.cmd) { -#include "llvm/Support/MachO.def" +#include "llvm/BinaryFormat/MachO.def" } IO.mapOptional("PayloadBytes", LoadCommand.PayloadBytes); IO.mapOptional("ZeroPadBytes", LoadCommand.ZeroPadBytes, (uint64_t)0ull); @@ -282,6 +290,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); @@ -296,13 +310,11 @@ void MappingTraits<MachO::dylib_command>::mapping( void MappingTraits<MachO::dylinker_command>::mapping( IO &IO, MachO::dylinker_command &LoadCommand) { - IO.mapRequired("name", LoadCommand.name); } void MappingTraits<MachO::dysymtab_command>::mapping( IO &IO, MachO::dysymtab_command &LoadCommand) { - IO.mapRequired("ilocalsym", LoadCommand.ilocalsym); IO.mapRequired("nlocalsym", LoadCommand.nlocalsym); IO.mapRequired("iextdefsym", LoadCommand.iextdefsym); @@ -325,7 +337,6 @@ void MappingTraits<MachO::dysymtab_command>::mapping( void MappingTraits<MachO::encryption_info_command>::mapping( IO &IO, MachO::encryption_info_command &LoadCommand) { - IO.mapRequired("cryptoff", LoadCommand.cryptoff); IO.mapRequired("cryptsize", LoadCommand.cryptsize); IO.mapRequired("cryptid", LoadCommand.cryptid); @@ -333,7 +344,6 @@ void MappingTraits<MachO::encryption_info_command>::mapping( void MappingTraits<MachO::encryption_info_command_64>::mapping( IO &IO, MachO::encryption_info_command_64 &LoadCommand) { - IO.mapRequired("cryptoff", LoadCommand.cryptoff); IO.mapRequired("cryptsize", LoadCommand.cryptsize); IO.mapRequired("cryptid", LoadCommand.cryptid); @@ -342,14 +352,12 @@ void MappingTraits<MachO::encryption_info_command_64>::mapping( void MappingTraits<MachO::entry_point_command>::mapping( IO &IO, MachO::entry_point_command &LoadCommand) { - IO.mapRequired("entryoff", LoadCommand.entryoff); IO.mapRequired("stacksize", LoadCommand.stacksize); } void MappingTraits<MachO::fvmfile_command>::mapping( IO &IO, MachO::fvmfile_command &LoadCommand) { - IO.mapRequired("name", LoadCommand.name); IO.mapRequired("header_addr", LoadCommand.header_addr); } @@ -362,7 +370,6 @@ void MappingTraits<MachO::fvmlib>::mapping(IO &IO, MachO::fvmlib &FVMLib) { void MappingTraits<MachO::fvmlib_command>::mapping( IO &IO, MachO::fvmlib_command &LoadCommand) { - IO.mapRequired("fvmlib", LoadCommand.fvmlib); } @@ -371,20 +378,17 @@ void MappingTraits<MachO::ident_command>::mapping( void MappingTraits<MachO::linkedit_data_command>::mapping( IO &IO, MachO::linkedit_data_command &LoadCommand) { - IO.mapRequired("dataoff", LoadCommand.dataoff); IO.mapRequired("datasize", LoadCommand.datasize); } void MappingTraits<MachO::linker_option_command>::mapping( IO &IO, MachO::linker_option_command &LoadCommand) { - IO.mapRequired("count", LoadCommand.count); } void MappingTraits<MachO::prebind_cksum_command>::mapping( IO &IO, MachO::prebind_cksum_command &LoadCommand) { - IO.mapRequired("cksum", LoadCommand.cksum); } @@ -393,7 +397,6 @@ void MappingTraits<MachO::load_command>::mapping( void MappingTraits<MachO::prebound_dylib_command>::mapping( IO &IO, MachO::prebound_dylib_command &LoadCommand) { - IO.mapRequired("name", LoadCommand.name); IO.mapRequired("nmodules", LoadCommand.nmodules); IO.mapRequired("linked_modules", LoadCommand.linked_modules); @@ -401,7 +404,6 @@ void MappingTraits<MachO::prebound_dylib_command>::mapping( void MappingTraits<MachO::routines_command>::mapping( IO &IO, MachO::routines_command &LoadCommand) { - IO.mapRequired("init_address", LoadCommand.init_address); IO.mapRequired("init_module", LoadCommand.init_module); IO.mapRequired("reserved1", LoadCommand.reserved1); @@ -414,7 +416,6 @@ void MappingTraits<MachO::routines_command>::mapping( void MappingTraits<MachO::routines_command_64>::mapping( IO &IO, MachO::routines_command_64 &LoadCommand) { - IO.mapRequired("init_address", LoadCommand.init_address); IO.mapRequired("init_module", LoadCommand.init_module); IO.mapRequired("reserved1", LoadCommand.reserved1); @@ -427,7 +428,6 @@ void MappingTraits<MachO::routines_command_64>::mapping( void MappingTraits<MachO::rpath_command>::mapping( IO &IO, MachO::rpath_command &LoadCommand) { - IO.mapRequired("path", LoadCommand.path); } @@ -463,7 +463,6 @@ void MappingTraits<MachO::section_64>::mapping(IO &IO, void MappingTraits<MachO::segment_command>::mapping( IO &IO, MachO::segment_command &LoadCommand) { - IO.mapRequired("segname", LoadCommand.segname); IO.mapRequired("vmaddr", LoadCommand.vmaddr); IO.mapRequired("vmsize", LoadCommand.vmsize); @@ -477,7 +476,6 @@ void MappingTraits<MachO::segment_command>::mapping( void MappingTraits<MachO::segment_command_64>::mapping( IO &IO, MachO::segment_command_64 &LoadCommand) { - IO.mapRequired("segname", LoadCommand.segname); IO.mapRequired("vmaddr", LoadCommand.vmaddr); IO.mapRequired("vmsize", LoadCommand.vmsize); @@ -491,44 +489,37 @@ void MappingTraits<MachO::segment_command_64>::mapping( void MappingTraits<MachO::source_version_command>::mapping( IO &IO, MachO::source_version_command &LoadCommand) { - IO.mapRequired("version", LoadCommand.version); } void MappingTraits<MachO::sub_client_command>::mapping( IO &IO, MachO::sub_client_command &LoadCommand) { - IO.mapRequired("client", LoadCommand.client); } void MappingTraits<MachO::sub_framework_command>::mapping( IO &IO, MachO::sub_framework_command &LoadCommand) { - IO.mapRequired("umbrella", LoadCommand.umbrella); } void MappingTraits<MachO::sub_library_command>::mapping( IO &IO, MachO::sub_library_command &LoadCommand) { - IO.mapRequired("sub_library", LoadCommand.sub_library); } void MappingTraits<MachO::sub_umbrella_command>::mapping( IO &IO, MachO::sub_umbrella_command &LoadCommand) { - IO.mapRequired("sub_umbrella", LoadCommand.sub_umbrella); } void MappingTraits<MachO::symseg_command>::mapping( IO &IO, MachO::symseg_command &LoadCommand) { - IO.mapRequired("offset", LoadCommand.offset); IO.mapRequired("size", LoadCommand.size); } void MappingTraits<MachO::symtab_command>::mapping( IO &IO, MachO::symtab_command &LoadCommand) { - IO.mapRequired("symoff", LoadCommand.symoff); IO.mapRequired("nsyms", LoadCommand.nsyms); IO.mapRequired("stroff", LoadCommand.stroff); @@ -540,24 +531,36 @@ void MappingTraits<MachO::thread_command>::mapping( void MappingTraits<MachO::twolevel_hints_command>::mapping( IO &IO, MachO::twolevel_hints_command &LoadCommand) { - IO.mapRequired("offset", LoadCommand.offset); IO.mapRequired("nhints", LoadCommand.nhints); } void MappingTraits<MachO::uuid_command>::mapping( IO &IO, MachO::uuid_command &LoadCommand) { - IO.mapRequired("uuid", LoadCommand.uuid); } void MappingTraits<MachO::version_min_command>::mapping( IO &IO, MachO::version_min_command &LoadCommand) { - IO.mapRequired("version", LoadCommand.version); IO.mapRequired("sdk", LoadCommand.sdk); } -} // namespace llvm::yaml +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); +} + +} // end namespace yaml -} // namespace llvm +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp b/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp index cbbaac6..850c1a5 100644 --- a/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp @@ -11,8 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ObjectYAML/YAML.h" #include "llvm/ObjectYAML/ObjectYAML.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/YAMLParser.h" +#include "llvm/Support/YAMLTraits.h" +#include <string> using namespace llvm; using namespace yaml; @@ -43,6 +46,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(); @@ -50,8 +56,8 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO, IO.setError("YAML Object File missing document type tag!"); else IO.setError( - llvm::Twine("YAML Object File unsupported document type tag '") + - llvm::Twine(Tag) + llvm::Twine("'!")); + Twine("YAML Object File unsupported document type tag '") + + Twine(Tag) + Twine("'!")); } } } diff --git a/contrib/llvm/lib/ObjectYAML/WasmYAML.cpp b/contrib/llvm/lib/ObjectYAML/WasmYAML.cpp new file mode 100644 index 0000000..6a68cd2 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -0,0 +1,411 @@ +//===- 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/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/YAMLTraits.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() = default; + +} // 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::NameSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Name", Section.Name); + IO.mapOptional("FunctionNames", Section.FunctionNames); +} + +static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Name", Section.Name); + IO.mapRequired("DataSize", Section.DataSize); + IO.mapRequired("DataAlignment", Section.DataAlignment); + IO.mapRequired("SymbolInfo", Section.SymbolInfos); +} + +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: { + StringRef SectionName; + if (IO.outputting()) { + auto CustomSection = cast<WasmYAML::CustomSection>(Section.get()); + SectionName = CustomSection->Name; + } else { + IO.mapRequired("Name", SectionName); + } + if (SectionName == "linking") { + if (!IO.outputting()) + Section.reset(new WasmYAML::LinkingSection()); + sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get())); + } else if (SectionName == "name") { + if (!IO.outputting()) + Section.reset(new WasmYAML::NameSection()); + sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get())); + } else { + if (!IO.outputting()) + Section.reset(new WasmYAML::CustomSection(SectionName)); + 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.mapOptional("Addend", Relocation.Addend, 0); +} + +void MappingTraits<WasmYAML::NameEntry>::mapping( + IO &IO, WasmYAML::NameEntry &NameEntry) { + IO.mapRequired("Index", NameEntry.Index); + IO.mapRequired("Name", NameEntry.Name); +} + +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.GlobalImport.Type); + IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable); + } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) { + IO.mapRequired("Table", Import.TableImport); + } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY ) { + IO.mapRequired("Memory", Import.Memory); + } 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; + case wasm::WASM_OPCODE_GET_GLOBAL: + IO.mapRequired("Index", Expr.Value.Global); + break; + } +} + +void MappingTraits<WasmYAML::DataSegment>::mapping( + IO &IO, WasmYAML::DataSegment &Segment) { + IO.mapOptional("SectionOffset", Segment.SectionOffset); + IO.mapRequired("MemoryIndex", Segment.MemoryIndex); + IO.mapRequired("Offset", Segment.Offset); + IO.mapRequired("Content", Segment.Content); +} + +void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO, + WasmYAML::SymbolInfo &Info) { + IO.mapRequired("Name", Info.Name); + IO.mapRequired("Flags", Info.Flags); +} + +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/BinaryFormat/WasmRelocs/WebAssembly.def" +#undef WASM_RELOC +} + +} // end namespace yaml + +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/YAML.cpp b/contrib/llvm/lib/ObjectYAML/YAML.cpp index 75cf1fb..67b5764 100644 --- a/contrib/llvm/lib/ObjectYAML/YAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/YAML.cpp @@ -16,11 +16,12 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" #include <cctype> +#include <cstdint> using namespace llvm; void yaml::ScalarTraits<yaml::BinaryRef>::output( - const yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) { + const yaml::BinaryRef &Val, void *, raw_ostream &Out) { Val.writeAsHex(Out); } @@ -34,7 +35,7 @@ StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *, if (!isxdigit(Scalar[I])) return "BinaryRef hex string must contain only hex digits."; Val = yaml::BinaryRef(Scalar); - return StringRef(); + return {}; } void yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const { |