1 //===-- ThreadMinidump.cpp ------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ThreadMinidump.h"
11 #include "ProcessMinidump.h"
13 #include "RegisterContextMinidump_ARM.h"
14 #include "RegisterContextMinidump_ARM64.h"
15 #include "RegisterContextMinidump_x86_32.h"
16 #include "RegisterContextMinidump_x86_64.h"
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"
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"
33 using namespace lldb_private
;
34 using namespace minidump
;
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
) {}
41 ThreadMinidump::~ThreadMinidump() = default;
43 void ThreadMinidump::RefreshStateAfterStop() {}
45 RegisterContextSP
ThreadMinidump::GetRegisterContext() {
46 if (!m_reg_context_sp
) {
47 m_reg_context_sp
= CreateRegisterContextForFrame(nullptr);
49 return m_reg_context_sp
;
53 ThreadMinidump::CreateRegisterContextForFrame(StackFrame
*frame
) {
54 RegisterContextSP reg_ctx_sp
;
55 uint32_t concrete_frame_idx
= 0;
58 concrete_frame_idx
= frame
->GetConcreteFrameIndex();
60 if (concrete_frame_idx
== 0) {
61 if (m_thread_reg_ctx_sp
)
62 return m_thread_reg_ctx_sp
;
64 ProcessMinidump
*process
=
65 static_cast<ProcessMinidump
*>(GetProcess().get());
66 ArchSpec arch
= process
->GetArchitecture();
67 RegisterInfoInterface
*reg_interface
= nullptr;
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
>());
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
>());
91 case llvm::Triple::aarch64
: {
92 DataExtractor
data(m_gpregset_data
.data(), m_gpregset_data
.size(),
93 lldb::eByteOrderLittle
, 8);
95 std::make_shared
<RegisterContextMinidump_ARM64
>(*this, data
);
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
);
110 reg_ctx_sp
= m_thread_reg_ctx_sp
;
111 } else if (m_unwinder_up
) {
112 reg_ctx_sp
= m_unwinder_up
->CreateRegisterContextForFrame(frame
);
118 bool ThreadMinidump::CalculateStopInfo() { return false; }