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 
28 ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid,
29                            llvm::StringRef name, llvm::StringRef queue,
30                            lldb::addr_t register_data_addr)
31     : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(),
32       m_name(name), m_queue(queue), m_register_data_addr(register_data_addr) {}
33 
34 ThreadMemory::~ThreadMemory() { DestroyThread(); }
35 
36 void ThreadMemory::WillResume(StateType resume_state) {
37   if (m_backing_thread_sp)
38     m_backing_thread_sp->WillResume(resume_state);
39 }
40 
41 void ThreadMemory::ClearStackFrames() {
42   if (m_backing_thread_sp)
43     m_backing_thread_sp->ClearStackFrames();
44   Thread::ClearStackFrames();
45 }
46 
47 RegisterContextSP ThreadMemory::GetRegisterContext() {
48   if (!m_reg_context_sp)
49     m_reg_context_sp = std::make_shared<RegisterContextThreadMemory>(
50         *this, m_register_data_addr);
51   return m_reg_context_sp;
52 }
53 
54 RegisterContextSP
55 ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) {
56   RegisterContextSP reg_ctx_sp;
57   uint32_t concrete_frame_idx = 0;
58 
59   if (frame)
60     concrete_frame_idx = frame->GetConcreteFrameIndex();
61 
62   if (concrete_frame_idx == 0) {
63     reg_ctx_sp = GetRegisterContext();
64   } else {
65     Unwind *unwinder = GetUnwinder();
66     if (unwinder != nullptr)
67       reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
68   }
69   return reg_ctx_sp;
70 }
71 
72 bool ThreadMemory::CalculateStopInfo() {
73   if (m_backing_thread_sp) {
74     lldb::StopInfoSP backing_stop_info_sp(
75         m_backing_thread_sp->GetPrivateStopInfo());
76     if (backing_stop_info_sp &&
77         backing_stop_info_sp->IsValidForOperatingSystemThread(*this)) {
78       backing_stop_info_sp->SetThread(shared_from_this());
79       SetStopInfo(backing_stop_info_sp);
80       return true;
81     }
82   } else {
83     ProcessSP process_sp(GetProcess());
84 
85     if (process_sp) {
86       OperatingSystem *os = process_sp->GetOperatingSystem();
87       if (os) {
88         SetStopInfo(os->CreateThreadStopReason(this));
89         return true;
90       }
91     }
92   }
93   return false;
94 }
95 
96 void ThreadMemory::RefreshStateAfterStop() {
97   if (m_backing_thread_sp)
98     return m_backing_thread_sp->RefreshStateAfterStop();
99 
100   if (m_reg_context_sp)
101     m_reg_context_sp->InvalidateAllRegisters();
102 }
103