[llvm] r356753 - [ObjectYAML] Add basic minidump generation support
Kristina Brooks via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 10 20:38:29 PDT 2019
Hi,
This doesn't build with modules enabled (using Clang r374503):
FAILED: lib/ObjectYAML/CMakeFiles/LLVMObjectYAML.dir/MinidumpYAML.cpp.o
/o/b/llvm-10/408/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG
-D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS
-D__STDC_LIMIT_MACROS -Ilib/ObjectYAML
-I/home/src2/llvm-tainted/lib/ObjectYAML -Iinclude
-I/home/src2/llvm-tainted/include -O3 -march=native
-Wno-unused-command-line-argument -gline-tables-only -stdlib=libc++
-fPIC -fvisibility-inlines-hidden -Werror=date-time
-Werror=unguarded-availability-new -std=c++14 -fmodules
-fmodules-cache-path=/o/b/llvm-10/409/module.cache -Xclang
-fmodules-local-submodule-visibility -Wall -Wextra
-Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wmissing-field-initializers -pedantic -Wno-long-long
-Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type
-Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion
-fdiagnostics-color -ffunction-sections -fdata-sections -flto=thin -O3
-UNDEBUG -fno-exceptions -fno-rtti -MD -MT
lib/ObjectYAML/CMakeFiles/LLVMObjectYAML.dir/MinidumpYAML.cpp.o -MF
lib/ObjectYAML/CMakeFiles/LLVMObjectYAML.dir/MinidumpYAML.cpp.o.d -o
lib/ObjectYAML/CMakeFiles/LLVMObjectYAML.dir/MinidumpYAML.cpp.o -c
/home/src2/llvm-tainted/lib/ObjectYAML/MinidumpYAML.cpp
In module 'LLVM_Utils' imported from
/home/src2/llvm-tainted/include/llvm/ObjectYAML/YAML.h:12:
/home/src2/llvm-tainted/include/llvm/Support/YAMLTraits.h:819:48:
error: call to function 'operator&' that is neither visible in the
template definition nor found by argument-dependent lookup
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
^
/home/src2/llvm-tainted/include/llvm/BinaryFormat/MinidumpConstants.def:118:1:
note: in instantiation of function template specialization
'llvm::yaml::IO::bitSetCase<llvm::minidump::MemoryProtection>'
requested here
HANDLE_MDMP_PROTECT(0x01, NoAccess, PAGE_NO_ACCESS)
^
/home/src2/llvm-tainted/lib/ObjectYAML/MinidumpYAML.cpp:119:6: note:
expanded from macro 'HANDLE_MDMP_PROTECT'
IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);
^
/home/src2/llvm-tainted/include/llvm/ADT/BitmaskEnum.h:111:3: note:
'operator&' should be declared prior to the call site or in namespace
'llvm::minidump'
E operator&(E LHS, E RHS) {
On Fri, Mar 22, 2019 at 2:46 PM Pavel Labath via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: labath
> Date: Fri Mar 22 07:47:26 2019
> New Revision: 356753
>
> URL: http://llvm.org/viewvc/llvm-project?rev=356753&view=rev
> Log:
> [ObjectYAML] Add basic minidump generation support
>
> Summary:
> This patch adds the ability to read a yaml form of a minidump file and
> write it out as binary. Apart from the minidump header and the stream
> directory, only three basic stream kinds are supported:
> - Text: This kind is used for streams which contain textual data. This
> is typically the contents of a /proc file on linux (e.g.
> /proc/PID/maps). In this case, we just put the raw stream contents
> into the yaml.
> - SystemInfo: This stream contains various bits of information about the
> host system in binary form. We expose the data in a structured form.
> - Raw: This kind is used as a fallback when we don't have any special
> knowledge about the stream. In this case, we just print the stream
> contents in hex.
>
> For this code to be really useful, more stream kinds will need to be
> added (particularly for things like lists of memory regions and loaded
> modules). However, these can be added incrementally.
>
> Reviewers: jhenderson, zturner, clayborg, aprantl
>
> Subscribers: mgorny, lemo, llvm-commits, lldb-commits
>
> Tags: #llvm
>
> Differential Revision: https://reviews.llvm.org/D59482
>
> Added:
> llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h
> llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp
> llvm/trunk/test/tools/yaml2obj/minidump-raw-stream-small-size.yaml
> llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-long.yaml
> llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-not-hex.yaml
> llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-short.yaml
> llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-long.yaml
> llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-short.yaml
> llvm/trunk/tools/yaml2obj/yaml2minidump.cpp
> llvm/trunk/unittests/ObjectYAML/MinidumpYAMLTest.cpp
> Modified:
> llvm/trunk/include/llvm/ObjectYAML/ObjectYAML.h
> llvm/trunk/lib/ObjectYAML/CMakeLists.txt
> llvm/trunk/lib/ObjectYAML/ObjectYAML.cpp
> llvm/trunk/tools/yaml2obj/CMakeLists.txt
> llvm/trunk/tools/yaml2obj/yaml2obj.cpp
> llvm/trunk/tools/yaml2obj/yaml2obj.h
> llvm/trunk/unittests/ObjectYAML/CMakeLists.txt
>
> Added: llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h (added)
> +++ llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,156 @@
> +//===- MinidumpYAML.h - Minidump YAMLIO implementation ----------*- C++ -*-===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_OBJECTYAML_MINIDUMPYAML_H
> +#define LLVM_OBJECTYAML_MINIDUMPYAML_H
> +
> +#include "llvm/BinaryFormat/Minidump.h"
> +#include "llvm/ObjectYAML/YAML.h"
> +#include "llvm/Support/YAMLTraits.h"
> +
> +namespace llvm {
> +namespace MinidumpYAML {
> +
> +/// The base class for all minidump streams. The "Type" of the stream
> +/// corresponds to the Stream Type field in the minidump file. The "Kind" field
> +/// specifies how are we going to treat it. For highly specialized streams (e.g.
> +/// SystemInfo), there is a 1:1 mapping between Types and Kinds, but in general
> +/// one stream Kind can be used to represent multiple stream Types (e.g. any
> +/// unrecognised stream Type will be handled via RawContentStream). The mapping
> +/// from Types to Kinds is fixed and given by the static getKind function.
> +struct Stream {
> + enum class StreamKind {
> + RawContent,
> + SystemInfo,
> + TextContent,
> + };
> +
> + Stream(StreamKind Kind, minidump::StreamType Type) : Kind(Kind), Type(Type) {}
> + virtual ~Stream(); // anchor
> +
> + const StreamKind Kind;
> + const minidump::StreamType Type;
> +
> + /// Get the stream Kind used for representing streams of a given Type.
> + static StreamKind getKind(minidump::StreamType Type);
> +
> + /// Create an empty stream of the given Type.
> + static std::unique_ptr<Stream> create(minidump::StreamType Type);
> +};
> +
> +/// A minidump stream represented as a sequence of hex bytes. This is used as a
> +/// fallback when no other stream kind is suitable.
> +struct RawContentStream : public Stream {
> + yaml::BinaryRef Content;
> + yaml::Hex32 Size;
> +
> + RawContentStream(minidump::StreamType Type, ArrayRef<uint8_t> Content = {})
> + : Stream(StreamKind::RawContent, Type), Content(Content),
> + Size(Content.size()) {}
> +
> + static bool classof(const Stream *S) {
> + return S->Kind == StreamKind::RawContent;
> + }
> +};
> +
> +/// SystemInfo minidump stream.
> +struct SystemInfoStream : public Stream {
> + minidump::SystemInfo Info;
> +
> + explicit SystemInfoStream(const minidump::SystemInfo &Info)
> + : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
> + Info(Info) {}
> +
> + SystemInfoStream()
> + : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo) {
> + memset(&Info, 0, sizeof(Info));
> + }
> +
> + static bool classof(const Stream *S) {
> + return S->Kind == StreamKind::SystemInfo;
> + }
> +};
> +
> +/// A StringRef, which is printed using YAML block notation.
> +LLVM_YAML_STRONG_TYPEDEF(StringRef, BlockStringRef)
> +
> +/// A minidump stream containing textual data (typically, the contents of a
> +/// /proc/<pid> file on linux).
> +struct TextContentStream : public Stream {
> + BlockStringRef Text;
> +
> + TextContentStream(minidump::StreamType Type, StringRef Text = {})
> + : Stream(StreamKind::TextContent, Type), Text(Text) {}
> +
> + static bool classof(const Stream *S) {
> + return S->Kind == StreamKind::TextContent;
> + }
> +};
> +
> +/// The top level structure representing a minidump object, consisting of a
> +/// minidump header, and zero or more streams. To construct an Object from a
> +/// minidump file, use the static create function. To serialize to/from yaml,
> +/// use the appropriate streaming operator on a yaml stream.
> +struct Object {
> + Object() = default;
> + Object(const Object &) = delete;
> + Object &operator=(const Object &) = delete;
> + Object(Object &&) = default;
> + Object &operator=(Object &&) = default;
> +
> + /// The minidump header.
> + minidump::Header Header;
> +
> + /// The list of streams in this minidump object.
> + std::vector<std::unique_ptr<Stream>> Streams;
> +};
> +
> +/// Serialize the minidump file represented by Obj to OS in binary form.
> +void writeAsBinary(Object &Obj, raw_ostream &OS);
> +
> +/// Serialize the yaml string as a minidump file to OS in binary form.
> +Error writeAsBinary(StringRef Yaml, raw_ostream &OS);
> +
> +} // namespace MinidumpYAML
> +
> +namespace yaml {
> +template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> {
> + static void output(const MinidumpYAML::BlockStringRef &Text, void *,
> + raw_ostream &OS) {
> + OS << Text;
> + }
> +
> + static StringRef input(StringRef Scalar, void *,
> + MinidumpYAML::BlockStringRef &Text) {
> + Text = Scalar;
> + return "";
> + }
> +};
> +
> +template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> {
> + static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
> + static StringRef validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
> +};
> +
> +} // namespace yaml
> +
> +} // namespace llvm
> +
> +LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture)
> +LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform)
> +LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType)
> +
> +LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo)
> +LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo)
> +LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info)
> +
> +LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MinidumpYAML::Stream>)
> +
> +LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
> +
> +#endif // LLVM_OBJECTYAML_MINIDUMPYAML_H
>
> Modified: llvm/trunk/include/llvm/ObjectYAML/ObjectYAML.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/ObjectYAML.h?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ObjectYAML/ObjectYAML.h (original)
> +++ llvm/trunk/include/llvm/ObjectYAML/ObjectYAML.h Fri Mar 22 07:47:26 2019
> @@ -12,6 +12,7 @@
> #include "llvm/ObjectYAML/COFFYAML.h"
> #include "llvm/ObjectYAML/ELFYAML.h"
> #include "llvm/ObjectYAML/MachOYAML.h"
> +#include "llvm/ObjectYAML/MinidumpYAML.h"
> #include "llvm/ObjectYAML/WasmYAML.h"
> #include "llvm/Support/YAMLTraits.h"
> #include <memory>
> @@ -26,6 +27,7 @@ struct YamlObjectFile {
> std::unique_ptr<COFFYAML::Object> Coff;
> std::unique_ptr<MachOYAML::Object> MachO;
> std::unique_ptr<MachOYAML::UniversalBinary> FatMachO;
> + std::unique_ptr<MinidumpYAML::Object> Minidump;
> std::unique_ptr<WasmYAML::Object> Wasm;
> };
>
>
> Modified: llvm/trunk/lib/ObjectYAML/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CMakeLists.txt?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ObjectYAML/CMakeLists.txt (original)
> +++ llvm/trunk/lib/ObjectYAML/CMakeLists.txt Fri Mar 22 07:47:26 2019
> @@ -10,6 +10,7 @@ add_llvm_library(LLVMObjectYAML
> ELFYAML.cpp
> MachOYAML.cpp
> ObjectYAML.cpp
> + MinidumpYAML.cpp
> WasmYAML.cpp
> YAML.cpp
> )
>
> Added: llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp (added)
> +++ llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,385 @@
> +//===- MinidumpYAML.cpp - Minidump YAMLIO implementation ------------------===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/ObjectYAML/MinidumpYAML.h"
> +
> +using namespace llvm;
> +using namespace llvm::MinidumpYAML;
> +using namespace llvm::minidump;
> +
> +namespace {
> +class BlobAllocator {
> +public:
> + size_t tell() const { return NextOffset; }
> +
> + size_t AllocateCallback(size_t Size,
> + std::function<void(raw_ostream &)> Callback) {
> + size_t Offset = NextOffset;
> + NextOffset += Size;
> + Callbacks.push_back(std::move(Callback));
> + return Offset;
> + }
> +
> + size_t AllocateBytes(ArrayRef<uint8_t> Data) {
> + return AllocateCallback(
> + Data.size(), [Data](raw_ostream &OS) { OS << toStringRef(Data); });
> + }
> +
> + template <typename T> size_t AllocateArray(ArrayRef<T> Data) {
> + return AllocateBytes({reinterpret_cast<const uint8_t *>(Data.data()),
> + sizeof(T) * Data.size()});
> + }
> +
> + template <typename T> size_t AllocateObject(const T &Data) {
> + return AllocateArray(makeArrayRef(Data));
> + }
> +
> + void writeTo(raw_ostream &OS) const;
> +
> +private:
> + size_t NextOffset = 0;
> +
> + std::vector<std::function<void(raw_ostream &)>> Callbacks;
> +};
> +} // namespace
> +
> +void BlobAllocator::writeTo(raw_ostream &OS) const {
> + size_t BeginOffset = OS.tell();
> + for (const auto &Callback : Callbacks)
> + Callback(OS);
> + assert(OS.tell() == BeginOffset + NextOffset &&
> + "Callbacks wrote an unexpected number of bytes.");
> + (void)BeginOffset;
> +}
> +
> +/// Perform an optional yaml-mapping of an endian-aware type EndianType. The
> +/// only purpose of this function is to avoid casting the Default value to the
> +/// endian type;
> +template <typename EndianType>
> +static inline void mapOptional(yaml::IO &IO, const char *Key, EndianType &Val,
> + typename EndianType::value_type Default) {
> + IO.mapOptional(Key, Val, EndianType(Default));
> +}
> +
> +/// Yaml-map an endian-aware type EndianType as some other type MapType.
> +template <typename MapType, typename EndianType>
> +static inline void mapRequiredAs(yaml::IO &IO, const char *Key,
> + EndianType &Val) {
> + MapType Mapped = static_cast<typename EndianType::value_type>(Val);
> + IO.mapRequired(Key, Mapped);
> + Val = static_cast<typename EndianType::value_type>(Mapped);
> +}
> +
> +/// Perform an optional yaml-mapping of an endian-aware type EndianType as some
> +/// other type MapType.
> +template <typename MapType, typename EndianType>
> +static inline void mapOptionalAs(yaml::IO &IO, const char *Key, EndianType &Val,
> + MapType Default) {
> + MapType Mapped = static_cast<typename EndianType::value_type>(Val);
> + IO.mapOptional(Key, Mapped, Default);
> + Val = static_cast<typename EndianType::value_type>(Mapped);
> +}
> +
> +namespace {
> +/// Return the appropriate yaml Hex type for a given endian-aware type.
> +template <typename EndianType> struct HexType;
> +template <> struct HexType<support::ulittle16_t> { using type = yaml::Hex16; };
> +template <> struct HexType<support::ulittle32_t> { using type = yaml::Hex32; };
> +template <> struct HexType<support::ulittle64_t> { using type = yaml::Hex64; };
> +} // namespace
> +
> +/// Yaml-map an endian-aware type as an appropriately-sized hex value.
> +template <typename EndianType>
> +static inline void mapRequiredHex(yaml::IO &IO, const char *Key,
> + EndianType &Val) {
> + mapRequiredAs<typename HexType<EndianType>::type>(IO, Key, Val);
> +}
> +
> +/// Perform an optional yaml-mapping of an endian-aware type as an
> +/// appropriately-sized hex value.
> +template <typename EndianType>
> +static inline void mapOptionalHex(yaml::IO &IO, const char *Key,
> + EndianType &Val,
> + typename EndianType::value_type Default) {
> + mapOptionalAs<typename HexType<EndianType>::type>(IO, Key, Val, Default);
> +}
> +
> +Stream::~Stream() = default;
> +
> +Stream::StreamKind Stream::getKind(StreamType Type) {
> + switch (Type) {
> + case StreamType::SystemInfo:
> + return StreamKind::SystemInfo;
> + case StreamType::LinuxCPUInfo:
> + case StreamType::LinuxProcStatus:
> + case StreamType::LinuxLSBRelease:
> + case StreamType::LinuxCMDLine:
> + case StreamType::LinuxMaps:
> + case StreamType::LinuxProcStat:
> + case StreamType::LinuxProcUptime:
> + return StreamKind::TextContent;
> + default:
> + return StreamKind::RawContent;
> + }
> +}
> +
> +std::unique_ptr<Stream> Stream::create(StreamType Type) {
> + StreamKind Kind = getKind(Type);
> + switch (Kind) {
> + case StreamKind::RawContent:
> + return llvm::make_unique<RawContentStream>(Type);
> + case StreamKind::SystemInfo:
> + return llvm::make_unique<SystemInfoStream>();
> + case StreamKind::TextContent:
> + return llvm::make_unique<TextContentStream>(Type);
> + }
> + llvm_unreachable("Unhandled stream kind!");
> +}
> +
> +void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
> + IO &IO, ProcessorArchitecture &Arch) {
> +#define HANDLE_MDMP_ARCH(CODE, NAME) \
> + IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
> +#include "llvm/BinaryFormat/MinidumpConstants.def"
> + IO.enumFallback<Hex16>(Arch);
> +}
> +
> +void yaml::ScalarEnumerationTraits<OSPlatform>::enumeration(IO &IO,
> + OSPlatform &Plat) {
> +#define HANDLE_MDMP_PLATFORM(CODE, NAME) \
> + IO.enumCase(Plat, #NAME, OSPlatform::NAME);
> +#include "llvm/BinaryFormat/MinidumpConstants.def"
> + IO.enumFallback<Hex32>(Plat);
> +}
> +
> +void yaml::ScalarEnumerationTraits<StreamType>::enumeration(IO &IO,
> + StreamType &Type) {
> +#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) \
> + IO.enumCase(Type, #NAME, StreamType::NAME);
> +#include "llvm/BinaryFormat/MinidumpConstants.def"
> + IO.enumFallback<Hex32>(Type);
> +}
> +
> +void yaml::MappingTraits<CPUInfo::ArmInfo>::mapping(IO &IO,
> + CPUInfo::ArmInfo &Info) {
> + mapRequiredHex(IO, "CPUID", Info.CPUID);
> + mapOptionalHex(IO, "ELF hwcaps", Info.ElfHWCaps, 0);
> +}
> +
> +namespace {
> +template <std::size_t N> struct FixedSizeHex {
> + FixedSizeHex(uint8_t (&Storage)[N]) : Storage(Storage) {}
> +
> + uint8_t (&Storage)[N];
> +};
> +} // namespace
> +
> +namespace llvm {
> +namespace yaml {
> +template <std::size_t N> struct ScalarTraits<FixedSizeHex<N>> {
> + static void output(const FixedSizeHex<N> &Fixed, void *, raw_ostream &OS) {
> + OS << toHex(makeArrayRef(Fixed.Storage));
> + }
> +
> + static StringRef input(StringRef Scalar, void *, FixedSizeHex<N> &Fixed) {
> + if (!all_of(Scalar, isHexDigit))
> + return "Invalid hex digit in input";
> + if (Scalar.size() < 2 * N)
> + return "String too short";
> + if (Scalar.size() > 2 * N)
> + return "String too long";
> + copy(fromHex(Scalar), Fixed.Storage);
> + return "";
> + }
> +
> + static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
> +};
> +} // namespace yaml
> +} // namespace llvm
> +void yaml::MappingTraits<CPUInfo::OtherInfo>::mapping(
> + IO &IO, CPUInfo::OtherInfo &Info) {
> + FixedSizeHex<sizeof(Info.ProcessorFeatures)> Features(Info.ProcessorFeatures);
> + IO.mapRequired("Features", Features);
> +}
> +
> +namespace {
> +/// A type which only accepts strings of a fixed size for yaml conversion.
> +template <std::size_t N> struct FixedSizeString {
> + FixedSizeString(char (&Storage)[N]) : Storage(Storage) {}
> +
> + char (&Storage)[N];
> +};
> +} // namespace
> +
> +namespace llvm {
> +namespace yaml {
> +template <std::size_t N> struct ScalarTraits<FixedSizeString<N>> {
> + static void output(const FixedSizeString<N> &Fixed, void *, raw_ostream &OS) {
> + OS << StringRef(Fixed.Storage, N);
> + }
> +
> + static StringRef input(StringRef Scalar, void *, FixedSizeString<N> &Fixed) {
> + if (Scalar.size() < N)
> + return "String too short";
> + if (Scalar.size() > N)
> + return "String too long";
> + copy(Scalar, Fixed.Storage);
> + return "";
> + }
> +
> + static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
> +};
> +} // namespace yaml
> +} // namespace llvm
> +
> +void yaml::MappingTraits<CPUInfo::X86Info>::mapping(IO &IO,
> + CPUInfo::X86Info &Info) {
> + FixedSizeString<sizeof(Info.VendorID)> VendorID(Info.VendorID);
> + IO.mapRequired("Vendor ID", VendorID);
> +
> + mapRequiredHex(IO, "Version Info", Info.VersionInfo);
> + mapRequiredHex(IO, "Feature Info", Info.FeatureInfo);
> + mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);
> +}
> +
> +static void streamMapping(yaml::IO &IO, RawContentStream &Stream) {
> + IO.mapOptional("Content", Stream.Content);
> + IO.mapOptional("Size", Stream.Size, Stream.Content.binary_size());
> +}
> +
> +static StringRef streamValidate(RawContentStream &Stream) {
> + if (Stream.Size.value < Stream.Content.binary_size())
> + return "Stream size must be greater or equal to the content size";
> + return "";
> +}
> +
> +static void streamMapping(yaml::IO &IO, SystemInfoStream &Stream) {
> + SystemInfo &Info = Stream.Info;
> + IO.mapRequired("Processor Arch", Info.ProcessorArch);
> + mapOptional(IO, "Processor Level", Info.ProcessorLevel, 0);
> + mapOptional(IO, "Processor Revision", Info.ProcessorRevision, 0);
> + IO.mapOptional("Number of Processors", Info.NumberOfProcessors, 0);
> + IO.mapOptional("Product type", Info.ProductType, 0);
> + mapOptional(IO, "Major Version", Info.MajorVersion, 0);
> + mapOptional(IO, "Minor Version", Info.MinorVersion, 0);
> + mapOptional(IO, "Build Number", Info.BuildNumber, 0);
> + IO.mapRequired("Platform ID", Info.PlatformId);
> + mapOptionalHex(IO, "CSD Version RVA", Info.CSDVersionRVA, 0);
> + mapOptionalHex(IO, "Suite Mask", Info.SuiteMask, 0);
> + mapOptionalHex(IO, "Reserved", Info.Reserved, 0);
> + switch (static_cast<ProcessorArchitecture>(Info.ProcessorArch)) {
> + case ProcessorArchitecture::X86:
> + case ProcessorArchitecture::AMD64:
> + IO.mapOptional("CPU", Info.CPU.X86);
> + break;
> + case ProcessorArchitecture::ARM:
> + case ProcessorArchitecture::ARM64:
> + IO.mapOptional("CPU", Info.CPU.Arm);
> + break;
> + default:
> + IO.mapOptional("CPU", Info.CPU.Other);
> + break;
> + }
> +}
> +
> +static void streamMapping(yaml::IO &IO, TextContentStream &Stream) {
> + IO.mapOptional("Text", Stream.Text);
> +}
> +
> +void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
> + yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
> + StreamType Type;
> + if (IO.outputting())
> + Type = S->Type;
> + IO.mapRequired("Type", Type);
> +
> + if (!IO.outputting())
> + S = MinidumpYAML::Stream::create(Type);
> + switch (S->Kind) {
> + case MinidumpYAML::Stream::StreamKind::RawContent:
> + streamMapping(IO, llvm::cast<RawContentStream>(*S));
> + break;
> + case MinidumpYAML::Stream::StreamKind::SystemInfo:
> + streamMapping(IO, llvm::cast<SystemInfoStream>(*S));
> + break;
> + case MinidumpYAML::Stream::StreamKind::TextContent:
> + streamMapping(IO, llvm::cast<TextContentStream>(*S));
> + break;
> + }
> +}
> +
> +StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
> + yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
> + switch (S->Kind) {
> + case MinidumpYAML::Stream::StreamKind::RawContent:
> + return streamValidate(cast<RawContentStream>(*S));
> + case MinidumpYAML::Stream::StreamKind::SystemInfo:
> + case MinidumpYAML::Stream::StreamKind::TextContent:
> + return "";
> + }
> + llvm_unreachable("Fully covered switch above!");
> +}
> +
> +void yaml::MappingTraits<Object>::mapping(IO &IO, Object &O) {
> + IO.mapTag("!minidump", true);
> + mapOptionalHex(IO, "Signature", O.Header.Signature, Header::MagicSignature);
> + mapOptionalHex(IO, "Version", O.Header.Version, Header::MagicVersion);
> + mapOptionalHex(IO, "Flags", O.Header.Flags, 0);
> + IO.mapRequired("Streams", O.Streams);
> +}
> +
> +static Directory layout(BlobAllocator &File, Stream &S) {
> + Directory Result;
> + Result.Type = S.Type;
> + Result.Location.RVA = File.tell();
> + switch (S.Kind) {
> + case Stream::StreamKind::RawContent: {
> + RawContentStream &Raw = cast<RawContentStream>(S);
> + File.AllocateCallback(Raw.Size, [&Raw](raw_ostream &OS) {
> + Raw.Content.writeAsBinary(OS);
> + assert(Raw.Content.binary_size() <= Raw.Size);
> + OS << std::string(Raw.Size - Raw.Content.binary_size(), '\0');
> + });
> + break;
> + }
> + case Stream::StreamKind::SystemInfo:
> + File.AllocateObject(cast<SystemInfoStream>(S).Info);
> + break;
> + case Stream::StreamKind::TextContent:
> + File.AllocateArray(arrayRefFromStringRef(cast<TextContentStream>(S).Text));
> + break;
> + }
> + Result.Location.DataSize = File.tell() - Result.Location.RVA;
> + return Result;
> +}
> +
> +void MinidumpYAML::writeAsBinary(Object &Obj, raw_ostream &OS) {
> + BlobAllocator File;
> + File.AllocateObject(Obj.Header);
> +
> + std::vector<Directory> StreamDirectory(Obj.Streams.size());
> + Obj.Header.StreamDirectoryRVA =
> + File.AllocateArray(makeArrayRef(StreamDirectory));
> + Obj.Header.NumberOfStreams = StreamDirectory.size();
> +
> + for (auto &Stream : enumerate(Obj.Streams))
> + StreamDirectory[Stream.index()] = layout(File, *Stream.value());
> +
> + File.writeTo(OS);
> +}
> +
> +Error MinidumpYAML::writeAsBinary(StringRef Yaml, raw_ostream &OS) {
> + yaml::Input Input(Yaml);
> + Object Obj;
> + Input >> Obj;
> + if (std::error_code EC = Input.error())
> + return errorCodeToError(EC);
> +
> + writeAsBinary(Obj, OS);
> + return Error::success();
> +}
>
> Modified: llvm/trunk/lib/ObjectYAML/ObjectYAML.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ObjectYAML.cpp?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ObjectYAML/ObjectYAML.cpp (original)
> +++ llvm/trunk/lib/ObjectYAML/ObjectYAML.cpp Fri Mar 22 07:47:26 2019
> @@ -45,6 +45,9 @@ void MappingTraits<YamlObjectFile>::mapp
> ObjectFile.FatMachO.reset(new MachOYAML::UniversalBinary());
> MappingTraits<MachOYAML::UniversalBinary>::mapping(IO,
> *ObjectFile.FatMachO);
> + } else if (IO.mapTag("!minidump")) {
> + ObjectFile.Minidump.reset(new MinidumpYAML::Object());
> + MappingTraits<MinidumpYAML::Object>::mapping(IO, *ObjectFile.Minidump);
> } else if (IO.mapTag("!WASM")) {
> ObjectFile.Wasm.reset(new WasmYAML::Object());
> MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm);
>
> Added: llvm/trunk/test/tools/yaml2obj/minidump-raw-stream-small-size.yaml
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/minidump-raw-stream-small-size.yaml?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/yaml2obj/minidump-raw-stream-small-size.yaml (added)
> +++ llvm/trunk/test/tools/yaml2obj/minidump-raw-stream-small-size.yaml Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,9 @@
> +# RUN: not yaml2obj %s 2>&1 | FileCheck %s
> +
> +--- !minidump
> +Streams:
> + - Type: LinuxAuxv
> + Size: 7
> + Content: DEADBEEFBAADF00D
> +
> +# CHECK: Stream size must be greater or equal to the content size
>
> Added: llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-long.yaml
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-long.yaml?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-long.yaml (added)
> +++ llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-long.yaml Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,13 @@
> +# RUN: not yaml2obj %s 2>&1 | FileCheck %s
> +
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: PPC
> + Platform ID: Linux
> + CPU:
> + Features: 000102030405060708090a0b0c0d0e0f0
> +
> +
> +# CHECK: String too long
> +# CHECK-NEXT: Features: 000102030405060708090a0b0c0d0e0f0
>
> Added: llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-not-hex.yaml
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-not-hex.yaml?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-not-hex.yaml (added)
> +++ llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-not-hex.yaml Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,13 @@
> +# RUN: not yaml2obj %s 2>&1 | FileCheck %s
> +
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: PPC
> + Platform ID: Linux
> + CPU:
> + Features: 000102030405060708090a0b0c0d0e0g
> +
> +
> +# CHECK: Invalid hex digit in input
> +# CHECK-NEXT: Features: 000102030405060708090a0b0c0d0e0g
>
> Added: llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-short.yaml
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-short.yaml?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-short.yaml (added)
> +++ llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-other-short.yaml Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,13 @@
> +# RUN: not yaml2obj %s 2>&1 | FileCheck %s
> +
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: PPC
> + Platform ID: Linux
> + CPU:
> + Features: 000102030405060708090a0b0c0d0e0
> +
> +
> +# CHECK: String too short
> +# CHECK-NEXT: Features: 000102030405060708090a0b0c0d0e0
>
> Added: llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-long.yaml
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-long.yaml?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-long.yaml (added)
> +++ llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-long.yaml Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,15 @@
> +# RUN: not yaml2obj %s 2>&1 | FileCheck %s
> +
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: X86
> + Platform ID: Linux
> + CPU:
> + Vendor ID: LLVMLLVMLLVML
> + Version Info: 0x01020304
> + Feature Info: 0x05060708
> + AMD Extended Features: 0x09000102
> +
> +# CHECK: String too long
> +# CHECK-NEXT: Vendor ID: LLVMLLVMLLVML
>
> Added: llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-short.yaml
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-short.yaml?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-short.yaml (added)
> +++ llvm/trunk/test/tools/yaml2obj/minidump-systeminfo-x86-short.yaml Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,15 @@
> +# RUN: not yaml2obj %s 2>&1 | FileCheck %s
> +
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: X86
> + Platform ID: Linux
> + CPU:
> + Vendor ID: LLVMLLVMLLV
> + Version Info: 0x01020304
> + Feature Info: 0x05060708
> + AMD Extended Features: 0x09000102
> +
> +# CHECK: String too short
> +# CHECK-NEXT: Vendor ID: LLVMLLVMLLV
>
> Modified: llvm/trunk/tools/yaml2obj/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/CMakeLists.txt?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/tools/yaml2obj/CMakeLists.txt (original)
> +++ llvm/trunk/tools/yaml2obj/CMakeLists.txt Fri Mar 22 07:47:26 2019
> @@ -11,5 +11,6 @@ add_llvm_tool(yaml2obj
> yaml2coff.cpp
> yaml2elf.cpp
> yaml2macho.cpp
> + yaml2minidump.cpp
> yaml2wasm.cpp
> )
>
> Added: llvm/trunk/tools/yaml2obj/yaml2minidump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2minidump.cpp?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/tools/yaml2obj/yaml2minidump.cpp (added)
> +++ llvm/trunk/tools/yaml2obj/yaml2minidump.cpp Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,18 @@
> +//===- yaml2minidump.cpp - Convert a YAML file to a minidump file ---------===//
> +//
> +// 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 "yaml2obj.h"
> +#include "llvm/ObjectYAML/MinidumpYAML.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +using namespace llvm;
> +
> +int yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out) {
> + writeAsBinary(Doc, Out);
> + return 0;
> +}
>
> Modified: llvm/trunk/tools/yaml2obj/yaml2obj.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2obj.cpp?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/tools/yaml2obj/yaml2obj.cpp (original)
> +++ llvm/trunk/tools/yaml2obj/yaml2obj.cpp Fri Mar 22 07:47:26 2019
> @@ -56,6 +56,8 @@ static int convertYAML(yaml::Input &YIn,
> return yaml2coff(*Doc.Coff, Out);
> if (Doc.MachO || Doc.FatMachO)
> return yaml2macho(Doc, Out);
> + if (Doc.Minidump)
> + return yaml2minidump(*Doc.Minidump, Out);
> if (Doc.Wasm)
> return yaml2wasm(*Doc.Wasm, Out);
> error("yaml2obj: Unknown document type!");
>
> Modified: llvm/trunk/tools/yaml2obj/yaml2obj.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2obj.h?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/tools/yaml2obj/yaml2obj.h (original)
> +++ llvm/trunk/tools/yaml2obj/yaml2obj.h Fri Mar 22 07:47:26 2019
> @@ -22,6 +22,10 @@ namespace ELFYAML {
> struct Object;
> }
>
> +namespace MinidumpYAML {
> +struct Object;
> +}
> +
> namespace WasmYAML {
> struct Object;
> }
> @@ -35,6 +39,7 @@ struct YamlObjectFile;
> int yaml2coff(llvm::COFFYAML::Object &Doc, llvm::raw_ostream &Out);
> int yaml2elf(llvm::ELFYAML::Object &Doc, llvm::raw_ostream &Out);
> int yaml2macho(llvm::yaml::YamlObjectFile &Doc, llvm::raw_ostream &Out);
> +int yaml2minidump(llvm::MinidumpYAML::Object &Doc, llvm::raw_ostream &Out);
> int yaml2wasm(llvm::WasmYAML::Object &Doc, llvm::raw_ostream &Out);
>
> #endif
>
> Modified: llvm/trunk/unittests/ObjectYAML/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ObjectYAML/CMakeLists.txt?rev=356753&r1=356752&r2=356753&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/ObjectYAML/CMakeLists.txt (original)
> +++ llvm/trunk/unittests/ObjectYAML/CMakeLists.txt Fri Mar 22 07:47:26 2019
> @@ -1,8 +1,11 @@
> set(LLVM_LINK_COMPONENTS
> + Object
> ObjectYAML
> )
>
> add_llvm_unittest(ObjectYAMLTests
> + MinidumpYAMLTest.cpp
> YAMLTest.cpp
> )
>
> +target_link_libraries(ObjectYAMLTests PRIVATE LLVMTestingSupport)
>
> Added: llvm/trunk/unittests/ObjectYAML/MinidumpYAMLTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ObjectYAML/MinidumpYAMLTest.cpp?rev=356753&view=auto
> ==============================================================================
> --- llvm/trunk/unittests/ObjectYAML/MinidumpYAMLTest.cpp (added)
> +++ llvm/trunk/unittests/ObjectYAML/MinidumpYAMLTest.cpp Fri Mar 22 07:47:26 2019
> @@ -0,0 +1,141 @@
> +//===- MinidumpYAMLTest.cpp - Tests for Minidump<->YAML code --------------===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/ObjectYAML/MinidumpYAML.h"
> +#include "llvm/Object/Minidump.h"
> +#include "llvm/ObjectYAML/ObjectYAML.h"
> +#include "llvm/Testing/Support/Error.h"
> +#include "gtest/gtest.h"
> +
> +using namespace llvm;
> +using namespace llvm::minidump;
> +
> +static Expected<std::unique_ptr<object::MinidumpFile>>
> +toBinary(SmallVectorImpl<char> &Storage, StringRef Yaml) {
> + Storage.clear();
> + raw_svector_ostream OS(Storage);
> + if (Error E = MinidumpYAML::writeAsBinary(Yaml, OS))
> + return std::move(E);
> +
> + return object::MinidumpFile::create(MemoryBufferRef(OS.str(), "Binary"));
> +}
> +
> +TEST(MinidumpYAML, Basic) {
> + SmallString<0> Storage;
> + auto ExpectedFile = toBinary(Storage, R"(
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: ARM64
> + Platform ID: Linux
> + CSD Version RVA: 0x01020304
> + CPU:
> + CPUID: 0x05060708
> + - Type: LinuxMaps
> + Text: |
> + 400d9000-400db000 r-xp 00000000 b3:04 227 /system/bin/app_process
> + 400db000-400dc000 r--p 00001000 b3:04 227 /system/bin/app_process
> +
> + - Type: LinuxAuxv
> + Content: DEADBEEFBAADF00D)");
> + ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
> + object::MinidumpFile &File = **ExpectedFile;
> +
> + ASSERT_EQ(3u, File.streams().size());
> +
> + EXPECT_EQ(StreamType::SystemInfo, File.streams()[0].Type);
> + auto ExpectedSysInfo = File.getSystemInfo();
> + ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
> + const SystemInfo &SysInfo = *ExpectedSysInfo;
> + EXPECT_EQ(ProcessorArchitecture::ARM64, SysInfo.ProcessorArch);
> + EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
> + EXPECT_EQ(0x01020304u, SysInfo.CSDVersionRVA);
> + EXPECT_EQ(0x05060708u, SysInfo.CPU.Arm.CPUID);
> +
> + EXPECT_EQ(StreamType::LinuxMaps, File.streams()[1].Type);
> + EXPECT_EQ("400d9000-400db000 r-xp 00000000 b3:04 227 "
> + "/system/bin/app_process\n"
> + "400db000-400dc000 r--p 00001000 b3:04 227 "
> + "/system/bin/app_process\n",
> + toStringRef(*File.getRawStream(StreamType::LinuxMaps)));
> +
> + EXPECT_EQ(StreamType::LinuxAuxv, File.streams()[2].Type);
> + EXPECT_EQ((ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D}),
> + File.getRawStream(StreamType::LinuxAuxv));
> +}
> +
> +TEST(MinidumpYAML, RawContent) {
> + SmallString<0> Storage;
> + auto ExpectedFile = toBinary(Storage, R"(
> +--- !minidump
> +Streams:
> + - Type: LinuxAuxv
> + Size: 9
> + Content: DEADBEEFBAADF00D)");
> + ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
> + object::MinidumpFile &File = **ExpectedFile;
> +
> + EXPECT_EQ(
> + (ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D, 0x00}),
> + File.getRawStream(StreamType::LinuxAuxv));
> +}
> +
> +TEST(MinidumpYAML, X86SystemInfo) {
> + SmallString<0> Storage;
> + auto ExpectedFile = toBinary(Storage, R"(
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: X86
> + Platform ID: Linux
> + CPU:
> + Vendor ID: LLVMLLVMLLVM
> + Version Info: 0x01020304
> + Feature Info: 0x05060708
> + AMD Extended Features: 0x09000102)");
> + ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
> + object::MinidumpFile &File = **ExpectedFile;
> +
> + ASSERT_EQ(1u, File.streams().size());
> +
> + auto ExpectedSysInfo = File.getSystemInfo();
> + ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
> + const SystemInfo &SysInfo = *ExpectedSysInfo;
> + EXPECT_EQ(ProcessorArchitecture::X86, SysInfo.ProcessorArch);
> + EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
> + EXPECT_EQ("LLVMLLVMLLVM", StringRef(SysInfo.CPU.X86.VendorID,
> + sizeof(SysInfo.CPU.X86.VendorID)));
> + EXPECT_EQ(0x01020304u, SysInfo.CPU.X86.VersionInfo);
> + EXPECT_EQ(0x05060708u, SysInfo.CPU.X86.FeatureInfo);
> + EXPECT_EQ(0x09000102u, SysInfo.CPU.X86.AMDExtendedFeatures);
> +}
> +
> +TEST(MinidumpYAML, OtherSystemInfo) {
> + SmallString<0> Storage;
> + auto ExpectedFile = toBinary(Storage, R"(
> +--- !minidump
> +Streams:
> + - Type: SystemInfo
> + Processor Arch: PPC
> + Platform ID: Linux
> + CPU:
> + Features: 000102030405060708090a0b0c0d0e0f)");
> + ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
> + object::MinidumpFile &File = **ExpectedFile;
> +
> + ASSERT_EQ(1u, File.streams().size());
> +
> + auto ExpectedSysInfo = File.getSystemInfo();
> + ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
> + const SystemInfo &SysInfo = *ExpectedSysInfo;
> + EXPECT_EQ(ProcessorArchitecture::PPC, SysInfo.ProcessorArch);
> + EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
> + EXPECT_EQ(
> + (ArrayRef<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
> + makeArrayRef(SysInfo.CPU.Other.ProcessorFeatures));
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list