forked from OSchip/llvm-project
Add minidump support to obj2yaml
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 llvm-svn: 357469
This commit is contained in:
parent
07ef786652
commit
3cee663e71
|
@ -10,6 +10,7 @@
|
|||
#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"
|
||||
|
||||
|
@ -41,6 +42,11 @@ struct Stream {
|
|||
|
||||
/// 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
|
||||
|
@ -103,11 +109,17 @@ struct Object {
|
|||
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.
|
||||
|
|
|
@ -383,3 +383,35 @@ Error MinidumpYAML::writeAsBinary(StringRef Yaml, raw_ostream &OS) {
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# 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: ...
|
|
@ -13,6 +13,7 @@ add_llvm_tool(obj2yaml
|
|||
dwarf2yaml.cpp
|
||||
elf2yaml.cpp
|
||||
macho2yaml.cpp
|
||||
minidump2yaml.cpp
|
||||
wasm2yaml.cpp
|
||||
Error.cpp
|
||||
)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//===- 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();
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
#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"
|
||||
|
||||
|
@ -40,6 +41,8 @@ static Error dumpInput(StringRef File) {
|
|||
// 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();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#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>
|
||||
|
@ -23,6 +24,8 @@ std::error_code elf2yaml(llvm::raw_ostream &Out,
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue