1 | //===-- ThreadMemory.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 "Plugins/Process/Utility/ThreadMemory.h" |
10 | |
11 | #include "Plugins/Process/Utility/RegisterContextThreadMemory.h" |
12 | #include "lldb/Target/OperatingSystem.h" |
13 | #include "lldb/Target/Process.h" |
14 | #include "lldb/Target/RegisterContext.h" |
15 | #include "lldb/Target/StopInfo.h" |
16 | #include "lldb/Target/Unwind.h" |
17 | |
18 | #include <memory> |
19 | |
20 | using namespace lldb; |
21 | using namespace lldb_private; |
22 | |
23 | ThreadMemory::ThreadMemory(Process &process, tid_t tid, |
24 | const ValueObjectSP &thread_info_valobj_sp) |
25 | : Thread(process, tid), m_backing_thread_sp(), |
26 | m_thread_info_valobj_sp(thread_info_valobj_sp), m_name(), m_queue(), |
27 | m_register_data_addr(LLDB_INVALID_ADDRESS) {} |
28 | |
29 | ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid, |
30 | llvm::StringRef name, llvm::StringRef queue, |
31 | lldb::addr_t register_data_addr) |
32 | : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(), |
33 | m_name(std::string(name)), m_queue(std::string(queue)), |
34 | m_register_data_addr(register_data_addr) {} |
35 | |
36 | ThreadMemory::~ThreadMemory() { DestroyThread(); } |
37 | |
38 | void ThreadMemory::WillResume(StateType resume_state) { |
39 | if (m_backing_thread_sp) |
40 | m_backing_thread_sp->WillResume(resume_state); |
41 | } |
42 | |
43 | void ThreadMemory::ClearStackFrames() { |
44 | if (m_backing_thread_sp) |
45 | m_backing_thread_sp->ClearStackFrames(); |
46 | Thread::ClearStackFrames(); |
47 | } |
48 | |
49 | RegisterContextSP ThreadMemory::GetRegisterContext() { |
50 | if (!m_reg_context_sp) |
51 | m_reg_context_sp = std::make_shared<RegisterContextThreadMemory>( |
52 | args&: *this, args&: m_register_data_addr); |
53 | return m_reg_context_sp; |
54 | } |
55 | |
56 | RegisterContextSP |
57 | ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) { |
58 | uint32_t concrete_frame_idx = 0; |
59 | |
60 | if (frame) |
61 | concrete_frame_idx = frame->GetConcreteFrameIndex(); |
62 | |
63 | if (concrete_frame_idx == 0) |
64 | return GetRegisterContext(); |
65 | return GetUnwinder().CreateRegisterContextForFrame(frame); |
66 | } |
67 | |
68 | bool ThreadMemory::CalculateStopInfo() { |
69 | if (m_backing_thread_sp) { |
70 | lldb::StopInfoSP backing_stop_info_sp( |
71 | m_backing_thread_sp->GetPrivateStopInfo()); |
72 | if (backing_stop_info_sp && |
73 | backing_stop_info_sp->IsValidForOperatingSystemThread(thread&: *this)) { |
74 | backing_stop_info_sp->SetThread(shared_from_this()); |
75 | SetStopInfo(backing_stop_info_sp); |
76 | return true; |
77 | } |
78 | } else { |
79 | ProcessSP process_sp(GetProcess()); |
80 | |
81 | if (process_sp) { |
82 | OperatingSystem *os = process_sp->GetOperatingSystem(); |
83 | if (os) { |
84 | SetStopInfo(os->CreateThreadStopReason(thread: this)); |
85 | return true; |
86 | } |
87 | } |
88 | } |
89 | return false; |
90 | } |
91 | |
92 | void ThreadMemory::RefreshStateAfterStop() { |
93 | if (m_backing_thread_sp) |
94 | return m_backing_thread_sp->RefreshStateAfterStop(); |
95 | |
96 | if (m_reg_context_sp) |
97 | m_reg_context_sp->InvalidateAllRegisters(); |
98 | } |
99 | |