summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/ObjectYAML
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ObjectYAML')
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/COFFYAML.cpp600
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp957
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp636
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp87
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp817
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/DWARFEmitter.cpp378
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/DWARFVisitor.cpp177
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/DWARFVisitor.h96
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/DWARFYAML.cpp175
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp1175
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/MachOYAML.cpp565
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/MinidumpYAML.cpp673
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/ObjectYAML.cpp63
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/WasmYAML.cpp605
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/XCOFFYAML.cpp109
-rw-r--r--contrib/llvm-project/llvm/lib/ObjectYAML/YAML.cpp62
16 files changed, 7175 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/COFFYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/COFFYAML.cpp
new file mode 100644
index 000000000000..b5154467f11a
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/COFFYAML.cpp
@@ -0,0 +1,600 @@
+//===- COFFYAML.cpp - COFF YAMLIO implementation --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of COFF.
+//
+//===----------------------------------------------------------------------===//
+
+#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);
+ ECase(IMAGE_COMDAT_SELECT_NODUPLICATES);
+ ECase(IMAGE_COMDAT_SELECT_ANY);
+ ECase(IMAGE_COMDAT_SELECT_SAME_SIZE);
+ ECase(IMAGE_COMDAT_SELECT_EXACT_MATCH);
+ ECase(IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+ ECase(IMAGE_COMDAT_SELECT_LARGEST);
+ ECase(IMAGE_COMDAT_SELECT_NEWEST);
+}
+
+void
+ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics>::enumeration(
+ IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
+ IO.enumCase(Value, "0", 0);
+ ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
+ ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
+ ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
+}
+
+void ScalarEnumerationTraits<COFFYAML::AuxSymbolType>::enumeration(
+ IO &IO, COFFYAML::AuxSymbolType &Value) {
+ ECase(IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF);
+}
+
+void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
+ IO &IO, COFF::MachineTypes &Value) {
+ ECase(IMAGE_FILE_MACHINE_UNKNOWN);
+ ECase(IMAGE_FILE_MACHINE_AM33);
+ ECase(IMAGE_FILE_MACHINE_AMD64);
+ ECase(IMAGE_FILE_MACHINE_ARM);
+ ECase(IMAGE_FILE_MACHINE_ARMNT);
+ ECase(IMAGE_FILE_MACHINE_ARM64);
+ ECase(IMAGE_FILE_MACHINE_EBC);
+ ECase(IMAGE_FILE_MACHINE_I386);
+ ECase(IMAGE_FILE_MACHINE_IA64);
+ ECase(IMAGE_FILE_MACHINE_M32R);
+ ECase(IMAGE_FILE_MACHINE_MIPS16);
+ ECase(IMAGE_FILE_MACHINE_MIPSFPU);
+ ECase(IMAGE_FILE_MACHINE_MIPSFPU16);
+ ECase(IMAGE_FILE_MACHINE_POWERPC);
+ ECase(IMAGE_FILE_MACHINE_POWERPCFP);
+ ECase(IMAGE_FILE_MACHINE_R4000);
+ ECase(IMAGE_FILE_MACHINE_SH3);
+ ECase(IMAGE_FILE_MACHINE_SH3DSP);
+ ECase(IMAGE_FILE_MACHINE_SH4);
+ ECase(IMAGE_FILE_MACHINE_SH5);
+ ECase(IMAGE_FILE_MACHINE_THUMB);
+ ECase(IMAGE_FILE_MACHINE_WCEMIPSV2);
+}
+
+void ScalarEnumerationTraits<COFF::SymbolBaseType>::enumeration(
+ IO &IO, COFF::SymbolBaseType &Value) {
+ ECase(IMAGE_SYM_TYPE_NULL);
+ ECase(IMAGE_SYM_TYPE_VOID);
+ ECase(IMAGE_SYM_TYPE_CHAR);
+ ECase(IMAGE_SYM_TYPE_SHORT);
+ ECase(IMAGE_SYM_TYPE_INT);
+ ECase(IMAGE_SYM_TYPE_LONG);
+ ECase(IMAGE_SYM_TYPE_FLOAT);
+ ECase(IMAGE_SYM_TYPE_DOUBLE);
+ ECase(IMAGE_SYM_TYPE_STRUCT);
+ ECase(IMAGE_SYM_TYPE_UNION);
+ ECase(IMAGE_SYM_TYPE_ENUM);
+ ECase(IMAGE_SYM_TYPE_MOE);
+ ECase(IMAGE_SYM_TYPE_BYTE);
+ ECase(IMAGE_SYM_TYPE_WORD);
+ ECase(IMAGE_SYM_TYPE_UINT);
+ ECase(IMAGE_SYM_TYPE_DWORD);
+}
+
+void ScalarEnumerationTraits<COFF::SymbolStorageClass>::enumeration(
+ IO &IO, COFF::SymbolStorageClass &Value) {
+ ECase(IMAGE_SYM_CLASS_END_OF_FUNCTION);
+ ECase(IMAGE_SYM_CLASS_NULL);
+ ECase(IMAGE_SYM_CLASS_AUTOMATIC);
+ ECase(IMAGE_SYM_CLASS_EXTERNAL);
+ ECase(IMAGE_SYM_CLASS_STATIC);
+ ECase(IMAGE_SYM_CLASS_REGISTER);
+ ECase(IMAGE_SYM_CLASS_EXTERNAL_DEF);
+ ECase(IMAGE_SYM_CLASS_LABEL);
+ ECase(IMAGE_SYM_CLASS_UNDEFINED_LABEL);
+ ECase(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT);
+ ECase(IMAGE_SYM_CLASS_ARGUMENT);
+ ECase(IMAGE_SYM_CLASS_STRUCT_TAG);
+ ECase(IMAGE_SYM_CLASS_MEMBER_OF_UNION);
+ ECase(IMAGE_SYM_CLASS_UNION_TAG);
+ ECase(IMAGE_SYM_CLASS_TYPE_DEFINITION);
+ ECase(IMAGE_SYM_CLASS_UNDEFINED_STATIC);
+ ECase(IMAGE_SYM_CLASS_ENUM_TAG);
+ ECase(IMAGE_SYM_CLASS_MEMBER_OF_ENUM);
+ ECase(IMAGE_SYM_CLASS_REGISTER_PARAM);
+ ECase(IMAGE_SYM_CLASS_BIT_FIELD);
+ ECase(IMAGE_SYM_CLASS_BLOCK);
+ ECase(IMAGE_SYM_CLASS_FUNCTION);
+ ECase(IMAGE_SYM_CLASS_END_OF_STRUCT);
+ ECase(IMAGE_SYM_CLASS_FILE);
+ ECase(IMAGE_SYM_CLASS_SECTION);
+ ECase(IMAGE_SYM_CLASS_WEAK_EXTERNAL);
+ ECase(IMAGE_SYM_CLASS_CLR_TOKEN);
+}
+
+void ScalarEnumerationTraits<COFF::SymbolComplexType>::enumeration(
+ IO &IO, COFF::SymbolComplexType &Value) {
+ ECase(IMAGE_SYM_DTYPE_NULL);
+ ECase(IMAGE_SYM_DTYPE_POINTER);
+ ECase(IMAGE_SYM_DTYPE_FUNCTION);
+ ECase(IMAGE_SYM_DTYPE_ARRAY);
+}
+
+void ScalarEnumerationTraits<COFF::RelocationTypeI386>::enumeration(
+ IO &IO, COFF::RelocationTypeI386 &Value) {
+ ECase(IMAGE_REL_I386_ABSOLUTE);
+ ECase(IMAGE_REL_I386_DIR16);
+ ECase(IMAGE_REL_I386_REL16);
+ ECase(IMAGE_REL_I386_DIR32);
+ ECase(IMAGE_REL_I386_DIR32NB);
+ ECase(IMAGE_REL_I386_SEG12);
+ ECase(IMAGE_REL_I386_SECTION);
+ ECase(IMAGE_REL_I386_SECREL);
+ ECase(IMAGE_REL_I386_TOKEN);
+ ECase(IMAGE_REL_I386_SECREL7);
+ ECase(IMAGE_REL_I386_REL32);
+}
+
+void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration(
+ IO &IO, COFF::RelocationTypeAMD64 &Value) {
+ ECase(IMAGE_REL_AMD64_ABSOLUTE);
+ ECase(IMAGE_REL_AMD64_ADDR64);
+ ECase(IMAGE_REL_AMD64_ADDR32);
+ ECase(IMAGE_REL_AMD64_ADDR32NB);
+ ECase(IMAGE_REL_AMD64_REL32);
+ ECase(IMAGE_REL_AMD64_REL32_1);
+ ECase(IMAGE_REL_AMD64_REL32_2);
+ ECase(IMAGE_REL_AMD64_REL32_3);
+ ECase(IMAGE_REL_AMD64_REL32_4);
+ ECase(IMAGE_REL_AMD64_REL32_5);
+ ECase(IMAGE_REL_AMD64_SECTION);
+ ECase(IMAGE_REL_AMD64_SECREL);
+ ECase(IMAGE_REL_AMD64_SECREL7);
+ ECase(IMAGE_REL_AMD64_TOKEN);
+ ECase(IMAGE_REL_AMD64_SREL32);
+ ECase(IMAGE_REL_AMD64_PAIR);
+ ECase(IMAGE_REL_AMD64_SSPAN32);
+}
+
+void ScalarEnumerationTraits<COFF::RelocationTypesARM>::enumeration(
+ IO &IO, COFF::RelocationTypesARM &Value) {
+ ECase(IMAGE_REL_ARM_ABSOLUTE);
+ ECase(IMAGE_REL_ARM_ADDR32);
+ ECase(IMAGE_REL_ARM_ADDR32NB);
+ ECase(IMAGE_REL_ARM_BRANCH24);
+ ECase(IMAGE_REL_ARM_BRANCH11);
+ ECase(IMAGE_REL_ARM_TOKEN);
+ ECase(IMAGE_REL_ARM_BLX24);
+ ECase(IMAGE_REL_ARM_BLX11);
+ ECase(IMAGE_REL_ARM_REL32);
+ ECase(IMAGE_REL_ARM_SECTION);
+ ECase(IMAGE_REL_ARM_SECREL);
+ ECase(IMAGE_REL_ARM_MOV32A);
+ ECase(IMAGE_REL_ARM_MOV32T);
+ ECase(IMAGE_REL_ARM_BRANCH20T);
+ ECase(IMAGE_REL_ARM_BRANCH24T);
+ ECase(IMAGE_REL_ARM_BLX23T);
+ ECase(IMAGE_REL_ARM_PAIR);
+}
+
+void ScalarEnumerationTraits<COFF::RelocationTypesARM64>::enumeration(
+ IO &IO, COFF::RelocationTypesARM64 &Value) {
+ ECase(IMAGE_REL_ARM64_ABSOLUTE);
+ ECase(IMAGE_REL_ARM64_ADDR32);
+ ECase(IMAGE_REL_ARM64_ADDR32NB);
+ ECase(IMAGE_REL_ARM64_BRANCH26);
+ ECase(IMAGE_REL_ARM64_PAGEBASE_REL21);
+ ECase(IMAGE_REL_ARM64_REL21);
+ ECase(IMAGE_REL_ARM64_PAGEOFFSET_12A);
+ ECase(IMAGE_REL_ARM64_PAGEOFFSET_12L);
+ ECase(IMAGE_REL_ARM64_SECREL);
+ ECase(IMAGE_REL_ARM64_SECREL_LOW12A);
+ ECase(IMAGE_REL_ARM64_SECREL_HIGH12A);
+ ECase(IMAGE_REL_ARM64_SECREL_LOW12L);
+ ECase(IMAGE_REL_ARM64_TOKEN);
+ ECase(IMAGE_REL_ARM64_SECTION);
+ ECase(IMAGE_REL_ARM64_ADDR64);
+ ECase(IMAGE_REL_ARM64_BRANCH19);
+ ECase(IMAGE_REL_ARM64_BRANCH14);
+ ECase(IMAGE_REL_ARM64_REL32);
+}
+
+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);
+}
+#undef ECase
+
+#define BCase(X) IO.bitSetCase(Value, #X, COFF::X);
+void ScalarBitSetTraits<COFF::Characteristics>::bitset(
+ IO &IO, COFF::Characteristics &Value) {
+ BCase(IMAGE_FILE_RELOCS_STRIPPED);
+ BCase(IMAGE_FILE_EXECUTABLE_IMAGE);
+ BCase(IMAGE_FILE_LINE_NUMS_STRIPPED);
+ BCase(IMAGE_FILE_LOCAL_SYMS_STRIPPED);
+ BCase(IMAGE_FILE_AGGRESSIVE_WS_TRIM);
+ BCase(IMAGE_FILE_LARGE_ADDRESS_AWARE);
+ BCase(IMAGE_FILE_BYTES_REVERSED_LO);
+ BCase(IMAGE_FILE_32BIT_MACHINE);
+ BCase(IMAGE_FILE_DEBUG_STRIPPED);
+ BCase(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP);
+ BCase(IMAGE_FILE_NET_RUN_FROM_SWAP);
+ BCase(IMAGE_FILE_SYSTEM);
+ BCase(IMAGE_FILE_DLL);
+ BCase(IMAGE_FILE_UP_SYSTEM_ONLY);
+ BCase(IMAGE_FILE_BYTES_REVERSED_HI);
+}
+
+void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset(
+ IO &IO, COFF::SectionCharacteristics &Value) {
+ BCase(IMAGE_SCN_TYPE_NOLOAD);
+ BCase(IMAGE_SCN_TYPE_NO_PAD);
+ BCase(IMAGE_SCN_CNT_CODE);
+ BCase(IMAGE_SCN_CNT_INITIALIZED_DATA);
+ BCase(IMAGE_SCN_CNT_UNINITIALIZED_DATA);
+ BCase(IMAGE_SCN_LNK_OTHER);
+ BCase(IMAGE_SCN_LNK_INFO);
+ BCase(IMAGE_SCN_LNK_REMOVE);
+ BCase(IMAGE_SCN_LNK_COMDAT);
+ BCase(IMAGE_SCN_GPREL);
+ BCase(IMAGE_SCN_MEM_PURGEABLE);
+ BCase(IMAGE_SCN_MEM_16BIT);
+ BCase(IMAGE_SCN_MEM_LOCKED);
+ BCase(IMAGE_SCN_MEM_PRELOAD);
+ BCase(IMAGE_SCN_LNK_NRELOC_OVFL);
+ BCase(IMAGE_SCN_MEM_DISCARDABLE);
+ BCase(IMAGE_SCN_MEM_NOT_CACHED);
+ BCase(IMAGE_SCN_MEM_NOT_PAGED);
+ BCase(IMAGE_SCN_MEM_SHARED);
+ BCase(IMAGE_SCN_MEM_EXECUTE);
+ BCase(IMAGE_SCN_MEM_READ);
+ BCase(IMAGE_SCN_MEM_WRITE);
+}
+
+void ScalarBitSetTraits<COFF::DLLCharacteristics>::bitset(
+ IO &IO, COFF::DLLCharacteristics &Value) {
+ BCase(IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA);
+ BCase(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE);
+ BCase(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY);
+ BCase(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT);
+ BCase(IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION);
+ BCase(IMAGE_DLL_CHARACTERISTICS_NO_SEH);
+ BCase(IMAGE_DLL_CHARACTERISTICS_NO_BIND);
+ BCase(IMAGE_DLL_CHARACTERISTICS_APPCONTAINER);
+ BCase(IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER);
+ BCase(IMAGE_DLL_CHARACTERISTICS_GUARD_CF);
+ BCase(IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE);
+}
+#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;
+};
+
+struct NWeakExternalCharacteristics {
+ NWeakExternalCharacteristics(IO &)
+ : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {}
+ NWeakExternalCharacteristics(IO &, uint32_t C)
+ : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {}
+
+ uint32_t denormalize(IO &) { return Characteristics; }
+
+ COFFYAML::WeakExternalCharacteristics Characteristics;
+};
+
+struct NSectionCharacteristics {
+ NSectionCharacteristics(IO &)
+ : Characteristics(COFF::SectionCharacteristics(0)) {}
+ NSectionCharacteristics(IO &, uint32_t C)
+ : Characteristics(COFF::SectionCharacteristics(C)) {}
+
+ uint32_t denormalize(IO &) { return Characteristics; }
+
+ COFF::SectionCharacteristics Characteristics;
+};
+
+struct NAuxTokenType {
+ NAuxTokenType(IO &)
+ : 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;
+};
+
+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;
+};
+
+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;
+};
+
+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;
+};
+
+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) {
+ IO.mapRequired("VirtualAddress", Rel.VirtualAddress);
+ IO.mapOptional("SymbolName", Rel.SymbolName, StringRef());
+ IO.mapOptional("SymbolTableIndex", Rel.SymbolTableIndex);
+
+ COFF::header &H = *static_cast<COFF::header *>(IO.getContext());
+ if (H.Machine == COFF::IMAGE_FILE_MACHINE_I386) {
+ MappingNormalization<NType<COFF::RelocationTypeI386>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
+ } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) {
+ MappingNormalization<NType<COFF::RelocationTypeAMD64>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
+ } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
+ MappingNormalization<NType<COFF::RelocationTypesARM>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
+ } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_ARM64) {
+ MappingNormalization<NType<COFF::RelocationTypesARM64>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
+ } else {
+ IO.mapRequired("Type", Rel.Type);
+ }
+}
+
+void MappingTraits<COFF::DataDirectory>::mapping(IO &IO,
+ COFF::DataDirectory &DD) {
+ IO.mapRequired("RelativeVirtualAddress", DD.RelativeVirtualAddress);
+ IO.mapRequired("Size", DD.Size);
+}
+
+void MappingTraits<COFFYAML::PEHeader>::mapping(IO &IO,
+ COFFYAML::PEHeader &PH) {
+ MappingNormalization<NWindowsSubsystem, uint16_t> NWS(IO,
+ PH.Header.Subsystem);
+ MappingNormalization<NDLLCharacteristics, uint16_t> NDC(
+ IO, PH.Header.DLLCharacteristics);
+
+ IO.mapRequired("AddressOfEntryPoint", PH.Header.AddressOfEntryPoint);
+ IO.mapRequired("ImageBase", PH.Header.ImageBase);
+ IO.mapRequired("SectionAlignment", PH.Header.SectionAlignment);
+ IO.mapRequired("FileAlignment", PH.Header.FileAlignment);
+ IO.mapRequired("MajorOperatingSystemVersion",
+ PH.Header.MajorOperatingSystemVersion);
+ IO.mapRequired("MinorOperatingSystemVersion",
+ PH.Header.MinorOperatingSystemVersion);
+ IO.mapRequired("MajorImageVersion", PH.Header.MajorImageVersion);
+ IO.mapRequired("MinorImageVersion", PH.Header.MinorImageVersion);
+ IO.mapRequired("MajorSubsystemVersion", PH.Header.MajorSubsystemVersion);
+ IO.mapRequired("MinorSubsystemVersion", PH.Header.MinorSubsystemVersion);
+ IO.mapRequired("Subsystem", NWS->Subsystem);
+ IO.mapRequired("DLLCharacteristics", NDC->Characteristics);
+ IO.mapRequired("SizeOfStackReserve", PH.Header.SizeOfStackReserve);
+ IO.mapRequired("SizeOfStackCommit", PH.Header.SizeOfStackCommit);
+ IO.mapRequired("SizeOfHeapReserve", PH.Header.SizeOfHeapReserve);
+ IO.mapRequired("SizeOfHeapCommit", PH.Header.SizeOfHeapCommit);
+
+ IO.mapOptional("ExportTable", PH.DataDirectories[COFF::EXPORT_TABLE]);
+ IO.mapOptional("ImportTable", PH.DataDirectories[COFF::IMPORT_TABLE]);
+ IO.mapOptional("ResourceTable", PH.DataDirectories[COFF::RESOURCE_TABLE]);
+ IO.mapOptional("ExceptionTable", PH.DataDirectories[COFF::EXCEPTION_TABLE]);
+ IO.mapOptional("CertificateTable", PH.DataDirectories[COFF::CERTIFICATE_TABLE]);
+ IO.mapOptional("BaseRelocationTable",
+ PH.DataDirectories[COFF::BASE_RELOCATION_TABLE]);
+ IO.mapOptional("Debug", PH.DataDirectories[COFF::DEBUG_DIRECTORY]);
+ IO.mapOptional("Architecture", PH.DataDirectories[COFF::ARCHITECTURE]);
+ IO.mapOptional("GlobalPtr", PH.DataDirectories[COFF::GLOBAL_PTR]);
+ IO.mapOptional("TlsTable", PH.DataDirectories[COFF::TLS_TABLE]);
+ IO.mapOptional("LoadConfigTable",
+ PH.DataDirectories[COFF::LOAD_CONFIG_TABLE]);
+ IO.mapOptional("BoundImport", PH.DataDirectories[COFF::BOUND_IMPORT]);
+ IO.mapOptional("IAT", PH.DataDirectories[COFF::IAT]);
+ IO.mapOptional("DelayImportDescriptor",
+ PH.DataDirectories[COFF::DELAY_IMPORT_DESCRIPTOR]);
+ IO.mapOptional("ClrRuntimeHeader",
+ PH.DataDirectories[COFF::CLR_RUNTIME_HEADER]);
+}
+
+void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
+ MappingNormalization<NMachine, uint16_t> NM(IO, H.Machine);
+ MappingNormalization<NHeaderCharacteristics, uint16_t> NC(IO,
+ H.Characteristics);
+
+ IO.mapRequired("Machine", NM->Machine);
+ IO.mapOptional("Characteristics", NC->Characteristics);
+ IO.setContext(static_cast<void *>(&H));
+}
+
+void MappingTraits<COFF::AuxiliaryFunctionDefinition>::mapping(
+ IO &IO, COFF::AuxiliaryFunctionDefinition &AFD) {
+ IO.mapRequired("TagIndex", AFD.TagIndex);
+ IO.mapRequired("TotalSize", AFD.TotalSize);
+ IO.mapRequired("PointerToLinenumber", AFD.PointerToLinenumber);
+ IO.mapRequired("PointerToNextFunction", AFD.PointerToNextFunction);
+}
+
+void MappingTraits<COFF::AuxiliarybfAndefSymbol>::mapping(
+ IO &IO, COFF::AuxiliarybfAndefSymbol &AAS) {
+ IO.mapRequired("Linenumber", AAS.Linenumber);
+ IO.mapRequired("PointerToNextFunction", AAS.PointerToNextFunction);
+}
+
+void MappingTraits<COFF::AuxiliaryWeakExternal>::mapping(
+ IO &IO, COFF::AuxiliaryWeakExternal &AWE) {
+ MappingNormalization<NWeakExternalCharacteristics, uint32_t> NWEC(
+ IO, AWE.Characteristics);
+ IO.mapRequired("TagIndex", AWE.TagIndex);
+ IO.mapRequired("Characteristics", NWEC->Characteristics);
+}
+
+void MappingTraits<COFF::AuxiliarySectionDefinition>::mapping(
+ IO &IO, COFF::AuxiliarySectionDefinition &ASD) {
+ MappingNormalization<NSectionSelectionType, uint8_t> NSST(
+ IO, ASD.Selection);
+
+ IO.mapRequired("Length", ASD.Length);
+ IO.mapRequired("NumberOfRelocations", ASD.NumberOfRelocations);
+ IO.mapRequired("NumberOfLinenumbers", ASD.NumberOfLinenumbers);
+ IO.mapRequired("CheckSum", ASD.CheckSum);
+ IO.mapRequired("Number", ASD.Number);
+ IO.mapOptional("Selection", NSST->SelectionType, COFFYAML::COMDATType(0));
+}
+
+void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
+ IO &IO, COFF::AuxiliaryCLRToken &ACT) {
+ MappingNormalization<NAuxTokenType, uint8_t> NATT(IO, ACT.AuxType);
+ IO.mapRequired("AuxType", NATT->AuxType);
+ IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
+}
+
+void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
+ MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass);
+
+ IO.mapRequired("Name", S.Name);
+ IO.mapRequired("Value", S.Header.Value);
+ IO.mapRequired("SectionNumber", S.Header.SectionNumber);
+ IO.mapRequired("SimpleType", S.SimpleType);
+ IO.mapRequired("ComplexType", S.ComplexType);
+ IO.mapRequired("StorageClass", NS->StorageClass);
+ IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
+ IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
+ IO.mapOptional("WeakExternal", S.WeakExternal);
+ IO.mapOptional("File", S.File, StringRef());
+ IO.mapOptional("SectionDefinition", S.SectionDefinition);
+ IO.mapOptional("CLRToken", S.CLRToken);
+}
+
+void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
+ MappingNormalization<NSectionCharacteristics, uint32_t> NC(
+ IO, Sec.Header.Characteristics);
+ IO.mapRequired("Name", Sec.Name);
+ IO.mapRequired("Characteristics", NC->Characteristics);
+ IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U);
+ IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U);
+ IO.mapOptional("Alignment", Sec.Alignment, 0U);
+
+ // If this is a .debug$S .debug$T .debug$P, or .debug$H 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);
+ else if (Sec.Name == ".debug$P")
+ IO.mapOptional("PrecompTypes", Sec.DebugP);
+ else if (Sec.Name == ".debug$H")
+ IO.mapOptional("GlobalHashes", Sec.DebugH);
+
+ // Uninitialized sections, such as .bss, typically have no data, but the size
+ // is carried in SizeOfRawData, even though PointerToRawData is zero.
+ if (Sec.SectionData.binary_size() == 0 &&
+ NC->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ IO.mapOptional("SizeOfRawData", Sec.Header.SizeOfRawData);
+
+ IO.mapOptional("Relocations", Sec.Relocations);
+}
+
+void MappingTraits<COFFYAML::Object>::mapping(IO &IO, COFFYAML::Object &Obj) {
+ IO.mapTag("!COFF", true);
+ IO.mapOptional("OptionalHeader", Obj.OptionalHeader);
+ IO.mapRequired("header", Obj.Header);
+ IO.mapRequired("sections", Obj.Sections);
+ IO.mapRequired("symbols", Obj.Symbols);
+}
+
+} // end namespace yaml
+
+} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
new file mode 100644
index 000000000000..eeebb694589b
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
@@ -0,0 +1,957 @@
+//===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// 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, QuotingType::None)
+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>(true);
+ 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-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
new file mode 100644
index 000000000000..227107c051dd
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -0,0 +1,636 @@
+//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// 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)
+LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
+
+// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
+LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
+
+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, QuotingType::Single)
+
+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 = getPublicSymFlagNames();
+ 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(CPUType::X64);
+ 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 yaml {
+template <> struct MappingTraits<LocalVariableAddrRange> {
+ static void mapping(IO &io, LocalVariableAddrRange &Range) {
+ io.mapRequired("OffsetStart", Range.OffsetStart);
+ io.mapRequired("ISectStart", Range.ISectStart);
+ io.mapRequired("Range", Range.Range);
+ }
+};
+template <> struct MappingTraits<LocalVariableAddrGap> {
+ static void mapping(IO &io, LocalVariableAddrGap &Gap) {
+ io.mapRequired("GapStartOffset", Gap.GapStartOffset);
+ io.mapRequired("Range", Gap.Range);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
+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(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) {
+ IO.mapRequired("Program", Symbol.Program);
+ IO.mapRequired("Range", Symbol.Range);
+ IO.mapRequired("Gaps", Symbol.Gaps);
+}
+
+template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
+ IO.mapRequired("Program", Symbol.Program);
+ IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
+ IO.mapRequired("Range", Symbol.Range);
+ IO.mapRequired("Gaps", Symbol.Gaps);
+}
+
+template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
+ IO.mapRequired("Register", Symbol.Hdr.Register);
+ IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
+ IO.mapRequired("Range", Symbol.Range);
+ IO.mapRequired("Gaps", Symbol.Gaps);
+}
+
+template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
+ IO.mapRequired("Offset", Symbol.Offset);
+ IO.mapRequired("Range", Symbol.Range);
+ IO.mapRequired("Gaps", Symbol.Gaps);
+}
+
+template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
+ IO.mapRequired("Register", Symbol.Hdr.Register);
+ IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
+ IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
+ IO.mapRequired("Range", Symbol.Range);
+ IO.mapRequired("Gaps", Symbol.Gaps);
+}
+
+template <>
+void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
+ IO.mapRequired("Register", Symbol.Offset);
+}
+
+template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
+ IO.mapRequired("Register", Symbol.Hdr.Register);
+ IO.mapRequired("Flags", Symbol.Hdr.Flags);
+ IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
+ IO.mapRequired("Range", Symbol.Range);
+ IO.mapRequired("Gaps", Symbol.Gaps);
+}
+
+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);
+}
+
+template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
+ IO.mapRequired("Namespace", Symbol.Name);
+}
+
+template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
+ IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
+ IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
+ IO.mapRequired("Strings", Symbol.Strings);
+}
+
+} // 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-project/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
new file mode 100644
index 000000000000..e921ae1e7d8d
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
@@ -0,0 +1,87 @@
+//===- CodeViewYAMLTypeHashing.cpp - CodeView YAMLIO type hashing ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of CodeView
+// Debug Info.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h"
+
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::CodeViewYAML;
+using namespace llvm::yaml;
+
+namespace llvm {
+namespace yaml {
+
+void MappingTraits<DebugHSection>::mapping(IO &io, DebugHSection &DebugH) {
+ io.mapRequired("Version", DebugH.Version);
+ io.mapRequired("HashAlgorithm", DebugH.HashAlgorithm);
+ io.mapOptional("HashValues", DebugH.Hashes);
+}
+
+void ScalarTraits<GlobalHash>::output(const GlobalHash &GH, void *Ctx,
+ raw_ostream &OS) {
+ ScalarTraits<BinaryRef>::output(GH.Hash, Ctx, OS);
+}
+
+StringRef ScalarTraits<GlobalHash>::input(StringRef Scalar, void *Ctx,
+ GlobalHash &GH) {
+ return ScalarTraits<BinaryRef>::input(Scalar, Ctx, GH.Hash);
+}
+
+} // end namespace yaml
+} // end namespace llvm
+
+DebugHSection llvm::CodeViewYAML::fromDebugH(ArrayRef<uint8_t> DebugH) {
+ assert(DebugH.size() >= 8);
+ assert((DebugH.size() - 8) % 8 == 0);
+
+ BinaryStreamReader Reader(DebugH, llvm::support::little);
+ DebugHSection DHS;
+ cantFail(Reader.readInteger(DHS.Magic));
+ cantFail(Reader.readInteger(DHS.Version));
+ cantFail(Reader.readInteger(DHS.HashAlgorithm));
+
+ while (Reader.bytesRemaining() != 0) {
+ ArrayRef<uint8_t> S;
+ cantFail(Reader.readBytes(S, 8));
+ DHS.Hashes.emplace_back(S);
+ }
+ assert(Reader.bytesRemaining() == 0);
+ return DHS;
+}
+
+ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugH(const DebugHSection &DebugH,
+ BumpPtrAllocator &Alloc) {
+ uint32_t Size = 8 + 8 * DebugH.Hashes.size();
+ uint8_t *Data = Alloc.Allocate<uint8_t>(Size);
+ MutableArrayRef<uint8_t> Buffer(Data, Size);
+ BinaryStreamWriter Writer(Buffer, llvm::support::little);
+
+ cantFail(Writer.writeInteger(DebugH.Magic));
+ cantFail(Writer.writeInteger(DebugH.Version));
+ cantFail(Writer.writeInteger(DebugH.HashAlgorithm));
+ SmallString<8> Hash;
+ for (const auto &H : DebugH.Hashes) {
+ Hash.clear();
+ raw_svector_ostream OS(Hash);
+ H.Hash.writeAsBinary(OS);
+ assert((Hash.size() == 8) && "Invalid hash size!");
+ cantFail(Writer.writeFixedString(Hash));
+ }
+ assert(Writer.bytesRemaining() == 0);
+ return Buffer;
+}
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
new file mode 100644
index 000000000000..a5e3ce1e71e8
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
@@ -0,0 +1,817 @@
+//===- CodeViewYAMLTypes.cpp - CodeView YAMLIO types implementation -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// 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/AppendingTypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.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, QuotingType::None)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
+
+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(AppendingTypeTableBuilder &TS) 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(AppendingTypeTableBuilder &TS) const override {
+ TS.writeLeafType(Record);
+ return CVType(TS.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(AppendingTypeTableBuilder &TS) 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(ContinuationRecordBuilder &CRB) = 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(ContinuationRecordBuilder &CRB) override {
+ CRB.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(
+ AppendingTypeTableBuilder &TS) const {
+ ContinuationRecordBuilder CRB;
+ CRB.begin(ContinuationRecordKind::FieldList);
+ for (const auto &Member : Members) {
+ Member.Member->writeTo(CRB);
+ }
+ TS.insertRecord(CRB);
+ return CVType(TS.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 LeafRecordImpl<PrecompRecord>::map(IO &IO) {
+ IO.mapRequired("StartTypeIndex", Record.StartTypeIndex);
+ IO.mapRequired("TypesCount", Record.TypesCount);
+ IO.mapRequired("Signature", Record.Signature);
+ IO.mapRequired("PrecompFilePath", Record.PrecompFilePath);
+}
+
+template <> void LeafRecordImpl<EndPrecompRecord>::map(IO &IO) {
+ IO.mapRequired("Signature", Record.Signature);
+}
+
+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(AppendingTypeTableBuilder &Serializer) const {
+ return Leaf->toCodeViewRecord(Serializer);
+}
+
+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> DebugTorP,
+ StringRef SectionName) {
+ ExitOnError Err("Invalid " + std::string(SectionName) + " section!");
+ BinaryStreamReader Reader(DebugTorP, support::little);
+ CVTypeArray Types;
+ uint32_t Magic;
+
+ Err(Reader.readInteger(Magic));
+ assert(Magic == COFF::DEBUG_SECTION_MAGIC &&
+ "Invalid .debug$T or .debug$P 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,
+ StringRef SectionName) {
+ AppendingTypeTableBuilder TS(Alloc);
+ uint32_t Size = sizeof(uint32_t);
+ for (const auto &Leaf : Leafs) {
+ CVType T = Leaf.Leaf->toCodeViewRecord(TS);
+ 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 " + std::string(SectionName) +
+ " section");
+ Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC));
+ for (const auto &R : TS.records()) {
+ Err(Writer.writeBytes(R));
+ }
+ assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!");
+ return Output;
+}
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFEmitter.cpp
new file mode 100644
index 000000000000..2ae66997cf59
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -0,0 +1,378 @@
+//===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// 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);
+}
+
+static 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');
+ }
+}
+
+namespace {
+/// 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) {}
+};
+} // namespace
+
+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);
+}
+
+namespace {
+class DIEFixupVisitor : public DWARFYAML::Visitor {
+ uint64_t Length;
+
+public:
+ DIEFixupVisitor(DWARFYAML::Data &DI) : DWARFYAML::Visitor(DI){};
+
+private:
+ virtual void onStartCompileUnit(DWARFYAML::Unit &CU) { Length = 7; }
+
+ virtual void onEndCompileUnit(DWARFYAML::Unit &CU) {
+ CU.Length.setLength(Length);
+ }
+
+ virtual void onStartDIE(DWARFYAML::Unit &CU, DWARFYAML::Entry &DIE) {
+ Length += getULEB128Size(DIE.AbbrCode);
+ }
+
+ virtual void onValue(const uint8_t U) { Length += 1; }
+ virtual void onValue(const uint16_t U) { Length += 2; }
+ virtual void onValue(const uint32_t U) { Length += 4; }
+ virtual void onValue(const uint64_t U, const bool LEB = false) {
+ if (LEB)
+ Length += getULEB128Size(U);
+ else
+ Length += 8;
+ }
+ virtual void onValue(const int64_t S, const bool LEB = false) {
+ if (LEB)
+ Length += getSLEB128Size(S);
+ else
+ Length += 8;
+ }
+ virtual void onValue(const StringRef String) { Length += String.size() + 1; }
+
+ virtual void onValue(const MemoryBufferRef MBR) {
+ Length += MBR.getBufferSize();
+ }
+};
+} // namespace
+
+Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
+DWARFYAML::EmitDebugSections(StringRef YAMLString, bool ApplyFixups,
+ bool IsLittleEndian) {
+ yaml::Input YIn(YAMLString);
+
+ DWARFYAML::Data DI;
+ DI.IsLittleEndian = IsLittleEndian;
+ YIn >> DI;
+ if (YIn.error())
+ return errorCodeToError(YIn.error());
+
+ if (ApplyFixups) {
+ DIEFixupVisitor DIFixer(DI);
+ DIFixer.traverseDebugInfo();
+ }
+
+ StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
+ 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-project/llvm/lib/ObjectYAML/DWARFVisitor.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFVisitor.cpp
new file mode 100644
index 000000000000..ecb5967ac532
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFVisitor.cpp
@@ -0,0 +1,177 @@
+//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#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.");
+ }
+}
+
+static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
+ return Unit.Length.isDWARF64() ? 8 : 4;
+}
+
+static 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-project/llvm/lib/ObjectYAML/DWARFVisitor.h b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFVisitor.h
new file mode 100644
index 000000000000..50e88aa7a26b
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFVisitor.h
@@ -0,0 +1,96 @@
+//===--- DWARFVisitor.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#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;
+
+/// 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-project/llvm/lib/ObjectYAML/DWARFYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFYAML.cpp
new file mode 100644
index 000000000000..bb3b1422eb62
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -0,0 +1,175 @@
+//===- DWARFYAML.cpp - DWARF YAMLIO implementation ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of DWARF Debug
+// Info.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/DWARFYAML.h"
+
+namespace llvm {
+
+bool DWARFYAML::Data::isEmpty() const {
+ return 0 == DebugStrings.size() + AbbrevDecls.size();
+}
+
+namespace yaml {
+
+void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
+ auto oldContext = IO.getContext();
+ IO.setContext(&DWARF);
+ IO.mapOptional("debug_str", DWARF.DebugStrings);
+ IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
+ if (!DWARF.ARanges.empty() || !IO.outputting())
+ IO.mapOptional("debug_aranges", DWARF.ARanges);
+ if (!DWARF.PubNames.Entries.empty() || !IO.outputting())
+ IO.mapOptional("debug_pubnames", DWARF.PubNames);
+ if (!DWARF.PubTypes.Entries.empty() || !IO.outputting())
+ IO.mapOptional("debug_pubtypes", DWARF.PubTypes);
+ if (!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
+ IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
+ if (!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
+ IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
+ IO.mapOptional("debug_info", DWARF.CompileUnits);
+ IO.mapOptional("debug_line", DWARF.DebugLines);
+ IO.setContext(&oldContext);
+}
+
+void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,
+ DWARFYAML::Abbrev &Abbrev) {
+ IO.mapRequired("Code", Abbrev.Code);
+ IO.mapRequired("Tag", Abbrev.Tag);
+ IO.mapRequired("Children", Abbrev.Children);
+ IO.mapRequired("Attributes", Abbrev.Attributes);
+}
+
+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(
+ IO &IO, DWARFYAML::ARangeDescriptor &Descriptor) {
+ IO.mapRequired("Address", Descriptor.Address);
+ IO.mapRequired("Length", Descriptor.Length);
+}
+
+void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,
+ DWARFYAML::ARange &Range) {
+ IO.mapRequired("Length", Range.Length);
+ IO.mapRequired("Version", Range.Version);
+ IO.mapRequired("CuOffset", Range.CuOffset);
+ IO.mapRequired("AddrSize", Range.AddrSize);
+ IO.mapRequired("SegSize", Range.SegSize);
+ IO.mapRequired("Descriptors", Range.Descriptors);
+}
+
+void MappingTraits<DWARFYAML::PubEntry>::mapping(IO &IO,
+ DWARFYAML::PubEntry &Entry) {
+ IO.mapRequired("DieOffset", Entry.DieOffset);
+ if (reinterpret_cast<DWARFYAML::PubSection *>(IO.getContext())->IsGNUStyle)
+ IO.mapRequired("Descriptor", Entry.Descriptor);
+ IO.mapRequired("Name", Entry.Name);
+}
+
+void MappingTraits<DWARFYAML::PubSection>::mapping(
+ IO &IO, DWARFYAML::PubSection &Section) {
+ auto OldContext = IO.getContext();
+ IO.setContext(&Section);
+
+ IO.mapRequired("Length", Section.Length);
+ IO.mapRequired("Version", Section.Version);
+ IO.mapRequired("UnitOffset", Section.UnitOffset);
+ IO.mapRequired("UnitSize", Section.UnitSize);
+ IO.mapRequired("Entries", Section.Entries);
+
+ IO.setContext(OldContext);
+}
+
+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);
+}
+
+void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
+ IO.mapRequired("AbbrCode", Entry.AbbrCode);
+ IO.mapRequired("Values", Entry.Values);
+}
+
+void MappingTraits<DWARFYAML::FormValue>::mapping(
+ IO &IO, DWARFYAML::FormValue &FormValue) {
+ IO.mapOptional("Value", FormValue.Value);
+ if (!FormValue.CStr.empty() || !IO.outputting())
+ IO.mapOptional("CStr", FormValue.CStr);
+ if (!FormValue.BlockData.empty() || !IO.outputting())
+ IO.mapOptional("BlockData", FormValue.BlockData);
+}
+
+void MappingTraits<DWARFYAML::File>::mapping(IO &IO, DWARFYAML::File &File) {
+ IO.mapRequired("Name", File.Name);
+ IO.mapRequired("DirIdx", File.DirIdx);
+ IO.mapRequired("ModTime", File.ModTime);
+ IO.mapRequired("Length", File.Length);
+}
+
+void MappingTraits<DWARFYAML::LineTableOpcode>::mapping(
+ IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode) {
+ IO.mapRequired("Opcode", LineTableOpcode.Opcode);
+ if (LineTableOpcode.Opcode == dwarf::DW_LNS_extended_op) {
+ IO.mapRequired("ExtLen", LineTableOpcode.ExtLen);
+ IO.mapRequired("SubOpcode", LineTableOpcode.SubOpcode);
+ }
+
+ if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
+ IO.mapOptional("UnknownOpcodeData", LineTableOpcode.UnknownOpcodeData);
+ if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
+ IO.mapOptional("StandardOpcodeData", LineTableOpcode.StandardOpcodeData);
+ if (!LineTableOpcode.FileEntry.Name.empty() || !IO.outputting())
+ IO.mapOptional("FileEntry", LineTableOpcode.FileEntry);
+ if (LineTableOpcode.Opcode == dwarf::DW_LNS_advance_line || !IO.outputting())
+ IO.mapOptional("SData", LineTableOpcode.SData);
+ IO.mapOptional("Data", LineTableOpcode.Data);
+}
+
+void MappingTraits<DWARFYAML::LineTable>::mapping(
+ IO &IO, DWARFYAML::LineTable &LineTable) {
+ IO.mapRequired("Length", LineTable.Length);
+ IO.mapRequired("Version", LineTable.Version);
+ IO.mapRequired("PrologueLength", LineTable.PrologueLength);
+ IO.mapRequired("MinInstLength", LineTable.MinInstLength);
+ if(LineTable.Version >= 4)
+ IO.mapRequired("MaxOpsPerInst", LineTable.MaxOpsPerInst);
+ IO.mapRequired("DefaultIsStmt", LineTable.DefaultIsStmt);
+ IO.mapRequired("LineBase", LineTable.LineBase);
+ IO.mapRequired("LineRange", LineTable.LineRange);
+ IO.mapRequired("OpcodeBase", LineTable.OpcodeBase);
+ IO.mapRequired("StandardOpcodeLengths", LineTable.StandardOpcodeLengths);
+ IO.mapRequired("IncludeDirs", LineTable.IncludeDirs);
+ IO.mapRequired("Files", LineTable.Files);
+ IO.mapRequired("Opcodes", LineTable.Opcodes);
+}
+
+void MappingTraits<DWARFYAML::InitialLength>::mapping(
+ IO &IO, DWARFYAML::InitialLength &InitialLength) {
+ IO.mapRequired("TotalLength", InitialLength.TotalLength);
+ if (InitialLength.isDWARF64())
+ IO.mapRequired("TotalLength64", InitialLength.TotalLength64);
+}
+
+} // end namespace yaml
+
+} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp
new file mode 100644
index 000000000000..7497154c757d
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -0,0 +1,1175 @@
+//===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of ELF.
+//
+//===----------------------------------------------------------------------===//
+
+#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() = 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);
+#undef ECase
+ IO.enumFallback<Hex16>(Value);
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_PT>::enumeration(
+ IO &IO, ELFYAML::ELF_PT &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X)
+ ECase(PT_NULL);
+ ECase(PT_LOAD);
+ ECase(PT_DYNAMIC);
+ ECase(PT_INTERP);
+ ECase(PT_NOTE);
+ ECase(PT_SHLIB);
+ ECase(PT_PHDR);
+ ECase(PT_TLS);
+ ECase(PT_GNU_EH_FRAME);
+#undef ECase
+ IO.enumFallback<Hex32>(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);
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
+ IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
+#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);
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
+ IO &IO, ELFYAML::ELF_ELFDATA &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X)
+ // ELFDATANONE is an invalid data encoding, but we accept it because
+ // we want to be able to produce invalid binaries for the tests.
+ ECase(ELFDATANONE);
+ 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_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_AMDGPU_HSA);
+ ECase(ELFOSABI_AMDGPU_PAL);
+ ECase(ELFOSABI_AMDGPU_MESA3D);
+ ECase(ELFOSABI_ARM);
+ ECase(ELFOSABI_C6000_ELFABI);
+ ECase(ELFOSABI_C6000_LINUX);
+ ECase(ELFOSABI_STANDALONE);
+#undef ECase
+}
+
+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)
+ 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);
+ 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);
+ 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_MACH_V55);
+ BCase(EF_HEXAGON_MACH_V60);
+ BCase(EF_HEXAGON_MACH_V62);
+ BCase(EF_HEXAGON_MACH_V65);
+ BCase(EF_HEXAGON_ISA_V2);
+ BCase(EF_HEXAGON_ISA_V3);
+ BCase(EF_HEXAGON_ISA_V4);
+ BCase(EF_HEXAGON_ISA_V5);
+ BCase(EF_HEXAGON_ISA_V55);
+ BCase(EF_HEXAGON_ISA_V60);
+ BCase(EF_HEXAGON_ISA_V62);
+ BCase(EF_HEXAGON_ISA_V65);
+ 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);
+ break;
+ case ELF::EM_RISCV:
+ BCase(EF_RISCV_RVC);
+ BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
+ BCaseMask(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI);
+ BCaseMask(EF_RISCV_FLOAT_ABI_DOUBLE, EF_RISCV_FLOAT_ABI);
+ BCaseMask(EF_RISCV_FLOAT_ABI_QUAD, EF_RISCV_FLOAT_ABI);
+ BCase(EF_RISCV_RVE);
+ break;
+ case ELF::EM_AMDGPU:
+ BCaseMask(EF_AMDGPU_MACH_NONE, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_R600, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_R630, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_RS880, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_RV670, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_RV710, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_RV730, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_RV770, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_CEDAR, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_CYPRESS, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_JUNIPER, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_REDWOOD, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_SUMO, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_BARTS, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_CAICOS, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_CAYMAN, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_R600_TURKS, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX600, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX601, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX700, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX701, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX702, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX703, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX704, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX801, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX802, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX803, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX810, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX900, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
+ BCase(EF_AMDGPU_XNACK);
+ BCase(EF_AMDGPU_SRAM_ECC);
+ break;
+ case ELF::EM_X86_64:
+ break;
+ default:
+ llvm_unreachable("Unsupported architecture");
+ }
+#undef BCase
+#undef BCaseMask
+}
+
+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);
+ ECase(SHT_SYMTAB);
+ // 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_RELR);
+ ECase(SHT_ANDROID_REL);
+ ECase(SHT_ANDROID_RELA);
+ ECase(SHT_ANDROID_RELR);
+ ECase(SHT_LLVM_ODRTAB);
+ ECase(SHT_LLVM_LINKER_OPTIONS);
+ ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
+ ECase(SHT_LLVM_ADDRSIG);
+ ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
+ ECase(SHT_GNU_ATTRIBUTES);
+ ECase(SHT_GNU_HASH);
+ ECase(SHT_GNU_verdef);
+ ECase(SHT_GNU_verneed);
+ ECase(SHT_GNU_versym);
+ 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);
+ break;
+ case ELF::EM_HEXAGON:
+ ECase(SHT_HEX_ORDERED);
+ break;
+ case ELF::EM_X86_64:
+ ECase(SHT_X86_64_UNWIND);
+ break;
+ case ELF::EM_MIPS:
+ ECase(SHT_MIPS_REGINFO);
+ ECase(SHT_MIPS_OPTIONS);
+ ECase(SHT_MIPS_DWARF);
+ ECase(SHT_MIPS_ABIFLAGS);
+ break;
+ default:
+ // Nothing to do.
+ break;
+ }
+#undef ECase
+ IO.enumFallback<Hex32>(Value);
+}
+
+void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO,
+ ELFYAML::ELF_PF &Value) {
+#define BCase(X) IO.bitSetCase(Value, #X, ELF::X)
+ BCase(PF_X);
+ BCase(PF_W);
+ BCase(PF_R);
+}
+
+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);
+ BCase(SHF_COMPRESSED);
+ switch (Object->Header.Machine) {
+ case ELF::EM_ARM:
+ BCase(SHF_ARM_PURECODE);
+ break;
+ case ELF::EM_HEXAGON:
+ 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);
+ break;
+ case ELF::EM_X86_64:
+ BCase(SHF_X86_64_LARGE);
+ break;
+ default:
+ // Nothing to do.
+ break;
+ }
+#undef BCase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
+ IO &IO, ELFYAML::ELF_SHN &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X)
+ ECase(SHN_UNDEF);
+ ECase(SHN_LORESERVE);
+ ECase(SHN_LOPROC);
+ ECase(SHN_HIPROC);
+ ECase(SHN_LOOS);
+ ECase(SHN_HIOS);
+ ECase(SHN_ABS);
+ ECase(SHN_COMMON);
+ ECase(SHN_XINDEX);
+ ECase(SHN_HIRESERVE);
+ ECase(SHN_AMDGPU_LDS);
+ ECase(SHN_HEXAGON_SCOMMON);
+ ECase(SHN_HEXAGON_SCOMMON_1);
+ ECase(SHN_HEXAGON_SCOMMON_2);
+ ECase(SHN_HEXAGON_SCOMMON_4);
+ ECase(SHN_HEXAGON_SCOMMON_8);
+#undef ECase
+ IO.enumFallback<Hex32>(Value);
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
+ IO &IO, ELFYAML::ELF_STB &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X)
+ ECase(STB_LOCAL);
+ ECase(STB_GLOBAL);
+ ECase(STB_WEAK);
+ ECase(STB_GNU_UNIQUE);
+#undef ECase
+ IO.enumFallback<Hex8>(Value);
+}
+
+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);
+#undef ECase
+ IO.enumFallback<Hex8>(Value);
+}
+
+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);
+#undef ECase
+}
+
+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)
+ switch (Object->Header.Machine) {
+ case ELF::EM_MIPS:
+ BCase(STO_MIPS_OPTIONAL);
+ BCase(STO_MIPS_PLT);
+ BCase(STO_MIPS_PIC);
+ BCase(STO_MIPS_MICROMIPS);
+ break;
+ default:
+ break; // Nothing to do
+ }
+#undef BCase
+#undef BCaseMask
+}
+
+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);
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
+ IO &IO, ELFYAML::ELF_REL &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_X86_64:
+#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
+ break;
+ case ELF::EM_MIPS:
+#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
+ break;
+ case ELF::EM_HEXAGON:
+#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
+ break;
+ case ELF::EM_386:
+ case ELF::EM_IAMCU:
+#include "llvm/BinaryFormat/ELFRelocs/i386.def"
+ break;
+ case ELF::EM_AARCH64:
+#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
+ break;
+ case ELF::EM_ARM:
+#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
+ break;
+ case ELF::EM_ARC:
+#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
+ break;
+ case ELF::EM_RISCV:
+#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
+ break;
+ case ELF::EM_LANAI:
+#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
+ break;
+ case ELF::EM_AMDGPU:
+#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
+ break;
+ case ELF::EM_BPF:
+#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
+ break;
+ default:
+ llvm_unreachable("Unsupported architecture");
+ }
+#undef ELF_RELOC
+ IO.enumFallback<Hex32>(Value);
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
+ IO &IO, ELFYAML::ELF_DYNTAG &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+
+// Disable architecture specific tags by default. We might enable them below.
+#define AARCH64_DYNAMIC_TAG(name, value)
+#define MIPS_DYNAMIC_TAG(name, value)
+#define HEXAGON_DYNAMIC_TAG(name, value)
+#define PPC_DYNAMIC_TAG(name, value)
+#define PPC64_DYNAMIC_TAG(name, value)
+// Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
+#define DYNAMIC_TAG_MARKER(name, value)
+
+#define STRINGIFY(X) (#X)
+#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_AARCH64:
+#undef AARCH64_DYNAMIC_TAG
+#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef AARCH64_DYNAMIC_TAG
+#define AARCH64_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_MIPS:
+#undef MIPS_DYNAMIC_TAG
+#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef MIPS_DYNAMIC_TAG
+#define MIPS_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_HEXAGON:
+#undef HEXAGON_DYNAMIC_TAG
+#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef HEXAGON_DYNAMIC_TAG
+#define HEXAGON_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_PPC:
+#undef PPC_DYNAMIC_TAG
+#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef PPC_DYNAMIC_TAG
+#define PPC_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_PPC64:
+#undef PPC64_DYNAMIC_TAG
+#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef PPC64_DYNAMIC_TAG
+#define PPC64_DYNAMIC_TAG(name, value)
+ break;
+ default:
+#include "llvm/BinaryFormat/DynamicTags.def"
+ break;
+ }
+#undef AARCH64_DYNAMIC_TAG
+#undef MIPS_DYNAMIC_TAG
+#undef HEXAGON_DYNAMIC_TAG
+#undef PPC_DYNAMIC_TAG
+#undef PPC64_DYNAMIC_TAG
+#undef DYNAMIC_TAG_MARKER
+#undef STRINGIFY
+#undef DYNAMIC_TAG
+
+ IO.enumFallback<Hex64>(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);
+#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);
+#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);
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
+ IO &IO, ELFYAML::MIPS_ISA &Value) {
+ IO.enumCase(Value, "MIPS1", 1);
+ IO.enumCase(Value, "MIPS2", 2);
+ IO.enumCase(Value, "MIPS3", 3);
+ IO.enumCase(Value, "MIPS4", 4);
+ IO.enumCase(Value, "MIPS5", 5);
+ IO.enumCase(Value, "MIPS32", 32);
+ IO.enumCase(Value, "MIPS64", 64);
+}
+
+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);
+#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);
+#undef BCase
+}
+
+void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
+ ELFYAML::FileHeader &FileHdr) {
+ IO.mapRequired("Class", FileHdr.Class);
+ IO.mapRequired("Data", FileHdr.Data);
+ IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
+ IO.mapOptional("ABIVersion", FileHdr.ABIVersion, Hex8(0));
+ IO.mapRequired("Type", FileHdr.Type);
+ IO.mapRequired("Machine", FileHdr.Machine);
+ IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
+ IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
+
+ IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
+ IO.mapOptional("SHOffset", FileHdr.SHOffset);
+ IO.mapOptional("SHNum", FileHdr.SHNum);
+ IO.mapOptional("SHStrNdx", FileHdr.SHStrNdx);
+}
+
+void MappingTraits<ELFYAML::ProgramHeader>::mapping(
+ IO &IO, ELFYAML::ProgramHeader &Phdr) {
+ IO.mapRequired("Type", Phdr.Type);
+ IO.mapOptional("Flags", Phdr.Flags, ELFYAML::ELF_PF(0));
+ IO.mapOptional("Sections", Phdr.Sections);
+ IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
+ IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
+ IO.mapOptional("Align", Phdr.Align);
+ IO.mapOptional("FileSize", Phdr.FileSize);
+ IO.mapOptional("MemSize", Phdr.MemSize);
+ IO.mapOptional("Offset", Phdr.Offset);
+}
+
+namespace {
+
+struct NormalizedOther {
+ NormalizedOther(IO &)
+ : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {}
+ NormalizedOther(IO &, uint8_t Original)
+ : Visibility(Original & 0x3), Other(Original & ~0x3) {}
+
+ uint8_t denormalize(IO &) { return Visibility | Other; }
+
+ 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());
+ IO.mapOptional("NameIndex", Symbol.NameIndex);
+ IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
+ IO.mapOptional("Section", Symbol.Section, StringRef());
+ IO.mapOptional("Index", Symbol.Index);
+ IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
+ IO.mapOptional("Value", Symbol.Value, Hex64(0));
+ IO.mapOptional("Size", Symbol.Size, Hex64(0));
+ MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
+ IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
+ IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
+}
+
+StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
+ ELFYAML::Symbol &Symbol) {
+ if (Symbol.Index && Symbol.Section.data())
+ return "Index and Section cannot both be specified for Symbol";
+ if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX))
+ return "Large indexes are not supported";
+ if (Symbol.NameIndex && !Symbol.Name.empty())
+ return "Name and NameIndex cannot both be specified for Symbol";
+ return StringRef();
+}
+
+static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
+ IO.mapOptional("Name", Section.Name, StringRef());
+ IO.mapRequired("Type", Section.Type);
+ IO.mapOptional("Flags", Section.Flags);
+ IO.mapOptional("Address", Section.Address, Hex64(0));
+ IO.mapOptional("Link", Section.Link, StringRef());
+ IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
+ IO.mapOptional("EntSize", Section.EntSize);
+
+ // obj2yaml does not dump these fields. They are expected to be empty when we
+ // are producing YAML, because yaml2obj sets appropriate values for sh_offset
+ // and sh_size automatically when they are not explicitly defined.
+ assert(!IO.outputting() ||
+ (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue()));
+ IO.mapOptional("ShOffset", Section.ShOffset);
+ IO.mapOptional("ShSize", Section.ShSize);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Entries", Section.Entries);
+ IO.mapOptional("Content", Section.Content);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Content", Section.Content);
+ IO.mapOptional("Size", Section.Size);
+ IO.mapOptional("Info", Section.Info);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Size", Section.Size, Hex64(0));
+}
+
+static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Info", Section.Info);
+ IO.mapRequired("Entries", Section.Entries);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Entries", Section.Entries);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Info", Section.Info);
+ IO.mapRequired("Dependencies", Section.VerneedV);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Info", Section.RelocatableSec, StringRef());
+ IO.mapOptional("Relocations", Section.Relocations);
+}
+
+static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
+ commonSectionMapping(IO, Group);
+ IO.mapOptional("Info", Group.Signature, StringRef());
+ IO.mapRequired("Members", Group.Members);
+}
+
+void MappingTraits<ELFYAML::SectionOrType>::mapping(
+ IO &IO, ELFYAML::SectionOrType &sectionOrType) {
+ IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
+}
+
+void MappingTraits<ELFYAML::SectionName>::mapping(
+ IO &IO, ELFYAML::SectionName &sectionName) {
+ IO.mapRequired("Section", sectionName.Section);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Version", Section.Version, Hex16(0));
+ IO.mapRequired("ISA", Section.ISALevel);
+ IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
+ IO.mapOptional("ISAExtension", Section.ISAExtension,
+ ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
+ IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
+ IO.mapOptional("FpABI", Section.FpABI,
+ ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
+ IO.mapOptional("GPRSize", Section.GPRSize,
+ ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
+ IO.mapOptional("CPR1Size", Section.CPR1Size,
+ ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
+ IO.mapOptional("CPR2Size", Section.CPR2Size,
+ ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
+ IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
+ IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
+}
+
+void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
+ IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
+ ELFYAML::ELF_SHT sectionType;
+ if (IO.outputting())
+ sectionType = Section->Type;
+ else
+ IO.mapRequired("Type", sectionType);
+
+ switch (sectionType) {
+ case ELF::SHT_DYNAMIC:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::DynamicSection());
+ sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
+ break;
+ case ELF::SHT_REL:
+ case ELF::SHT_RELA:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::RelocationSection());
+ sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
+ break;
+ case ELF::SHT_GROUP:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::Group());
+ groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
+ break;
+ case ELF::SHT_NOBITS:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::NoBitsSection());
+ sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
+ break;
+ case ELF::SHT_MIPS_ABIFLAGS:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::MipsABIFlags());
+ sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
+ break;
+ case ELF::SHT_GNU_verdef:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::VerdefSection());
+ sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
+ break;
+ case ELF::SHT_GNU_versym:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::SymverSection());
+ sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
+ break;
+ case ELF::SHT_GNU_verneed:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::VerneedSection());
+ sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
+ break;
+ default:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::RawContentSection());
+ sectionMapping(IO, *cast<ELFYAML::RawContentSection>(Section.get()));
+ }
+}
+
+StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
+ IO &io, std::unique_ptr<ELFYAML::Section> &Section) {
+ const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(Section.get());
+ if (!RawSection)
+ return {};
+ if (RawSection->Size && RawSection->Content &&
+ (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size())
+ return "Section size must be greater than or equal to the content size";
+ return {};
+}
+
+namespace {
+
+struct NormalizedMips64RelType {
+ NormalizedMips64RelType(IO &)
+ : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
+ NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
+ : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
+ Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
+
+ ELFYAML::ELF_REL denormalize(IO &) {
+ ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
+ return Res;
+ }
+
+ ELFYAML::ELF_REL Type;
+ ELFYAML::ELF_REL Type2;
+ ELFYAML::ELF_REL Type3;
+ ELFYAML::ELF_RSS SpecSym;
+};
+
+} // end anonymous namespace
+
+void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
+ ELFYAML::DynamicEntry &Rel) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Tag", Rel.Tag);
+ IO.mapRequired("Value", Rel.Val);
+}
+
+void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
+ ELFYAML::VerdefEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Version", E.Version);
+ IO.mapRequired("Flags", E.Flags);
+ IO.mapRequired("VersionNdx", E.VersionNdx);
+ IO.mapRequired("Hash", E.Hash);
+ IO.mapRequired("Names", E.VerNames);
+}
+
+void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
+ ELFYAML::VerneedEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Version", E.Version);
+ IO.mapRequired("File", E.File);
+ IO.mapRequired("Entries", E.AuxV);
+}
+
+void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO,
+ ELFYAML::VernauxEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Name", E.Name);
+ IO.mapRequired("Hash", E.Hash);
+ IO.mapRequired("Flags", E.Flags);
+ IO.mapRequired("Other", E.Other);
+}
+
+void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
+ ELFYAML::Relocation &Rel) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+
+ IO.mapRequired("Offset", Rel.Offset);
+ IO.mapOptional("Symbol", Rel.Symbol);
+
+ if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
+ Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
+ MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
+ IO, Rel.Type);
+ IO.mapRequired("Type", Key->Type);
+ IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
+ IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
+ IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
+ } else
+ IO.mapRequired("Type", Rel.Type);
+
+ IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
+}
+
+void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
+ assert(!IO.getContext() && "The IO context is initialized already");
+ IO.setContext(&Object);
+ IO.mapTag("!ELF", true);
+ IO.mapRequired("FileHeader", Object.Header);
+ IO.mapOptional("ProgramHeaders", Object.ProgramHeaders);
+ IO.mapOptional("Sections", Object.Sections);
+ IO.mapOptional("Symbols", Object.Symbols);
+ IO.mapOptional("DynamicSymbols", Object.DynamicSymbols);
+ IO.setContext(nullptr);
+}
+
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
+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-project/llvm/lib/ObjectYAML/MachOYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/MachOYAML.cpp
new file mode 100644
index 000000000000..d12f12cf4435
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/MachOYAML.cpp
@@ -0,0 +1,565 @@
+//===- MachOYAML.cpp - MachO YAMLIO implementation ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of MachO.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/MachOYAML.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cinttypes>
+#include <cstdint>
+#include <cstring>
+
+namespace llvm {
+
+MachOYAML::LoadCommand::~LoadCommand() = default;
+
+bool MachOYAML::LinkEditData::isEmpty() const {
+ return 0 ==
+ RebaseOpcodes.size() + BindOpcodes.size() + WeakBindOpcodes.size() +
+ LazyBindOpcodes.size() + ExportTrie.Children.size() +
+ NameList.size() + StringTable.size();
+}
+
+namespace yaml {
+
+void ScalarTraits<char_16>::output(const char_16 &Val, void *,
+ raw_ostream &Out) {
+ auto Len = strnlen(&Val[0], 16);
+ Out << StringRef(&Val[0], Len);
+}
+
+StringRef ScalarTraits<char_16>::input(StringRef Scalar, void *, char_16 &Val) {
+ size_t CopySize = 16 >= Scalar.size() ? 16 : Scalar.size();
+ memcpy((void *)Val, Scalar.data(), CopySize);
+
+ if (Scalar.size() < 16) {
+ memset((void *)&Val[Scalar.size()], 0, 16 - Scalar.size());
+ }
+
+ return StringRef();
+}
+
+QuotingType ScalarTraits<char_16>::mustQuote(StringRef S) {
+ return needsQuotes(S);
+}
+
+void ScalarTraits<uuid_t>::output(const uuid_t &Val, void *, raw_ostream &Out) {
+ Out.write_uuid(Val);
+}
+
+StringRef ScalarTraits<uuid_t>::input(StringRef Scalar, void *, uuid_t &Val) {
+ size_t OutIdx = 0;
+ for (size_t Idx = 0; Idx < Scalar.size(); ++Idx) {
+ if (Scalar[Idx] == '-' || OutIdx >= 16)
+ continue;
+ unsigned long long TempInt;
+ if (getAsUnsignedInteger(Scalar.slice(Idx, Idx + 2), 16, TempInt))
+ return "invalid number";
+ if (TempInt > 0xFF)
+ return "out of range number";
+ Val[OutIdx] = static_cast<uint8_t>(TempInt);
+ ++Idx; // increment idx an extra time because we're consuming 2 chars
+ ++OutIdx;
+ }
+ return StringRef();
+}
+
+QuotingType ScalarTraits<uuid_t>::mustQuote(StringRef S) {
+ return needsQuotes(S);
+}
+
+void MappingTraits<MachOYAML::FileHeader>::mapping(
+ IO &IO, MachOYAML::FileHeader &FileHdr) {
+ IO.mapRequired("magic", FileHdr.magic);
+ IO.mapRequired("cputype", FileHdr.cputype);
+ IO.mapRequired("cpusubtype", FileHdr.cpusubtype);
+ IO.mapRequired("filetype", FileHdr.filetype);
+ IO.mapRequired("ncmds", FileHdr.ncmds);
+ IO.mapRequired("sizeofcmds", FileHdr.sizeofcmds);
+ IO.mapRequired("flags", FileHdr.flags);
+ if (FileHdr.magic == MachO::MH_MAGIC_64 ||
+ FileHdr.magic == MachO::MH_CIGAM_64)
+ IO.mapRequired("reserved", FileHdr.reserved);
+}
+
+void MappingTraits<MachOYAML::Object>::mapping(IO &IO,
+ MachOYAML::Object &Object) {
+ // If the context isn't already set, tag the document as !mach-o.
+ // For Fat files there will be a different tag so they can be differentiated.
+ if (!IO.getContext()) {
+ IO.setContext(&Object);
+ }
+ IO.mapTag("!mach-o", true);
+ IO.mapOptional("IsLittleEndian", Object.IsLittleEndian,
+ sys::IsLittleEndianHost);
+ Object.DWARF.IsLittleEndian = Object.IsLittleEndian;
+
+ IO.mapRequired("FileHeader", Object.Header);
+ IO.mapOptional("LoadCommands", Object.LoadCommands);
+ if(!Object.LinkEdit.isEmpty() || !IO.outputting())
+ IO.mapOptional("LinkEditData", Object.LinkEdit);
+
+ if(!Object.DWARF.isEmpty() || !IO.outputting())
+ IO.mapOptional("DWARF", Object.DWARF);
+
+ if (IO.getContext() == &Object)
+ IO.setContext(nullptr);
+}
+
+void MappingTraits<MachOYAML::FatHeader>::mapping(
+ IO &IO, MachOYAML::FatHeader &FatHeader) {
+ IO.mapRequired("magic", FatHeader.magic);
+ IO.mapRequired("nfat_arch", FatHeader.nfat_arch);
+}
+
+void MappingTraits<MachOYAML::FatArch>::mapping(IO &IO,
+ MachOYAML::FatArch &FatArch) {
+ IO.mapRequired("cputype", FatArch.cputype);
+ IO.mapRequired("cpusubtype", FatArch.cpusubtype);
+ IO.mapRequired("offset", FatArch.offset);
+ IO.mapRequired("size", FatArch.size);
+ IO.mapRequired("align", FatArch.align);
+ IO.mapOptional("reserved", FatArch.reserved,
+ static_cast<llvm::yaml::Hex32>(0));
+}
+
+void MappingTraits<MachOYAML::UniversalBinary>::mapping(
+ IO &IO, MachOYAML::UniversalBinary &UniversalBinary) {
+ if (!IO.getContext()) {
+ IO.setContext(&UniversalBinary);
+ IO.mapTag("!fat-mach-o", true);
+ }
+ IO.mapRequired("FatHeader", UniversalBinary.Header);
+ IO.mapRequired("FatArchs", UniversalBinary.FatArchs);
+ IO.mapRequired("Slices", UniversalBinary.Slices);
+
+ if (IO.getContext() == &UniversalBinary)
+ IO.setContext(nullptr);
+}
+
+void MappingTraits<MachOYAML::LinkEditData>::mapping(
+ IO &IO, MachOYAML::LinkEditData &LinkEditData) {
+ IO.mapOptional("RebaseOpcodes", LinkEditData.RebaseOpcodes);
+ IO.mapOptional("BindOpcodes", LinkEditData.BindOpcodes);
+ IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes);
+ IO.mapOptional("LazyBindOpcodes", LinkEditData.LazyBindOpcodes);
+ if (!LinkEditData.ExportTrie.Children.empty() || !IO.outputting())
+ IO.mapOptional("ExportTrie", LinkEditData.ExportTrie);
+ IO.mapOptional("NameList", LinkEditData.NameList);
+ IO.mapOptional("StringTable", LinkEditData.StringTable);
+}
+
+void MappingTraits<MachOYAML::RebaseOpcode>::mapping(
+ IO &IO, MachOYAML::RebaseOpcode &RebaseOpcode) {
+ IO.mapRequired("Opcode", RebaseOpcode.Opcode);
+ IO.mapRequired("Imm", RebaseOpcode.Imm);
+ IO.mapOptional("ExtraData", RebaseOpcode.ExtraData);
+}
+
+void MappingTraits<MachOYAML::BindOpcode>::mapping(
+ IO &IO, MachOYAML::BindOpcode &BindOpcode) {
+ IO.mapRequired("Opcode", BindOpcode.Opcode);
+ IO.mapRequired("Imm", BindOpcode.Imm);
+ IO.mapOptional("ULEBExtraData", BindOpcode.ULEBExtraData);
+ IO.mapOptional("SLEBExtraData", BindOpcode.SLEBExtraData);
+ IO.mapOptional("Symbol", BindOpcode.Symbol);
+}
+
+void MappingTraits<MachOYAML::ExportEntry>::mapping(
+ IO &IO, MachOYAML::ExportEntry &ExportEntry) {
+ IO.mapRequired("TerminalSize", ExportEntry.TerminalSize);
+ IO.mapOptional("NodeOffset", ExportEntry.NodeOffset);
+ IO.mapOptional("Name", ExportEntry.Name);
+ IO.mapOptional("Flags", ExportEntry.Flags);
+ IO.mapOptional("Address", ExportEntry.Address);
+ IO.mapOptional("Other", ExportEntry.Other);
+ IO.mapOptional("ImportName", ExportEntry.ImportName);
+ IO.mapOptional("Children", ExportEntry.Children);
+}
+
+void MappingTraits<MachOYAML::NListEntry>::mapping(
+ IO &IO, MachOYAML::NListEntry &NListEntry) {
+ IO.mapRequired("n_strx", NListEntry.n_strx);
+ IO.mapRequired("n_type", NListEntry.n_type);
+ IO.mapRequired("n_sect", NListEntry.n_sect);
+ IO.mapRequired("n_desc", NListEntry.n_desc);
+ IO.mapRequired("n_value", NListEntry.n_value);
+}
+
+template <typename StructType>
+void mapLoadCommandData(IO &IO, MachOYAML::LoadCommand &LoadCommand) {}
+
+template <>
+void mapLoadCommandData<MachO::segment_command>(
+ IO &IO, MachOYAML::LoadCommand &LoadCommand) {
+ IO.mapOptional("Sections", LoadCommand.Sections);
+}
+
+template <>
+void mapLoadCommandData<MachO::segment_command_64>(
+ IO &IO, MachOYAML::LoadCommand &LoadCommand) {
+ IO.mapOptional("Sections", LoadCommand.Sections);
+}
+
+template <>
+void mapLoadCommandData<MachO::dylib_command>(
+ IO &IO, MachOYAML::LoadCommand &LoadCommand) {
+ IO.mapOptional("PayloadString", LoadCommand.PayloadString);
+}
+
+template <>
+void mapLoadCommandData<MachO::rpath_command>(
+ IO &IO, MachOYAML::LoadCommand &LoadCommand) {
+ IO.mapOptional("PayloadString", LoadCommand.PayloadString);
+}
+
+template <>
+void mapLoadCommandData<MachO::dylinker_command>(
+ IO &IO, MachOYAML::LoadCommand &LoadCommand) {
+ 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>(
+ LoadCommand.Data.load_command_data.cmd);
+ IO.mapRequired("cmd", TempCmd);
+ LoadCommand.Data.load_command_data.cmd = TempCmd;
+ IO.mapRequired("cmdsize", LoadCommand.Data.load_command_data.cmdsize);
+
+#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
+ case MachO::LCName: \
+ MappingTraits<MachO::LCStruct>::mapping(IO, \
+ LoadCommand.Data.LCStruct##_data); \
+ mapLoadCommandData<MachO::LCStruct>(IO, LoadCommand); \
+ break;
+
+ switch (LoadCommand.Data.load_command_data.cmd) {
+#include "llvm/BinaryFormat/MachO.def"
+ }
+ IO.mapOptional("PayloadBytes", LoadCommand.PayloadBytes);
+ IO.mapOptional("ZeroPadBytes", LoadCommand.ZeroPadBytes, (uint64_t)0ull);
+}
+
+void MappingTraits<MachO::dyld_info_command>::mapping(
+ IO &IO, MachO::dyld_info_command &LoadCommand) {
+ IO.mapRequired("rebase_off", LoadCommand.rebase_off);
+ IO.mapRequired("rebase_size", LoadCommand.rebase_size);
+ IO.mapRequired("bind_off", LoadCommand.bind_off);
+ IO.mapRequired("bind_size", LoadCommand.bind_size);
+ IO.mapRequired("weak_bind_off", LoadCommand.weak_bind_off);
+ IO.mapRequired("weak_bind_size", LoadCommand.weak_bind_size);
+ IO.mapRequired("lazy_bind_off", LoadCommand.lazy_bind_off);
+ IO.mapRequired("lazy_bind_size", LoadCommand.lazy_bind_size);
+ IO.mapRequired("export_off", LoadCommand.export_off);
+ IO.mapRequired("export_size", LoadCommand.export_size);
+}
+
+void MappingTraits<MachOYAML::Section>::mapping(IO &IO,
+ MachOYAML::Section &Section) {
+ IO.mapRequired("sectname", Section.sectname);
+ IO.mapRequired("segname", Section.segname);
+ IO.mapRequired("addr", Section.addr);
+ IO.mapRequired("size", Section.size);
+ IO.mapRequired("offset", Section.offset);
+ IO.mapRequired("align", Section.align);
+ IO.mapRequired("reloff", Section.reloff);
+ IO.mapRequired("nreloc", Section.nreloc);
+ IO.mapRequired("flags", Section.flags);
+ IO.mapRequired("reserved1", Section.reserved1);
+ IO.mapRequired("reserved2", Section.reserved2);
+ 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);
+ IO.mapRequired("current_version", DylibStruct.current_version);
+ IO.mapRequired("compatibility_version", DylibStruct.compatibility_version);
+}
+
+void MappingTraits<MachO::dylib_command>::mapping(
+ IO &IO, MachO::dylib_command &LoadCommand) {
+ IO.mapRequired("dylib", LoadCommand.dylib);
+}
+
+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);
+ IO.mapRequired("nextdefsym", LoadCommand.nextdefsym);
+ IO.mapRequired("iundefsym", LoadCommand.iundefsym);
+ IO.mapRequired("nundefsym", LoadCommand.nundefsym);
+ IO.mapRequired("tocoff", LoadCommand.tocoff);
+ IO.mapRequired("ntoc", LoadCommand.ntoc);
+ IO.mapRequired("modtaboff", LoadCommand.modtaboff);
+ IO.mapRequired("nmodtab", LoadCommand.nmodtab);
+ IO.mapRequired("extrefsymoff", LoadCommand.extrefsymoff);
+ IO.mapRequired("nextrefsyms", LoadCommand.nextrefsyms);
+ IO.mapRequired("indirectsymoff", LoadCommand.indirectsymoff);
+ IO.mapRequired("nindirectsyms", LoadCommand.nindirectsyms);
+ IO.mapRequired("extreloff", LoadCommand.extreloff);
+ IO.mapRequired("nextrel", LoadCommand.nextrel);
+ IO.mapRequired("locreloff", LoadCommand.locreloff);
+ IO.mapRequired("nlocrel", LoadCommand.nlocrel);
+}
+
+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);
+}
+
+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);
+ IO.mapRequired("pad", LoadCommand.pad);
+}
+
+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);
+}
+
+void MappingTraits<MachO::fvmlib>::mapping(IO &IO, MachO::fvmlib &FVMLib) {
+ IO.mapRequired("name", FVMLib.name);
+ IO.mapRequired("minor_version", FVMLib.minor_version);
+ IO.mapRequired("header_addr", FVMLib.header_addr);
+}
+
+void MappingTraits<MachO::fvmlib_command>::mapping(
+ IO &IO, MachO::fvmlib_command &LoadCommand) {
+ IO.mapRequired("fvmlib", LoadCommand.fvmlib);
+}
+
+void MappingTraits<MachO::ident_command>::mapping(
+ IO &IO, MachO::ident_command &LoadCommand) {}
+
+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);
+}
+
+void MappingTraits<MachO::load_command>::mapping(
+ IO &IO, MachO::load_command &LoadCommand) {}
+
+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);
+}
+
+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);
+ IO.mapRequired("reserved2", LoadCommand.reserved2);
+ IO.mapRequired("reserved3", LoadCommand.reserved3);
+ IO.mapRequired("reserved4", LoadCommand.reserved4);
+ IO.mapRequired("reserved5", LoadCommand.reserved5);
+ IO.mapRequired("reserved6", LoadCommand.reserved6);
+}
+
+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);
+ IO.mapRequired("reserved2", LoadCommand.reserved2);
+ IO.mapRequired("reserved3", LoadCommand.reserved3);
+ IO.mapRequired("reserved4", LoadCommand.reserved4);
+ IO.mapRequired("reserved5", LoadCommand.reserved5);
+ IO.mapRequired("reserved6", LoadCommand.reserved6);
+}
+
+void MappingTraits<MachO::rpath_command>::mapping(
+ IO &IO, MachO::rpath_command &LoadCommand) {
+ IO.mapRequired("path", LoadCommand.path);
+}
+
+void MappingTraits<MachO::section>::mapping(IO &IO, MachO::section &Section) {
+ IO.mapRequired("sectname", Section.sectname);
+ IO.mapRequired("segname", Section.segname);
+ IO.mapRequired("addr", Section.addr);
+ IO.mapRequired("size", Section.size);
+ IO.mapRequired("offset", Section.offset);
+ IO.mapRequired("align", Section.align);
+ IO.mapRequired("reloff", Section.reloff);
+ IO.mapRequired("nreloc", Section.nreloc);
+ IO.mapRequired("flags", Section.flags);
+ IO.mapRequired("reserved1", Section.reserved1);
+ IO.mapRequired("reserved2", Section.reserved2);
+}
+
+void MappingTraits<MachO::section_64>::mapping(IO &IO,
+ MachO::section_64 &Section) {
+ IO.mapRequired("sectname", Section.sectname);
+ IO.mapRequired("segname", Section.segname);
+ IO.mapRequired("addr", Section.addr);
+ IO.mapRequired("size", Section.size);
+ IO.mapRequired("offset", Section.offset);
+ IO.mapRequired("align", Section.align);
+ IO.mapRequired("reloff", Section.reloff);
+ IO.mapRequired("nreloc", Section.nreloc);
+ IO.mapRequired("flags", Section.flags);
+ IO.mapRequired("reserved1", Section.reserved1);
+ IO.mapRequired("reserved2", Section.reserved2);
+ IO.mapRequired("reserved3", Section.reserved3);
+}
+
+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);
+ IO.mapRequired("fileoff", LoadCommand.fileoff);
+ IO.mapRequired("filesize", LoadCommand.filesize);
+ IO.mapRequired("maxprot", LoadCommand.maxprot);
+ IO.mapRequired("initprot", LoadCommand.initprot);
+ IO.mapRequired("nsects", LoadCommand.nsects);
+ IO.mapRequired("flags", LoadCommand.flags);
+}
+
+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);
+ IO.mapRequired("fileoff", LoadCommand.fileoff);
+ IO.mapRequired("filesize", LoadCommand.filesize);
+ IO.mapRequired("maxprot", LoadCommand.maxprot);
+ IO.mapRequired("initprot", LoadCommand.initprot);
+ IO.mapRequired("nsects", LoadCommand.nsects);
+ IO.mapRequired("flags", LoadCommand.flags);
+}
+
+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);
+ IO.mapRequired("strsize", LoadCommand.strsize);
+}
+
+void MappingTraits<MachO::thread_command>::mapping(
+ IO &IO, MachO::thread_command &LoadCommand) {}
+
+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);
+}
+
+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
+
+} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/MinidumpYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/MinidumpYAML.cpp
new file mode 100644
index 000000000000..f5f2acd0cc4b
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/MinidumpYAML.cpp
@@ -0,0 +1,673 @@
+//===- MinidumpYAML.cpp - Minidump YAMLIO implementation ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/MinidumpYAML.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ConvertUTF.h"
+
+using namespace llvm;
+using namespace llvm::MinidumpYAML;
+using namespace llvm::minidump;
+
+namespace {
+/// A helper class to manage the placement of various structures into the final
+/// minidump binary. Space for objects can be allocated via various allocate***
+/// methods, while the final minidump file is written by calling the writeTo
+/// method. The plain versions of allocation functions take a reference to the
+/// data which is to be written (and hence the data must be available until
+/// writeTo is called), while the "New" versions allocate the data in an
+/// allocator-managed buffer, which is available until the allocator object is
+/// destroyed. For both kinds of functions, it is possible to modify the
+/// data for which the space has been "allocated" until the final writeTo call.
+/// This is useful for "linking" the allocated structures via their offsets.
+class BlobAllocator {
+public:
+ size_t tell() const { return NextOffset; }
+
+ size_t allocateCallback(size_t Size,
+ std::function<void(raw_ostream &)> Callback) {
+ size_t Offset = NextOffset;
+ NextOffset += Size;
+ Callbacks.push_back(std::move(Callback));
+ return Offset;
+ }
+
+ size_t allocateBytes(ArrayRef<uint8_t> Data) {
+ return allocateCallback(
+ Data.size(), [Data](raw_ostream &OS) { OS << toStringRef(Data); });
+ }
+
+ size_t allocateBytes(yaml::BinaryRef Data) {
+ return allocateCallback(Data.binary_size(), [Data](raw_ostream &OS) {
+ Data.writeAsBinary(OS);
+ });
+ }
+
+ template <typename T> size_t allocateArray(ArrayRef<T> Data) {
+ return allocateBytes({reinterpret_cast<const uint8_t *>(Data.data()),
+ sizeof(T) * Data.size()});
+ }
+
+ template <typename T, typename RangeType>
+ std::pair<size_t, MutableArrayRef<T>>
+ allocateNewArray(const iterator_range<RangeType> &Range);
+
+ template <typename T> size_t allocateObject(const T &Data) {
+ return allocateArray(makeArrayRef(Data));
+ }
+
+ template <typename T, typename... Types>
+ std::pair<size_t, T *> allocateNewObject(Types &&... Args) {
+ T *Object = new (Temporaries.Allocate<T>()) T(std::forward<Types>(Args)...);
+ return {allocateObject(*Object), Object};
+ }
+
+ size_t allocateString(StringRef Str);
+
+ void writeTo(raw_ostream &OS) const;
+
+private:
+ size_t NextOffset = 0;
+
+ BumpPtrAllocator Temporaries;
+ std::vector<std::function<void(raw_ostream &)>> Callbacks;
+};
+} // namespace
+
+template <typename T, typename RangeType>
+std::pair<size_t, MutableArrayRef<T>>
+BlobAllocator::allocateNewArray(const iterator_range<RangeType> &Range) {
+ size_t Num = std::distance(Range.begin(), Range.end());
+ MutableArrayRef<T> Array(Temporaries.Allocate<T>(Num), Num);
+ std::uninitialized_copy(Range.begin(), Range.end(), Array.begin());
+ return {allocateArray(Array), Array};
+}
+
+size_t BlobAllocator::allocateString(StringRef Str) {
+ SmallVector<UTF16, 32> WStr;
+ bool OK = convertUTF8ToUTF16String(Str, WStr);
+ assert(OK && "Invalid UTF8 in Str?");
+ (void)OK;
+
+ // The utf16 string is null-terminated, but the terminator is not counted in
+ // the string size.
+ WStr.push_back(0);
+ size_t Result =
+ allocateNewObject<support::ulittle32_t>(2 * (WStr.size() - 1)).first;
+ allocateNewArray<support::ulittle16_t>(make_range(WStr.begin(), WStr.end()));
+ return Result;
+}
+
+void BlobAllocator::writeTo(raw_ostream &OS) const {
+ size_t BeginOffset = OS.tell();
+ for (const auto &Callback : Callbacks)
+ Callback(OS);
+ assert(OS.tell() == BeginOffset + NextOffset &&
+ "Callbacks wrote an unexpected number of bytes.");
+ (void)BeginOffset;
+}
+
+/// Perform an optional yaml-mapping of an endian-aware type EndianType. The
+/// only purpose of this function is to avoid casting the Default value to the
+/// endian type;
+template <typename EndianType>
+static inline void mapOptional(yaml::IO &IO, const char *Key, EndianType &Val,
+ typename EndianType::value_type Default) {
+ IO.mapOptional(Key, Val, EndianType(Default));
+}
+
+/// Yaml-map an endian-aware type EndianType as some other type MapType.
+template <typename MapType, typename EndianType>
+static inline void mapRequiredAs(yaml::IO &IO, const char *Key,
+ EndianType &Val) {
+ MapType Mapped = static_cast<typename EndianType::value_type>(Val);
+ IO.mapRequired(Key, Mapped);
+ Val = static_cast<typename EndianType::value_type>(Mapped);
+}
+
+/// Perform an optional yaml-mapping of an endian-aware type EndianType as some
+/// other type MapType.
+template <typename MapType, typename EndianType>
+static inline void mapOptionalAs(yaml::IO &IO, const char *Key, EndianType &Val,
+ MapType Default) {
+ MapType Mapped = static_cast<typename EndianType::value_type>(Val);
+ IO.mapOptional(Key, Mapped, Default);
+ Val = static_cast<typename EndianType::value_type>(Mapped);
+}
+
+namespace {
+/// Return the appropriate yaml Hex type for a given endian-aware type.
+template <typename EndianType> struct HexType;
+template <> struct HexType<support::ulittle16_t> { using type = yaml::Hex16; };
+template <> struct HexType<support::ulittle32_t> { using type = yaml::Hex32; };
+template <> struct HexType<support::ulittle64_t> { using type = yaml::Hex64; };
+} // namespace
+
+/// Yaml-map an endian-aware type as an appropriately-sized hex value.
+template <typename EndianType>
+static inline void mapRequiredHex(yaml::IO &IO, const char *Key,
+ EndianType &Val) {
+ mapRequiredAs<typename HexType<EndianType>::type>(IO, Key, Val);
+}
+
+/// Perform an optional yaml-mapping of an endian-aware type as an
+/// appropriately-sized hex value.
+template <typename EndianType>
+static inline void mapOptionalHex(yaml::IO &IO, const char *Key,
+ EndianType &Val,
+ typename EndianType::value_type Default) {
+ mapOptionalAs<typename HexType<EndianType>::type>(IO, Key, Val, Default);
+}
+
+Stream::~Stream() = default;
+
+Stream::StreamKind Stream::getKind(StreamType Type) {
+ switch (Type) {
+ case StreamType::MemoryList:
+ return StreamKind::MemoryList;
+ case StreamType::ModuleList:
+ return StreamKind::ModuleList;
+ case StreamType::SystemInfo:
+ return StreamKind::SystemInfo;
+ case StreamType::LinuxCPUInfo:
+ case StreamType::LinuxProcStatus:
+ case StreamType::LinuxLSBRelease:
+ case StreamType::LinuxCMDLine:
+ case StreamType::LinuxMaps:
+ case StreamType::LinuxProcStat:
+ case StreamType::LinuxProcUptime:
+ return StreamKind::TextContent;
+ case StreamType::ThreadList:
+ return StreamKind::ThreadList;
+ default:
+ return StreamKind::RawContent;
+ }
+}
+
+std::unique_ptr<Stream> Stream::create(StreamType Type) {
+ StreamKind Kind = getKind(Type);
+ switch (Kind) {
+ case StreamKind::MemoryList:
+ return llvm::make_unique<MemoryListStream>();
+ case StreamKind::ModuleList:
+ return llvm::make_unique<ModuleListStream>();
+ case StreamKind::RawContent:
+ return llvm::make_unique<RawContentStream>(Type);
+ case StreamKind::SystemInfo:
+ return llvm::make_unique<SystemInfoStream>();
+ case StreamKind::TextContent:
+ return llvm::make_unique<TextContentStream>(Type);
+ case StreamKind::ThreadList:
+ return llvm::make_unique<ThreadListStream>();
+ }
+ llvm_unreachable("Unhandled stream kind!");
+}
+
+void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
+ IO &IO, ProcessorArchitecture &Arch) {
+#define HANDLE_MDMP_ARCH(CODE, NAME) \
+ IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+ IO.enumFallback<Hex16>(Arch);
+}
+
+void yaml::ScalarEnumerationTraits<OSPlatform>::enumeration(IO &IO,
+ OSPlatform &Plat) {
+#define HANDLE_MDMP_PLATFORM(CODE, NAME) \
+ IO.enumCase(Plat, #NAME, OSPlatform::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+ IO.enumFallback<Hex32>(Plat);
+}
+
+void yaml::ScalarEnumerationTraits<StreamType>::enumeration(IO &IO,
+ StreamType &Type) {
+#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) \
+ IO.enumCase(Type, #NAME, StreamType::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+ IO.enumFallback<Hex32>(Type);
+}
+
+void yaml::MappingTraits<CPUInfo::ArmInfo>::mapping(IO &IO,
+ CPUInfo::ArmInfo &Info) {
+ mapRequiredHex(IO, "CPUID", Info.CPUID);
+ mapOptionalHex(IO, "ELF hwcaps", Info.ElfHWCaps, 0);
+}
+
+namespace {
+template <std::size_t N> struct FixedSizeHex {
+ FixedSizeHex(uint8_t (&Storage)[N]) : Storage(Storage) {}
+
+ uint8_t (&Storage)[N];
+};
+} // namespace
+
+namespace llvm {
+namespace yaml {
+template <std::size_t N> struct ScalarTraits<FixedSizeHex<N>> {
+ static void output(const FixedSizeHex<N> &Fixed, void *, raw_ostream &OS) {
+ OS << toHex(makeArrayRef(Fixed.Storage));
+ }
+
+ static StringRef input(StringRef Scalar, void *, FixedSizeHex<N> &Fixed) {
+ if (!all_of(Scalar, isHexDigit))
+ return "Invalid hex digit in input";
+ if (Scalar.size() < 2 * N)
+ return "String too short";
+ if (Scalar.size() > 2 * N)
+ return "String too long";
+ copy(fromHex(Scalar), Fixed.Storage);
+ return "";
+ }
+
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
+};
+} // namespace yaml
+} // namespace llvm
+void yaml::MappingTraits<CPUInfo::OtherInfo>::mapping(
+ IO &IO, CPUInfo::OtherInfo &Info) {
+ FixedSizeHex<sizeof(Info.ProcessorFeatures)> Features(Info.ProcessorFeatures);
+ IO.mapRequired("Features", Features);
+}
+
+namespace {
+/// A type which only accepts strings of a fixed size for yaml conversion.
+template <std::size_t N> struct FixedSizeString {
+ FixedSizeString(char (&Storage)[N]) : Storage(Storage) {}
+
+ char (&Storage)[N];
+};
+} // namespace
+
+namespace llvm {
+namespace yaml {
+template <std::size_t N> struct ScalarTraits<FixedSizeString<N>> {
+ static void output(const FixedSizeString<N> &Fixed, void *, raw_ostream &OS) {
+ OS << StringRef(Fixed.Storage, N);
+ }
+
+ static StringRef input(StringRef Scalar, void *, FixedSizeString<N> &Fixed) {
+ if (Scalar.size() < N)
+ return "String too short";
+ if (Scalar.size() > N)
+ return "String too long";
+ copy(Scalar, Fixed.Storage);
+ return "";
+ }
+
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
+};
+} // namespace yaml
+} // namespace llvm
+
+void yaml::MappingTraits<CPUInfo::X86Info>::mapping(IO &IO,
+ CPUInfo::X86Info &Info) {
+ FixedSizeString<sizeof(Info.VendorID)> VendorID(Info.VendorID);
+ IO.mapRequired("Vendor ID", VendorID);
+
+ mapRequiredHex(IO, "Version Info", Info.VersionInfo);
+ mapRequiredHex(IO, "Feature Info", Info.FeatureInfo);
+ mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);
+}
+
+void yaml::MappingTraits<VSFixedFileInfo>::mapping(IO &IO,
+ VSFixedFileInfo &Info) {
+ mapOptionalHex(IO, "Signature", Info.Signature, 0);
+ mapOptionalHex(IO, "Struct Version", Info.StructVersion, 0);
+ mapOptionalHex(IO, "File Version High", Info.FileVersionHigh, 0);
+ mapOptionalHex(IO, "File Version Low", Info.FileVersionLow, 0);
+ mapOptionalHex(IO, "Product Version High", Info.ProductVersionHigh, 0);
+ mapOptionalHex(IO, "Product Version Low", Info.ProductVersionLow, 0);
+ mapOptionalHex(IO, "File Flags Mask", Info.FileFlagsMask, 0);
+ mapOptionalHex(IO, "File Flags", Info.FileFlags, 0);
+ mapOptionalHex(IO, "File OS", Info.FileOS, 0);
+ mapOptionalHex(IO, "File Type", Info.FileType, 0);
+ mapOptionalHex(IO, "File Subtype", Info.FileSubtype, 0);
+ mapOptionalHex(IO, "File Date High", Info.FileDateHigh, 0);
+ mapOptionalHex(IO, "File Date Low", Info.FileDateLow, 0);
+}
+
+void yaml::MappingTraits<ModuleListStream::entry_type>::mapping(
+ IO &IO, ModuleListStream::entry_type &M) {
+ mapRequiredHex(IO, "Base of Image", M.Entry.BaseOfImage);
+ mapRequiredHex(IO, "Size of Image", M.Entry.SizeOfImage);
+ mapOptionalHex(IO, "Checksum", M.Entry.Checksum, 0);
+ IO.mapOptional("Time Date Stamp", M.Entry.TimeDateStamp,
+ support::ulittle32_t(0));
+ IO.mapRequired("Module Name", M.Name);
+ IO.mapOptional("Version Info", M.Entry.VersionInfo, VSFixedFileInfo());
+ IO.mapRequired("CodeView Record", M.CvRecord);
+ IO.mapOptional("Misc Record", M.MiscRecord, yaml::BinaryRef());
+ mapOptionalHex(IO, "Reserved0", M.Entry.Reserved0, 0);
+ mapOptionalHex(IO, "Reserved1", M.Entry.Reserved1, 0);
+}
+
+static void streamMapping(yaml::IO &IO, RawContentStream &Stream) {
+ IO.mapOptional("Content", Stream.Content);
+ IO.mapOptional("Size", Stream.Size, Stream.Content.binary_size());
+}
+
+static StringRef streamValidate(RawContentStream &Stream) {
+ if (Stream.Size.value < Stream.Content.binary_size())
+ return "Stream size must be greater or equal to the content size";
+ return "";
+}
+
+void yaml::MappingTraits<MemoryListStream::entry_type>::mapping(
+ IO &IO, MemoryListStream::entry_type &Range) {
+ MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
+ IO, Range.Entry, Range.Content);
+}
+
+static void streamMapping(yaml::IO &IO, MemoryListStream &Stream) {
+ IO.mapRequired("Memory Ranges", Stream.Entries);
+}
+
+static void streamMapping(yaml::IO &IO, ModuleListStream &Stream) {
+ IO.mapRequired("Modules", Stream.Entries);
+}
+
+static void streamMapping(yaml::IO &IO, SystemInfoStream &Stream) {
+ SystemInfo &Info = Stream.Info;
+ IO.mapRequired("Processor Arch", Info.ProcessorArch);
+ mapOptional(IO, "Processor Level", Info.ProcessorLevel, 0);
+ mapOptional(IO, "Processor Revision", Info.ProcessorRevision, 0);
+ IO.mapOptional("Number of Processors", Info.NumberOfProcessors, 0);
+ IO.mapOptional("Product type", Info.ProductType, 0);
+ mapOptional(IO, "Major Version", Info.MajorVersion, 0);
+ mapOptional(IO, "Minor Version", Info.MinorVersion, 0);
+ mapOptional(IO, "Build Number", Info.BuildNumber, 0);
+ IO.mapRequired("Platform ID", Info.PlatformId);
+ IO.mapOptional("CSD Version", Stream.CSDVersion, "");
+ mapOptionalHex(IO, "Suite Mask", Info.SuiteMask, 0);
+ mapOptionalHex(IO, "Reserved", Info.Reserved, 0);
+ switch (static_cast<ProcessorArchitecture>(Info.ProcessorArch)) {
+ case ProcessorArchitecture::X86:
+ case ProcessorArchitecture::AMD64:
+ IO.mapOptional("CPU", Info.CPU.X86);
+ break;
+ case ProcessorArchitecture::ARM:
+ case ProcessorArchitecture::ARM64:
+ IO.mapOptional("CPU", Info.CPU.Arm);
+ break;
+ default:
+ IO.mapOptional("CPU", Info.CPU.Other);
+ break;
+ }
+}
+
+static void streamMapping(yaml::IO &IO, TextContentStream &Stream) {
+ IO.mapOptional("Text", Stream.Text);
+}
+
+void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
+ IO &IO, MemoryDescriptor &Memory, BinaryRef &Content) {
+ mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);
+ IO.mapRequired("Content", Content);
+}
+
+void yaml::MappingTraits<ThreadListStream::entry_type>::mapping(
+ IO &IO, ThreadListStream::entry_type &T) {
+ mapRequiredHex(IO, "Thread Id", T.Entry.ThreadId);
+ mapOptionalHex(IO, "Suspend Count", T.Entry.SuspendCount, 0);
+ mapOptionalHex(IO, "Priority Class", T.Entry.PriorityClass, 0);
+ mapOptionalHex(IO, "Priority", T.Entry.Priority, 0);
+ mapOptionalHex(IO, "Environment Block", T.Entry.EnvironmentBlock, 0);
+ IO.mapRequired("Context", T.Context);
+ IO.mapRequired("Stack", T.Entry.Stack, T.Stack);
+}
+
+static void streamMapping(yaml::IO &IO, ThreadListStream &Stream) {
+ IO.mapRequired("Threads", Stream.Entries);
+}
+
+void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
+ yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
+ StreamType Type;
+ if (IO.outputting())
+ Type = S->Type;
+ IO.mapRequired("Type", Type);
+
+ if (!IO.outputting())
+ S = MinidumpYAML::Stream::create(Type);
+ switch (S->Kind) {
+ case MinidumpYAML::Stream::StreamKind::MemoryList:
+ streamMapping(IO, llvm::cast<MemoryListStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::ModuleList:
+ streamMapping(IO, llvm::cast<ModuleListStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::RawContent:
+ streamMapping(IO, llvm::cast<RawContentStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::SystemInfo:
+ streamMapping(IO, llvm::cast<SystemInfoStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::TextContent:
+ streamMapping(IO, llvm::cast<TextContentStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::ThreadList:
+ streamMapping(IO, llvm::cast<ThreadListStream>(*S));
+ break;
+ }
+}
+
+StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
+ yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
+ switch (S->Kind) {
+ case MinidumpYAML::Stream::StreamKind::RawContent:
+ return streamValidate(cast<RawContentStream>(*S));
+ case MinidumpYAML::Stream::StreamKind::MemoryList:
+ case MinidumpYAML::Stream::StreamKind::ModuleList:
+ case MinidumpYAML::Stream::StreamKind::SystemInfo:
+ case MinidumpYAML::Stream::StreamKind::TextContent:
+ case MinidumpYAML::Stream::StreamKind::ThreadList:
+ return "";
+ }
+ llvm_unreachable("Fully covered switch above!");
+}
+
+void yaml::MappingTraits<Object>::mapping(IO &IO, Object &O) {
+ IO.mapTag("!minidump", true);
+ mapOptionalHex(IO, "Signature", O.Header.Signature, Header::MagicSignature);
+ mapOptionalHex(IO, "Version", O.Header.Version, Header::MagicVersion);
+ mapOptionalHex(IO, "Flags", O.Header.Flags, 0);
+ IO.mapRequired("Streams", O.Streams);
+}
+
+static LocationDescriptor layout(BlobAllocator &File, yaml::BinaryRef Data) {
+ return {support::ulittle32_t(Data.binary_size()),
+ support::ulittle32_t(File.allocateBytes(Data))};
+}
+
+static void layout(BlobAllocator &File, MemoryListStream::entry_type &Range) {
+ Range.Entry.Memory = layout(File, Range.Content);
+}
+
+static void layout(BlobAllocator &File, ModuleListStream::entry_type &M) {
+ M.Entry.ModuleNameRVA = File.allocateString(M.Name);
+
+ M.Entry.CvRecord = layout(File, M.CvRecord);
+ M.Entry.MiscRecord = layout(File, M.MiscRecord);
+}
+
+static void layout(BlobAllocator &File, ThreadListStream::entry_type &T) {
+ T.Entry.Stack.Memory = layout(File, T.Stack);
+ T.Entry.Context = layout(File, T.Context);
+}
+
+template <typename EntryT>
+static size_t layout(BlobAllocator &File,
+ MinidumpYAML::detail::ListStream<EntryT> &S) {
+
+ File.allocateNewObject<support::ulittle32_t>(S.Entries.size());
+ for (auto &E : S.Entries)
+ File.allocateObject(E.Entry);
+
+ size_t DataEnd = File.tell();
+
+ // Lay out the auxiliary data, (which is not a part of the stream).
+ DataEnd = File.tell();
+ for (auto &E : S.Entries)
+ layout(File, E);
+
+ return DataEnd;
+}
+
+static Directory layout(BlobAllocator &File, Stream &S) {
+ Directory Result;
+ Result.Type = S.Type;
+ Result.Location.RVA = File.tell();
+ Optional<size_t> DataEnd;
+ switch (S.Kind) {
+ case Stream::StreamKind::MemoryList:
+ DataEnd = layout(File, cast<MemoryListStream>(S));
+ break;
+ case Stream::StreamKind::ModuleList:
+ DataEnd = layout(File, cast<ModuleListStream>(S));
+ break;
+ case Stream::StreamKind::RawContent: {
+ RawContentStream &Raw = cast<RawContentStream>(S);
+ File.allocateCallback(Raw.Size, [&Raw](raw_ostream &OS) {
+ Raw.Content.writeAsBinary(OS);
+ assert(Raw.Content.binary_size() <= Raw.Size);
+ OS << std::string(Raw.Size - Raw.Content.binary_size(), '\0');
+ });
+ break;
+ }
+ case Stream::StreamKind::SystemInfo: {
+ SystemInfoStream &SystemInfo = cast<SystemInfoStream>(S);
+ File.allocateObject(SystemInfo.Info);
+ // The CSD string is not a part of the stream.
+ DataEnd = File.tell();
+ SystemInfo.Info.CSDVersionRVA = File.allocateString(SystemInfo.CSDVersion);
+ break;
+ }
+ case Stream::StreamKind::TextContent:
+ File.allocateArray(arrayRefFromStringRef(cast<TextContentStream>(S).Text));
+ break;
+ case Stream::StreamKind::ThreadList:
+ DataEnd = layout(File, cast<ThreadListStream>(S));
+ break;
+ }
+ // If DataEnd is not set, we assume everything we generated is a part of the
+ // stream.
+ Result.Location.DataSize =
+ DataEnd.getValueOr(File.tell()) - Result.Location.RVA;
+ return Result;
+}
+
+void MinidumpYAML::writeAsBinary(Object &Obj, raw_ostream &OS) {
+ BlobAllocator File;
+ File.allocateObject(Obj.Header);
+
+ std::vector<Directory> StreamDirectory(Obj.Streams.size());
+ Obj.Header.StreamDirectoryRVA =
+ File.allocateArray(makeArrayRef(StreamDirectory));
+ Obj.Header.NumberOfStreams = StreamDirectory.size();
+
+ for (auto &Stream : enumerate(Obj.Streams))
+ StreamDirectory[Stream.index()] = layout(File, *Stream.value());
+
+ File.writeTo(OS);
+}
+
+Error MinidumpYAML::writeAsBinary(StringRef Yaml, raw_ostream &OS) {
+ yaml::Input Input(Yaml);
+ Object Obj;
+ Input >> Obj;
+ if (std::error_code EC = Input.error())
+ return errorCodeToError(EC);
+
+ writeAsBinary(Obj, OS);
+ return Error::success();
+}
+
+Expected<std::unique_ptr<Stream>>
+Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
+ StreamKind Kind = getKind(StreamDesc.Type);
+ switch (Kind) {
+ case StreamKind::MemoryList: {
+ auto ExpectedList = File.getMemoryList();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<MemoryListStream::entry_type> Ranges;
+ for (const MemoryDescriptor &MD : *ExpectedList) {
+ auto ExpectedContent = File.getRawData(MD.Memory);
+ if (!ExpectedContent)
+ return ExpectedContent.takeError();
+ Ranges.push_back({MD, *ExpectedContent});
+ }
+ return llvm::make_unique<MemoryListStream>(std::move(Ranges));
+ }
+ case StreamKind::ModuleList: {
+ auto ExpectedList = File.getModuleList();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<ModuleListStream::entry_type> Modules;
+ for (const Module &M : *ExpectedList) {
+ auto ExpectedName = File.getString(M.ModuleNameRVA);
+ if (!ExpectedName)
+ return ExpectedName.takeError();
+ auto ExpectedCv = File.getRawData(M.CvRecord);
+ if (!ExpectedCv)
+ return ExpectedCv.takeError();
+ auto ExpectedMisc = File.getRawData(M.MiscRecord);
+ if (!ExpectedMisc)
+ return ExpectedMisc.takeError();
+ Modules.push_back(
+ {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});
+ }
+ return llvm::make_unique<ModuleListStream>(std::move(Modules));
+ }
+ case StreamKind::RawContent:
+ return llvm::make_unique<RawContentStream>(StreamDesc.Type,
+ File.getRawStream(StreamDesc));
+ case StreamKind::SystemInfo: {
+ auto ExpectedInfo = File.getSystemInfo();
+ if (!ExpectedInfo)
+ return ExpectedInfo.takeError();
+ auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);
+ if (!ExpectedCSDVersion)
+ return ExpectedInfo.takeError();
+ return llvm::make_unique<SystemInfoStream>(*ExpectedInfo,
+ std::move(*ExpectedCSDVersion));
+ }
+ case StreamKind::TextContent:
+ return llvm::make_unique<TextContentStream>(
+ StreamDesc.Type, toStringRef(File.getRawStream(StreamDesc)));
+ case StreamKind::ThreadList: {
+ auto ExpectedList = File.getThreadList();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<ThreadListStream::entry_type> Threads;
+ for (const Thread &T : *ExpectedList) {
+ auto ExpectedStack = File.getRawData(T.Stack.Memory);
+ if (!ExpectedStack)
+ return ExpectedStack.takeError();
+ auto ExpectedContext = File.getRawData(T.Context);
+ if (!ExpectedContext)
+ return ExpectedContext.takeError();
+ Threads.push_back({T, *ExpectedStack, *ExpectedContext});
+ }
+ return llvm::make_unique<ThreadListStream>(std::move(Threads));
+ }
+ }
+ llvm_unreachable("Unhandled stream kind!");
+}
+
+Expected<Object> Object::create(const object::MinidumpFile &File) {
+ std::vector<std::unique_ptr<Stream>> Streams;
+ Streams.reserve(File.streams().size());
+ for (const Directory &StreamDesc : File.streams()) {
+ auto ExpectedStream = Stream::create(StreamDesc, File);
+ if (!ExpectedStream)
+ return ExpectedStream.takeError();
+ Streams.push_back(std::move(*ExpectedStream));
+ }
+ return Object(File.header(), std::move(Streams));
+}
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/ObjectYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/ObjectYAML.cpp
new file mode 100644
index 000000000000..7f636f4eabac
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/ObjectYAML.cpp
@@ -0,0 +1,63 @@
+//===- ObjectYAML.cpp - YAML utilities for object files -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a wrapper class for handling tagged YAML input
+//
+//===----------------------------------------------------------------------===//
+
+#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;
+
+void MappingTraits<YamlObjectFile>::mapping(IO &IO,
+ YamlObjectFile &ObjectFile) {
+ if (IO.outputting()) {
+ if (ObjectFile.Elf)
+ MappingTraits<ELFYAML::Object>::mapping(IO, *ObjectFile.Elf);
+ if (ObjectFile.Coff)
+ MappingTraits<COFFYAML::Object>::mapping(IO, *ObjectFile.Coff);
+ if (ObjectFile.MachO)
+ MappingTraits<MachOYAML::Object>::mapping(IO, *ObjectFile.MachO);
+ if (ObjectFile.FatMachO)
+ MappingTraits<MachOYAML::UniversalBinary>::mapping(IO,
+ *ObjectFile.FatMachO);
+ } else {
+ Input &In = (Input &)IO;
+ if (IO.mapTag("!ELF")) {
+ ObjectFile.Elf.reset(new ELFYAML::Object());
+ MappingTraits<ELFYAML::Object>::mapping(IO, *ObjectFile.Elf);
+ } else if (IO.mapTag("!COFF")) {
+ ObjectFile.Coff.reset(new COFFYAML::Object());
+ MappingTraits<COFFYAML::Object>::mapping(IO, *ObjectFile.Coff);
+ } else if (IO.mapTag("!mach-o")) {
+ ObjectFile.MachO.reset(new MachOYAML::Object());
+ MappingTraits<MachOYAML::Object>::mapping(IO, *ObjectFile.MachO);
+ } else if (IO.mapTag("!fat-mach-o")) {
+ ObjectFile.FatMachO.reset(new MachOYAML::UniversalBinary());
+ MappingTraits<MachOYAML::UniversalBinary>::mapping(IO,
+ *ObjectFile.FatMachO);
+ } else if (IO.mapTag("!minidump")) {
+ ObjectFile.Minidump.reset(new MinidumpYAML::Object());
+ MappingTraits<MinidumpYAML::Object>::mapping(IO, *ObjectFile.Minidump);
+ } else if (IO.mapTag("!WASM")) {
+ ObjectFile.Wasm.reset(new WasmYAML::Object());
+ MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm);
+ } else if (const Node *N = In.getCurrentNode()) {
+ if (N->getRawTag().empty())
+ IO.setError("YAML Object File missing document type tag!");
+ else
+ IO.setError("YAML Object File unsupported document type tag '" +
+ N->getRawTag() + "'!");
+ }
+ }
+}
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/WasmYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/WasmYAML.cpp
new file mode 100644
index 000000000000..88491d955c49
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -0,0 +1,605 @@
+//===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// 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::DylinkSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapRequired("MemorySize", Section.MemorySize);
+ IO.mapRequired("MemoryAlignment", Section.MemoryAlignment);
+ IO.mapRequired("TableSize", Section.TableSize);
+ IO.mapRequired("TableAlignment", Section.TableAlignment);
+ IO.mapRequired("Needed", Section.Needed);
+}
+
+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("Version", Section.Version);
+ IO.mapOptional("SymbolTable", Section.SymbolTable);
+ IO.mapOptional("SegmentInfo", Section.SegmentInfos);
+ IO.mapOptional("InitFunctions", Section.InitFunctions);
+ IO.mapOptional("Comdats", Section.Comdats);
+}
+
+static void sectionMapping(IO &IO, WasmYAML::ProducersSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapOptional("Languages", Section.Languages);
+ IO.mapOptional("Tools", Section.Tools);
+ IO.mapOptional("SDKs", Section.SDKs);
+}
+
+static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapRequired("Features", Section.Features);
+}
+
+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::EventSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Events", Section.Events);
+}
+
+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);
+}
+
+static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Count", Section.Count);
+}
+
+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 == "dylink") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::DylinkSection());
+ sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get()));
+ } else 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 (SectionName == "producers") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::ProducersSection());
+ sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
+ } else if (SectionName == "target_features") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::TargetFeaturesSection());
+ sectionMapping(IO, *cast<WasmYAML::TargetFeaturesSection>(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_EVENT:
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::EventSection());
+ sectionMapping(IO, *cast<WasmYAML::EventSection>(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;
+ case wasm::WASM_SEC_DATACOUNT:
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::DataCountSection());
+ sectionMapping(IO, *cast<WasmYAML::DataCountSection>(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(EVENT);
+ ECase(EXPORT);
+ ECase(START);
+ ECase(ELEM);
+ ECase(CODE);
+ ECase(DATA);
+ ECase(DATACOUNT);
+#undef ECase
+}
+
+void MappingTraits<WasmYAML::Signature>::mapping(
+ IO &IO, WasmYAML::Signature &Signature) {
+ IO.mapRequired("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("Index", Function.Index);
+ 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::ProducerEntry>::mapping(
+ IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
+ IO.mapRequired("Name", ProducerEntry.Name);
+ IO.mapRequired("Version", ProducerEntry.Version);
+}
+
+void ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix>::enumeration(
+ IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X);
+ ECase(USED);
+ ECase(REQUIRED);
+ ECase(DISALLOWED);
+#undef ECase
+}
+
+void MappingTraits<WasmYAML::FeatureEntry>::mapping(
+ IO &IO, WasmYAML::FeatureEntry &FeatureEntry) {
+ IO.mapRequired("Prefix", FeatureEntry.Prefix);
+ IO.mapRequired("Name", FeatureEntry.Name);
+}
+
+void MappingTraits<WasmYAML::SegmentInfo>::mapping(
+ IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
+ IO.mapRequired("Index", SegmentInfo.Index);
+ IO.mapRequired("Name", SegmentInfo.Name);
+ IO.mapRequired("Alignment", SegmentInfo.Alignment);
+ IO.mapRequired("Flags", SegmentInfo.Flags);
+}
+
+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_EVENT) {
+ IO.mapRequired("EventAttribute", Import.EventImport.Attribute);
+ IO.mapRequired("EventSigIndex", Import.EventImport.SigIndex);
+ } 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("Index", Global.Index);
+ 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_GLOBAL_GET:
+ IO.mapRequired("Index", Expr.Value.Global);
+ break;
+ }
+}
+
+void MappingTraits<WasmYAML::DataSegment>::mapping(
+ IO &IO, WasmYAML::DataSegment &Segment) {
+ IO.mapOptional("SectionOffset", Segment.SectionOffset);
+ IO.mapRequired("InitFlags", Segment.InitFlags);
+ if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) {
+ IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
+ } else {
+ Segment.MemoryIndex = 0;
+ }
+ if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) {
+ IO.mapRequired("Offset", Segment.Offset);
+ } else {
+ Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
+ Segment.Offset.Value.Int32 = 0;
+ }
+ IO.mapRequired("Content", Segment.Content);
+}
+
+void MappingTraits<WasmYAML::InitFunction>::mapping(
+ IO &IO, WasmYAML::InitFunction &Init) {
+ IO.mapRequired("Priority", Init.Priority);
+ IO.mapRequired("Symbol", Init.Symbol);
+}
+
+void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
+ IO &IO, WasmYAML::ComdatKind &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
+ ECase(FUNCTION);
+ ECase(DATA);
+#undef ECase
+}
+
+void MappingTraits<WasmYAML::ComdatEntry>::mapping(
+ IO &IO, WasmYAML::ComdatEntry &ComdatEntry) {
+ IO.mapRequired("Kind", ComdatEntry.Kind);
+ IO.mapRequired("Index", ComdatEntry.Index);
+}
+
+void MappingTraits<WasmYAML::Comdat>::mapping(IO &IO,
+ WasmYAML::Comdat &Comdat) {
+ IO.mapRequired("Name", Comdat.Name);
+ IO.mapRequired("Entries", Comdat.Entries);
+}
+
+void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
+ WasmYAML::SymbolInfo &Info) {
+ IO.mapRequired("Index", Info.Index);
+ IO.mapRequired("Kind", Info.Kind);
+ if (Info.Kind != wasm::WASM_SYMBOL_TYPE_SECTION)
+ IO.mapRequired("Name", Info.Name);
+ IO.mapRequired("Flags", Info.Flags);
+ if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
+ IO.mapRequired("Function", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
+ IO.mapRequired("Global", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
+ IO.mapRequired("Event", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
+ IO.mapRequired("Segment", Info.DataRef.Segment);
+ IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
+ IO.mapRequired("Size", Info.DataRef.Size);
+ }
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) {
+ IO.mapRequired("Section", Info.ElementIndex);
+ } else {
+ llvm_unreachable("unsupported symbol kind");
+ }
+}
+
+void MappingTraits<WasmYAML::Event>::mapping(IO &IO, WasmYAML::Event &Event) {
+ IO.mapRequired("Index", Event.Index);
+ IO.mapRequired("Attribute", Event.Attribute);
+ IO.mapRequired("SigIndex", Event.SigIndex);
+}
+
+void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
+ IO &IO, WasmYAML::LimitFlags &Value) {
+#define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
+ BCase(HAS_MAX);
+ BCase(IS_SHARED);
+#undef BCase
+}
+
+void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset(
+ IO &IO, WasmYAML::SegmentFlags &Value) {}
+
+void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
+ IO &IO, WasmYAML::SymbolFlags &Value) {
+#define BCaseMask(M, X) \
+ IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
+ // BCaseMask(BINDING_MASK, BINDING_GLOBAL);
+ BCaseMask(BINDING_MASK, BINDING_WEAK);
+ BCaseMask(BINDING_MASK, BINDING_LOCAL);
+ // BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
+ BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
+ BCaseMask(UNDEFINED, UNDEFINED);
+ BCaseMask(EXPORTED, EXPORTED);
+ BCaseMask(EXPLICIT_NAME, EXPLICIT_NAME);
+#undef BCaseMask
+}
+
+void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
+ IO &IO, WasmYAML::SymbolKind &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
+ ECase(FUNCTION);
+ ECase(DATA);
+ ECase(GLOBAL);
+ ECase(SECTION);
+ ECase(EVENT);
+#undef ECase
+}
+
+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(V128);
+ ECase(FUNCREF);
+ 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);
+ ECase(EVENT);
+#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(GLOBAL_GET);
+#undef ECase
+}
+
+void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration(
+ IO &IO, WasmYAML::TableType &Type) {
+#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
+ ECase(FUNCREF);
+#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.def"
+#undef WASM_RELOC
+}
+
+} // end namespace yaml
+
+} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/XCOFFYAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/XCOFFYAML.cpp
new file mode 100644
index 000000000000..982e6aecbb98
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/XCOFFYAML.cpp
@@ -0,0 +1,109 @@
+//===-- XCOFFYAML.cpp - XCOFF YAMLIO implementation -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of XCOFF.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/XCOFFYAML.h"
+#include "llvm/BinaryFormat/XCOFF.h"
+#include <string.h>
+
+namespace llvm {
+namespace XCOFFYAML {
+
+Object::Object() { memset(&Header, 0, sizeof(Header)); }
+
+} // namespace XCOFFYAML
+
+namespace yaml {
+
+void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
+ IO &IO, XCOFF::StorageClass &Value) {
+#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
+ ECase(C_NULL);
+ ECase(C_AUTO);
+ ECase(C_EXT);
+ ECase(C_STAT);
+ ECase(C_REG);
+ ECase(C_EXTDEF);
+ ECase(C_LABEL);
+ ECase(C_ULABEL);
+ ECase(C_MOS);
+ ECase(C_ARG);
+ ECase(C_STRTAG);
+ ECase(C_MOU);
+ ECase(C_UNTAG);
+ ECase(C_TPDEF);
+ ECase(C_USTATIC);
+ ECase(C_ENTAG);
+ ECase(C_MOE);
+ ECase(C_REGPARM);
+ ECase(C_FIELD);
+ ECase(C_BLOCK);
+ ECase(C_FCN);
+ ECase(C_EOS);
+ ECase(C_FILE);
+ ECase(C_LINE);
+ ECase(C_ALIAS);
+ ECase(C_HIDDEN);
+ ECase(C_HIDEXT);
+ ECase(C_BINCL);
+ ECase(C_EINCL);
+ ECase(C_INFO);
+ ECase(C_WEAKEXT);
+ ECase(C_DWARF);
+ ECase(C_GSYM);
+ ECase(C_LSYM);
+ ECase(C_PSYM);
+ ECase(C_RSYM);
+ ECase(C_RPSYM);
+ ECase(C_STSYM);
+ ECase(C_TCSYM);
+ ECase(C_BCOMM);
+ ECase(C_ECOML);
+ ECase(C_ECOMM);
+ ECase(C_DECL);
+ ECase(C_ENTRY);
+ ECase(C_FUN);
+ ECase(C_BSTAT);
+ ECase(C_ESTAT);
+ ECase(C_GTLS);
+ ECase(C_STTLS);
+ ECase(C_EFCN);
+#undef ECase
+}
+
+void MappingTraits<XCOFFYAML::FileHeader>::mapping(
+ IO &IO, XCOFFYAML::FileHeader &FileHdr) {
+ IO.mapRequired("MagicNumber", FileHdr.Magic);
+ IO.mapRequired("NumberOfSections", FileHdr.NumberOfSections);
+ IO.mapRequired("CreationTime", FileHdr.TimeStamp);
+ IO.mapRequired("OffsetToSymbolTable", FileHdr.SymbolTableOffset);
+ IO.mapRequired("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries);
+ IO.mapRequired("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize);
+ IO.mapRequired("Flags", FileHdr.Flags);
+}
+
+void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
+ IO.mapRequired("Name", S.SymbolName);
+ IO.mapRequired("Value", S.Value);
+ IO.mapRequired("Section", S.SectionName);
+ IO.mapRequired("Type", S.Type);
+ IO.mapRequired("StorageClass", S.StorageClass);
+ IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries);
+}
+
+void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) {
+ IO.mapTag("!XCOFF", true);
+ IO.mapRequired("FileHeader", Obj.Header);
+ IO.mapRequired("Symbols", Obj.Symbols);
+}
+
+} // namespace yaml
+} // namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/ObjectYAML/YAML.cpp b/contrib/llvm-project/llvm/lib/ObjectYAML/YAML.cpp
new file mode 100644
index 000000000000..6eba16e36c2a
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/ObjectYAML/YAML.cpp
@@ -0,0 +1,62 @@
+//===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utility classes for handling the YAML representation of
+// object files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/YAML.h"
+#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 *, raw_ostream &Out) {
+ Val.writeAsHex(Out);
+}
+
+StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *,
+ yaml::BinaryRef &Val) {
+ if (Scalar.size() % 2 != 0)
+ return "BinaryRef hex string must contain an even number of nybbles.";
+ // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
+ // (e.g. a caret pointing to the offending character).
+ for (unsigned I = 0, N = Scalar.size(); I != N; ++I)
+ if (!llvm::isHexDigit(Scalar[I]))
+ return "BinaryRef hex string must contain only hex digits.";
+ Val = yaml::BinaryRef(Scalar);
+ return {};
+}
+
+void yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const {
+ if (!DataIsHexString) {
+ OS.write((const char *)Data.data(), Data.size());
+ return;
+ }
+ for (unsigned I = 0, N = Data.size(); I != N; I += 2) {
+ uint8_t Byte = llvm::hexDigitValue(Data[I]);
+ Byte <<= 4;
+ Byte |= llvm::hexDigitValue(Data[I + 1]);
+ OS.write(Byte);
+ }
+}
+
+void yaml::BinaryRef::writeAsHex(raw_ostream &OS) const {
+ if (binary_size() == 0)
+ return;
+ if (DataIsHexString) {
+ OS.write((const char *)Data.data(), Data.size());
+ return;
+ }
+ for (uint8_t Byte : Data)
+ OS << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
+}