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