Summary:
This patch adds the code needed to parse a minidump file into the
MinidumpYAML model, and the necessary glue code so that obj2yaml can
recognise the minidump files and process them.
Reviewers: jhenderson, zturner, clayborg
Subscribers: mgorny, lldb-commits, amccarth, markmentovai, aprantl, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59634
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357469
91177308-0d34-0410-b5e6-
96231b3b80d8
#define LLVM_OBJECTYAML_MINIDUMPYAML_H
#include "llvm/BinaryFormat/Minidump.h"
+#include "llvm/Object/Minidump.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
/// Create an empty stream of the given Type.
static std::unique_ptr<Stream> create(minidump::StreamType Type);
+
+ /// Create a stream from the given stream directory entry.
+ static Expected<std::unique_ptr<Stream>>
+ create(const minidump::Directory &StreamDesc,
+ const object::MinidumpFile &File);
};
/// A minidump stream represented as a sequence of hex bytes. This is used as a
Object(Object &&) = default;
Object &operator=(Object &&) = default;
+ Object(const minidump::Header &Header,
+ std::vector<std::unique_ptr<Stream>> Streams)
+ : Header(Header), Streams(std::move(Streams)) {}
+
/// The minidump header.
minidump::Header Header;
/// The list of streams in this minidump object.
std::vector<std::unique_ptr<Stream>> Streams;
+
+ static Expected<Object> create(const object::MinidumpFile &File);
};
/// Serialize the minidump file represented by Obj to OS in binary form.
writeAsBinary(Obj, OS);
return Error::success();
}
+
+Expected<std::unique_ptr<Stream>>
+Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
+ StreamKind Kind = getKind(StreamDesc.Type);
+ switch (Kind) {
+ case StreamKind::RawContent:
+ return make_unique<RawContentStream>(StreamDesc.Type,
+ File.getRawStream(StreamDesc));
+ case StreamKind::SystemInfo: {
+ auto ExpectedInfo = File.getSystemInfo();
+ if (!ExpectedInfo)
+ return ExpectedInfo.takeError();
+ return make_unique<SystemInfoStream>(*ExpectedInfo);
+ }
+ case StreamKind::TextContent:
+ return make_unique<TextContentStream>(
+ StreamDesc.Type, toStringRef(File.getRawStream(StreamDesc)));
+ }
+ llvm_unreachable("Unhandled stream kind!");
+}
+
+Expected<Object> Object::create(const object::MinidumpFile &File) {
+ std::vector<std::unique_ptr<Stream>> Streams;
+ Streams.reserve(File.streams().size());
+ for (const Directory &StreamDesc : File.streams()) {
+ auto ExpectedStream = Stream::create(StreamDesc, File);
+ if (!ExpectedStream)
+ return ExpectedStream.takeError();
+ Streams.push_back(std::move(*ExpectedStream));
+ }
+ return Object(File.header(), std::move(Streams));
+}
--- /dev/null
+# RUN: yaml2obj %s | obj2yaml - | FileCheck %s
+
+--- !minidump
+Streams:
+ - Type: SystemInfo
+ Processor Arch: ARM64
+ Platform ID: Linux
+ CSD Version RVA: 0x01020304
+ CPU:
+ CPUID: 0x05060708
+ - Type: LinuxAuxv
+ Content: DEADBEEFBAADF00D
+ - 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
+
+...
+
+# CHECK: --- !minidump
+# CHECK-NEXT: Streams:
+# CHECK-NEXT: - Type: SystemInfo
+# CHECK-NEXT: Processor Arch: ARM64
+# CHECK-NEXT: Platform ID: Linux
+# CHECK-NEXT: CSD Version RVA: 0x01020304
+# CHECK-NEXT: CPU:
+# CHECK-NEXT: CPUID: 0x05060708
+# CHECK-NEXT: - Type: LinuxAuxv
+# CHECK-NEXT: Content: DEADBEEFBAADF00D
+# CHECK-NEXT: - Type: LinuxMaps
+# CHECK-NEXT: Text: |
+# CHECK-NEXT: 400d9000-400db000 r-xp 00000000 b3:04 227 /system/bin/app_process
+# CHECK-NEXT: 400db000-400dc000 r--p 00001000 b3:04 227 /system/bin/app_process
+# CHECK-EMPTY:
+# CHECK-NEXT: ...
dwarf2yaml.cpp
elf2yaml.cpp
macho2yaml.cpp
+ minidump2yaml.cpp
wasm2yaml.cpp
Error.cpp
)
--- /dev/null
+//===- minidump2yaml.cpp - Minidump to yaml conversion tool -----*- 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 "Error.h"
+#include "obj2yaml.h"
+#include "llvm/Object/Minidump.h"
+#include "llvm/ObjectYAML/MinidumpYAML.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace llvm;
+
+Error minidump2yaml(raw_ostream &Out, const object::MinidumpFile &Obj) {
+ auto ExpectedObject = MinidumpYAML::Object::create(Obj);
+ if (!ExpectedObject)
+ return ExpectedObject.takeError();
+ yaml::Output Output(Out);
+ Output << *ExpectedObject;
+ return llvm::Error::success();
+}
#include "Error.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/Minidump.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
// TODO: If this is an archive, then burst it and dump each entry
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
return errorCodeToError(dumpObject(*Obj));
+ if (MinidumpFile *Minidump = dyn_cast<MinidumpFile>(&Binary))
+ return minidump2yaml(outs(), *Minidump);
return Error::success();
}
#define LLVM_TOOLS_OBJ2YAML_OBJ2YAML_H
#include "llvm/Object/COFF.h"
+#include "llvm/Object/Minidump.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
const llvm::object::ObjectFile &Obj);
std::error_code macho2yaml(llvm::raw_ostream &Out,
const llvm::object::Binary &Obj);
+llvm::Error minidump2yaml(llvm::raw_ostream &Out,
+ const llvm::object::MinidumpFile &Obj);
std::error_code wasm2yaml(llvm::raw_ostream &Out,
const llvm::object::WasmObjectFile &Obj);