180814287SRaphael Isemann //===-- ExecutionContext.cpp ----------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
1030fdc8d8SChris Lattner #include "lldb/Target/ExecutionContextScope.h"
1130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
12b9c1b51eSKate Stone #include "lldb/Target/StackFrame.h"
1330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
1430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
15d821c997SPavel Labath #include "lldb/Utility/State.h"
1630fdc8d8SChris Lattner 
1730fdc8d8SChris Lattner using namespace lldb_private;
1830fdc8d8SChris Lattner 
ExecutionContext()19b9c1b51eSKate Stone ExecutionContext::ExecutionContext()
20b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
2130fdc8d8SChris Lattner 
22*24f9a2f5SShafik Yaghmour ExecutionContext::ExecutionContext(const ExecutionContext &rhs) = default;
23c14ee32dSGreg Clayton 
ExecutionContext(const lldb::TargetSP & target_sp,bool get_process)24b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
25b9c1b51eSKate Stone                                    bool get_process)
26b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
27cc4d0146SGreg Clayton   if (target_sp)
28cc4d0146SGreg Clayton     SetContext(target_sp, get_process);
29c14ee32dSGreg Clayton }
30cc4d0146SGreg Clayton 
ExecutionContext(const lldb::ProcessSP & process_sp)31b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
32b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
33cc4d0146SGreg Clayton   if (process_sp)
34cc4d0146SGreg Clayton     SetContext(process_sp);
35cc4d0146SGreg Clayton }
36cc4d0146SGreg Clayton 
ExecutionContext(const lldb::ThreadSP & thread_sp)37b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
38b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
39cc4d0146SGreg Clayton   if (thread_sp)
40cc4d0146SGreg Clayton     SetContext(thread_sp);
41cc4d0146SGreg Clayton }
42cc4d0146SGreg Clayton 
ExecutionContext(const lldb::StackFrameSP & frame_sp)43b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
44b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
45cc4d0146SGreg Clayton   if (frame_sp)
46cc4d0146SGreg Clayton     SetContext(frame_sp);
47c14ee32dSGreg Clayton }
48c14ee32dSGreg Clayton 
ExecutionContext(const lldb::TargetWP & target_wp,bool get_process)49b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
50b9c1b51eSKate Stone                                    bool get_process)
51b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
521ac04c30SGreg Clayton   lldb::TargetSP target_sp(target_wp.lock());
531ac04c30SGreg Clayton   if (target_sp)
541ac04c30SGreg Clayton     SetContext(target_sp, get_process);
551ac04c30SGreg Clayton }
561ac04c30SGreg Clayton 
ExecutionContext(const lldb::ProcessWP & process_wp)57b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
58b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
591ac04c30SGreg Clayton   lldb::ProcessSP process_sp(process_wp.lock());
601ac04c30SGreg Clayton   if (process_sp)
611ac04c30SGreg Clayton     SetContext(process_sp);
621ac04c30SGreg Clayton }
631ac04c30SGreg Clayton 
ExecutionContext(const lldb::ThreadWP & thread_wp)64b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
65b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
661ac04c30SGreg Clayton   lldb::ThreadSP thread_sp(thread_wp.lock());
671ac04c30SGreg Clayton   if (thread_sp)
681ac04c30SGreg Clayton     SetContext(thread_sp);
691ac04c30SGreg Clayton }
701ac04c30SGreg Clayton 
ExecutionContext(const lldb::StackFrameWP & frame_wp)71b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
72b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
73b57e4a1bSJason Molenda   lldb::StackFrameSP frame_sp(frame_wp.lock());
741ac04c30SGreg Clayton   if (frame_sp)
751ac04c30SGreg Clayton     SetContext(frame_sp);
761ac04c30SGreg Clayton }
771ac04c30SGreg Clayton 
ExecutionContext(Target * t,bool fill_current_process_thread_frame)78b9c1b51eSKate Stone ExecutionContext::ExecutionContext(Target *t,
79b9c1b51eSKate Stone                                    bool fill_current_process_thread_frame)
80b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
81b9c1b51eSKate Stone   if (t) {
82526ae040SGreg Clayton     m_target_sp = t->shared_from_this();
83b9c1b51eSKate Stone     if (fill_current_process_thread_frame) {
84c14ee32dSGreg Clayton       m_process_sp = t->GetProcessSP();
85b9c1b51eSKate Stone       if (m_process_sp) {
86c14ee32dSGreg Clayton         m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
87c14ee32dSGreg Clayton         if (m_thread_sp)
88e1cd1be6SGreg Clayton           m_frame_sp = m_thread_sp->GetSelectedFrame();
8930fdc8d8SChris Lattner       }
9030fdc8d8SChris Lattner     }
9130fdc8d8SChris Lattner   }
92526ae040SGreg Clayton }
9330fdc8d8SChris Lattner 
ExecutionContext(Process * process,Thread * thread,StackFrame * frame)94b9c1b51eSKate Stone ExecutionContext::ExecutionContext(Process *process, Thread *thread,
95b9c1b51eSKate Stone                                    StackFrame *frame)
96b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
97b9c1b51eSKate Stone   if (process) {
98526ae040SGreg Clayton     m_process_sp = process->shared_from_this();
99e1cd1be6SGreg Clayton     m_target_sp = process->GetTarget().shared_from_this();
10030fdc8d8SChris Lattner   }
101526ae040SGreg Clayton   if (thread)
102526ae040SGreg Clayton     m_thread_sp = thread->shared_from_this();
103526ae040SGreg Clayton   if (frame)
104526ae040SGreg Clayton     m_frame_sp = frame->shared_from_this();
105526ae040SGreg Clayton }
10630fdc8d8SChris Lattner 
ExecutionContext(const ExecutionContextRef & exe_ctx_ref)107b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
108b9c1b51eSKate Stone     : m_target_sp(exe_ctx_ref.GetTargetSP()),
109cc4d0146SGreg Clayton       m_process_sp(exe_ctx_ref.GetProcessSP()),
110cc4d0146SGreg Clayton       m_thread_sp(exe_ctx_ref.GetThreadSP()),
111b9c1b51eSKate Stone       m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
112cc4d0146SGreg Clayton 
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,bool thread_and_frame_only_if_stopped)113b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
114b9c1b51eSKate Stone                                    bool thread_and_frame_only_if_stopped)
115b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
116b9c1b51eSKate Stone   if (exe_ctx_ref_ptr) {
117cc4d0146SGreg Clayton     m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
118cc4d0146SGreg Clayton     m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
119b9c1b51eSKate Stone     if (!thread_and_frame_only_if_stopped ||
120b9c1b51eSKate Stone         (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
121cc4d0146SGreg Clayton       m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
122cc4d0146SGreg Clayton       m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
123cc4d0146SGreg Clayton     }
124cc4d0146SGreg Clayton   }
12544d93782SGreg Clayton }
126cc4d0146SGreg Clayton 
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,std::unique_lock<std::recursive_mutex> & lock)127bb19a13cSSaleem Abdulrasool ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
128bb19a13cSSaleem Abdulrasool                                    std::unique_lock<std::recursive_mutex> &lock)
129b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
130b9c1b51eSKate Stone   if (exe_ctx_ref_ptr) {
1314fc6cb9cSJim Ingham     m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
132b9c1b51eSKate Stone     if (m_target_sp) {
133bb19a13cSSaleem Abdulrasool       lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
134bb19a13cSSaleem Abdulrasool 
1354fc6cb9cSJim Ingham       m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
1364fc6cb9cSJim Ingham       m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
1374fc6cb9cSJim Ingham       m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
1384fc6cb9cSJim Ingham     }
1394fc6cb9cSJim Ingham   }
1404fc6cb9cSJim Ingham }
1414fc6cb9cSJim Ingham 
ExecutionContext(const ExecutionContextRef & exe_ctx_ref,std::unique_lock<std::recursive_mutex> & lock)142b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
143b9c1b51eSKate Stone                                    std::unique_lock<std::recursive_mutex> &lock)
144b9c1b51eSKate Stone     : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
145b9c1b51eSKate Stone       m_frame_sp() {
146b9c1b51eSKate Stone   if (m_target_sp) {
147bb19a13cSSaleem Abdulrasool     lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
148bb19a13cSSaleem Abdulrasool 
1494fc6cb9cSJim Ingham     m_process_sp = exe_ctx_ref.GetProcessSP();
1504fc6cb9cSJim Ingham     m_thread_sp = exe_ctx_ref.GetThreadSP();
1514fc6cb9cSJim Ingham     m_frame_sp = exe_ctx_ref.GetFrameSP();
1524fc6cb9cSJim Ingham   }
1534fc6cb9cSJim Ingham }
1544fc6cb9cSJim Ingham 
ExecutionContext(ExecutionContextScope * exe_scope_ptr)155b9c1b51eSKate Stone ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
156b9c1b51eSKate Stone     : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
15730fdc8d8SChris Lattner   if (exe_scope_ptr)
1580603aa9dSGreg Clayton     exe_scope_ptr->CalculateExecutionContext(*this);
15930fdc8d8SChris Lattner }
16030fdc8d8SChris Lattner 
ExecutionContext(ExecutionContextScope & exe_scope_ref)161b9c1b51eSKate Stone ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
1620603aa9dSGreg Clayton   exe_scope_ref.CalculateExecutionContext(*this);
16330fdc8d8SChris Lattner }
16430fdc8d8SChris Lattner 
Clear()165b9c1b51eSKate Stone void ExecutionContext::Clear() {
166c14ee32dSGreg Clayton   m_target_sp.reset();
167c14ee32dSGreg Clayton   m_process_sp.reset();
168c14ee32dSGreg Clayton   m_thread_sp.reset();
169c14ee32dSGreg Clayton   m_frame_sp.reset();
170c14ee32dSGreg Clayton }
171c14ee32dSGreg Clayton 
1729394d772SEugene Zelenko ExecutionContext::~ExecutionContext() = default;
17330fdc8d8SChris Lattner 
GetAddressByteSize() const174b9c1b51eSKate Stone uint32_t ExecutionContext::GetAddressByteSize() const {
175cc4d0146SGreg Clayton   if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
176ed69e30dSHafiz Abid Qadeer     return m_target_sp->GetArchitecture().GetAddressByteSize();
177cc4d0146SGreg Clayton   if (m_process_sp)
178ed69e30dSHafiz Abid Qadeer     return m_process_sp->GetAddressByteSize();
179cc4d0146SGreg Clayton   return sizeof(void *);
180cc4d0146SGreg Clayton }
181cc4d0146SGreg Clayton 
GetByteOrder() const182b9c1b51eSKate Stone lldb::ByteOrder ExecutionContext::GetByteOrder() const {
183347c2aa3SEnrico Granata   if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
184af0c828aSJonas Devlieghere     return m_target_sp->GetArchitecture().GetByteOrder();
185347c2aa3SEnrico Granata   if (m_process_sp)
186af0c828aSJonas Devlieghere     return m_process_sp->GetByteOrder();
1879ccb970fSBruce Mitchener   return endian::InlHostByteOrder();
188347c2aa3SEnrico Granata }
18930fdc8d8SChris Lattner 
GetRegisterContext() const190b9c1b51eSKate Stone RegisterContext *ExecutionContext::GetRegisterContext() const {
191c14ee32dSGreg Clayton   if (m_frame_sp)
192c14ee32dSGreg Clayton     return m_frame_sp->GetRegisterContext().get();
193c14ee32dSGreg Clayton   else if (m_thread_sp)
194c14ee32dSGreg Clayton     return m_thread_sp->GetRegisterContext().get();
1959394d772SEugene Zelenko   return nullptr;
196c14ee32dSGreg Clayton }
197c14ee32dSGreg Clayton 
GetTargetPtr() const198b9c1b51eSKate Stone Target *ExecutionContext::GetTargetPtr() const {
199c14ee32dSGreg Clayton   if (m_target_sp)
200c14ee32dSGreg Clayton     return m_target_sp.get();
201c14ee32dSGreg Clayton   if (m_process_sp)
202c14ee32dSGreg Clayton     return &m_process_sp->GetTarget();
2039394d772SEugene Zelenko   return nullptr;
204c14ee32dSGreg Clayton }
205c14ee32dSGreg Clayton 
GetProcessPtr() const206b9c1b51eSKate Stone Process *ExecutionContext::GetProcessPtr() const {
207c14ee32dSGreg Clayton   if (m_process_sp)
208c14ee32dSGreg Clayton     return m_process_sp.get();
209c14ee32dSGreg Clayton   if (m_target_sp)
210c14ee32dSGreg Clayton     return m_target_sp->GetProcessSP().get();
2119394d772SEugene Zelenko   return nullptr;
21230fdc8d8SChris Lattner }
21330fdc8d8SChris Lattner 
GetBestExecutionContextScope() const214b9c1b51eSKate Stone ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
215c14ee32dSGreg Clayton   if (m_frame_sp)
216c14ee32dSGreg Clayton     return m_frame_sp.get();
217c14ee32dSGreg Clayton   if (m_thread_sp)
218c14ee32dSGreg Clayton     return m_thread_sp.get();
219c14ee32dSGreg Clayton   if (m_process_sp)
220c14ee32dSGreg Clayton     return m_process_sp.get();
221c14ee32dSGreg Clayton   return m_target_sp.get();
22230fdc8d8SChris Lattner }
223644247c1SGreg Clayton 
GetTargetRef() const224b9c1b51eSKate Stone Target &ExecutionContext::GetTargetRef() const {
2259394d772SEugene Zelenko   assert(m_target_sp);
226c14ee32dSGreg Clayton   return *m_target_sp;
227644247c1SGreg Clayton }
228c14ee32dSGreg Clayton 
GetProcessRef() const229b9c1b51eSKate Stone Process &ExecutionContext::GetProcessRef() const {
2309394d772SEugene Zelenko   assert(m_process_sp);
231c14ee32dSGreg Clayton   return *m_process_sp;
232c14ee32dSGreg Clayton }
233c14ee32dSGreg Clayton 
GetThreadRef() const234b9c1b51eSKate Stone Thread &ExecutionContext::GetThreadRef() const {
2359394d772SEugene Zelenko   assert(m_thread_sp);
236c14ee32dSGreg Clayton   return *m_thread_sp;
237c14ee32dSGreg Clayton }
238c14ee32dSGreg Clayton 
GetFrameRef() const239b9c1b51eSKate Stone StackFrame &ExecutionContext::GetFrameRef() const {
2409394d772SEugene Zelenko   assert(m_frame_sp);
241c14ee32dSGreg Clayton   return *m_frame_sp;
242c14ee32dSGreg Clayton }
243c14ee32dSGreg Clayton 
SetTargetSP(const lldb::TargetSP & target_sp)244b9c1b51eSKate Stone void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
245c14ee32dSGreg Clayton   m_target_sp = target_sp;
246c14ee32dSGreg Clayton }
247c14ee32dSGreg Clayton 
SetProcessSP(const lldb::ProcessSP & process_sp)248b9c1b51eSKate Stone void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
249c14ee32dSGreg Clayton   m_process_sp = process_sp;
250c14ee32dSGreg Clayton }
251c14ee32dSGreg Clayton 
SetThreadSP(const lldb::ThreadSP & thread_sp)252b9c1b51eSKate Stone void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
253c14ee32dSGreg Clayton   m_thread_sp = thread_sp;
254c14ee32dSGreg Clayton }
255c14ee32dSGreg Clayton 
SetFrameSP(const lldb::StackFrameSP & frame_sp)256b9c1b51eSKate Stone void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
257c14ee32dSGreg Clayton   m_frame_sp = frame_sp;
258c14ee32dSGreg Clayton }
259c14ee32dSGreg Clayton 
SetTargetPtr(Target * target)260b9c1b51eSKate Stone void ExecutionContext::SetTargetPtr(Target *target) {
261e1cd1be6SGreg Clayton   if (target)
262e1cd1be6SGreg Clayton     m_target_sp = target->shared_from_this();
263e1cd1be6SGreg Clayton   else
264e1cd1be6SGreg Clayton     m_target_sp.reset();
265c14ee32dSGreg Clayton }
266c14ee32dSGreg Clayton 
SetProcessPtr(Process * process)267b9c1b51eSKate Stone void ExecutionContext::SetProcessPtr(Process *process) {
268e1cd1be6SGreg Clayton   if (process)
269e1cd1be6SGreg Clayton     m_process_sp = process->shared_from_this();
270e1cd1be6SGreg Clayton   else
271e1cd1be6SGreg Clayton     m_process_sp.reset();
272c14ee32dSGreg Clayton }
273c14ee32dSGreg Clayton 
SetThreadPtr(Thread * thread)274b9c1b51eSKate Stone void ExecutionContext::SetThreadPtr(Thread *thread) {
275e1cd1be6SGreg Clayton   if (thread)
276e1cd1be6SGreg Clayton     m_thread_sp = thread->shared_from_this();
277e1cd1be6SGreg Clayton   else
278e1cd1be6SGreg Clayton     m_thread_sp.reset();
279c14ee32dSGreg Clayton }
280c14ee32dSGreg Clayton 
SetFramePtr(StackFrame * frame)281b9c1b51eSKate Stone void ExecutionContext::SetFramePtr(StackFrame *frame) {
282e1cd1be6SGreg Clayton   if (frame)
283e1cd1be6SGreg Clayton     m_frame_sp = frame->shared_from_this();
284e1cd1be6SGreg Clayton   else
285e1cd1be6SGreg Clayton     m_frame_sp.reset();
286c14ee32dSGreg Clayton }
287c14ee32dSGreg Clayton 
SetContext(const lldb::TargetSP & target_sp,bool get_process)288b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
289b9c1b51eSKate Stone                                   bool get_process) {
290cc4d0146SGreg Clayton   m_target_sp = target_sp;
291cc4d0146SGreg Clayton   if (get_process && target_sp)
292cc4d0146SGreg Clayton     m_process_sp = target_sp->GetProcessSP();
293cc4d0146SGreg Clayton   else
294cc4d0146SGreg Clayton     m_process_sp.reset();
295cc4d0146SGreg Clayton   m_thread_sp.reset();
296cc4d0146SGreg Clayton   m_frame_sp.reset();
297cc4d0146SGreg Clayton }
298cc4d0146SGreg Clayton 
SetContext(const lldb::ProcessSP & process_sp)299b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
300cc4d0146SGreg Clayton   m_process_sp = process_sp;
301cc4d0146SGreg Clayton   if (process_sp)
302cc4d0146SGreg Clayton     m_target_sp = process_sp->GetTarget().shared_from_this();
303cc4d0146SGreg Clayton   else
304cc4d0146SGreg Clayton     m_target_sp.reset();
305cc4d0146SGreg Clayton   m_thread_sp.reset();
306cc4d0146SGreg Clayton   m_frame_sp.reset();
307cc4d0146SGreg Clayton }
308cc4d0146SGreg Clayton 
SetContext(const lldb::ThreadSP & thread_sp)309b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
310cc4d0146SGreg Clayton   m_frame_sp.reset();
311cc4d0146SGreg Clayton   m_thread_sp = thread_sp;
312b9c1b51eSKate Stone   if (thread_sp) {
3131ac04c30SGreg Clayton     m_process_sp = thread_sp->GetProcess();
314cc4d0146SGreg Clayton     if (m_process_sp)
315cc4d0146SGreg Clayton       m_target_sp = m_process_sp->GetTarget().shared_from_this();
316cc4d0146SGreg Clayton     else
317cc4d0146SGreg Clayton       m_target_sp.reset();
318b9c1b51eSKate Stone   } else {
319cc4d0146SGreg Clayton     m_target_sp.reset();
320cc4d0146SGreg Clayton     m_process_sp.reset();
321cc4d0146SGreg Clayton   }
322cc4d0146SGreg Clayton }
323cc4d0146SGreg Clayton 
SetContext(const lldb::StackFrameSP & frame_sp)324b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
325cc4d0146SGreg Clayton   m_frame_sp = frame_sp;
326b9c1b51eSKate Stone   if (frame_sp) {
327d9e416c0SGreg Clayton     m_thread_sp = frame_sp->CalculateThread();
328b9c1b51eSKate Stone     if (m_thread_sp) {
3291ac04c30SGreg Clayton       m_process_sp = m_thread_sp->GetProcess();
330cc4d0146SGreg Clayton       if (m_process_sp)
331cc4d0146SGreg Clayton         m_target_sp = m_process_sp->GetTarget().shared_from_this();
332cc4d0146SGreg Clayton       else
333cc4d0146SGreg Clayton         m_target_sp.reset();
334b9c1b51eSKate Stone     } else {
335cc4d0146SGreg Clayton       m_target_sp.reset();
336cc4d0146SGreg Clayton       m_process_sp.reset();
337cc4d0146SGreg Clayton     }
338b9c1b51eSKate Stone   } else {
339cc4d0146SGreg Clayton     m_target_sp.reset();
340cc4d0146SGreg Clayton     m_process_sp.reset();
341cc4d0146SGreg Clayton     m_thread_sp.reset();
342cc4d0146SGreg Clayton   }
343cc4d0146SGreg Clayton }
344cc4d0146SGreg Clayton 
operator =(const ExecutionContext & rhs)345b9c1b51eSKate Stone ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
346b9c1b51eSKate Stone   if (this != &rhs) {
347cc4d0146SGreg Clayton     m_target_sp = rhs.m_target_sp;
348cc4d0146SGreg Clayton     m_process_sp = rhs.m_process_sp;
349cc4d0146SGreg Clayton     m_thread_sp = rhs.m_thread_sp;
350cc4d0146SGreg Clayton     m_frame_sp = rhs.m_frame_sp;
351cc4d0146SGreg Clayton   }
352cc4d0146SGreg Clayton   return *this;
353cc4d0146SGreg Clayton }
354cc4d0146SGreg Clayton 
operator ==(const ExecutionContext & rhs) const355b9c1b51eSKate Stone bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
356b9c1b51eSKate Stone   // Check that the frame shared pointers match, or both are valid and their
35705097246SAdrian Prantl   // stack IDs match since sometimes we get new objects that represent the same
358cc4d0146SGreg Clayton   // frame within a thread.
359b9c1b51eSKate Stone   if ((m_frame_sp == rhs.m_frame_sp) ||
360b9c1b51eSKate Stone       (m_frame_sp && rhs.m_frame_sp &&
361b9c1b51eSKate Stone        m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
36205097246SAdrian Prantl     // Check that the thread shared pointers match, or both are valid and their
36305097246SAdrian Prantl     // thread IDs match since sometimes we get new objects that represent the
36405097246SAdrian Prantl     // same thread within a process.
365b9c1b51eSKate Stone     if ((m_thread_sp == rhs.m_thread_sp) ||
366b9c1b51eSKate Stone         (m_thread_sp && rhs.m_thread_sp &&
367b9c1b51eSKate Stone          m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
368cc4d0146SGreg Clayton       // Processes and targets don't change much
369cc4d0146SGreg Clayton       return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
370cc4d0146SGreg Clayton     }
371cc4d0146SGreg Clayton   }
372cc4d0146SGreg Clayton   return false;
373cc4d0146SGreg Clayton }
374cc4d0146SGreg Clayton 
operator !=(const ExecutionContext & rhs) const375b9c1b51eSKate Stone bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
376cc4d0146SGreg Clayton   return !(*this == rhs);
377cc4d0146SGreg Clayton }
378cc4d0146SGreg Clayton 
HasTargetScope() const379b9c1b51eSKate Stone bool ExecutionContext::HasTargetScope() const {
380b9c1b51eSKate Stone   return ((bool)m_target_sp && m_target_sp->IsValid());
3814fc6cb9cSJim Ingham }
3824fc6cb9cSJim Ingham 
HasProcessScope() const383b9c1b51eSKate Stone bool ExecutionContext::HasProcessScope() const {
384b9c1b51eSKate Stone   return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
3854fc6cb9cSJim Ingham }
3864fc6cb9cSJim Ingham 
HasThreadScope() const387b9c1b51eSKate Stone bool ExecutionContext::HasThreadScope() const {
388b9c1b51eSKate Stone   return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
3894fc6cb9cSJim Ingham }
3904fc6cb9cSJim Ingham 
HasFrameScope() const391b9c1b51eSKate Stone bool ExecutionContext::HasFrameScope() const {
3924fc6cb9cSJim Ingham   return HasThreadScope() && m_frame_sp;
3934fc6cb9cSJim Ingham }
394cc4d0146SGreg Clayton 
ExecutionContextRef()395b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef()
3969494c510SJonas Devlieghere     : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {}
397cc4d0146SGreg Clayton 
ExecutionContextRef(const ExecutionContext * exe_ctx)398b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
39928c878aeSShafik Yaghmour     : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
400cc4d0146SGreg Clayton   if (exe_ctx)
401cc4d0146SGreg Clayton     *this = *exe_ctx;
402cc4d0146SGreg Clayton }
403cc4d0146SGreg Clayton 
ExecutionContextRef(const ExecutionContext & exe_ctx)404b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
40528c878aeSShafik Yaghmour     : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
406cc4d0146SGreg Clayton   *this = exe_ctx;
407cc4d0146SGreg Clayton }
408cc4d0146SGreg Clayton 
ExecutionContextRef(Target * target,bool adopt_selected)409b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
41028c878aeSShafik Yaghmour     : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
411cc4d0146SGreg Clayton   SetTargetPtr(target, adopt_selected);
412cc4d0146SGreg Clayton }
413cc4d0146SGreg Clayton 
414b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
415*24f9a2f5SShafik Yaghmour 
416*24f9a2f5SShafik Yaghmour     = default;
417cc4d0146SGreg Clayton 
418b9c1b51eSKate Stone ExecutionContextRef &ExecutionContextRef::
operator =(const ExecutionContextRef & rhs)419b9c1b51eSKate Stone operator=(const ExecutionContextRef &rhs) {
420b9c1b51eSKate Stone   if (this != &rhs) {
421cc4d0146SGreg Clayton     m_target_wp = rhs.m_target_wp;
422cc4d0146SGreg Clayton     m_process_wp = rhs.m_process_wp;
423cc4d0146SGreg Clayton     m_thread_wp = rhs.m_thread_wp;
424cc4d0146SGreg Clayton     m_tid = rhs.m_tid;
425cc4d0146SGreg Clayton     m_stack_id = rhs.m_stack_id;
426cc4d0146SGreg Clayton   }
427cc4d0146SGreg Clayton   return *this;
428cc4d0146SGreg Clayton }
429cc4d0146SGreg Clayton 
430b9c1b51eSKate Stone ExecutionContextRef &ExecutionContextRef::
operator =(const ExecutionContext & exe_ctx)431b9c1b51eSKate Stone operator=(const ExecutionContext &exe_ctx) {
432cc4d0146SGreg Clayton   m_target_wp = exe_ctx.GetTargetSP();
433cc4d0146SGreg Clayton   m_process_wp = exe_ctx.GetProcessSP();
4347fdf9ef1SGreg Clayton   lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
4357fdf9ef1SGreg Clayton   m_thread_wp = thread_sp;
4367fdf9ef1SGreg Clayton   if (thread_sp)
4377fdf9ef1SGreg Clayton     m_tid = thread_sp->GetID();
4387fdf9ef1SGreg Clayton   else
4397fdf9ef1SGreg Clayton     m_tid = LLDB_INVALID_THREAD_ID;
440b57e4a1bSJason Molenda   lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
4417fdf9ef1SGreg Clayton   if (frame_sp)
4427fdf9ef1SGreg Clayton     m_stack_id = frame_sp->GetStackID();
4437fdf9ef1SGreg Clayton   else
4447fdf9ef1SGreg Clayton     m_stack_id.Clear();
445cc4d0146SGreg Clayton   return *this;
446cc4d0146SGreg Clayton }
447cc4d0146SGreg Clayton 
Clear()448b9c1b51eSKate Stone void ExecutionContextRef::Clear() {
449cc4d0146SGreg Clayton   m_target_wp.reset();
450cc4d0146SGreg Clayton   m_process_wp.reset();
4517fdf9ef1SGreg Clayton   ClearThread();
4527fdf9ef1SGreg Clayton   ClearFrame();
453cc4d0146SGreg Clayton }
454cc4d0146SGreg Clayton 
4559394d772SEugene Zelenko ExecutionContextRef::~ExecutionContextRef() = default;
456cc4d0146SGreg Clayton 
SetTargetSP(const lldb::TargetSP & target_sp)457b9c1b51eSKate Stone void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
458cc4d0146SGreg Clayton   m_target_wp = target_sp;
459cc4d0146SGreg Clayton }
460cc4d0146SGreg Clayton 
SetProcessSP(const lldb::ProcessSP & process_sp)461b9c1b51eSKate Stone void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
462b9c1b51eSKate Stone   if (process_sp) {
463cc4d0146SGreg Clayton     m_process_wp = process_sp;
4647fdf9ef1SGreg Clayton     SetTargetSP(process_sp->GetTarget().shared_from_this());
465b9c1b51eSKate Stone   } else {
4667fdf9ef1SGreg Clayton     m_process_wp.reset();
4677fdf9ef1SGreg Clayton     m_target_wp.reset();
4687fdf9ef1SGreg Clayton   }
469cc4d0146SGreg Clayton }
470cc4d0146SGreg Clayton 
SetThreadSP(const lldb::ThreadSP & thread_sp)471b9c1b51eSKate Stone void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
472b9c1b51eSKate Stone   if (thread_sp) {
4737fdf9ef1SGreg Clayton     m_thread_wp = thread_sp;
474cc4d0146SGreg Clayton     m_tid = thread_sp->GetID();
4757fdf9ef1SGreg Clayton     SetProcessSP(thread_sp->GetProcess());
476b9c1b51eSKate Stone   } else {
4777fdf9ef1SGreg Clayton     ClearThread();
4787fdf9ef1SGreg Clayton     m_process_wp.reset();
4797fdf9ef1SGreg Clayton     m_target_wp.reset();
4807fdf9ef1SGreg Clayton   }
481cc4d0146SGreg Clayton }
482cc4d0146SGreg Clayton 
SetFrameSP(const lldb::StackFrameSP & frame_sp)483b9c1b51eSKate Stone void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
484b9c1b51eSKate Stone   if (frame_sp) {
485cc4d0146SGreg Clayton     m_stack_id = frame_sp->GetStackID();
4867fdf9ef1SGreg Clayton     SetThreadSP(frame_sp->GetThread());
487b9c1b51eSKate Stone   } else {
4887fdf9ef1SGreg Clayton     ClearFrame();
4897fdf9ef1SGreg Clayton     ClearThread();
4907fdf9ef1SGreg Clayton     m_process_wp.reset();
4917fdf9ef1SGreg Clayton     m_target_wp.reset();
4927fdf9ef1SGreg Clayton   }
493cc4d0146SGreg Clayton }
494cc4d0146SGreg Clayton 
SetTargetPtr(Target * target,bool adopt_selected)495b9c1b51eSKate Stone void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
496cc4d0146SGreg Clayton   Clear();
497b9c1b51eSKate Stone   if (target) {
498cc4d0146SGreg Clayton     lldb::TargetSP target_sp(target->shared_from_this());
499b9c1b51eSKate Stone     if (target_sp) {
500cc4d0146SGreg Clayton       m_target_wp = target_sp;
501b9c1b51eSKate Stone       if (adopt_selected) {
502cc4d0146SGreg Clayton         lldb::ProcessSP process_sp(target_sp->GetProcessSP());
503b9c1b51eSKate Stone         if (process_sp) {
504cc4d0146SGreg Clayton           m_process_wp = process_sp;
505b9c1b51eSKate Stone           if (process_sp) {
5069b5450f6SGreg Clayton             // Only fill in the thread and frame if our process is stopped
507d5ac1ab6SJim Ingham             // Don't just check the state, since we might be in the middle of
508d5ac1ab6SJim Ingham             // resuming.
509d5ac1ab6SJim Ingham             Process::StopLocker stop_locker;
510d5ac1ab6SJim Ingham 
511b9c1b51eSKate Stone             if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
512b9c1b51eSKate Stone                 StateIsStoppedState(process_sp->GetState(), true)) {
513b9c1b51eSKate Stone               lldb::ThreadSP thread_sp(
514b9c1b51eSKate Stone                   process_sp->GetThreadList().GetSelectedThread());
515cc4d0146SGreg Clayton               if (!thread_sp)
516cc4d0146SGreg Clayton                 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
517cc4d0146SGreg Clayton 
518b9c1b51eSKate Stone               if (thread_sp) {
519cc4d0146SGreg Clayton                 SetThreadSP(thread_sp);
520b57e4a1bSJason Molenda                 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame());
521cc4d0146SGreg Clayton                 if (!frame_sp)
522cc4d0146SGreg Clayton                   frame_sp = thread_sp->GetStackFrameAtIndex(0);
523cc4d0146SGreg Clayton                 if (frame_sp)
524cc4d0146SGreg Clayton                   SetFrameSP(frame_sp);
525cc4d0146SGreg Clayton               }
526cc4d0146SGreg Clayton             }
527cc4d0146SGreg Clayton           }
528cc4d0146SGreg Clayton         }
529cc4d0146SGreg Clayton       }
530cc4d0146SGreg Clayton     }
531cc4d0146SGreg Clayton   }
5329b5450f6SGreg Clayton }
533cc4d0146SGreg Clayton 
SetProcessPtr(Process * process)534b9c1b51eSKate Stone void ExecutionContextRef::SetProcessPtr(Process *process) {
535b9c1b51eSKate Stone   if (process) {
5367fdf9ef1SGreg Clayton     SetProcessSP(process->shared_from_this());
537b9c1b51eSKate Stone   } else {
538cc4d0146SGreg Clayton     m_process_wp.reset();
5397fdf9ef1SGreg Clayton     m_target_wp.reset();
5407fdf9ef1SGreg Clayton   }
541cc4d0146SGreg Clayton }
542cc4d0146SGreg Clayton 
SetThreadPtr(Thread * thread)543b9c1b51eSKate Stone void ExecutionContextRef::SetThreadPtr(Thread *thread) {
544b9c1b51eSKate Stone   if (thread) {
5457fdf9ef1SGreg Clayton     SetThreadSP(thread->shared_from_this());
546b9c1b51eSKate Stone   } else {
5477fdf9ef1SGreg Clayton     ClearThread();
5487fdf9ef1SGreg Clayton     m_process_wp.reset();
5497fdf9ef1SGreg Clayton     m_target_wp.reset();
5507fdf9ef1SGreg Clayton   }
551cc4d0146SGreg Clayton }
552cc4d0146SGreg Clayton 
SetFramePtr(StackFrame * frame)553b9c1b51eSKate Stone void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
554cc4d0146SGreg Clayton   if (frame)
5557fdf9ef1SGreg Clayton     SetFrameSP(frame->shared_from_this());
556cc4d0146SGreg Clayton   else
5577fdf9ef1SGreg Clayton     Clear();
558cc4d0146SGreg Clayton }
559cc4d0146SGreg Clayton 
GetTargetSP() const560b9c1b51eSKate Stone lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
5614fc6cb9cSJim Ingham   lldb::TargetSP target_sp(m_target_wp.lock());
5624fc6cb9cSJim Ingham   if (target_sp && !target_sp->IsValid())
5634fc6cb9cSJim Ingham     target_sp.reset();
5644fc6cb9cSJim Ingham   return target_sp;
5654fc6cb9cSJim Ingham }
5664fc6cb9cSJim Ingham 
GetProcessSP() const567b9c1b51eSKate Stone lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
5684fc6cb9cSJim Ingham   lldb::ProcessSP process_sp(m_process_wp.lock());
5694fc6cb9cSJim Ingham   if (process_sp && !process_sp->IsValid())
5704fc6cb9cSJim Ingham     process_sp.reset();
5714fc6cb9cSJim Ingham   return process_sp;
5724fc6cb9cSJim Ingham }
573cc4d0146SGreg Clayton 
GetThreadSP() const574b9c1b51eSKate Stone lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
575cc4d0146SGreg Clayton   lldb::ThreadSP thread_sp(m_thread_wp.lock());
5764fc6cb9cSJim Ingham 
577b9c1b51eSKate Stone   if (m_tid != LLDB_INVALID_THREAD_ID) {
57805097246SAdrian Prantl     // We check if the thread has been destroyed in cases where clients might
57905097246SAdrian Prantl     // still have shared pointer to a thread, but the thread is not valid
58005097246SAdrian Prantl     // anymore (not part of the process)
581b9c1b51eSKate Stone     if (!thread_sp || !thread_sp->IsValid()) {
582cc4d0146SGreg Clayton       lldb::ProcessSP process_sp(GetProcessSP());
583b9c1b51eSKate Stone       if (process_sp && process_sp->IsValid()) {
584cc4d0146SGreg Clayton         thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
585cc4d0146SGreg Clayton         m_thread_wp = thread_sp;
586cc4d0146SGreg Clayton       }
587cc4d0146SGreg Clayton     }
5880b88d815SGreg Clayton   }
5894fc6cb9cSJim Ingham 
59005097246SAdrian Prantl   // Check that we aren't about to return an invalid thread sp.  We might
59105097246SAdrian Prantl   // return a nullptr thread_sp, but don't return an invalid one.
5924fc6cb9cSJim Ingham 
5934fc6cb9cSJim Ingham   if (thread_sp && !thread_sp->IsValid())
5944fc6cb9cSJim Ingham     thread_sp.reset();
5954fc6cb9cSJim Ingham 
596cc4d0146SGreg Clayton   return thread_sp;
597cc4d0146SGreg Clayton }
598cc4d0146SGreg Clayton 
GetFrameSP() const599b9c1b51eSKate Stone lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
600b9c1b51eSKate Stone   if (m_stack_id.IsValid()) {
601cc4d0146SGreg Clayton     lldb::ThreadSP thread_sp(GetThreadSP());
6026482d230SGreg Clayton     if (thread_sp)
6036482d230SGreg Clayton       return thread_sp->GetFrameWithStackID(m_stack_id);
6047bcb93d5SGreg Clayton   }
605b57e4a1bSJason Molenda   return lldb::StackFrameSP();
606ebafd2f1SEnrico Granata }
607cc4d0146SGreg Clayton 
608cc4d0146SGreg Clayton ExecutionContext
Lock(bool thread_and_frame_only_if_stopped) const609b9c1b51eSKate Stone ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
61044d93782SGreg Clayton   return ExecutionContext(this, thread_and_frame_only_if_stopped);
611cc4d0146SGreg Clayton }
612