1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
//===-- MinidumpParser.h -----------------------------------------*- 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 LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
#include "MinidumpTypes.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/UUID.h"
#include "lldb/Utility/RangeMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Minidump.h"
// C includes
// C++ includes
#include <cstring>
#include <optional>
#include <unordered_map>
namespace lldb_private {
namespace minidump {
// Describes a range of memory captured in the Minidump
struct Range {
// Default constructor required for range data vector
// but unusued.
Range() = default;
lldb::addr_t start; // virtual address of the beginning of the range
// range_ref - absolute pointer to the first byte of the range and size
llvm::ArrayRef<uint8_t> range_ref;
Range(lldb::addr_t start, llvm::ArrayRef<uint8_t> range_ref)
: start(start), range_ref(range_ref) {}
friend bool operator==(const Range &lhs, const Range &rhs) {
return lhs.start == rhs.start && lhs.range_ref == rhs.range_ref;
}
friend bool operator<(const Range &lhs, const Range &rhs) {
if (lhs.start == rhs.start)
return lhs.range_ref.size() < rhs.range_ref.size();
return lhs.start < rhs.start;
}
};
using MemoryRangeVector =
lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, minidump::Range>;
using FallibleMemory64Iterator =
llvm::object::MinidumpFile::FallibleMemory64Iterator;
using ExceptionStreamsIterator =
llvm::object::MinidumpFile::ExceptionStreamsIterator;
class MinidumpParser {
public:
static llvm::Expected<MinidumpParser>
Create(const lldb::DataBufferSP &data_buf_sp);
llvm::ArrayRef<uint8_t> GetData();
llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type);
std::optional<llvm::ArrayRef<uint8_t>> GetRawStream(StreamType stream_type);
UUID GetModuleUUID(const minidump::Module *module);
llvm::ArrayRef<minidump::Thread> GetThreads();
llvm::ArrayRef<uint8_t> GetThreadContext(const LocationDescriptor &location);
llvm::ArrayRef<uint8_t> GetThreadContext(const minidump::Thread &td);
llvm::ArrayRef<uint8_t> GetThreadContextWow64(const minidump::Thread &td);
ArchSpec GetArchitecture();
const MinidumpMiscInfo *GetMiscInfo();
std::optional<LinuxProcStatus> GetLinuxProcStatus();
std::optional<lldb::pid_t> GetPid();
llvm::ArrayRef<minidump::Module> GetModuleList();
// There are cases in which there is more than one record in the ModuleList
// for the same module name.(e.g. when the binary has non contiguous segments)
// So this function returns a filtered module list - if it finds records that
// have the same name, it keeps the copy with the lowest load address.
std::vector<const minidump::Module *> GetFilteredModuleList();
llvm::iterator_range<ExceptionStreamsIterator> GetExceptionStreams();
std::optional<Range> FindMemoryRange(lldb::addr_t addr);
llvm::Expected<llvm::ArrayRef<uint8_t>> GetMemory(lldb::addr_t addr,
size_t size);
/// Returns a list of memory regions and a flag indicating whether the list is
/// complete (includes all regions mapped into the process memory).
std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
llvm::iterator_range<FallibleMemory64Iterator>
GetMemory64Iterator(llvm::Error &err);
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
llvm::object::MinidumpFile &GetMinidumpFile() { return *m_file; }
static MemoryRegionInfo GetMemoryRegionInfo(const MemoryRegionInfos ®ions,
lldb::addr_t load_addr);
private:
MinidumpParser(lldb::DataBufferSP data_sp,
std::unique_ptr<llvm::object::MinidumpFile> file);
void PopulateMemoryRanges();
lldb::DataBufferSP m_data_sp;
std::unique_ptr<llvm::object::MinidumpFile> m_file;
ArchSpec m_arch;
MemoryRangeVector m_memory_ranges;
};
} // end namespace minidump
} // end namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
|