119 lines · cpp
1//===-- ThreadMinidump.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "ThreadMinidump.h"10 11#include "ProcessMinidump.h"12 13#include "RegisterContextMinidump_ARM.h"14#include "RegisterContextMinidump_ARM64.h"15#include "RegisterContextMinidump_x86_32.h"16#include "RegisterContextMinidump_x86_64.h"17 18#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"19#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"20#include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"21#include "Plugins/Process/elf-core/RegisterUtilities.h"22 23#include "lldb/Target/RegisterContext.h"24#include "lldb/Target/StopInfo.h"25#include "lldb/Target/Target.h"26#include "lldb/Target/Unwind.h"27#include "lldb/Utility/DataExtractor.h"28#include "lldb/Utility/Log.h"29 30#include <memory>31 32using namespace lldb;33using namespace lldb_private;34using namespace minidump;35 36ThreadMinidump::ThreadMinidump(Process &process, const minidump::Thread &td,37 llvm::ArrayRef<uint8_t> gpregset_data)38 : Thread(process, td.ThreadId), m_thread_reg_ctx_sp(),39 m_gpregset_data(gpregset_data) {}40 41ThreadMinidump::~ThreadMinidump() = default;42 43void ThreadMinidump::RefreshStateAfterStop() {}44 45RegisterContextSP ThreadMinidump::GetRegisterContext() {46 if (!m_reg_context_sp) {47 m_reg_context_sp = CreateRegisterContextForFrame(nullptr);48 }49 return m_reg_context_sp;50}51 52RegisterContextSP53ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {54 RegisterContextSP reg_ctx_sp;55 uint32_t concrete_frame_idx = 0;56 57 if (frame)58 concrete_frame_idx = frame->GetConcreteFrameIndex();59 60 if (concrete_frame_idx == 0) {61 if (m_thread_reg_ctx_sp)62 return m_thread_reg_ctx_sp;63 64 ProcessMinidump *process =65 static_cast<ProcessMinidump *>(GetProcess().get());66 ArchSpec arch = process->GetArchitecture();67 RegisterInfoInterface *reg_interface = nullptr;68 69 // TODO write other register contexts and add them here70 switch (arch.GetMachine()) {71 case llvm::Triple::x86: {72 reg_interface = new RegisterContextLinux_i386(arch);73 lldb::DataBufferSP buf =74 ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);75 DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);76 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(77 *this, reg_interface, gpregset,78 llvm::ArrayRef<lldb_private::CoreNote>());79 break;80 }81 case llvm::Triple::x86_64: {82 reg_interface = new RegisterContextLinux_x86_64(arch);83 lldb::DataBufferSP buf =84 ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);85 DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);86 m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>(87 *this, reg_interface, gpregset,88 llvm::ArrayRef<lldb_private::CoreNote>());89 break;90 }91 case llvm::Triple::aarch64: {92 DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),93 lldb::eByteOrderLittle, 8);94 m_thread_reg_ctx_sp =95 std::make_shared<RegisterContextMinidump_ARM64>(*this, data);96 break;97 }98 case llvm::Triple::arm: {99 DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),100 lldb::eByteOrderLittle, 8);101 const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple;102 m_thread_reg_ctx_sp =103 std::make_shared<RegisterContextMinidump_ARM>(*this, data, apple);104 break;105 }106 default:107 break;108 }109 110 reg_ctx_sp = m_thread_reg_ctx_sp;111 } else if (m_unwinder_up) {112 reg_ctx_sp = m_unwinder_up->CreateRegisterContextForFrame(frame);113 }114 115 return reg_ctx_sp;116}117 118bool ThreadMinidump::CalculateStopInfo() { return false; }119