aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/BinaryFormat
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/BinaryFormat')
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/AMDGPUMetadataVerifier.cpp321
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/COFF.cpp57
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/DXContainer.cpp30
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp821
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/ELF.cpp570
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MachO.cpp107
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Magic.cpp262
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Minidump.cpp14
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocument.cpp314
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp248
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp255
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp210
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Wasm.cpp86
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/XCOFF.cpp277
14 files changed, 3572 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/AMDGPUMetadataVerifier.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/AMDGPUMetadataVerifier.cpp
new file mode 100644
index 000000000000..35a79ec04b6e
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/AMDGPUMetadataVerifier.cpp
@@ -0,0 +1,321 @@
+//===- AMDGPUMetadataVerifier.cpp - MsgPack Types ---------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Implements a verifier for AMDGPU HSA metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/MsgPackDocument.h"
+
+#include <map>
+#include <utility>
+
+namespace llvm {
+namespace AMDGPU {
+namespace HSAMD {
+namespace V3 {
+
+bool MetadataVerifier::verifyScalar(
+ msgpack::DocNode &Node, msgpack::Type SKind,
+ function_ref<bool(msgpack::DocNode &)> verifyValue) {
+ if (!Node.isScalar())
+ return false;
+ if (Node.getKind() != SKind) {
+ if (Strict)
+ return false;
+ // If we are not strict, we interpret string values as "implicitly typed"
+ // and attempt to coerce them to the expected type here.
+ if (Node.getKind() != msgpack::Type::String)
+ return false;
+ StringRef StringValue = Node.getString();
+ Node.fromString(StringValue);
+ if (Node.getKind() != SKind)
+ return false;
+ }
+ if (verifyValue)
+ return verifyValue(Node);
+ return true;
+}
+
+bool MetadataVerifier::verifyInteger(msgpack::DocNode &Node) {
+ if (!verifyScalar(Node, msgpack::Type::UInt))
+ if (!verifyScalar(Node, msgpack::Type::Int))
+ return false;
+ return true;
+}
+
+bool MetadataVerifier::verifyArray(
+ msgpack::DocNode &Node, function_ref<bool(msgpack::DocNode &)> verifyNode,
+ std::optional<size_t> Size) {
+ if (!Node.isArray())
+ return false;
+ auto &Array = Node.getArray();
+ if (Size && Array.size() != *Size)
+ return false;
+ return llvm::all_of(Array, verifyNode);
+}
+
+bool MetadataVerifier::verifyEntry(
+ msgpack::MapDocNode &MapNode, StringRef Key, bool Required,
+ function_ref<bool(msgpack::DocNode &)> verifyNode) {
+ auto Entry = MapNode.find(Key);
+ if (Entry == MapNode.end())
+ return !Required;
+ return verifyNode(Entry->second);
+}
+
+bool MetadataVerifier::verifyScalarEntry(
+ msgpack::MapDocNode &MapNode, StringRef Key, bool Required,
+ msgpack::Type SKind,
+ function_ref<bool(msgpack::DocNode &)> verifyValue) {
+ return verifyEntry(MapNode, Key, Required, [=](msgpack::DocNode &Node) {
+ return verifyScalar(Node, SKind, verifyValue);
+ });
+}
+
+bool MetadataVerifier::verifyIntegerEntry(msgpack::MapDocNode &MapNode,
+ StringRef Key, bool Required) {
+ return verifyEntry(MapNode, Key, Required, [this](msgpack::DocNode &Node) {
+ return verifyInteger(Node);
+ });
+}
+
+bool MetadataVerifier::verifyKernelArgs(msgpack::DocNode &Node) {
+ if (!Node.isMap())
+ return false;
+ auto &ArgsMap = Node.getMap();
+
+ if (!verifyScalarEntry(ArgsMap, ".name", false,
+ msgpack::Type::String))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".type_name", false,
+ msgpack::Type::String))
+ return false;
+ if (!verifyIntegerEntry(ArgsMap, ".size", true))
+ return false;
+ if (!verifyIntegerEntry(ArgsMap, ".offset", true))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".value_kind", true, msgpack::Type::String,
+ [](msgpack::DocNode &SNode) {
+ return StringSwitch<bool>(SNode.getString())
+ .Case("by_value", true)
+ .Case("global_buffer", true)
+ .Case("dynamic_shared_pointer", true)
+ .Case("sampler", true)
+ .Case("image", true)
+ .Case("pipe", true)
+ .Case("queue", true)
+ .Case("hidden_block_count_x", true)
+ .Case("hidden_block_count_y", true)
+ .Case("hidden_block_count_z", true)
+ .Case("hidden_group_size_x", true)
+ .Case("hidden_group_size_y", true)
+ .Case("hidden_group_size_z", true)
+ .Case("hidden_remainder_x", true)
+ .Case("hidden_remainder_y", true)
+ .Case("hidden_remainder_z", true)
+ .Case("hidden_global_offset_x", true)
+ .Case("hidden_global_offset_y", true)
+ .Case("hidden_global_offset_z", true)
+ .Case("hidden_grid_dims", true)
+ .Case("hidden_none", true)
+ .Case("hidden_printf_buffer", true)
+ .Case("hidden_hostcall_buffer", true)
+ .Case("hidden_heap_v1", true)
+ .Case("hidden_default_queue", true)
+ .Case("hidden_completion_action", true)
+ .Case("hidden_multigrid_sync_arg", true)
+ .Case("hidden_private_base", true)
+ .Case("hidden_shared_base", true)
+ .Case("hidden_queue_ptr", true)
+ .Default(false);
+ }))
+ return false;
+ if (!verifyIntegerEntry(ArgsMap, ".pointee_align", false))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".address_space", false,
+ msgpack::Type::String,
+ [](msgpack::DocNode &SNode) {
+ return StringSwitch<bool>(SNode.getString())
+ .Case("private", true)
+ .Case("global", true)
+ .Case("constant", true)
+ .Case("local", true)
+ .Case("generic", true)
+ .Case("region", true)
+ .Default(false);
+ }))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".access", false,
+ msgpack::Type::String,
+ [](msgpack::DocNode &SNode) {
+ return StringSwitch<bool>(SNode.getString())
+ .Case("read_only", true)
+ .Case("write_only", true)
+ .Case("read_write", true)
+ .Default(false);
+ }))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".actual_access", false,
+ msgpack::Type::String,
+ [](msgpack::DocNode &SNode) {
+ return StringSwitch<bool>(SNode.getString())
+ .Case("read_only", true)
+ .Case("write_only", true)
+ .Case("read_write", true)
+ .Default(false);
+ }))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".is_const", false,
+ msgpack::Type::Boolean))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".is_restrict", false,
+ msgpack::Type::Boolean))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".is_volatile", false,
+ msgpack::Type::Boolean))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".is_pipe", false,
+ msgpack::Type::Boolean))
+ return false;
+
+ return true;
+}
+
+bool MetadataVerifier::verifyKernel(msgpack::DocNode &Node) {
+ if (!Node.isMap())
+ return false;
+ auto &KernelMap = Node.getMap();
+
+ if (!verifyScalarEntry(KernelMap, ".name", true,
+ msgpack::Type::String))
+ return false;
+ if (!verifyScalarEntry(KernelMap, ".symbol", true,
+ msgpack::Type::String))
+ return false;
+ if (!verifyScalarEntry(KernelMap, ".language", false,
+ msgpack::Type::String,
+ [](msgpack::DocNode &SNode) {
+ return StringSwitch<bool>(SNode.getString())
+ .Case("OpenCL C", true)
+ .Case("OpenCL C++", true)
+ .Case("HCC", true)
+ .Case("HIP", true)
+ .Case("OpenMP", true)
+ .Case("Assembler", true)
+ .Default(false);
+ }))
+ return false;
+ if (!verifyEntry(
+ KernelMap, ".language_version", false, [this](msgpack::DocNode &Node) {
+ return verifyArray(
+ Node,
+ [this](msgpack::DocNode &Node) { return verifyInteger(Node); }, 2);
+ }))
+ return false;
+ if (!verifyEntry(KernelMap, ".args", false, [this](msgpack::DocNode &Node) {
+ return verifyArray(Node, [this](msgpack::DocNode &Node) {
+ return verifyKernelArgs(Node);
+ });
+ }))
+ return false;
+ if (!verifyEntry(KernelMap, ".reqd_workgroup_size", false,
+ [this](msgpack::DocNode &Node) {
+ return verifyArray(Node,
+ [this](msgpack::DocNode &Node) {
+ return verifyInteger(Node);
+ },
+ 3);
+ }))
+ return false;
+ if (!verifyEntry(KernelMap, ".workgroup_size_hint", false,
+ [this](msgpack::DocNode &Node) {
+ return verifyArray(Node,
+ [this](msgpack::DocNode &Node) {
+ return verifyInteger(Node);
+ },
+ 3);
+ }))
+ return false;
+ if (!verifyScalarEntry(KernelMap, ".vec_type_hint", false,
+ msgpack::Type::String))
+ return false;
+ if (!verifyScalarEntry(KernelMap, ".device_enqueue_symbol", false,
+ msgpack::Type::String))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".kernarg_segment_size", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".group_segment_fixed_size", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".private_segment_fixed_size", true))
+ return false;
+ if (!verifyScalarEntry(KernelMap, ".uses_dynamic_stack", false,
+ msgpack::Type::Boolean))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".workgroup_processor_mode", false))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".kernarg_segment_align", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".wavefront_size", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".sgpr_count", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".vgpr_count", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".max_flat_workgroup_size", true))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".sgpr_spill_count", false))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".vgpr_spill_count", false))
+ return false;
+ if (!verifyIntegerEntry(KernelMap, ".uniform_work_group_size", false))
+ return false;
+
+
+ return true;
+}
+
+bool MetadataVerifier::verify(msgpack::DocNode &HSAMetadataRoot) {
+ if (!HSAMetadataRoot.isMap())
+ return false;
+ auto &RootMap = HSAMetadataRoot.getMap();
+
+ if (!verifyEntry(
+ RootMap, "amdhsa.version", true, [this](msgpack::DocNode &Node) {
+ return verifyArray(
+ Node,
+ [this](msgpack::DocNode &Node) { return verifyInteger(Node); }, 2);
+ }))
+ return false;
+ if (!verifyEntry(
+ RootMap, "amdhsa.printf", false, [this](msgpack::DocNode &Node) {
+ return verifyArray(Node, [this](msgpack::DocNode &Node) {
+ return verifyScalar(Node, msgpack::Type::String);
+ });
+ }))
+ return false;
+ if (!verifyEntry(RootMap, "amdhsa.kernels", true,
+ [this](msgpack::DocNode &Node) {
+ return verifyArray(Node, [this](msgpack::DocNode &Node) {
+ return verifyKernel(Node);
+ });
+ }))
+ return false;
+
+ return true;
+}
+
+} // end namespace V3
+} // end namespace HSAMD
+} // end namespace AMDGPU
+} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/COFF.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/COFF.cpp
new file mode 100644
index 000000000000..8fbee0218b79
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/COFF.cpp
@@ -0,0 +1,57 @@
+//===- llvm/BinaryFormat/COFF.cpp - The COFF format -----------------------===//
+//
+// 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/BinaryFormat/COFF.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+
+// Maximum offsets for different string table entry encodings.
+enum : unsigned { Max7DecimalOffset = 9999999U };
+enum : uint64_t { MaxBase64Offset = 0xFFFFFFFFFULL }; // 64^6, including 0
+
+// Encode a string table entry offset in base 64, padded to 6 chars, and
+// prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
+// Buffer must be at least 8 bytes large. No terminating null appended.
+static void encodeBase64StringEntry(char *Buffer, uint64_t Value) {
+ assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
+ "Illegal section name encoding for value");
+
+ static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+ Buffer[0] = '/';
+ Buffer[1] = '/';
+
+ char *Ptr = Buffer + 7;
+ for (unsigned i = 0; i < 6; ++i) {
+ unsigned Rem = Value % 64;
+ Value /= 64;
+ *(Ptr--) = Alphabet[Rem];
+ }
+}
+
+bool llvm::COFF::encodeSectionName(char *Out, uint64_t Offset) {
+ if (Offset <= Max7DecimalOffset) {
+ // Offsets of 7 digits or less are encoded in ASCII.
+ SmallVector<char, COFF::NameSize> Buffer;
+ Twine('/').concat(Twine(Offset)).toVector(Buffer);
+ assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
+ std::memcpy(Out, Buffer.data(), Buffer.size());
+ return true;
+ }
+
+ if (Offset <= MaxBase64Offset) {
+ // Starting with 10,000,000, offsets are encoded as base64.
+ encodeBase64StringEntry(Out, Offset);
+ return true;
+ }
+
+ // The offset is too large to be encoded.
+ return false;
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/DXContainer.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/DXContainer.cpp
new file mode 100644
index 000000000000..60a89c66d28c
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/DXContainer.cpp
@@ -0,0 +1,30 @@
+
+//===-- llvm/BinaryFormat/DXContainer.cpp - DXContainer Utils ----*- 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 contains utility functions for working with DXContainers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace llvm;
+using namespace llvm::dxbc;
+
+dxbc::PartType dxbc::parsePartType(StringRef S) {
+#define CONTAINER_PART(PartName) .Case(#PartName, PartType::PartName)
+ return StringSwitch<dxbc::PartType>(S)
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ .Default(dxbc::PartType::Unknown);
+}
+
+bool ShaderHash::isPopulated() {
+ static uint8_t Zeros[16] = {0};
+ return Flags > 0 || 0 != memcmp(&Digest, &Zeros, 16);
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp
new file mode 100644
index 000000000000..a9bbe41125b1
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -0,0 +1,821 @@
+//===-- llvm/BinaryFormat/Dwarf.cpp - Dwarf Framework ------------*- 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 contains support for generic dwarf information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+using namespace dwarf;
+
+StringRef llvm::dwarf::TagString(unsigned Tag) {
+ switch (Tag) {
+ default:
+ return StringRef();
+#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
+ case DW_TAG_##NAME: \
+ return "DW_TAG_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getTag(StringRef TagString) {
+ return StringSwitch<unsigned>(TagString)
+#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
+ .Case("DW_TAG_" #NAME, DW_TAG_##NAME)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Default(DW_TAG_invalid);
+}
+
+unsigned llvm::dwarf::TagVersion(dwarf::Tag Tag) {
+ switch (Tag) {
+ default:
+ return 0;
+#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
+ case DW_TAG_##NAME: \
+ return VERSION;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::TagVendor(dwarf::Tag Tag) {
+ switch (Tag) {
+ default:
+ return 0;
+#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
+ case DW_TAG_##NAME: \
+ return DWARF_VENDOR_##VENDOR;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::ChildrenString(unsigned Children) {
+ switch (Children) {
+ case DW_CHILDREN_no:
+ return "DW_CHILDREN_no";
+ case DW_CHILDREN_yes:
+ return "DW_CHILDREN_yes";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::AttributeString(unsigned Attribute) {
+ switch (Attribute) {
+ default:
+ return StringRef();
+#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
+ case DW_AT_##NAME: \
+ return "DW_AT_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::AttributeVersion(dwarf::Attribute Attribute) {
+ switch (Attribute) {
+ default:
+ return 0;
+#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
+ case DW_AT_##NAME: \
+ return VERSION;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::AttributeVendor(dwarf::Attribute Attribute) {
+ switch (Attribute) {
+ default:
+ return 0;
+#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
+ case DW_AT_##NAME: \
+ return DWARF_VENDOR_##VENDOR;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::FormEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
+ case DW_FORM_##NAME: \
+ return "DW_FORM_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::FormVersion(dwarf::Form Form) {
+ switch (Form) {
+ default:
+ return 0;
+#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
+ case DW_FORM_##NAME: \
+ return VERSION;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::FormVendor(dwarf::Form Form) {
+ switch (Form) {
+ default:
+ return 0;
+#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
+ case DW_FORM_##NAME: \
+ return DWARF_VENDOR_##VENDOR;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
+ case DW_OP_##NAME: \
+ return "DW_OP_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ case DW_OP_LLVM_convert:
+ return "DW_OP_LLVM_convert";
+ case DW_OP_LLVM_fragment:
+ return "DW_OP_LLVM_fragment";
+ case DW_OP_LLVM_tag_offset:
+ return "DW_OP_LLVM_tag_offset";
+ case DW_OP_LLVM_entry_value:
+ return "DW_OP_LLVM_entry_value";
+ case DW_OP_LLVM_implicit_pointer:
+ return "DW_OP_LLVM_implicit_pointer";
+ case DW_OP_LLVM_arg:
+ return "DW_OP_LLVM_arg";
+ }
+}
+
+unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
+ return StringSwitch<unsigned>(OperationEncodingString)
+#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
+ .Case("DW_OP_" #NAME, DW_OP_##NAME)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Case("DW_OP_LLVM_convert", DW_OP_LLVM_convert)
+ .Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
+ .Case("DW_OP_LLVM_tag_offset", DW_OP_LLVM_tag_offset)
+ .Case("DW_OP_LLVM_entry_value", DW_OP_LLVM_entry_value)
+ .Case("DW_OP_LLVM_implicit_pointer", DW_OP_LLVM_implicit_pointer)
+ .Case("DW_OP_LLVM_arg", DW_OP_LLVM_arg)
+ .Default(0);
+}
+
+unsigned llvm::dwarf::OperationVersion(dwarf::LocationAtom Op) {
+ switch (Op) {
+ default:
+ return 0;
+#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
+ case DW_OP_##NAME: \
+ return VERSION;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::OperationVendor(dwarf::LocationAtom Op) {
+ switch (Op) {
+ default:
+ return 0;
+#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
+ case DW_OP_##NAME: \
+ return DWARF_VENDOR_##VENDOR;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
+ case DW_ATE_##NAME: \
+ return "DW_ATE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
+ return StringSwitch<unsigned>(EncodingString)
+#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
+ .Case("DW_ATE_" #NAME, DW_ATE_##NAME)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Default(0);
+}
+
+unsigned llvm::dwarf::AttributeEncodingVersion(dwarf::TypeKind ATE) {
+ switch (ATE) {
+ default:
+ return 0;
+#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
+ case DW_ATE_##NAME: \
+ return VERSION;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::AttributeEncodingVendor(dwarf::TypeKind ATE) {
+ switch (ATE) {
+ default:
+ return 0;
+#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
+ case DW_ATE_##NAME: \
+ return DWARF_VENDOR_##VENDOR;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::DecimalSignString(unsigned Sign) {
+ switch (Sign) {
+ case DW_DS_unsigned:
+ return "DW_DS_unsigned";
+ case DW_DS_leading_overpunch:
+ return "DW_DS_leading_overpunch";
+ case DW_DS_trailing_overpunch:
+ return "DW_DS_trailing_overpunch";
+ case DW_DS_leading_separate:
+ return "DW_DS_leading_separate";
+ case DW_DS_trailing_separate:
+ return "DW_DS_trailing_separate";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::EndianityString(unsigned Endian) {
+ switch (Endian) {
+ case DW_END_default:
+ return "DW_END_default";
+ case DW_END_big:
+ return "DW_END_big";
+ case DW_END_little:
+ return "DW_END_little";
+ case DW_END_lo_user:
+ return "DW_END_lo_user";
+ case DW_END_hi_user:
+ return "DW_END_hi_user";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::AccessibilityString(unsigned Access) {
+ switch (Access) {
+ // Accessibility codes
+ case DW_ACCESS_public:
+ return "DW_ACCESS_public";
+ case DW_ACCESS_protected:
+ return "DW_ACCESS_protected";
+ case DW_ACCESS_private:
+ return "DW_ACCESS_private";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::DefaultedMemberString(unsigned DefaultedEncodings) {
+ switch (DefaultedEncodings) {
+ // Defaulted Member Encodings codes
+ case DW_DEFAULTED_no:
+ return "DW_DEFAULTED_no";
+ case DW_DEFAULTED_in_class:
+ return "DW_DEFAULTED_in_class";
+ case DW_DEFAULTED_out_of_class:
+ return "DW_DEFAULTED_out_of_class";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::VisibilityString(unsigned Visibility) {
+ switch (Visibility) {
+ case DW_VIS_local:
+ return "DW_VIS_local";
+ case DW_VIS_exported:
+ return "DW_VIS_exported";
+ case DW_VIS_qualified:
+ return "DW_VIS_qualified";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::VirtualityString(unsigned Virtuality) {
+ switch (Virtuality) {
+ default:
+ return StringRef();
+#define HANDLE_DW_VIRTUALITY(ID, NAME) \
+ case DW_VIRTUALITY_##NAME: \
+ return "DW_VIRTUALITY_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getVirtuality(StringRef VirtualityString) {
+ return StringSwitch<unsigned>(VirtualityString)
+#define HANDLE_DW_VIRTUALITY(ID, NAME) \
+ .Case("DW_VIRTUALITY_" #NAME, DW_VIRTUALITY_##NAME)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Default(DW_VIRTUALITY_invalid);
+}
+
+StringRef llvm::dwarf::LanguageString(unsigned Language) {
+ switch (Language) {
+ default:
+ return StringRef();
+#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
+ case DW_LANG_##NAME: \
+ return "DW_LANG_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
+ return StringSwitch<unsigned>(LanguageString)
+#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
+ .Case("DW_LANG_" #NAME, DW_LANG_##NAME)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Default(0);
+}
+
+unsigned llvm::dwarf::LanguageVersion(dwarf::SourceLanguage Lang) {
+ switch (Lang) {
+ default:
+ return 0;
+#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
+ case DW_LANG_##NAME: \
+ return VERSION;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::LanguageVendor(dwarf::SourceLanguage Lang) {
+ switch (Lang) {
+ default:
+ return 0;
+#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
+ case DW_LANG_##NAME: \
+ return DWARF_VENDOR_##VENDOR;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+std::optional<unsigned>
+llvm::dwarf::LanguageLowerBound(dwarf::SourceLanguage Lang) {
+ switch (Lang) {
+ default:
+ return std::nullopt;
+#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
+ case DW_LANG_##NAME: \
+ return LOWER_BOUND;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::CaseString(unsigned Case) {
+ switch (Case) {
+ case DW_ID_case_sensitive:
+ return "DW_ID_case_sensitive";
+ case DW_ID_up_case:
+ return "DW_ID_up_case";
+ case DW_ID_down_case:
+ return "DW_ID_down_case";
+ case DW_ID_case_insensitive:
+ return "DW_ID_case_insensitive";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::ConventionString(unsigned CC) {
+ switch (CC) {
+ default:
+ return StringRef();
+#define HANDLE_DW_CC(ID, NAME) \
+ case DW_CC_##NAME: \
+ return "DW_CC_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getCallingConvention(StringRef CCString) {
+ return StringSwitch<unsigned>(CCString)
+#define HANDLE_DW_CC(ID, NAME) .Case("DW_CC_" #NAME, DW_CC_##NAME)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Default(0);
+}
+
+StringRef llvm::dwarf::InlineCodeString(unsigned Code) {
+ switch (Code) {
+ case DW_INL_not_inlined:
+ return "DW_INL_not_inlined";
+ case DW_INL_inlined:
+ return "DW_INL_inlined";
+ case DW_INL_declared_not_inlined:
+ return "DW_INL_declared_not_inlined";
+ case DW_INL_declared_inlined:
+ return "DW_INL_declared_inlined";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::ArrayOrderString(unsigned Order) {
+ switch (Order) {
+ case DW_ORD_row_major:
+ return "DW_ORD_row_major";
+ case DW_ORD_col_major:
+ return "DW_ORD_col_major";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::LNStandardString(unsigned Standard) {
+ switch (Standard) {
+ default:
+ return StringRef();
+#define HANDLE_DW_LNS(ID, NAME) \
+ case DW_LNS_##NAME: \
+ return "DW_LNS_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::LNExtendedString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_LNE(ID, NAME) \
+ case DW_LNE_##NAME: \
+ return "DW_LNE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::MacinfoString(unsigned Encoding) {
+ switch (Encoding) {
+ // Macinfo Type Encodings
+ case DW_MACINFO_define:
+ return "DW_MACINFO_define";
+ case DW_MACINFO_undef:
+ return "DW_MACINFO_undef";
+ case DW_MACINFO_start_file:
+ return "DW_MACINFO_start_file";
+ case DW_MACINFO_end_file:
+ return "DW_MACINFO_end_file";
+ case DW_MACINFO_vendor_ext:
+ return "DW_MACINFO_vendor_ext";
+ case DW_MACINFO_invalid:
+ return "DW_MACINFO_invalid";
+ }
+ return StringRef();
+}
+
+unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) {
+ return StringSwitch<unsigned>(MacinfoString)
+ .Case("DW_MACINFO_define", DW_MACINFO_define)
+ .Case("DW_MACINFO_undef", DW_MACINFO_undef)
+ .Case("DW_MACINFO_start_file", DW_MACINFO_start_file)
+ .Case("DW_MACINFO_end_file", DW_MACINFO_end_file)
+ .Case("DW_MACINFO_vendor_ext", DW_MACINFO_vendor_ext)
+ .Default(DW_MACINFO_invalid);
+}
+
+StringRef llvm::dwarf::MacroString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_MACRO(ID, NAME) \
+ case DW_MACRO_##NAME: \
+ return "DW_MACRO_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::GnuMacroString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_MACRO_GNU(ID, NAME) \
+ case DW_MACRO_GNU_##NAME: \
+ return "DW_MACRO_GNU_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getMacro(StringRef MacroString) {
+ return StringSwitch<unsigned>(MacroString)
+#define HANDLE_DW_MACRO(ID, NAME) .Case("DW_MACRO_" #NAME, ID)
+#include "llvm/BinaryFormat/Dwarf.def"
+ .Default(DW_MACINFO_invalid);
+}
+StringRef llvm::dwarf::RangeListEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_RLE(ID, NAME) \
+ case DW_RLE_##NAME: \
+ return "DW_RLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::LocListEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_LLE(ID, NAME) \
+ case DW_LLE_##NAME: \
+ return "DW_LLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::CallFrameString(unsigned Encoding,
+ Triple::ArchType Arch) {
+ assert(Arch != llvm::Triple::ArchType::UnknownArch);
+#define SELECT_AARCH64 (Arch == llvm::Triple::aarch64_be || Arch == llvm::Triple::aarch64)
+#define SELECT_MIPS64 Arch == llvm::Triple::mips64
+#define SELECT_SPARC (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9)
+#define SELECT_X86 (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64)
+#define HANDLE_DW_CFA(ID, NAME)
+#define HANDLE_DW_CFA_PRED(ID, NAME, PRED) \
+ if (ID == Encoding && PRED) \
+ return "DW_CFA_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_CFA_PRED(ID, NAME, PRED)
+#define HANDLE_DW_CFA(ID, NAME) \
+ case DW_CFA_##NAME: \
+ return "DW_CFA_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+
+#undef SELECT_X86
+#undef SELECT_SPARC
+#undef SELECT_MIPS64
+#undef SELECT_AARCH64
+ }
+}
+
+StringRef llvm::dwarf::ApplePropertyString(unsigned Prop) {
+ switch (Prop) {
+ default:
+ return StringRef();
+#define HANDLE_DW_APPLE_PROPERTY(ID, NAME) \
+ case DW_APPLE_PROPERTY_##NAME: \
+ return "DW_APPLE_PROPERTY_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::UnitTypeString(unsigned UT) {
+ switch (UT) {
+ default:
+ return StringRef();
+#define HANDLE_DW_UT(ID, NAME) \
+ case DW_UT_##NAME: \
+ return "DW_UT_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+StringRef llvm::dwarf::AtomTypeString(unsigned AT) {
+ switch (AT) {
+ case dwarf::DW_ATOM_null:
+ return "DW_ATOM_null";
+ case dwarf::DW_ATOM_die_offset:
+ return "DW_ATOM_die_offset";
+ case DW_ATOM_cu_offset:
+ return "DW_ATOM_cu_offset";
+ case DW_ATOM_die_tag:
+ return "DW_ATOM_die_tag";
+ case DW_ATOM_type_flags:
+ case DW_ATOM_type_type_flags:
+ return "DW_ATOM_type_flags";
+ case DW_ATOM_qual_name_hash:
+ return "DW_ATOM_qual_name_hash";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) {
+ switch (Kind) {
+ case GIEK_NONE:
+ return "NONE";
+ case GIEK_TYPE:
+ return "TYPE";
+ case GIEK_VARIABLE:
+ return "VARIABLE";
+ case GIEK_FUNCTION:
+ return "FUNCTION";
+ case GIEK_OTHER:
+ return "OTHER";
+ case GIEK_UNUSED5:
+ return "UNUSED5";
+ case GIEK_UNUSED6:
+ return "UNUSED6";
+ case GIEK_UNUSED7:
+ return "UNUSED7";
+ }
+ llvm_unreachable("Unknown GDBIndexEntryKind value");
+}
+
+StringRef
+llvm::dwarf::GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage) {
+ switch (Linkage) {
+ case GIEL_EXTERNAL:
+ return "EXTERNAL";
+ case GIEL_STATIC:
+ return "STATIC";
+ }
+ llvm_unreachable("Unknown GDBIndexEntryLinkage value");
+}
+
+StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
+ switch (Attr) {
+ case DW_AT_accessibility:
+ return AccessibilityString(Val);
+ case DW_AT_virtuality:
+ return VirtualityString(Val);
+ case DW_AT_language:
+ return LanguageString(Val);
+ case DW_AT_encoding:
+ return AttributeEncodingString(Val);
+ case DW_AT_decimal_sign:
+ return DecimalSignString(Val);
+ case DW_AT_endianity:
+ return EndianityString(Val);
+ case DW_AT_visibility:
+ return VisibilityString(Val);
+ case DW_AT_identifier_case:
+ return CaseString(Val);
+ case DW_AT_calling_convention:
+ return ConventionString(Val);
+ case DW_AT_inline:
+ return InlineCodeString(Val);
+ case DW_AT_ordering:
+ return ArrayOrderString(Val);
+ case DW_AT_APPLE_runtime_class:
+ return LanguageString(Val);
+ case DW_AT_defaulted:
+ return DefaultedMemberString(Val);
+ }
+
+ return StringRef();
+}
+
+StringRef llvm::dwarf::AtomValueString(uint16_t Atom, unsigned Val) {
+ switch (Atom) {
+ case DW_ATOM_null:
+ return "NULL";
+ case DW_ATOM_die_tag:
+ return TagString(Val);
+ }
+
+ return StringRef();
+}
+
+StringRef llvm::dwarf::IndexString(unsigned Idx) {
+ switch (Idx) {
+ default:
+ return StringRef();
+#define HANDLE_DW_IDX(ID, NAME) \
+ case DW_IDX_##NAME: \
+ return "DW_IDX_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+std::optional<uint8_t> llvm::dwarf::getFixedFormByteSize(dwarf::Form Form,
+ FormParams Params) {
+ switch (Form) {
+ case DW_FORM_addr:
+ if (Params)
+ return Params.AddrSize;
+ return std::nullopt;
+
+ case DW_FORM_block: // ULEB128 length L followed by L bytes.
+ case DW_FORM_block1: // 1 byte length L followed by L bytes.
+ case DW_FORM_block2: // 2 byte length L followed by L bytes.
+ case DW_FORM_block4: // 4 byte length L followed by L bytes.
+ case DW_FORM_string: // C-string with null terminator.
+ case DW_FORM_sdata: // SLEB128.
+ case DW_FORM_udata: // ULEB128.
+ case DW_FORM_ref_udata: // ULEB128.
+ case DW_FORM_indirect: // ULEB128.
+ case DW_FORM_exprloc: // ULEB128 length L followed by L bytes.
+ case DW_FORM_strx: // ULEB128.
+ case DW_FORM_addrx: // ULEB128.
+ case DW_FORM_loclistx: // ULEB128.
+ case DW_FORM_rnglistx: // ULEB128.
+ case DW_FORM_GNU_addr_index: // ULEB128.
+ case DW_FORM_GNU_str_index: // ULEB128.
+ return std::nullopt;
+
+ case DW_FORM_ref_addr:
+ if (Params)
+ return Params.getRefAddrByteSize();
+ return std::nullopt;
+
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_strx1:
+ case DW_FORM_addrx1:
+ return 1;
+
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ case DW_FORM_strx2:
+ case DW_FORM_addrx2:
+ return 2;
+
+ case DW_FORM_strx3:
+ return 3;
+
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_ref_sup4:
+ case DW_FORM_strx4:
+ case DW_FORM_addrx4:
+ return 4;
+
+ case DW_FORM_strp:
+ case DW_FORM_GNU_ref_alt:
+ case DW_FORM_GNU_strp_alt:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp_sup:
+ if (Params)
+ return Params.getDwarfOffsetByteSize();
+ return std::nullopt;
+
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_ref_sup8:
+ return 8;
+
+ case DW_FORM_flag_present:
+ return 0;
+
+ case DW_FORM_data16:
+ return 16;
+
+ case DW_FORM_implicit_const:
+ // The implicit value is stored in the abbreviation as a SLEB128, and
+ // there no data in debug info.
+ return 0;
+
+ default:
+ break;
+ }
+ return std::nullopt;
+}
+
+bool llvm::dwarf::isValidFormForVersion(Form F, unsigned Version,
+ bool ExtensionsOk) {
+ if (FormVendor(F) == DWARF_VENDOR_DWARF) {
+ unsigned FV = FormVersion(F);
+ return FV > 0 && FV <= Version;
+ }
+ return ExtensionsOk;
+}
+
+StringRef llvm::dwarf::FormatString(DwarfFormat Format) {
+ switch (Format) {
+ case DWARF32:
+ return "DWARF32";
+ case DWARF64:
+ return "DWARF64";
+ }
+ return StringRef();
+}
+
+StringRef llvm::dwarf::FormatString(bool IsDWARF64) {
+ return FormatString(IsDWARF64 ? DWARF64 : DWARF32);
+}
+
+StringRef llvm::dwarf::RLEString(unsigned RLE) {
+ switch (RLE) {
+ default:
+ return StringRef();
+#define HANDLE_DW_RLE(ID, NAME) \
+ case DW_RLE_##NAME: \
+ return "DW_RLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
+constexpr char llvm::dwarf::EnumTraits<Attribute>::Type[];
+constexpr char llvm::dwarf::EnumTraits<Form>::Type[];
+constexpr char llvm::dwarf::EnumTraits<Index>::Type[];
+constexpr char llvm::dwarf::EnumTraits<Tag>::Type[];
+constexpr char llvm::dwarf::EnumTraits<LineNumberOps>::Type[];
+constexpr char llvm::dwarf::EnumTraits<LocationAtom>::Type[];
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/ELF.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/ELF.cpp
new file mode 100644
index 000000000000..dc8f3051a149
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/ELF.cpp
@@ -0,0 +1,570 @@
+//===- llvm/BinaryFormat/ELF.cpp - The ELF format ---------------*- 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 "llvm/BinaryFormat/ELF.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace llvm;
+using namespace ELF;
+
+/// Convert an architecture name into ELF's e_machine value.
+uint16_t ELF::convertArchNameToEMachine(StringRef Arch) {
+ std::string LowerArch = Arch.lower();
+ return StringSwitch<uint16_t>(LowerArch)
+ .Case("none", EM_NONE)
+ .Case("m32", EM_M32)
+ .Case("sparc", EM_SPARC)
+ .Case("386", EM_386)
+ .Case("68k", EM_68K)
+ .Case("88k", EM_88K)
+ .Case("iamcu", EM_IAMCU)
+ .Case("860", EM_860)
+ .Case("mips", EM_MIPS)
+ .Case("s370", EM_S370)
+ .Case("mips_rs3_le", EM_MIPS_RS3_LE)
+ .Case("parisc", EM_PARISC)
+ .Case("vpp500", EM_VPP500)
+ .Case("sparc32plus", EM_SPARC32PLUS)
+ .Case("960", EM_960)
+ .Case("ppc", EM_PPC)
+ .Case("ppc64", EM_PPC64)
+ .Case("s390", EM_S390)
+ .Case("spu", EM_SPU)
+ .Case("v800", EM_V800)
+ .Case("fr20", EM_FR20)
+ .Case("rh32", EM_RH32)
+ .Case("rce", EM_RCE)
+ .Case("arm", EM_ARM)
+ .Case("alpha", EM_ALPHA)
+ .Case("sh", EM_SH)
+ .Case("sparcv9", EM_SPARCV9)
+ .Case("tricore", EM_TRICORE)
+ .Case("arc", EM_ARC)
+ .Case("h8_300", EM_H8_300)
+ .Case("h8_300h", EM_H8_300H)
+ .Case("h8s", EM_H8S)
+ .Case("h8_500", EM_H8_500)
+ .Case("ia_64", EM_IA_64)
+ .Case("mips_x", EM_MIPS_X)
+ .Case("coldfire", EM_COLDFIRE)
+ .Case("68hc12", EM_68HC12)
+ .Case("mma", EM_MMA)
+ .Case("pcp", EM_PCP)
+ .Case("ncpu", EM_NCPU)
+ .Case("ndr1", EM_NDR1)
+ .Case("starcore", EM_STARCORE)
+ .Case("me16", EM_ME16)
+ .Case("st100", EM_ST100)
+ .Case("tinyj", EM_TINYJ)
+ .Case("x86_64", EM_X86_64)
+ .Case("pdsp", EM_PDSP)
+ .Case("pdp10", EM_PDP10)
+ .Case("pdp11", EM_PDP11)
+ .Case("fx66", EM_FX66)
+ .Case("st9plus", EM_ST9PLUS)
+ .Case("st7", EM_ST7)
+ .Case("68hc16", EM_68HC16)
+ .Case("68hc11", EM_68HC11)
+ .Case("68hc08", EM_68HC08)
+ .Case("68hc05", EM_68HC05)
+ .Case("svx", EM_SVX)
+ .Case("st19", EM_ST19)
+ .Case("vax", EM_VAX)
+ .Case("cris", EM_CRIS)
+ .Case("javelin", EM_JAVELIN)
+ .Case("firepath", EM_FIREPATH)
+ .Case("zsp", EM_ZSP)
+ .Case("mmix", EM_MMIX)
+ .Case("huany", EM_HUANY)
+ .Case("prism", EM_PRISM)
+ .Case("avr", EM_AVR)
+ .Case("fr30", EM_FR30)
+ .Case("d10v", EM_D10V)
+ .Case("d30v", EM_D30V)
+ .Case("v850", EM_V850)
+ .Case("m32r", EM_M32R)
+ .Case("mn10300", EM_MN10300)
+ .Case("mn10200", EM_MN10200)
+ .Case("pj", EM_PJ)
+ .Case("openrisc", EM_OPENRISC)
+ .Case("arc_compact", EM_ARC_COMPACT)
+ .Case("xtensa", EM_XTENSA)
+ .Case("videocore", EM_VIDEOCORE)
+ .Case("tmm_gpp", EM_TMM_GPP)
+ .Case("ns32k", EM_NS32K)
+ .Case("tpc", EM_TPC)
+ .Case("snp1k", EM_SNP1K)
+ .Case("st200", EM_ST200)
+ .Case("ip2k", EM_IP2K)
+ .Case("max", EM_MAX)
+ .Case("cr", EM_CR)
+ .Case("f2mc16", EM_F2MC16)
+ .Case("msp430", EM_MSP430)
+ .Case("blackfin", EM_BLACKFIN)
+ .Case("se_c33", EM_SE_C33)
+ .Case("sep", EM_SEP)
+ .Case("arca", EM_ARCA)
+ .Case("unicore", EM_UNICORE)
+ .Case("excess", EM_EXCESS)
+ .Case("dxp", EM_DXP)
+ .Case("altera_nios2", EM_ALTERA_NIOS2)
+ .Case("crx", EM_CRX)
+ .Case("xgate", EM_XGATE)
+ .Case("c166", EM_C166)
+ .Case("m16c", EM_M16C)
+ .Case("dspic30f", EM_DSPIC30F)
+ .Case("ce", EM_CE)
+ .Case("m32c", EM_M32C)
+ .Case("tsk3000", EM_TSK3000)
+ .Case("rs08", EM_RS08)
+ .Case("sharc", EM_SHARC)
+ .Case("ecog2", EM_ECOG2)
+ .Case("score7", EM_SCORE7)
+ .Case("dsp24", EM_DSP24)
+ .Case("videocore3", EM_VIDEOCORE3)
+ .Case("latticemico32", EM_LATTICEMICO32)
+ .Case("se_c17", EM_SE_C17)
+ .Case("ti_c6000", EM_TI_C6000)
+ .Case("ti_c2000", EM_TI_C2000)
+ .Case("ti_c5500", EM_TI_C5500)
+ .Case("mmdsp_plus", EM_MMDSP_PLUS)
+ .Case("cypress_m8c", EM_CYPRESS_M8C)
+ .Case("r32c", EM_R32C)
+ .Case("trimedia", EM_TRIMEDIA)
+ .Case("hexagon", EM_HEXAGON)
+ .Case("8051", EM_8051)
+ .Case("stxp7x", EM_STXP7X)
+ .Case("nds32", EM_NDS32)
+ .Case("ecog1", EM_ECOG1)
+ .Case("ecog1x", EM_ECOG1X)
+ .Case("maxq30", EM_MAXQ30)
+ .Case("ximo16", EM_XIMO16)
+ .Case("manik", EM_MANIK)
+ .Case("craynv2", EM_CRAYNV2)
+ .Case("rx", EM_RX)
+ .Case("metag", EM_METAG)
+ .Case("mcst_elbrus", EM_MCST_ELBRUS)
+ .Case("ecog16", EM_ECOG16)
+ .Case("cr16", EM_CR16)
+ .Case("etpu", EM_ETPU)
+ .Case("sle9x", EM_SLE9X)
+ .Case("l10m", EM_L10M)
+ .Case("k10m", EM_K10M)
+ .Case("aarch64", EM_AARCH64)
+ .Case("avr32", EM_AVR32)
+ .Case("stm8", EM_STM8)
+ .Case("tile64", EM_TILE64)
+ .Case("tilepro", EM_TILEPRO)
+ .Case("cuda", EM_CUDA)
+ .Case("tilegx", EM_TILEGX)
+ .Case("cloudshield", EM_CLOUDSHIELD)
+ .Case("corea_1st", EM_COREA_1ST)
+ .Case("corea_2nd", EM_COREA_2ND)
+ .Case("arc_compact2", EM_ARC_COMPACT2)
+ .Case("open8", EM_OPEN8)
+ .Case("rl78", EM_RL78)
+ .Case("videocore5", EM_VIDEOCORE5)
+ .Case("78kor", EM_78KOR)
+ .Case("56800ex", EM_56800EX)
+ .Case("ba1", EM_BA1)
+ .Case("ba2", EM_BA2)
+ .Case("xcore", EM_XCORE)
+ .Case("mchp_pic", EM_MCHP_PIC)
+ .Case("intel205", EM_INTEL205)
+ .Case("intel206", EM_INTEL206)
+ .Case("intel207", EM_INTEL207)
+ .Case("intel208", EM_INTEL208)
+ .Case("intel209", EM_INTEL209)
+ .Case("km32", EM_KM32)
+ .Case("kmx32", EM_KMX32)
+ .Case("kmx16", EM_KMX16)
+ .Case("kmx8", EM_KMX8)
+ .Case("kvarc", EM_KVARC)
+ .Case("cdp", EM_CDP)
+ .Case("coge", EM_COGE)
+ .Case("cool", EM_COOL)
+ .Case("norc", EM_NORC)
+ .Case("csr_kalimba", EM_CSR_KALIMBA)
+ .Case("amdgpu", EM_AMDGPU)
+ .Case("riscv", EM_RISCV)
+ .Case("lanai", EM_LANAI)
+ .Case("bpf", EM_BPF)
+ .Case("ve", EM_VE)
+ .Case("csky", EM_CSKY)
+ .Case("loongarch", EM_LOONGARCH)
+ .Default(EM_NONE);
+}
+
+/// Convert an ELF's e_machine value into an architecture name.
+StringRef ELF::convertEMachineToArchName(uint16_t EMachine) {
+ switch (EMachine) {
+ case EM_NONE:
+ return "None";
+ case EM_M32:
+ return "m32";
+ case EM_SPARC:
+ return "sparc";
+ case EM_386:
+ return "386";
+ case EM_68K:
+ return "68k";
+ case EM_88K:
+ return "88k";
+ case EM_IAMCU:
+ return "iamcu";
+ case EM_860:
+ return "860";
+ case EM_MIPS:
+ return "mips";
+ case EM_S370:
+ return "s370";
+ case EM_MIPS_RS3_LE:
+ return "mips_rs3_le";
+ case EM_PARISC:
+ return "parisc";
+ case EM_VPP500:
+ return "vpp500";
+ case EM_SPARC32PLUS:
+ return "sparc32plus";
+ case EM_960:
+ return "960";
+ case EM_PPC:
+ return "ppc";
+ case EM_PPC64:
+ return "ppc64";
+ case EM_S390:
+ return "s390";
+ case EM_SPU:
+ return "spu";
+ case EM_V800:
+ return "v800";
+ case EM_FR20:
+ return "fr20";
+ case EM_RH32:
+ return "rh32";
+ case EM_RCE:
+ return "rce";
+ case EM_ARM:
+ return "arm";
+ case EM_ALPHA:
+ return "alpha";
+ case EM_SH:
+ return "sh";
+ case EM_SPARCV9:
+ return "sparcv9";
+ case EM_TRICORE:
+ return "tricore";
+ case EM_ARC:
+ return "arc";
+ case EM_H8_300:
+ return "h8_300";
+ case EM_H8_300H:
+ return "h8_300h";
+ case EM_H8S:
+ return "h8s";
+ case EM_H8_500:
+ return "h8_500";
+ case EM_IA_64:
+ return "ia_64";
+ case EM_MIPS_X:
+ return "mips_x";
+ case EM_COLDFIRE:
+ return "coldfire";
+ case EM_68HC12:
+ return "68hc12";
+ case EM_MMA:
+ return "mma";
+ case EM_PCP:
+ return "pcp";
+ case EM_NCPU:
+ return "ncpu";
+ case EM_NDR1:
+ return "ndr1";
+ case EM_STARCORE:
+ return "starcore";
+ case EM_ME16:
+ return "me16";
+ case EM_ST100:
+ return "st100";
+ case EM_TINYJ:
+ return "tinyj";
+ case EM_X86_64:
+ return "x86_64";
+ case EM_PDSP:
+ return "pdsp";
+ case EM_PDP10:
+ return "pdp10";
+ case EM_PDP11:
+ return "pdp11";
+ case EM_FX66:
+ return "fx66";
+ case EM_ST9PLUS:
+ return "st9plus";
+ case EM_ST7:
+ return "st7";
+ case EM_68HC16:
+ return "68hc16";
+ case EM_68HC11:
+ return "68hc11";
+ case EM_68HC08:
+ return "68hc08";
+ case EM_68HC05:
+ return "68hc05";
+ case EM_SVX:
+ return "svx";
+ case EM_ST19:
+ return "st19";
+ case EM_VAX:
+ return "vax";
+ case EM_CRIS:
+ return "cris";
+ case EM_JAVELIN:
+ return "javelin";
+ case EM_FIREPATH:
+ return "firepath";
+ case EM_ZSP:
+ return "zsp";
+ case EM_MMIX:
+ return "mmix";
+ case EM_HUANY:
+ return "huany";
+ case EM_PRISM:
+ return "prism";
+ case EM_AVR:
+ return "avr";
+ case EM_FR30:
+ return "fr30";
+ case EM_D10V:
+ return "d10v";
+ case EM_D30V:
+ return "d30v";
+ case EM_V850:
+ return "v850";
+ case EM_M32R:
+ return "m32r";
+ case EM_MN10300:
+ return "mn10300";
+ case EM_MN10200:
+ return "mn10200";
+ case EM_PJ:
+ return "pj";
+ case EM_OPENRISC:
+ return "openrisc";
+ case EM_ARC_COMPACT:
+ return "arc_compact";
+ case EM_XTENSA:
+ return "xtensa";
+ case EM_VIDEOCORE:
+ return "videocore";
+ case EM_TMM_GPP:
+ return "tmm_gpp";
+ case EM_NS32K:
+ return "ns32k";
+ case EM_TPC:
+ return "tpc";
+ case EM_SNP1K:
+ return "snp1k";
+ case EM_ST200:
+ return "st200";
+ case EM_IP2K:
+ return "ip2k";
+ case EM_MAX:
+ return "max";
+ case EM_CR:
+ return "cr";
+ case EM_F2MC16:
+ return "f2mc16";
+ case EM_MSP430:
+ return "msp430";
+ case EM_BLACKFIN:
+ return "blackfin";
+ case EM_SE_C33:
+ return "se_c33";
+ case EM_SEP:
+ return "sep";
+ case EM_ARCA:
+ return "arca";
+ case EM_UNICORE:
+ return "unicore";
+ case EM_EXCESS:
+ return "excess";
+ case EM_DXP:
+ return "dxp";
+ case EM_ALTERA_NIOS2:
+ return "altera_nios2";
+ case EM_CRX:
+ return "crx";
+ case EM_XGATE:
+ return "xgate";
+ case EM_C166:
+ return "c166";
+ case EM_M16C:
+ return "m16c";
+ case EM_DSPIC30F:
+ return "dspic30f";
+ case EM_CE:
+ return "ce";
+ case EM_M32C:
+ return "m32c";
+ case EM_TSK3000:
+ return "tsk3000";
+ case EM_RS08:
+ return "rs08";
+ case EM_SHARC:
+ return "sharc";
+ case EM_ECOG2:
+ return "ecog2";
+ case EM_SCORE7:
+ return "score7";
+ case EM_DSP24:
+ return "dsp24";
+ case EM_VIDEOCORE3:
+ return "videocore3";
+ case EM_LATTICEMICO32:
+ return "latticemico32";
+ case EM_SE_C17:
+ return "se_c17";
+ case EM_TI_C6000:
+ return "ti_c6000";
+ case EM_TI_C2000:
+ return "ti_c2000";
+ case EM_TI_C5500:
+ return "ti_c5500";
+ case EM_MMDSP_PLUS:
+ return "mmdsp_plus";
+ case EM_CYPRESS_M8C:
+ return "cypress_m8c";
+ case EM_R32C:
+ return "r32c";
+ case EM_TRIMEDIA:
+ return "trimedia";
+ case EM_HEXAGON:
+ return "hexagon";
+ case EM_8051:
+ return "8051";
+ case EM_STXP7X:
+ return "stxp7x";
+ case EM_NDS32:
+ return "nds32";
+ case EM_ECOG1:
+ return "ecog1";
+ case EM_MAXQ30:
+ return "maxq30";
+ case EM_XIMO16:
+ return "ximo16";
+ case EM_MANIK:
+ return "manik";
+ case EM_CRAYNV2:
+ return "craynv2";
+ case EM_RX:
+ return "rx";
+ case EM_METAG:
+ return "metag";
+ case EM_MCST_ELBRUS:
+ return "mcst_elbrus";
+ case EM_ECOG16:
+ return "ecog16";
+ case EM_CR16:
+ return "cr16";
+ case EM_ETPU:
+ return "etpu";
+ case EM_SLE9X:
+ return "sle9x";
+ case EM_L10M:
+ return "l10m";
+ case EM_K10M:
+ return "k10m";
+ case EM_AARCH64:
+ return "AArch64";
+ case EM_AVR32:
+ return "avr32";
+ case EM_STM8:
+ return "stm8";
+ case EM_TILE64:
+ return "tile64";
+ case EM_TILEPRO:
+ return "tilepro";
+ case EM_CUDA:
+ return "cuda";
+ case EM_TILEGX:
+ return "tilegx";
+ case EM_CLOUDSHIELD:
+ return "cloudshield";
+ case EM_COREA_1ST:
+ return "corea_1st";
+ case EM_COREA_2ND:
+ return "corea_2nd";
+ case EM_ARC_COMPACT2:
+ return "arc_compact2";
+ case EM_OPEN8:
+ return "open8";
+ case EM_RL78:
+ return "rl78";
+ case EM_VIDEOCORE5:
+ return "videocore5";
+ case EM_78KOR:
+ return "78kor";
+ case EM_56800EX:
+ return "56800ex";
+ case EM_BA1:
+ return "ba1";
+ case EM_BA2:
+ return "ba2";
+ case EM_XCORE:
+ return "xcore";
+ case EM_MCHP_PIC:
+ return "mchp_pic";
+ case EM_INTEL205:
+ return "intel205";
+ case EM_INTEL206:
+ return "intel206";
+ case EM_INTEL207:
+ return "intel207";
+ case EM_INTEL208:
+ return "intel208";
+ case EM_INTEL209:
+ return "intel209";
+ case EM_KM32:
+ return "km32";
+ case EM_KMX32:
+ return "kmx32";
+ case EM_KMX16:
+ return "kmx16";
+ case EM_KMX8:
+ return "kmx8";
+ case EM_KVARC:
+ return "kvarc";
+ case EM_CDP:
+ return "cdp";
+ case EM_COGE:
+ return "coge";
+ case EM_COOL:
+ return "cool";
+ case EM_NORC:
+ return "norc";
+ case EM_CSR_KALIMBA:
+ return "csr_kalimba";
+ case EM_AMDGPU:
+ return "amdgpu";
+ case EM_RISCV:
+ return "riscv";
+ case EM_LANAI:
+ return "lanai";
+ case EM_BPF:
+ return "bpf";
+ case EM_VE:
+ return "ve";
+ case EM_CSKY:
+ return "csky";
+ case EM_LOONGARCH:
+ return "loongarch";
+ default:
+ return "None";
+ }
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/MachO.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/MachO.cpp
new file mode 100644
index 000000000000..02a515c94399
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MachO.cpp
@@ -0,0 +1,107 @@
+//===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- 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 "llvm/BinaryFormat/MachO.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ARMTargetParser.h"
+
+using namespace llvm;
+
+static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) {
+ assert(T.isX86());
+ if (T.isArch32Bit())
+ return MachO::CPU_SUBTYPE_I386_ALL;
+
+ assert(T.isArch64Bit());
+ if (T.getArchName() == "x86_64h")
+ return MachO::CPU_SUBTYPE_X86_64_H;
+ return MachO::CPU_SUBTYPE_X86_64_ALL;
+}
+
+static MachO::CPUSubTypeARM getARMSubType(const Triple &T) {
+ assert(T.isARM() || T.isThumb());
+ StringRef Arch = T.getArchName();
+ ARM::ArchKind AK = ARM::parseArch(Arch);
+ switch (AK) {
+ default:
+ return MachO::CPU_SUBTYPE_ARM_V7;
+ case ARM::ArchKind::ARMV4T:
+ return MachO::CPU_SUBTYPE_ARM_V4T;
+ case ARM::ArchKind::ARMV5T:
+ case ARM::ArchKind::ARMV5TE:
+ case ARM::ArchKind::ARMV5TEJ:
+ return MachO::CPU_SUBTYPE_ARM_V5;
+ case ARM::ArchKind::ARMV6:
+ case ARM::ArchKind::ARMV6K:
+ return MachO::CPU_SUBTYPE_ARM_V6;
+ case ARM::ArchKind::ARMV7A:
+ return MachO::CPU_SUBTYPE_ARM_V7;
+ case ARM::ArchKind::ARMV7S:
+ return MachO::CPU_SUBTYPE_ARM_V7S;
+ case ARM::ArchKind::ARMV7K:
+ return MachO::CPU_SUBTYPE_ARM_V7K;
+ case ARM::ArchKind::ARMV6M:
+ return MachO::CPU_SUBTYPE_ARM_V6M;
+ case ARM::ArchKind::ARMV7M:
+ return MachO::CPU_SUBTYPE_ARM_V7M;
+ case ARM::ArchKind::ARMV7EM:
+ return MachO::CPU_SUBTYPE_ARM_V7EM;
+ }
+}
+
+static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
+ assert(T.isAArch64());
+ if (T.isArch32Bit())
+ return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
+ if (T.isArm64e())
+ return MachO::CPU_SUBTYPE_ARM64E;
+
+ return MachO::CPU_SUBTYPE_ARM64_ALL;
+}
+
+static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) {
+ return MachO::CPU_SUBTYPE_POWERPC_ALL;
+}
+
+static Error unsupported(const char *Str, const Triple &T) {
+ return createStringError(std::errc::invalid_argument,
+ "Unsupported triple for mach-o cpu %s: %s", Str,
+ T.str().c_str());
+}
+
+Expected<uint32_t> MachO::getCPUType(const Triple &T) {
+ if (!T.isOSBinFormatMachO())
+ return unsupported("type", T);
+ if (T.isX86() && T.isArch32Bit())
+ return MachO::CPU_TYPE_X86;
+ if (T.isX86() && T.isArch64Bit())
+ return MachO::CPU_TYPE_X86_64;
+ if (T.isARM() || T.isThumb())
+ return MachO::CPU_TYPE_ARM;
+ if (T.isAArch64())
+ return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64;
+ if (T.getArch() == Triple::ppc)
+ return MachO::CPU_TYPE_POWERPC;
+ if (T.getArch() == Triple::ppc64)
+ return MachO::CPU_TYPE_POWERPC64;
+ return unsupported("type", T);
+}
+
+Expected<uint32_t> MachO::getCPUSubType(const Triple &T) {
+ if (!T.isOSBinFormatMachO())
+ return unsupported("subtype", T);
+ if (T.isX86())
+ return getX86SubType(T);
+ if (T.isARM() || T.isThumb())
+ return getARMSubType(T);
+ if (T.isAArch64() || T.getArch() == Triple::aarch64_32)
+ return getARM64SubType(T);
+ if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64)
+ return getPowerPCSubType(T);
+ return unsupported("subtype", T);
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/Magic.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/Magic.cpp
new file mode 100644
index 000000000000..0e5a5ea279b5
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Magic.cpp
@@ -0,0 +1,262 @@
+//===- llvm/BinaryFormat/Magic.cpp - File magic identification --*- 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 "llvm/BinaryFormat/Magic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+using namespace llvm;
+using namespace llvm::support::endian;
+using namespace llvm::sys::fs;
+
+template <size_t N>
+static bool startswith(StringRef Magic, const char (&S)[N]) {
+ return Magic.startswith(StringRef(S, N - 1));
+}
+
+/// Identify the magic in magic.
+file_magic llvm::identify_magic(StringRef Magic) {
+ if (Magic.size() < 4)
+ return file_magic::unknown;
+ switch ((unsigned char)Magic[0]) {
+ case 0x00: {
+ // COFF bigobj, CL.exe's LTO object file, or short import library file
+ if (startswith(Magic, "\0\0\xFF\xFF")) {
+ size_t MinSize =
+ offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
+ if (Magic.size() < MinSize)
+ return file_magic::coff_import_library;
+
+ const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
+ if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) == 0)
+ return file_magic::coff_object;
+ if (memcmp(Start, COFF::ClGlObjMagic, sizeof(COFF::BigObjMagic)) == 0)
+ return file_magic::coff_cl_gl_object;
+ return file_magic::coff_import_library;
+ }
+ // Windows resource file
+ if (Magic.size() >= sizeof(COFF::WinResMagic) &&
+ memcmp(Magic.data(), COFF::WinResMagic, sizeof(COFF::WinResMagic)) == 0)
+ return file_magic::windows_resource;
+ // 0x0000 = COFF unknown machine type
+ if (Magic[1] == 0)
+ return file_magic::coff_object;
+ if (startswith(Magic, "\0asm"))
+ return file_magic::wasm_object;
+ break;
+ }
+
+ case 0x01:
+ // XCOFF format
+ if (startswith(Magic, "\x01\xDF"))
+ return file_magic::xcoff_object_32;
+ if (startswith(Magic, "\x01\xF7"))
+ return file_magic::xcoff_object_64;
+ break;
+
+ case 0x03:
+ if (startswith(Magic, "\x03\xF0\x00"))
+ return file_magic::goff_object;
+ break;
+
+ case 0x10:
+ if (startswith(Magic, "\x10\xFF\x10\xAD"))
+ return file_magic::offload_binary;
+ break;
+
+ case 0xDE: // 0x0B17C0DE = BC wraper
+ if (startswith(Magic, "\xDE\xC0\x17\x0B"))
+ return file_magic::bitcode;
+ break;
+ case 'B':
+ if (startswith(Magic, "BC\xC0\xDE"))
+ return file_magic::bitcode;
+ break;
+ case '!':
+ if (startswith(Magic, "!<arch>\n") || startswith(Magic, "!<thin>\n"))
+ return file_magic::archive;
+ break;
+ case '<':
+ if (startswith(Magic, "<bigaf>\n"))
+ return file_magic::archive;
+ break;
+ case '\177':
+ if (startswith(Magic, "\177ELF") && Magic.size() >= 18) {
+ bool Data2MSB = Magic[5] == 2;
+ unsigned high = Data2MSB ? 16 : 17;
+ unsigned low = Data2MSB ? 17 : 16;
+ if (Magic[high] == 0) {
+ switch (Magic[low]) {
+ default:
+ return file_magic::elf;
+ case 1:
+ return file_magic::elf_relocatable;
+ case 2:
+ return file_magic::elf_executable;
+ case 3:
+ return file_magic::elf_shared_object;
+ case 4:
+ return file_magic::elf_core;
+ }
+ }
+ // It's still some type of ELF file.
+ return file_magic::elf;
+ }
+ break;
+
+ case 0xCA:
+ if (startswith(Magic, "\xCA\xFE\xBA\xBE") ||
+ startswith(Magic, "\xCA\xFE\xBA\xBF")) {
+ // This is complicated by an overlap with Java class files.
+ // See the Mach-O section in /usr/share/file/magic for details.
+ if (Magic.size() >= 8 && Magic[7] < 43)
+ return file_magic::macho_universal_binary;
+ }
+ break;
+
+ // The two magic numbers for mach-o are:
+ // 0xfeedface - 32-bit mach-o
+ // 0xfeedfacf - 64-bit mach-o
+ case 0xFE:
+ case 0xCE:
+ case 0xCF: {
+ uint16_t type = 0;
+ if (startswith(Magic, "\xFE\xED\xFA\xCE") ||
+ startswith(Magic, "\xFE\xED\xFA\xCF")) {
+ /* Native endian */
+ size_t MinSize;
+ if (Magic[3] == char(0xCE))
+ MinSize = sizeof(MachO::mach_header);
+ else
+ MinSize = sizeof(MachO::mach_header_64);
+ if (Magic.size() >= MinSize)
+ type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
+ } else if (startswith(Magic, "\xCE\xFA\xED\xFE") ||
+ startswith(Magic, "\xCF\xFA\xED\xFE")) {
+ /* Reverse endian */
+ size_t MinSize;
+ if (Magic[0] == char(0xCE))
+ MinSize = sizeof(MachO::mach_header);
+ else
+ MinSize = sizeof(MachO::mach_header_64);
+ if (Magic.size() >= MinSize)
+ type = Magic[15] << 24 | Magic[14] << 12 | Magic[13] << 8 | Magic[12];
+ }
+ switch (type) {
+ default:
+ break;
+ case 1:
+ return file_magic::macho_object;
+ case 2:
+ return file_magic::macho_executable;
+ case 3:
+ return file_magic::macho_fixed_virtual_memory_shared_lib;
+ case 4:
+ return file_magic::macho_core;
+ case 5:
+ return file_magic::macho_preload_executable;
+ case 6:
+ return file_magic::macho_dynamically_linked_shared_lib;
+ case 7:
+ return file_magic::macho_dynamic_linker;
+ case 8:
+ return file_magic::macho_bundle;
+ case 9:
+ return file_magic::macho_dynamically_linked_shared_lib_stub;
+ case 10:
+ return file_magic::macho_dsym_companion;
+ case 11:
+ return file_magic::macho_kext_bundle;
+ case 12:
+ return file_magic::macho_file_set;
+ }
+ break;
+ }
+ case 0xF0: // PowerPC Windows
+ case 0x83: // Alpha 32-bit
+ case 0x84: // Alpha 64-bit
+ case 0x66: // MPS R4000 Windows
+ case 0x50: // mc68K
+ if (startswith(Magic, "\x50\xed\x55\xba"))
+ return file_magic::cuda_fatbinary;
+ [[fallthrough]];
+
+ case 0x4c: // 80386 Windows
+ case 0xc4: // ARMNT Windows
+ if (Magic[1] == 0x01)
+ return file_magic::coff_object;
+ [[fallthrough]];
+
+ case 0x90: // PA-RISC Windows
+ case 0x68: // mc68K Windows
+ if (Magic[1] == 0x02)
+ return file_magic::coff_object;
+ break;
+
+ case 'M': // Possible MS-DOS stub on Windows PE file, MSF/PDB file or a
+ // Minidump file.
+ if (startswith(Magic, "MZ") && Magic.size() >= 0x3c + 4) {
+ uint32_t off = read32le(Magic.data() + 0x3c);
+ // PE/COFF file, either EXE or DLL.
+ if (Magic.substr(off).startswith(
+ StringRef(COFF::PEMagic, sizeof(COFF::PEMagic))))
+ return file_magic::pecoff_executable;
+ }
+ if (Magic.startswith("Microsoft C/C++ MSF 7.00\r\n"))
+ return file_magic::pdb;
+ if (startswith(Magic, "MDMP"))
+ return file_magic::minidump;
+ break;
+
+ case 0x64: // x86-64 or ARM64 Windows.
+ if (Magic[1] == char(0x86) || Magic[1] == char(0xaa))
+ return file_magic::coff_object;
+ break;
+
+ case 0x2d: // YAML '-'
+ if (startswith(Magic, "--- !tapi") || startswith(Magic, "---\narchs:"))
+ return file_magic::tapi_file;
+ break;
+
+ case 'D': // DirectX container file - DXBC
+ if (startswith(Magic, "DXBC"))
+ return file_magic::dxcontainer_object;
+ break;
+
+ case 0x41: // ARM64EC windows
+ if (Magic[1] == char(0xA6))
+ return file_magic::coff_object;
+ break;
+
+ default:
+ break;
+ }
+ return file_magic::unknown;
+}
+
+std::error_code llvm::identify_magic(const Twine &Path, file_magic &Result) {
+ auto FileOrError = MemoryBuffer::getFile(Path, /*IsText=*/false,
+ /*RequiresNullTerminator=*/false);
+ if (!FileOrError)
+ return FileOrError.getError();
+
+ std::unique_ptr<MemoryBuffer> FileBuffer = std::move(*FileOrError);
+ Result = identify_magic(FileBuffer->getBuffer());
+
+ return std::error_code();
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/Minidump.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/Minidump.cpp
new file mode 100644
index 000000000000..b618fb157012
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Minidump.cpp
@@ -0,0 +1,14 @@
+//===-- Minidump.cpp - Minidump constants and structures ---------*- 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 "llvm/BinaryFormat/Minidump.h"
+
+using namespace llvm::minidump;
+
+constexpr uint32_t Header::MagicSignature;
+constexpr uint16_t Header::MagicVersion;
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocument.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocument.cpp
new file mode 100644
index 000000000000..81ea4cee1a9d
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocument.cpp
@@ -0,0 +1,314 @@
+//===-- MsgPackDocument.cpp - MsgPack Document --------------------------*-===//
+//
+// 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 implements a class that exposes a simple in-memory representation
+/// of a document of MsgPack objects, that can be read from MsgPack, written to
+/// MsgPack, and inspected and modified in memory. This is intended to be a
+/// lighter-weight (in terms of memory allocations) replacement for
+/// MsgPackTypes.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/MsgPackDocument.h"
+#include "llvm/BinaryFormat/MsgPackWriter.h"
+
+using namespace llvm;
+using namespace msgpack;
+
+// Convert this DocNode into an empty array.
+void DocNode::convertToArray() { *this = getDocument()->getArrayNode(); }
+
+// Convert this DocNode into an empty map.
+void DocNode::convertToMap() { *this = getDocument()->getMapNode(); }
+
+/// Find the key in the MapDocNode.
+DocNode::MapTy::iterator MapDocNode::find(StringRef S) {
+ return find(getDocument()->getNode(S));
+}
+
+/// Member access for MapDocNode. The string data must remain valid for the
+/// lifetime of the Document.
+DocNode &MapDocNode::operator[](StringRef S) {
+ return (*this)[getDocument()->getNode(S)];
+}
+
+/// Member access for MapDocNode.
+DocNode &MapDocNode::operator[](DocNode Key) {
+ assert(!Key.isEmpty());
+ DocNode &N = (*Map)[Key];
+ if (N.isEmpty()) {
+ // Ensure a new element has its KindAndDoc initialized.
+ N = getDocument()->getEmptyNode();
+ }
+ return N;
+}
+
+/// Member access for MapDocNode for integer key.
+DocNode &MapDocNode::operator[](int Key) {
+ return (*this)[getDocument()->getNode(Key)];
+}
+DocNode &MapDocNode::operator[](unsigned Key) {
+ return (*this)[getDocument()->getNode(Key)];
+}
+DocNode &MapDocNode::operator[](int64_t Key) {
+ return (*this)[getDocument()->getNode(Key)];
+}
+DocNode &MapDocNode::operator[](uint64_t Key) {
+ return (*this)[getDocument()->getNode(Key)];
+}
+
+/// Array element access. This extends the array if necessary.
+DocNode &ArrayDocNode::operator[](size_t Index) {
+ if (size() <= Index) {
+ // Ensure new elements have their KindAndDoc initialized.
+ Array->resize(Index + 1, getDocument()->getEmptyNode());
+ }
+ return (*Array)[Index];
+}
+
+// Convenience assignment operators. This only works if the destination
+// DocNode has an associated Document, i.e. it was not constructed using the
+// default constructor. The string one does not copy, so the string must
+// remain valid for the lifetime of the Document. Use fromString to avoid
+// that restriction.
+DocNode &DocNode::operator=(StringRef Val) {
+ *this = getDocument()->getNode(Val);
+ return *this;
+}
+DocNode &DocNode::operator=(bool Val) {
+ *this = getDocument()->getNode(Val);
+ return *this;
+}
+DocNode &DocNode::operator=(int Val) {
+ *this = getDocument()->getNode(Val);
+ return *this;
+}
+DocNode &DocNode::operator=(unsigned Val) {
+ *this = getDocument()->getNode(Val);
+ return *this;
+}
+DocNode &DocNode::operator=(int64_t Val) {
+ *this = getDocument()->getNode(Val);
+ return *this;
+}
+DocNode &DocNode::operator=(uint64_t Val) {
+ *this = getDocument()->getNode(Val);
+ return *this;
+}
+
+// A level in the document reading stack.
+struct StackLevel {
+ StackLevel(DocNode Node, size_t StartIndex, size_t Length,
+ DocNode *MapEntry = nullptr)
+ : Node(Node), Index(StartIndex), End(StartIndex + Length),
+ MapEntry(MapEntry) {}
+ DocNode Node;
+ size_t Index;
+ size_t End;
+ // Points to map entry when we have just processed a map key.
+ DocNode *MapEntry;
+ DocNode MapKey;
+};
+
+// Read a document from a binary msgpack blob, merging into anything already in
+// the Document.
+// The blob data must remain valid for the lifetime of this Document (because a
+// string object in the document contains a StringRef into the original blob).
+// If Multi, then this sets root to an array and adds top-level objects to it.
+// If !Multi, then it only reads a single top-level object, even if there are
+// more, and sets root to that.
+// Returns false if failed due to illegal format or merge error.
+
+bool Document::readFromBlob(
+ StringRef Blob, bool Multi,
+ function_ref<int(DocNode *DestNode, DocNode SrcNode, DocNode MapKey)>
+ Merger) {
+ msgpack::Reader MPReader(Blob);
+ SmallVector<StackLevel, 4> Stack;
+ if (Multi) {
+ // Create the array for multiple top-level objects.
+ Root = getArrayNode();
+ Stack.push_back(StackLevel(Root, 0, (size_t)-1));
+ }
+ do {
+ // On to next element (or key if doing a map key next).
+ // Read the value.
+ Object Obj;
+ if (!MPReader.read(Obj)) {
+ if (Multi && Stack.size() == 1) {
+ // OK to finish here as we've just done a top-level element with Multi
+ break;
+ }
+ return false; // Finished too early
+ }
+ // Convert it into a DocNode.
+ DocNode Node;
+ switch (Obj.Kind) {
+ case Type::Nil:
+ Node = getNode();
+ break;
+ case Type::Int:
+ Node = getNode(Obj.Int);
+ break;
+ case Type::UInt:
+ Node = getNode(Obj.UInt);
+ break;
+ case Type::Boolean:
+ Node = getNode(Obj.Bool);
+ break;
+ case Type::Float:
+ Node = getNode(Obj.Float);
+ break;
+ case Type::String:
+ Node = getNode(Obj.Raw);
+ break;
+ case Type::Map:
+ Node = getMapNode();
+ break;
+ case Type::Array:
+ Node = getArrayNode();
+ break;
+ default:
+ return false; // Raw and Extension not supported
+ }
+
+ // Store it.
+ DocNode *DestNode = nullptr;
+ if (Stack.empty())
+ DestNode = &Root;
+ else if (Stack.back().Node.getKind() == Type::Array) {
+ // Reading an array entry.
+ auto &Array = Stack.back().Node.getArray();
+ DestNode = &Array[Stack.back().Index++];
+ } else {
+ auto &Map = Stack.back().Node.getMap();
+ if (!Stack.back().MapEntry) {
+ // Reading a map key.
+ Stack.back().MapKey = Node;
+ Stack.back().MapEntry = &Map[Node];
+ continue;
+ }
+ // Reading the value for the map key read in the last iteration.
+ DestNode = Stack.back().MapEntry;
+ Stack.back().MapEntry = nullptr;
+ ++Stack.back().Index;
+ }
+ int MergeResult = 0;
+ if (!DestNode->isEmpty()) {
+ // In a merge, there is already a value at this position. Call the
+ // callback to attempt to resolve the conflict. The resolution must result
+ // in an array or map if Node is an array or map respectively.
+ DocNode MapKey = !Stack.empty() && !Stack.back().MapKey.isEmpty()
+ ? Stack.back().MapKey
+ : getNode();
+ MergeResult = Merger(DestNode, Node, MapKey);
+ if (MergeResult < 0)
+ return false; // Merge conflict resolution failed
+ assert(!((Node.isMap() && !DestNode->isMap()) ||
+ (Node.isArray() && !DestNode->isArray())));
+ } else
+ *DestNode = Node;
+
+ // See if we're starting a new array or map.
+ switch (DestNode->getKind()) {
+ case msgpack::Type::Array:
+ case msgpack::Type::Map:
+ Stack.push_back(StackLevel(*DestNode, MergeResult, Obj.Length, nullptr));
+ break;
+ default:
+ break;
+ }
+
+ // Pop finished stack levels.
+ while (!Stack.empty()) {
+ if (Stack.back().MapEntry)
+ break;
+ if (Stack.back().Index != Stack.back().End)
+ break;
+ Stack.pop_back();
+ }
+ } while (!Stack.empty());
+ return true;
+}
+
+struct WriterStackLevel {
+ DocNode Node;
+ DocNode::MapTy::iterator MapIt;
+ DocNode::ArrayTy::iterator ArrayIt;
+ bool OnKey;
+};
+
+/// Write a MsgPack document to a binary MsgPack blob.
+void Document::writeToBlob(std::string &Blob) {
+ Blob.clear();
+ raw_string_ostream OS(Blob);
+ msgpack::Writer MPWriter(OS);
+ SmallVector<WriterStackLevel, 4> Stack;
+ DocNode Node = getRoot();
+ for (;;) {
+ switch (Node.getKind()) {
+ case Type::Array:
+ MPWriter.writeArraySize(Node.getArray().size());
+ Stack.push_back(
+ {Node, DocNode::MapTy::iterator(), Node.getArray().begin(), false});
+ break;
+ case Type::Map:
+ MPWriter.writeMapSize(Node.getMap().size());
+ Stack.push_back(
+ {Node, Node.getMap().begin(), DocNode::ArrayTy::iterator(), true});
+ break;
+ case Type::Nil:
+ MPWriter.writeNil();
+ break;
+ case Type::Boolean:
+ MPWriter.write(Node.getBool());
+ break;
+ case Type::Int:
+ MPWriter.write(Node.getInt());
+ break;
+ case Type::UInt:
+ MPWriter.write(Node.getUInt());
+ break;
+ case Type::String:
+ MPWriter.write(Node.getString());
+ break;
+ case Type::Empty:
+ llvm_unreachable("unhandled empty msgpack node");
+ default:
+ llvm_unreachable("unhandled msgpack object kind");
+ }
+ // Pop finished stack levels.
+ while (!Stack.empty()) {
+ if (Stack.back().Node.getKind() == Type::Map) {
+ if (Stack.back().MapIt != Stack.back().Node.getMap().end())
+ break;
+ } else {
+ if (Stack.back().ArrayIt != Stack.back().Node.getArray().end())
+ break;
+ }
+ Stack.pop_back();
+ }
+ if (Stack.empty())
+ break;
+ // Get the next value.
+ if (Stack.back().Node.getKind() == Type::Map) {
+ if (Stack.back().OnKey) {
+ // Do the key of a key,value pair in a map.
+ Node = Stack.back().MapIt->first;
+ Stack.back().OnKey = false;
+ } else {
+ Node = Stack.back().MapIt->second;
+ ++Stack.back().MapIt;
+ Stack.back().OnKey = true;
+ }
+ } else {
+ Node = *Stack.back().ArrayIt;
+ ++Stack.back().ArrayIt;
+ }
+ }
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp
new file mode 100644
index 000000000000..3de3dccce0c6
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp
@@ -0,0 +1,248 @@
+//===-- MsgPackDocumentYAML.cpp - MsgPack Document YAML interface -------*-===//
+//
+// 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 implements YAMLIO on a msgpack::Document.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/MsgPackDocument.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace llvm;
+using namespace msgpack;
+
+namespace {
+
+// Struct used to represent scalar node. (MapDocNode and ArrayDocNode already
+// exist in MsgPackDocument.h.)
+struct ScalarDocNode : DocNode {
+ ScalarDocNode(DocNode N) : DocNode(N) {}
+
+ /// Get the YAML tag for this ScalarDocNode. This normally returns ""; it only
+ /// returns something else if the result of toString would be ambiguous, e.g.
+ /// a string that parses as a number or boolean.
+ StringRef getYAMLTag() const;
+};
+
+} // namespace
+
+/// Convert this DocNode to a string, assuming it is scalar.
+std::string DocNode::toString() const {
+ std::string S;
+ raw_string_ostream OS(S);
+ switch (getKind()) {
+ case msgpack::Type::String:
+ OS << Raw;
+ break;
+ case msgpack::Type::Nil:
+ break;
+ case msgpack::Type::Boolean:
+ OS << (Bool ? "true" : "false");
+ break;
+ case msgpack::Type::Int:
+ OS << Int;
+ break;
+ case msgpack::Type::UInt:
+ if (getDocument()->getHexMode())
+ OS << format("%#llx", (unsigned long long)UInt);
+ else
+ OS << UInt;
+ break;
+ case msgpack::Type::Float:
+ OS << Float;
+ break;
+ default:
+ llvm_unreachable("not scalar");
+ break;
+ }
+ return OS.str();
+}
+
+/// Convert the StringRef and use it to set this DocNode (assuming scalar). If
+/// it is a string, copy the string into the Document's strings list so we do
+/// not rely on S having a lifetime beyond this call. Tag is "" or a YAML tag.
+StringRef DocNode::fromString(StringRef S, StringRef Tag) {
+ if (Tag == "tag:yaml.org,2002:str")
+ Tag = "";
+ if (Tag == "!int" || Tag == "") {
+ // Try unsigned int then signed int.
+ *this = getDocument()->getNode(uint64_t(0));
+ StringRef Err = yaml::ScalarTraits<uint64_t>::input(S, nullptr, getUInt());
+ if (Err != "") {
+ *this = getDocument()->getNode(int64_t(0));
+ Err = yaml::ScalarTraits<int64_t>::input(S, nullptr, getInt());
+ }
+ if (Err == "" || Tag != "")
+ return Err;
+ }
+ if (Tag == "!nil") {
+ *this = getDocument()->getNode();
+ return "";
+ }
+ if (Tag == "!bool" || Tag == "") {
+ *this = getDocument()->getNode(false);
+ StringRef Err = yaml::ScalarTraits<bool>::input(S, nullptr, getBool());
+ if (Err == "" || Tag != "")
+ return Err;
+ }
+ if (Tag == "!float" || Tag == "") {
+ *this = getDocument()->getNode(0.0);
+ StringRef Err = yaml::ScalarTraits<double>::input(S, nullptr, getFloat());
+ if (Err == "" || Tag != "")
+ return Err;
+ }
+ assert((Tag == "!str" || Tag == "") && "unsupported tag");
+ std::string V;
+ StringRef Err = yaml::ScalarTraits<std::string>::input(S, nullptr, V);
+ if (Err == "")
+ *this = getDocument()->getNode(V, /*Copy=*/true);
+ return Err;
+}
+
+/// Get the YAML tag for this ScalarDocNode. This normally returns ""; it only
+/// returns something else if the result of toString would be ambiguous, e.g.
+/// a string that parses as a number or boolean.
+StringRef ScalarDocNode::getYAMLTag() const {
+ if (getKind() == msgpack::Type::Nil)
+ return "!nil";
+ // Try converting both ways and see if we get the same kind. If not, we need
+ // a tag.
+ ScalarDocNode N = getDocument()->getNode();
+ N.fromString(toString(), "");
+ if (N.getKind() == getKind())
+ return "";
+ // Tolerate signedness of int changing, as tags do not differentiate between
+ // them anyway.
+ if (N.getKind() == msgpack::Type::UInt && getKind() == msgpack::Type::Int)
+ return "";
+ if (N.getKind() == msgpack::Type::Int && getKind() == msgpack::Type::UInt)
+ return "";
+ // We do need a tag.
+ switch (getKind()) {
+ case msgpack::Type::String:
+ return "!str";
+ case msgpack::Type::Int:
+ return "!int";
+ case msgpack::Type::UInt:
+ return "!int";
+ case msgpack::Type::Boolean:
+ return "!bool";
+ case msgpack::Type::Float:
+ return "!float";
+ default:
+ llvm_unreachable("unrecognized kind");
+ }
+}
+
+namespace llvm {
+namespace yaml {
+
+/// YAMLIO for DocNode
+template <> struct PolymorphicTraits<DocNode> {
+
+ static NodeKind getKind(const DocNode &N) {
+ switch (N.getKind()) {
+ case msgpack::Type::Map:
+ return NodeKind::Map;
+ case msgpack::Type::Array:
+ return NodeKind::Sequence;
+ default:
+ return NodeKind::Scalar;
+ }
+ }
+
+ static MapDocNode &getAsMap(DocNode &N) { return N.getMap(/*Convert=*/true); }
+
+ static ArrayDocNode &getAsSequence(DocNode &N) {
+ N.getArray(/*Convert=*/true);
+ return *static_cast<ArrayDocNode *>(&N);
+ }
+
+ static ScalarDocNode &getAsScalar(DocNode &N) {
+ return *static_cast<ScalarDocNode *>(&N);
+ }
+};
+
+/// YAMLIO for ScalarDocNode
+template <> struct TaggedScalarTraits<ScalarDocNode> {
+
+ static void output(const ScalarDocNode &S, void *Ctxt, raw_ostream &OS,
+ raw_ostream &TagOS) {
+ TagOS << S.getYAMLTag();
+ OS << S.toString();
+ }
+
+ static StringRef input(StringRef Str, StringRef Tag, void *Ctxt,
+ ScalarDocNode &S) {
+ return S.fromString(Str, Tag);
+ }
+
+ static QuotingType mustQuote(const ScalarDocNode &S, StringRef ScalarStr) {
+ switch (S.getKind()) {
+ case Type::Int:
+ return ScalarTraits<int64_t>::mustQuote(ScalarStr);
+ case Type::UInt:
+ return ScalarTraits<uint64_t>::mustQuote(ScalarStr);
+ case Type::Nil:
+ return ScalarTraits<StringRef>::mustQuote(ScalarStr);
+ case Type::Boolean:
+ return ScalarTraits<bool>::mustQuote(ScalarStr);
+ case Type::Float:
+ return ScalarTraits<double>::mustQuote(ScalarStr);
+ case Type::Binary:
+ case Type::String:
+ return ScalarTraits<std::string>::mustQuote(ScalarStr);
+ default:
+ llvm_unreachable("unrecognized ScalarKind");
+ }
+ }
+};
+
+/// YAMLIO for MapDocNode
+template <> struct CustomMappingTraits<MapDocNode> {
+
+ static void inputOne(IO &IO, StringRef Key, MapDocNode &M) {
+ ScalarDocNode KeyObj = M.getDocument()->getNode();
+ KeyObj.fromString(Key, "");
+ IO.mapRequired(Key.str().c_str(), M.getMap()[KeyObj]);
+ }
+
+ static void output(IO &IO, MapDocNode &M) {
+ for (auto I : M.getMap()) {
+ IO.mapRequired(I.first.toString().c_str(), I.second);
+ }
+ }
+};
+
+/// YAMLIO for ArrayNode
+template <> struct SequenceTraits<ArrayDocNode> {
+
+ static size_t size(IO &IO, ArrayDocNode &A) { return A.size(); }
+
+ static DocNode &element(IO &IO, ArrayDocNode &A, size_t Index) {
+ return A[Index];
+ }
+};
+
+} // namespace yaml
+} // namespace llvm
+
+/// Convert MsgPack Document to YAML text.
+void msgpack::Document::toYAML(raw_ostream &OS) {
+ yaml::Output Yout(OS);
+ Yout << getRoot();
+}
+
+/// Read YAML text into the MsgPack document. Returns false on failure.
+bool msgpack::Document::fromYAML(StringRef S) {
+ clear();
+ yaml::Input Yin(S);
+ Yin >> getRoot();
+ return !Yin.error();
+}
+
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp
new file mode 100644
index 000000000000..146edaa95b81
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp
@@ -0,0 +1,255 @@
+//===- MsgPackReader.cpp - Simple MsgPack reader ----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements a MessagePack reader.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/MsgPackReader.h"
+#include "llvm/BinaryFormat/MsgPack.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace llvm;
+using namespace llvm::support;
+using namespace msgpack;
+
+Reader::Reader(MemoryBufferRef InputBuffer)
+ : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
+ End(InputBuffer.getBufferEnd()) {}
+
+Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}
+
+Expected<bool> Reader::read(Object &Obj) {
+ if (Current == End)
+ return false;
+
+ uint8_t FB = static_cast<uint8_t>(*Current++);
+
+ switch (FB) {
+ case FirstByte::Nil:
+ Obj.Kind = Type::Nil;
+ return true;
+ case FirstByte::True:
+ Obj.Kind = Type::Boolean;
+ Obj.Bool = true;
+ return true;
+ case FirstByte::False:
+ Obj.Kind = Type::Boolean;
+ Obj.Bool = false;
+ return true;
+ case FirstByte::Int8:
+ Obj.Kind = Type::Int;
+ return readInt<int8_t>(Obj);
+ case FirstByte::Int16:
+ Obj.Kind = Type::Int;
+ return readInt<int16_t>(Obj);
+ case FirstByte::Int32:
+ Obj.Kind = Type::Int;
+ return readInt<int32_t>(Obj);
+ case FirstByte::Int64:
+ Obj.Kind = Type::Int;
+ return readInt<int64_t>(Obj);
+ case FirstByte::UInt8:
+ Obj.Kind = Type::UInt;
+ return readUInt<uint8_t>(Obj);
+ case FirstByte::UInt16:
+ Obj.Kind = Type::UInt;
+ return readUInt<uint16_t>(Obj);
+ case FirstByte::UInt32:
+ Obj.Kind = Type::UInt;
+ return readUInt<uint32_t>(Obj);
+ case FirstByte::UInt64:
+ Obj.Kind = Type::UInt;
+ return readUInt<uint64_t>(Obj);
+ case FirstByte::Float32:
+ Obj.Kind = Type::Float;
+ if (sizeof(float) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Float32 with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Float = BitsToFloat(endian::read<uint32_t, Endianness>(Current));
+ Current += sizeof(float);
+ return true;
+ case FirstByte::Float64:
+ Obj.Kind = Type::Float;
+ if (sizeof(double) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Float64 with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Float = BitsToDouble(endian::read<uint64_t, Endianness>(Current));
+ Current += sizeof(double);
+ return true;
+ case FirstByte::Str8:
+ Obj.Kind = Type::String;
+ return readRaw<uint8_t>(Obj);
+ case FirstByte::Str16:
+ Obj.Kind = Type::String;
+ return readRaw<uint16_t>(Obj);
+ case FirstByte::Str32:
+ Obj.Kind = Type::String;
+ return readRaw<uint32_t>(Obj);
+ case FirstByte::Bin8:
+ Obj.Kind = Type::Binary;
+ return readRaw<uint8_t>(Obj);
+ case FirstByte::Bin16:
+ Obj.Kind = Type::Binary;
+ return readRaw<uint16_t>(Obj);
+ case FirstByte::Bin32:
+ Obj.Kind = Type::Binary;
+ return readRaw<uint32_t>(Obj);
+ case FirstByte::Array16:
+ Obj.Kind = Type::Array;
+ return readLength<uint16_t>(Obj);
+ case FirstByte::Array32:
+ Obj.Kind = Type::Array;
+ return readLength<uint32_t>(Obj);
+ case FirstByte::Map16:
+ Obj.Kind = Type::Map;
+ return readLength<uint16_t>(Obj);
+ case FirstByte::Map32:
+ Obj.Kind = Type::Map;
+ return readLength<uint32_t>(Obj);
+ case FirstByte::FixExt1:
+ Obj.Kind = Type::Extension;
+ return createExt(Obj, FixLen::Ext1);
+ case FirstByte::FixExt2:
+ Obj.Kind = Type::Extension;
+ return createExt(Obj, FixLen::Ext2);
+ case FirstByte::FixExt4:
+ Obj.Kind = Type::Extension;
+ return createExt(Obj, FixLen::Ext4);
+ case FirstByte::FixExt8:
+ Obj.Kind = Type::Extension;
+ return createExt(Obj, FixLen::Ext8);
+ case FirstByte::FixExt16:
+ Obj.Kind = Type::Extension;
+ return createExt(Obj, FixLen::Ext16);
+ case FirstByte::Ext8:
+ Obj.Kind = Type::Extension;
+ return readExt<uint8_t>(Obj);
+ case FirstByte::Ext16:
+ Obj.Kind = Type::Extension;
+ return readExt<uint16_t>(Obj);
+ case FirstByte::Ext32:
+ Obj.Kind = Type::Extension;
+ return readExt<uint32_t>(Obj);
+ }
+
+ if ((FB & FixBitsMask::NegativeInt) == FixBits::NegativeInt) {
+ Obj.Kind = Type::Int;
+ int8_t I;
+ static_assert(sizeof(I) == sizeof(FB), "Unexpected type sizes");
+ memcpy(&I, &FB, sizeof(FB));
+ Obj.Int = I;
+ return true;
+ }
+
+ if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
+ Obj.Kind = Type::UInt;
+ Obj.UInt = FB;
+ return true;
+ }
+
+ if ((FB & FixBitsMask::String) == FixBits::String) {
+ Obj.Kind = Type::String;
+ uint8_t Size = FB & ~FixBitsMask::String;
+ return createRaw(Obj, Size);
+ }
+
+ if ((FB & FixBitsMask::Array) == FixBits::Array) {
+ Obj.Kind = Type::Array;
+ Obj.Length = FB & ~FixBitsMask::Array;
+ return true;
+ }
+
+ if ((FB & FixBitsMask::Map) == FixBits::Map) {
+ Obj.Kind = Type::Map;
+ Obj.Length = FB & ~FixBitsMask::Map;
+ return true;
+ }
+
+ return make_error<StringError>(
+ "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
+}
+
+template <class T> Expected<bool> Reader::readRaw(Object &Obj) {
+ if (sizeof(T) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Raw with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ T Size = endian::read<T, Endianness>(Current);
+ Current += sizeof(T);
+ return createRaw(Obj, Size);
+}
+
+template <class T> Expected<bool> Reader::readInt(Object &Obj) {
+ if (sizeof(T) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Int with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Int = static_cast<int64_t>(endian::read<T, Endianness>(Current));
+ Current += sizeof(T);
+ return true;
+}
+
+template <class T> Expected<bool> Reader::readUInt(Object &Obj) {
+ if (sizeof(T) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Int with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.UInt = static_cast<uint64_t>(endian::read<T, Endianness>(Current));
+ Current += sizeof(T);
+ return true;
+}
+
+template <class T> Expected<bool> Reader::readLength(Object &Obj) {
+ if (sizeof(T) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Map/Array with invalid length",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Length = static_cast<size_t>(endian::read<T, Endianness>(Current));
+ Current += sizeof(T);
+ return true;
+}
+
+template <class T> Expected<bool> Reader::readExt(Object &Obj) {
+ if (sizeof(T) > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Ext with invalid length",
+ std::make_error_code(std::errc::invalid_argument));
+ T Size = endian::read<T, Endianness>(Current);
+ Current += sizeof(T);
+ return createExt(Obj, Size);
+}
+
+Expected<bool> Reader::createRaw(Object &Obj, uint32_t Size) {
+ if (Size > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Raw with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Raw = StringRef(Current, Size);
+ Current += Size;
+ return true;
+}
+
+Expected<bool> Reader::createExt(Object &Obj, uint32_t Size) {
+ if (Current == End)
+ return make_error<StringError>(
+ "Invalid Ext with no type",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Extension.Type = *Current++;
+ if (Size > remainingSpace())
+ return make_error<StringError>(
+ "Invalid Ext with insufficient payload",
+ std::make_error_code(std::errc::invalid_argument));
+ Obj.Extension.Bytes = StringRef(Current, Size);
+ Current += Size;
+ return true;
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp
new file mode 100644
index 000000000000..d3b557d00577
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp
@@ -0,0 +1,210 @@
+//===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements a MessagePack writer.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/MsgPackWriter.h"
+#include "llvm/BinaryFormat/MsgPack.h"
+
+#include <cmath>
+
+using namespace llvm;
+using namespace msgpack;
+
+Writer::Writer(raw_ostream &OS, bool Compatible)
+ : EW(OS, Endianness), Compatible(Compatible) {}
+
+void Writer::writeNil() { EW.write(FirstByte::Nil); }
+
+void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }
+
+void Writer::write(int64_t i) {
+ if (i >= 0) {
+ write(static_cast<uint64_t>(i));
+ return;
+ }
+
+ if (i >= FixMin::NegativeInt) {
+ EW.write(static_cast<int8_t>(i));
+ return;
+ }
+
+ if (i >= INT8_MIN) {
+ EW.write(FirstByte::Int8);
+ EW.write(static_cast<int8_t>(i));
+ return;
+ }
+
+ if (i >= INT16_MIN) {
+ EW.write(FirstByte::Int16);
+ EW.write(static_cast<int16_t>(i));
+ return;
+ }
+
+ if (i >= INT32_MIN) {
+ EW.write(FirstByte::Int32);
+ EW.write(static_cast<int32_t>(i));
+ return;
+ }
+
+ EW.write(FirstByte::Int64);
+ EW.write(i);
+}
+
+void Writer::write(uint64_t u) {
+ if (u <= FixMax::PositiveInt) {
+ EW.write(static_cast<uint8_t>(u));
+ return;
+ }
+
+ if (u <= UINT8_MAX) {
+ EW.write(FirstByte::UInt8);
+ EW.write(static_cast<uint8_t>(u));
+ return;
+ }
+
+ if (u <= UINT16_MAX) {
+ EW.write(FirstByte::UInt16);
+ EW.write(static_cast<uint16_t>(u));
+ return;
+ }
+
+ if (u <= UINT32_MAX) {
+ EW.write(FirstByte::UInt32);
+ EW.write(static_cast<uint32_t>(u));
+ return;
+ }
+
+ EW.write(FirstByte::UInt64);
+ EW.write(u);
+}
+
+void Writer::write(double d) {
+ // If no loss of precision, encode as a Float32.
+ double a = std::fabs(d);
+ if (a >= std::numeric_limits<float>::min() &&
+ a <= std::numeric_limits<float>::max()) {
+ EW.write(FirstByte::Float32);
+ EW.write(static_cast<float>(d));
+ } else {
+ EW.write(FirstByte::Float64);
+ EW.write(d);
+ }
+}
+
+void Writer::write(StringRef s) {
+ size_t Size = s.size();
+
+ if (Size <= FixMax::String)
+ EW.write(static_cast<uint8_t>(FixBits::String | Size));
+ else if (!Compatible && Size <= UINT8_MAX) {
+ EW.write(FirstByte::Str8);
+ EW.write(static_cast<uint8_t>(Size));
+ } else if (Size <= UINT16_MAX) {
+ EW.write(FirstByte::Str16);
+ EW.write(static_cast<uint16_t>(Size));
+ } else {
+ assert(Size <= UINT32_MAX && "String object too long to be encoded");
+ EW.write(FirstByte::Str32);
+ EW.write(static_cast<uint32_t>(Size));
+ }
+
+ EW.OS << s;
+}
+
+void Writer::write(MemoryBufferRef Buffer) {
+ assert(!Compatible && "Attempt to write Bin format in compatible mode");
+
+ size_t Size = Buffer.getBufferSize();
+
+ if (Size <= UINT8_MAX) {
+ EW.write(FirstByte::Bin8);
+ EW.write(static_cast<uint8_t>(Size));
+ } else if (Size <= UINT16_MAX) {
+ EW.write(FirstByte::Bin16);
+ EW.write(static_cast<uint16_t>(Size));
+ } else {
+ assert(Size <= UINT32_MAX && "Binary object too long to be encoded");
+ EW.write(FirstByte::Bin32);
+ EW.write(static_cast<uint32_t>(Size));
+ }
+
+ EW.OS.write(Buffer.getBufferStart(), Size);
+}
+
+void Writer::writeArraySize(uint32_t Size) {
+ if (Size <= FixMax::Array) {
+ EW.write(static_cast<uint8_t>(FixBits::Array | Size));
+ return;
+ }
+
+ if (Size <= UINT16_MAX) {
+ EW.write(FirstByte::Array16);
+ EW.write(static_cast<uint16_t>(Size));
+ return;
+ }
+
+ EW.write(FirstByte::Array32);
+ EW.write(Size);
+}
+
+void Writer::writeMapSize(uint32_t Size) {
+ if (Size <= FixMax::Map) {
+ EW.write(static_cast<uint8_t>(FixBits::Map | Size));
+ return;
+ }
+
+ if (Size <= UINT16_MAX) {
+ EW.write(FirstByte::Map16);
+ EW.write(static_cast<uint16_t>(Size));
+ return;
+ }
+
+ EW.write(FirstByte::Map32);
+ EW.write(Size);
+}
+
+void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {
+ size_t Size = Buffer.getBufferSize();
+
+ switch (Size) {
+ case FixLen::Ext1:
+ EW.write(FirstByte::FixExt1);
+ break;
+ case FixLen::Ext2:
+ EW.write(FirstByte::FixExt2);
+ break;
+ case FixLen::Ext4:
+ EW.write(FirstByte::FixExt4);
+ break;
+ case FixLen::Ext8:
+ EW.write(FirstByte::FixExt8);
+ break;
+ case FixLen::Ext16:
+ EW.write(FirstByte::FixExt16);
+ break;
+ default:
+ if (Size <= UINT8_MAX) {
+ EW.write(FirstByte::Ext8);
+ EW.write(static_cast<uint8_t>(Size));
+ } else if (Size <= UINT16_MAX) {
+ EW.write(FirstByte::Ext16);
+ EW.write(static_cast<uint16_t>(Size));
+ } else {
+ assert(Size <= UINT32_MAX && "Ext size too large to be encoded");
+ EW.write(FirstByte::Ext32);
+ EW.write(static_cast<uint32_t>(Size));
+ }
+ }
+
+ EW.write(Type);
+ EW.OS.write(Buffer.getBufferStart(), Size);
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/Wasm.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/Wasm.cpp
new file mode 100644
index 000000000000..babeb12e49ef
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Wasm.cpp
@@ -0,0 +1,86 @@
+//===-- llvm/BinaryFormat/Wasm.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 "llvm/BinaryFormat/Wasm.h"
+
+llvm::StringRef llvm::wasm::toString(wasm::WasmSymbolType Type) {
+ switch (Type) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ return "WASM_SYMBOL_TYPE_FUNCTION";
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ return "WASM_SYMBOL_TYPE_GLOBAL";
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ return "WASM_SYMBOL_TYPE_TABLE";
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ return "WASM_SYMBOL_TYPE_DATA";
+ case wasm::WASM_SYMBOL_TYPE_SECTION:
+ return "WASM_SYMBOL_TYPE_SECTION";
+ case wasm::WASM_SYMBOL_TYPE_TAG:
+ return "WASM_SYMBOL_TYPE_TAG";
+ }
+ llvm_unreachable("unknown symbol type");
+}
+
+llvm::StringRef llvm::wasm::relocTypetoString(uint32_t Type) {
+ switch (Type) {
+#define WASM_RELOC(NAME, VALUE) \
+ case VALUE: \
+ return #NAME;
+#include "llvm/BinaryFormat/WasmRelocs.def"
+#undef WASM_RELOC
+ default:
+ llvm_unreachable("unknown reloc type");
+ }
+}
+
+llvm::StringRef llvm::wasm::sectionTypeToString(uint32_t Type) {
+#define ECase(X) \
+ case wasm::WASM_SEC_##X: \
+ return #X;
+ switch (Type) {
+ ECase(CUSTOM);
+ ECase(TYPE);
+ ECase(IMPORT);
+ ECase(FUNCTION);
+ ECase(TABLE);
+ ECase(MEMORY);
+ ECase(GLOBAL);
+ ECase(EXPORT);
+ ECase(START);
+ ECase(ELEM);
+ ECase(CODE);
+ ECase(DATA);
+ ECase(DATACOUNT);
+ ECase(TAG);
+ default:
+ llvm_unreachable("unknown section type");
+ }
+#undef ECase
+}
+
+bool llvm::wasm::relocTypeHasAddend(uint32_t Type) {
+ switch (Type) {
+ case R_WASM_MEMORY_ADDR_LEB:
+ case R_WASM_MEMORY_ADDR_LEB64:
+ case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_SLEB64:
+ case R_WASM_MEMORY_ADDR_REL_SLEB:
+ case R_WASM_MEMORY_ADDR_REL_SLEB64:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_MEMORY_ADDR_I64:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB:
+ case R_WASM_MEMORY_ADDR_TLS_SLEB64:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_FUNCTION_OFFSET_I64:
+ case R_WASM_SECTION_OFFSET_I32:
+ case R_WASM_MEMORY_ADDR_LOCREL_I32:
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/contrib/llvm-project/llvm/lib/BinaryFormat/XCOFF.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/XCOFF.cpp
new file mode 100644
index 000000000000..6b11ab2ff96b
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/XCOFF.cpp
@@ -0,0 +1,277 @@
+//===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- 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 "llvm/BinaryFormat/XCOFF.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+using namespace llvm;
+
+#define SMC_CASE(A) \
+ case XCOFF::XMC_##A: \
+ return #A;
+StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {
+ switch (SMC) {
+ SMC_CASE(PR)
+ SMC_CASE(RO)
+ SMC_CASE(DB)
+ SMC_CASE(GL)
+ SMC_CASE(XO)
+ SMC_CASE(SV)
+ SMC_CASE(SV64)
+ SMC_CASE(SV3264)
+ SMC_CASE(TI)
+ SMC_CASE(TB)
+ SMC_CASE(RW)
+ SMC_CASE(TC0)
+ SMC_CASE(TC)
+ SMC_CASE(TD)
+ SMC_CASE(DS)
+ SMC_CASE(UA)
+ SMC_CASE(BS)
+ SMC_CASE(UC)
+ SMC_CASE(TL)
+ SMC_CASE(UL)
+ SMC_CASE(TE)
+#undef SMC_CASE
+ }
+
+ // TODO: need to add a test case for "Unknown" and other SMC.
+ return "Unknown";
+}
+
+#define RELOC_CASE(A) \
+ case XCOFF::A: \
+ return #A;
+StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
+ switch (Type) {
+ RELOC_CASE(R_POS)
+ RELOC_CASE(R_RL)
+ RELOC_CASE(R_RLA)
+ RELOC_CASE(R_NEG)
+ RELOC_CASE(R_REL)
+ RELOC_CASE(R_TOC)
+ RELOC_CASE(R_TRL)
+ RELOC_CASE(R_TRLA)
+ RELOC_CASE(R_GL)
+ RELOC_CASE(R_TCL)
+ RELOC_CASE(R_REF)
+ RELOC_CASE(R_BA)
+ RELOC_CASE(R_BR)
+ RELOC_CASE(R_RBA)
+ RELOC_CASE(R_RBR)
+ RELOC_CASE(R_TLS)
+ RELOC_CASE(R_TLS_IE)
+ RELOC_CASE(R_TLS_LD)
+ RELOC_CASE(R_TLS_LE)
+ RELOC_CASE(R_TLSM)
+ RELOC_CASE(R_TLSML)
+ RELOC_CASE(R_TOCU)
+ RELOC_CASE(R_TOCL)
+ }
+ return "Unknown";
+}
+#undef RELOC_CASE
+
+#define LANG_CASE(A) \
+ case XCOFF::TracebackTable::A: \
+ return #A;
+
+StringRef XCOFF::getNameForTracebackTableLanguageId(
+ XCOFF::TracebackTable::LanguageID LangId) {
+ switch (LangId) {
+ LANG_CASE(C)
+ LANG_CASE(Fortran)
+ LANG_CASE(Pascal)
+ LANG_CASE(Ada)
+ LANG_CASE(PL1)
+ LANG_CASE(Basic)
+ LANG_CASE(Lisp)
+ LANG_CASE(Cobol)
+ LANG_CASE(Modula2)
+ LANG_CASE(Rpg)
+ LANG_CASE(PL8)
+ LANG_CASE(Assembly)
+ LANG_CASE(Java)
+ LANG_CASE(ObjectiveC)
+ LANG_CASE(CPlusPlus)
+ }
+ return "Unknown";
+}
+#undef LANG_CASE
+
+Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
+ unsigned FixedParmsNum,
+ unsigned FloatingParmsNum) {
+ SmallString<32> ParmsType;
+ int Bits = 0;
+ unsigned ParsedFixedNum = 0;
+ unsigned ParsedFloatingNum = 0;
+ unsigned ParsedNum = 0;
+ unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
+
+ // In the function PPCFunctionInfo::getParmsType(), when there are no vector
+ // parameters, the 31st bit of ParmsType is always zero even if it indicates a
+ // floating point parameter. The parameter type information is lost. There
+ // are only 8 GPRs used for parameters passing, the floating parameters
+ // also occupy GPRs if there are available, so the 31st bit can never be a
+ // fixed parameter. At the same time, we also do not know whether the zero of
+ // the 31st bit indicates a float or double parameter type here. Therefore, we
+ // ignore the 31st bit.
+ while (Bits < 31 && ParsedNum < ParmsNum) {
+ if (++ParsedNum > 1)
+ ParmsType += ", ";
+ if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
+ // Fixed parameter type.
+ ParmsType += "i";
+ ++ParsedFixedNum;
+ Value <<= 1;
+ ++Bits;
+ } else {
+ if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
+ // Float parameter type.
+ ParmsType += "f";
+ else
+ // Double parameter type.
+ ParmsType += "d";
+ ++ParsedFloatingNum;
+ Value <<= 2;
+ Bits += 2;
+ }
+ }
+
+ // We have more parameters than the 32 Bits could encode.
+ if (ParsedNum < ParmsNum)
+ ParmsType += ", ...";
+
+ if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
+ ParsedFloatingNum > FloatingParmsNum)
+ return createStringError(errc::invalid_argument,
+ "ParmsType encodes can not map to ParmsNum "
+ "parameters in parseParmsType.");
+ return ParmsType;
+}
+
+SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
+ SmallString<32> Res;
+
+ if (Flag & ExtendedTBTableFlag::TB_OS1)
+ Res += "TB_OS1 ";
+ if (Flag & ExtendedTBTableFlag::TB_RESERVED)
+ Res += "TB_RESERVED ";
+ if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
+ Res += "TB_SSP_CANARY ";
+ if (Flag & ExtendedTBTableFlag::TB_OS2)
+ Res += "TB_OS2 ";
+ if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
+ Res += "TB_EH_INFO ";
+ if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
+ Res += "TB_LONGTBTABLE2 ";
+
+ // Two of the bits that haven't got used in the mask.
+ if (Flag & 0x06)
+ Res += "Unknown ";
+
+ // Pop the last space.
+ Res.pop_back();
+ return Res;
+}
+
+Expected<SmallString<32>>
+XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
+ unsigned FloatingParmsNum,
+ unsigned VectorParmsNum) {
+ SmallString<32> ParmsType;
+
+ unsigned ParsedFixedNum = 0;
+ unsigned ParsedFloatingNum = 0;
+ unsigned ParsedVectorNum = 0;
+ unsigned ParsedNum = 0;
+ unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
+
+ for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
+ if (++ParsedNum > 1)
+ ParmsType += ", ";
+
+ switch (Value & TracebackTable::ParmTypeMask) {
+ case TracebackTable::ParmTypeIsFixedBits:
+ ParmsType += "i";
+ ++ParsedFixedNum;
+ break;
+ case TracebackTable::ParmTypeIsVectorBits:
+ ParmsType += "v";
+ ++ParsedVectorNum;
+ break;
+ case TracebackTable::ParmTypeIsFloatingBits:
+ ParmsType += "f";
+ ++ParsedFloatingNum;
+ break;
+ case TracebackTable::ParmTypeIsDoubleBits:
+ ParmsType += "d";
+ ++ParsedFloatingNum;
+ break;
+ default:
+ assert(false && "Unrecognized bits in ParmsType.");
+ }
+ Value <<= 2;
+ }
+
+ // We have more parameters than the 32 Bits could encode.
+ if (ParsedNum < ParmsNum)
+ ParmsType += ", ...";
+
+ if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
+ ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
+ return createStringError(
+ errc::invalid_argument,
+ "ParmsType encodes can not map to ParmsNum parameters "
+ "in parseParmsTypeWithVecInfo.");
+
+ return ParmsType;
+}
+
+Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
+ unsigned ParmsNum) {
+ SmallString<32> ParmsType;
+ unsigned ParsedNum = 0;
+ for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
+ if (++ParsedNum > 1)
+ ParmsType += ", ";
+ switch (Value & TracebackTable::ParmTypeMask) {
+ case TracebackTable::ParmTypeIsVectorCharBit:
+ ParmsType += "vc";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorShortBit:
+ ParmsType += "vs";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorIntBit:
+ ParmsType += "vi";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorFloatBit:
+ ParmsType += "vf";
+ break;
+ }
+
+ Value <<= 2;
+ }
+
+ // We have more parameters than the 32 Bits could encode.
+ if (ParsedNum < ParmsNum)
+ ParmsType += ", ...";
+
+ if (Value != 0u)
+ return createStringError(errc::invalid_argument,
+ "ParmsType encodes more than ParmsNum parameters "
+ "in parseVectorParmsType.");
+ return ParmsType;
+}