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.cpp316
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp730
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Magic.cpp228
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Minidump.cpp14
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocument.cpp245
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp249
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp254
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp208
-rw-r--r--contrib/llvm-project/llvm/lib/BinaryFormat/Wasm.cpp51
9 files changed, 2295 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..3f36dff9f55c
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/AMDGPUMetadataVerifier.cpp
@@ -0,0 +1,316 @@
+//===- 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/Support/AMDGPUMetadata.h"
+
+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,
+ Optional<size_t> Size) {
+ if (!Node.isArray())
+ return false;
+ auto &Array = Node.getArray();
+ if (Size && Array.size() != *Size)
+ return false;
+ for (auto &Item : Array)
+ if (!verifyNode(Item))
+ return false;
+
+ return true;
+}
+
+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_global_offset_x", true)
+ .Case("hidden_global_offset_y", true)
+ .Case("hidden_global_offset_z", true)
+ .Case("hidden_none", true)
+ .Case("hidden_printf_buffer", true)
+ .Case("hidden_default_queue", true)
+ .Case("hidden_completion_action", true)
+ .Case("hidden_multigrid_sync_arg", true)
+ .Default(false);
+ }))
+ return false;
+ if (!verifyScalarEntry(ArgsMap, ".value_type", true,
+ msgpack::Type::String,
+ [](msgpack::DocNode &SNode) {
+ return StringSwitch<bool>(SNode.getString())
+ .Case("struct", true)
+ .Case("i8", true)
+ .Case("u8", true)
+ .Case("i16", true)
+ .Case("u16", true)
+ .Case("f16", true)
+ .Case("i32", true)
+ .Case("u32", true)
+ .Case("f32", true)
+ .Case("i64", true)
+ .Case("u64", true)
+ .Case("f64", 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 (!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;
+
+ 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/Dwarf.cpp b/contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp
new file mode 100644
index 000000000000..eb6bd33ce583
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -0,0 +1,730 @@
+//===-- 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) \
+ 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) \
+ .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) \
+ 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) \
+ 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";
+ }
+}
+
+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)
+ .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::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"
+ }
+}
+
+Optional<unsigned> llvm::dwarf::LanguageLowerBound(dwarf::SourceLanguage Lang) {
+ switch (Lang) {
+ default:
+ return None;
+#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::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::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);
+ }
+
+ 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"
+ }
+}
+
+Optional<uint8_t> llvm::dwarf::getFixedFormByteSize(dwarf::Form Form,
+ FormParams Params) {
+ switch (Form) {
+ case DW_FORM_addr:
+ if (Params)
+ return Params.AddrSize;
+ return None;
+
+ 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 None;
+
+ case DW_FORM_ref_addr:
+ if (Params)
+ return Params.getRefAddrByteSize();
+ return None;
+
+ 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 None;
+
+ 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 None;
+}
+
+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;
+}
+
+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[];
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..7dfe23690a50
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Magic.cpp
@@ -0,0 +1,228 @@
+//===- 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/BinaryFormat/COFF.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/FileSystem.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 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 '\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;
+ }
+ break;
+ }
+ case 0xF0: // PowerPC Windows
+ case 0x83: // Alpha 32-bit
+ case 0x84: // Alpha 64-bit
+ case 0x66: // MPS R4000 Windows
+ case 0x50: // mc68K
+ case 0x4c: // 80386 Windows
+ case 0xc4: // ARMNT Windows
+ if (Magic[1] == 0x01)
+ return file_magic::coff_object;
+ LLVM_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;
+
+ default:
+ break;
+ }
+ return file_magic::unknown;
+}
+
+std::error_code llvm::identify_magic(const Twine &Path, file_magic &Result) {
+ auto FileOrError = MemoryBuffer::getFile(Path, -1LL, 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..e12c54a37ad0
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocument.cpp
@@ -0,0 +1,245 @@
+//===-- 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());
+ MapTy::value_type Entry(Key, DocNode());
+ auto ItAndInserted = Map->insert(Entry);
+ if (ItAndInserted.second) {
+ // Ensure a new element has its KindAndDoc initialized.
+ ItAndInserted.first->second = getDocument()->getNode();
+ }
+ return ItAndInserted.first->second;
+}
+
+/// 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()->getNode());
+ }
+ return (*Array)[Index];
+}
+
+// A level in the document reading stack.
+struct StackLevel {
+ DocNode Node;
+ size_t Length;
+ // Points to map entry when we have just processed a map key.
+ DocNode *MapEntry;
+};
+
+// Read a document from a binary msgpack blob.
+// 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.
+bool Document::readFromBlob(StringRef Blob, bool Multi) {
+ 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, (size_t)-1, nullptr}));
+ }
+ 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.
+ if (Stack.empty())
+ Root = Node;
+ else if (Stack.back().Node.getKind() == Type::Array) {
+ // Reading an array entry.
+ auto &Array = Stack.back().Node.getArray();
+ Array.push_back(Node);
+ } else {
+ auto &Map = Stack.back().Node.getMap();
+ if (!Stack.back().MapEntry) {
+ // Reading a map key.
+ Stack.back().MapEntry = &Map[Node];
+ } else {
+ // Reading the value for the map key read in the last iteration.
+ *Stack.back().MapEntry = Node;
+ Stack.back().MapEntry = nullptr;
+ }
+ }
+
+ // See if we're starting a new array or map.
+ switch (Node.getKind()) {
+ case msgpack::Type::Array:
+ case msgpack::Type::Map:
+ Stack.push_back(StackLevel({Node, Obj.Length, nullptr}));
+ break;
+ default:
+ break;
+ }
+
+ // Pop finished stack levels.
+ while (!Stack.empty()) {
+ if (Stack.back().Node.getKind() == msgpack::Type::Array) {
+ if (Stack.back().Node.getArray().size() != Stack.back().Length)
+ break;
+ } else {
+ if (Stack.back().MapEntry ||
+ Stack.back().Node.getMap().size() != Stack.back().Length)
+ 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;
+ 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..1d9c81ef8ebc
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp
@@ -0,0 +1,249 @@
+//===-- MsgPackDocumentYAML.cpp - MsgPack Document YAML interface -------*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// 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..872a6e0e29f8
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp
@@ -0,0 +1,254 @@
+//===- 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"
+
+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..b4d70e8f78c1
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp
@@ -0,0 +1,208 @@
+//===- 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"
+
+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..d46be481edb3
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/BinaryFormat/Wasm.cpp
@@ -0,0 +1,51 @@
+//===-- 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"
+
+std::string 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_DATA:
+ return "WASM_SYMBOL_TYPE_DATA";
+ case wasm::WASM_SYMBOL_TYPE_SECTION:
+ return "WASM_SYMBOL_TYPE_SECTION";
+ case wasm::WASM_SYMBOL_TYPE_EVENT:
+ return "WASM_SYMBOL_TYPE_EVENT";
+ }
+ llvm_unreachable("unknown symbol type");
+}
+
+std::string 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");
+ }
+}
+
+bool llvm::wasm::relocTypeHasAddend(uint32_t Type) {
+ switch (Type) {
+ case R_WASM_MEMORY_ADDR_LEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_REL_SLEB:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
+ return true;
+ default:
+ return false;
+ }
+}