• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-exception
6 //
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 
32 using namespace lldb;
33 using namespace lldb_private;
34 using namespace minidump;
35 
ThreadMinidump(Process & process,const minidump::Thread & td,llvm::ArrayRef<uint8_t> gpregset_data)36 ThreadMinidump::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 
~ThreadMinidump()41 ThreadMinidump::~ThreadMinidump() {}
42 
RefreshStateAfterStop()43 void ThreadMinidump::RefreshStateAfterStop() {}
44 
GetRegisterContext()45 RegisterContextSP ThreadMinidump::GetRegisterContext() {
46   if (!m_reg_context_sp) {
47     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
48   }
49   return m_reg_context_sp;
50 }
51 
52 RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)53 ThreadMinidump::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 here
70     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 
CalculateStopInfo()118 bool ThreadMinidump::CalculateStopInfo() { return false; }
119