| File: | src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp |
| Warning: | line 65, column 33 Called C++ object pointer is uninitialized |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //===-- RegisterContextMinidump_x86_64.cpp --------------------------------===// | |||
| 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 | #include "RegisterContextMinidump_x86_64.h" | |||
| 10 | ||||
| 11 | #include "lldb/Utility/DataBufferHeap.h" | |||
| 12 | ||||
| 13 | // C includes | |||
| 14 | // C++ includes | |||
| 15 | ||||
| 16 | using namespace lldb_private; | |||
| 17 | using namespace minidump; | |||
| 18 | ||||
| 19 | static llvm::MutableArrayRef<uint8_t> getDestRegister(uint8_t *context, | |||
| 20 | const RegisterInfo ®) { | |||
| 21 | auto bytes = reg.mutable_data(context); | |||
| 22 | ||||
| 23 | switch (reg.kinds[lldb::eRegisterKindLLDB]) { | |||
| 24 | case lldb_cs_x86_64: | |||
| 25 | case lldb_ds_x86_64: | |||
| 26 | case lldb_es_x86_64: | |||
| 27 | case lldb_fs_x86_64: | |||
| 28 | case lldb_gs_x86_64: | |||
| 29 | case lldb_ss_x86_64: | |||
| 30 | return bytes.take_front(2); | |||
| 31 | break; | |||
| 32 | case lldb_rflags_x86_64: | |||
| 33 | return bytes.take_front(4); | |||
| 34 | break; | |||
| 35 | default: | |||
| 36 | return bytes.take_front(8); | |||
| 37 | break; | |||
| 38 | } | |||
| 39 | } | |||
| 40 | ||||
| 41 | static void writeRegister(const void *reg_src, uint8_t *context, | |||
| 42 | const RegisterInfo ®) { | |||
| 43 | llvm::MutableArrayRef<uint8_t> reg_dest = getDestRegister(context, reg); | |||
| 44 | memcpy(reg_dest.data(), reg_src, reg_dest.size()); | |||
| 45 | } | |||
| 46 | ||||
| 47 | lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64( | |||
| 48 | llvm::ArrayRef<uint8_t> source_data, | |||
| 49 | RegisterInfoInterface *target_reg_interface) { | |||
| 50 | ||||
| 51 | const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo(); | |||
| 52 | ||||
| 53 | lldb::DataBufferSP result_context_buf( | |||
| 54 | new DataBufferHeap(target_reg_interface->GetGPRSize(), 0)); | |||
| 55 | uint8_t *result_base = result_context_buf->GetBytes(); | |||
| 56 | ||||
| 57 | if (source_data.size() < sizeof(MinidumpContext_x86_64)) | |||
| ||||
| 58 | return nullptr; | |||
| 59 | ||||
| 60 | const MinidumpContext_x86_64 *context; | |||
| 61 | consumeObject(source_data, context); | |||
| 62 | ||||
| 63 | const MinidumpContext_x86_64_Flags context_flags = | |||
| 64 | static_cast<MinidumpContext_x86_64_Flags>( | |||
| 65 | static_cast<uint32_t>(context->context_flags)); | |||
| ||||
| 66 | auto x86_64_Flag = MinidumpContext_x86_64_Flags::x86_64_Flag; | |||
| 67 | auto ControlFlag = MinidumpContext_x86_64_Flags::Control; | |||
| 68 | auto IntegerFlag = MinidumpContext_x86_64_Flags::Integer; | |||
| 69 | auto SegmentsFlag = MinidumpContext_x86_64_Flags::Segments; | |||
| 70 | ||||
| 71 | if ((context_flags & x86_64_Flag) != x86_64_Flag) | |||
| 72 | return nullptr; | |||
| 73 | ||||
| 74 | if ((context_flags & ControlFlag) == ControlFlag) { | |||
| 75 | writeRegister(&context->cs, result_base, reg_info[lldb_cs_x86_64]); | |||
| 76 | writeRegister(&context->ss, result_base, reg_info[lldb_ss_x86_64]); | |||
| 77 | writeRegister(&context->eflags, result_base, reg_info[lldb_rflags_x86_64]); | |||
| 78 | writeRegister(&context->rsp, result_base, reg_info[lldb_rsp_x86_64]); | |||
| 79 | writeRegister(&context->rip, result_base, reg_info[lldb_rip_x86_64]); | |||
| 80 | } | |||
| 81 | ||||
| 82 | if ((context_flags & SegmentsFlag) == SegmentsFlag) { | |||
| 83 | writeRegister(&context->ds, result_base, reg_info[lldb_ds_x86_64]); | |||
| 84 | writeRegister(&context->es, result_base, reg_info[lldb_es_x86_64]); | |||
| 85 | writeRegister(&context->fs, result_base, reg_info[lldb_fs_x86_64]); | |||
| 86 | writeRegister(&context->gs, result_base, reg_info[lldb_gs_x86_64]); | |||
| 87 | } | |||
| 88 | ||||
| 89 | if ((context_flags & IntegerFlag) == IntegerFlag) { | |||
| 90 | writeRegister(&context->rax, result_base, reg_info[lldb_rax_x86_64]); | |||
| 91 | writeRegister(&context->rcx, result_base, reg_info[lldb_rcx_x86_64]); | |||
| 92 | writeRegister(&context->rdx, result_base, reg_info[lldb_rdx_x86_64]); | |||
| 93 | writeRegister(&context->rbx, result_base, reg_info[lldb_rbx_x86_64]); | |||
| 94 | writeRegister(&context->rbp, result_base, reg_info[lldb_rbp_x86_64]); | |||
| 95 | writeRegister(&context->rsi, result_base, reg_info[lldb_rsi_x86_64]); | |||
| 96 | writeRegister(&context->rdi, result_base, reg_info[lldb_rdi_x86_64]); | |||
| 97 | writeRegister(&context->r8, result_base, reg_info[lldb_r8_x86_64]); | |||
| 98 | writeRegister(&context->r9, result_base, reg_info[lldb_r9_x86_64]); | |||
| 99 | writeRegister(&context->r10, result_base, reg_info[lldb_r10_x86_64]); | |||
| 100 | writeRegister(&context->r11, result_base, reg_info[lldb_r11_x86_64]); | |||
| 101 | writeRegister(&context->r12, result_base, reg_info[lldb_r12_x86_64]); | |||
| 102 | writeRegister(&context->r13, result_base, reg_info[lldb_r13_x86_64]); | |||
| 103 | writeRegister(&context->r14, result_base, reg_info[lldb_r14_x86_64]); | |||
| 104 | writeRegister(&context->r15, result_base, reg_info[lldb_r15_x86_64]); | |||
| 105 | } | |||
| 106 | ||||
| 107 | // TODO parse the floating point registers | |||
| 108 | ||||
| 109 | return result_context_buf; | |||
| 110 | } |
| 1 | //===-- MinidumpTypes.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_MINIDUMPTYPES_H |
| 10 | #define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H |
| 11 | |
| 12 | #include "lldb/Utility/Status.h" |
| 13 | |
| 14 | #include "llvm/ADT/ArrayRef.h" |
| 15 | #include "llvm/ADT/BitmaskEnum.h" |
| 16 | #include "llvm/ADT/Optional.h" |
| 17 | #include "llvm/ADT/SmallVector.h" |
| 18 | #include "llvm/ADT/StringRef.h" |
| 19 | #include "llvm/BinaryFormat/Minidump.h" |
| 20 | #include "llvm/Support/ConvertUTF.h" |
| 21 | #include "llvm/Support/Endian.h" |
| 22 | |
| 23 | // C includes |
| 24 | // C++ includes |
| 25 | |
| 26 | // Reference: |
| 27 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms679293(v=vs.85).aspx |
| 28 | // https://chromium.googlesource.com/breakpad/breakpad/ |
| 29 | |
| 30 | namespace lldb_private { |
| 31 | |
| 32 | namespace minidump { |
| 33 | |
| 34 | using namespace llvm::minidump; |
| 35 | |
| 36 | LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()using ::llvm::BitmaskEnumDetail::operator~; using ::llvm::BitmaskEnumDetail ::operator|; using ::llvm::BitmaskEnumDetail::operator&; using ::llvm::BitmaskEnumDetail::operator^; using ::llvm::BitmaskEnumDetail ::operator|=; using ::llvm::BitmaskEnumDetail::operator&= ; using ::llvm::BitmaskEnumDetail::operator^=; |
| 37 | |
| 38 | enum class CvSignature : uint32_t { |
| 39 | Pdb70 = 0x53445352, // RSDS |
| 40 | ElfBuildId = 0x4270454c, // BpEL (Breakpad/Crashpad minidumps) |
| 41 | }; |
| 42 | |
| 43 | enum class MinidumpMiscInfoFlags : uint32_t { |
| 44 | ProcessID = (1 << 0), |
| 45 | ProcessTimes = (1 << 1), |
| 46 | LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)LLVM_BITMASK_LARGEST_ENUMERATOR = ProcessTimes |
| 47 | }; |
| 48 | |
| 49 | template <typename T> |
| 50 | Status consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) { |
| 51 | Status error; |
| 52 | if (Buffer.size() < sizeof(T)) { |
| 53 | error.SetErrorString("Insufficient buffer!"); |
| 54 | return error; |
| 55 | } |
| 56 | |
| 57 | Object = reinterpret_cast<const T *>(Buffer.data()); |
| 58 | Buffer = Buffer.drop_front(sizeof(T)); |
| 59 | return error; |
| 60 | } |
| 61 | |
| 62 | struct MinidumpMemoryDescriptor64 { |
| 63 | llvm::support::ulittle64_t start_of_memory_range; |
| 64 | llvm::support::ulittle64_t data_size; |
| 65 | |
| 66 | static std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t> |
| 67 | ParseMemory64List(llvm::ArrayRef<uint8_t> &data); |
| 68 | }; |
| 69 | static_assert(sizeof(MinidumpMemoryDescriptor64) == 16, |
| 70 | "sizeof MinidumpMemoryDescriptor64 is not correct!"); |
| 71 | |
| 72 | // TODO misc2, misc3 ? |
| 73 | // Reference: |
| 74 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx |
| 75 | struct MinidumpMiscInfo { |
| 76 | llvm::support::ulittle32_t size; |
| 77 | // flags1 represents what info in the struct is valid |
| 78 | llvm::support::ulittle32_t flags1; |
| 79 | llvm::support::ulittle32_t process_id; |
| 80 | llvm::support::ulittle32_t process_create_time; |
| 81 | llvm::support::ulittle32_t process_user_time; |
| 82 | llvm::support::ulittle32_t process_kernel_time; |
| 83 | |
| 84 | static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data); |
| 85 | |
| 86 | llvm::Optional<lldb::pid_t> GetPid() const; |
| 87 | }; |
| 88 | static_assert(sizeof(MinidumpMiscInfo) == 24, |
| 89 | "sizeof MinidumpMiscInfo is not correct!"); |
| 90 | |
| 91 | // The /proc/pid/status is saved as an ascii string in the file |
| 92 | class LinuxProcStatus { |
| 93 | public: |
| 94 | llvm::StringRef proc_status; |
| 95 | lldb::pid_t pid; |
| 96 | |
| 97 | static llvm::Optional<LinuxProcStatus> Parse(llvm::ArrayRef<uint8_t> &data); |
| 98 | |
| 99 | lldb::pid_t GetPid() const; |
| 100 | |
| 101 | private: |
| 102 | LinuxProcStatus() = default; |
| 103 | }; |
| 104 | |
| 105 | } // namespace minidump |
| 106 | } // namespace lldb_private |
| 107 | #endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H |