1//===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Target/ExecutionContext.h"
11
12#include "lldb/Core/State.h"
13#include "lldb/Target/ExecutionContextScope.h"
14#include "lldb/Target/StackFrame.h"
15#include "lldb/Target/Process.h"
16#include "lldb/Target/Target.h"
17#include "lldb/Target/Thread.h"
18
19using namespace lldb_private;
20
21ExecutionContext::ExecutionContext() :
22    m_target_sp (),
23    m_process_sp (),
24    m_thread_sp (),
25    m_frame_sp ()
26{
27}
28
29ExecutionContext::ExecutionContext (const ExecutionContext &rhs) :
30    m_target_sp(rhs.m_target_sp),
31    m_process_sp(rhs.m_process_sp),
32    m_thread_sp(rhs.m_thread_sp),
33    m_frame_sp(rhs.m_frame_sp)
34{
35}
36
37ExecutionContext::ExecutionContext (const lldb::TargetSP &target_sp, bool get_process) :
38    m_target_sp (),
39    m_process_sp (),
40    m_thread_sp (),
41    m_frame_sp ()
42{
43    if (target_sp)
44        SetContext (target_sp, get_process);
45}
46
47ExecutionContext::ExecutionContext (const lldb::ProcessSP &process_sp) :
48    m_target_sp (),
49    m_process_sp (),
50    m_thread_sp (),
51    m_frame_sp ()
52{
53    if (process_sp)
54        SetContext (process_sp);
55}
56
57ExecutionContext::ExecutionContext (const lldb::ThreadSP &thread_sp) :
58    m_target_sp (),
59    m_process_sp (),
60    m_thread_sp (),
61    m_frame_sp ()
62{
63    if (thread_sp)
64        SetContext (thread_sp);
65}
66
67ExecutionContext::ExecutionContext (const lldb::StackFrameSP &frame_sp) :
68    m_target_sp (),
69    m_process_sp (),
70    m_thread_sp (),
71    m_frame_sp ()
72{
73    if (frame_sp)
74        SetContext (frame_sp);
75}
76
77ExecutionContext::ExecutionContext (const lldb::TargetWP &target_wp, bool get_process) :
78    m_target_sp (),
79    m_process_sp (),
80    m_thread_sp (),
81    m_frame_sp ()
82{
83    lldb::TargetSP target_sp(target_wp.lock());
84    if (target_sp)
85        SetContext (target_sp, get_process);
86}
87
88ExecutionContext::ExecutionContext (const lldb::ProcessWP &process_wp) :
89    m_target_sp (),
90    m_process_sp (),
91    m_thread_sp (),
92    m_frame_sp ()
93{
94    lldb::ProcessSP process_sp(process_wp.lock());
95    if (process_sp)
96        SetContext (process_sp);
97}
98
99ExecutionContext::ExecutionContext (const lldb::ThreadWP &thread_wp) :
100    m_target_sp (),
101    m_process_sp (),
102    m_thread_sp (),
103    m_frame_sp ()
104{
105    lldb::ThreadSP thread_sp(thread_wp.lock());
106    if (thread_sp)
107        SetContext (thread_sp);
108}
109
110ExecutionContext::ExecutionContext (const lldb::StackFrameWP &frame_wp) :
111    m_target_sp (),
112    m_process_sp (),
113    m_thread_sp (),
114    m_frame_sp ()
115{
116    lldb::StackFrameSP frame_sp(frame_wp.lock());
117    if (frame_sp)
118        SetContext (frame_sp);
119}
120
121ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
122    m_target_sp (t->shared_from_this()),
123    m_process_sp (),
124    m_thread_sp (),
125    m_frame_sp ()
126{
127    if (t && fill_current_process_thread_frame)
128    {
129        m_process_sp = t->GetProcessSP();
130        if (m_process_sp)
131        {
132            m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
133            if (m_thread_sp)
134                m_frame_sp = m_thread_sp->GetSelectedFrame();
135        }
136    }
137}
138
139ExecutionContext::ExecutionContext(Process* process, Thread *thread, StackFrame *frame) :
140    m_target_sp (),
141    m_process_sp (process->shared_from_this()),
142    m_thread_sp (thread->shared_from_this()),
143    m_frame_sp (frame->shared_from_this())
144{
145    if (process)
146        m_target_sp = process->GetTarget().shared_from_this();
147}
148
149ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) :
150    m_target_sp (exe_ctx_ref.GetTargetSP()),
151    m_process_sp (exe_ctx_ref.GetProcessSP()),
152    m_thread_sp (exe_ctx_ref.GetThreadSP()),
153    m_frame_sp (exe_ctx_ref.GetFrameSP())
154{
155}
156
157ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr) :
158    m_target_sp (),
159    m_process_sp (),
160    m_thread_sp (),
161    m_frame_sp ()
162{
163    if (exe_ctx_ref_ptr)
164    {
165        m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
166        m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
167        m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
168        m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
169    }
170}
171
172ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) :
173    m_target_sp (),
174    m_process_sp (),
175    m_thread_sp (),
176    m_frame_sp ()
177{
178    if (exe_ctx_ref_ptr)
179    {
180        m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
181        if (m_target_sp)
182        {
183            locker.Lock(m_target_sp->GetAPIMutex());
184            m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
185            m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
186            m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
187        }
188    }
189}
190
191ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) :
192    m_target_sp (exe_ctx_ref.GetTargetSP()),
193    m_process_sp (),
194    m_thread_sp (),
195    m_frame_sp ()
196{
197    if (m_target_sp)
198    {
199        locker.Lock(m_target_sp->GetAPIMutex());
200        m_process_sp = exe_ctx_ref.GetProcessSP();
201        m_thread_sp  = exe_ctx_ref.GetThreadSP();
202        m_frame_sp   = exe_ctx_ref.GetFrameSP();
203    }
204}
205
206ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) :
207    m_target_sp (),
208    m_process_sp (),
209    m_thread_sp (),
210    m_frame_sp ()
211{
212    if (exe_scope_ptr)
213        exe_scope_ptr->CalculateExecutionContext (*this);
214}
215
216ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
217{
218    exe_scope_ref.CalculateExecutionContext (*this);
219}
220
221void
222ExecutionContext::Clear()
223{
224    m_target_sp.reset();
225    m_process_sp.reset();
226    m_thread_sp.reset();
227    m_frame_sp.reset();
228}
229
230ExecutionContext::~ExecutionContext()
231{
232}
233
234uint32_t
235ExecutionContext::GetAddressByteSize() const
236{
237    if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
238        m_target_sp->GetArchitecture().GetAddressByteSize();
239    if (m_process_sp)
240        m_process_sp->GetAddressByteSize();
241    return sizeof(void *);
242}
243
244
245
246RegisterContext *
247ExecutionContext::GetRegisterContext () const
248{
249    if (m_frame_sp)
250        return m_frame_sp->GetRegisterContext().get();
251    else if (m_thread_sp)
252        return m_thread_sp->GetRegisterContext().get();
253    return NULL;
254}
255
256Target *
257ExecutionContext::GetTargetPtr () const
258{
259    if (m_target_sp)
260        return m_target_sp.get();
261    if (m_process_sp)
262        return &m_process_sp->GetTarget();
263    return NULL;
264}
265
266Process *
267ExecutionContext::GetProcessPtr () const
268{
269    if (m_process_sp)
270        return m_process_sp.get();
271    if (m_target_sp)
272        return m_target_sp->GetProcessSP().get();
273    return NULL;
274}
275
276ExecutionContextScope *
277ExecutionContext::GetBestExecutionContextScope () const
278{
279    if (m_frame_sp)
280        return m_frame_sp.get();
281    if (m_thread_sp)
282        return m_thread_sp.get();
283    if (m_process_sp)
284        return m_process_sp.get();
285    return m_target_sp.get();
286}
287
288Target &
289ExecutionContext::GetTargetRef () const
290{
291#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
292    assert (m_target_sp.get());
293#endif
294    return *m_target_sp;
295}
296
297Process &
298ExecutionContext::GetProcessRef () const
299{
300#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
301    assert (m_process_sp.get());
302#endif
303    return *m_process_sp;
304}
305
306Thread &
307ExecutionContext::GetThreadRef () const
308{
309#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
310    assert (m_thread_sp.get());
311#endif
312    return *m_thread_sp;
313}
314
315StackFrame &
316ExecutionContext::GetFrameRef () const
317{
318#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
319    assert (m_frame_sp.get());
320#endif
321    return *m_frame_sp;
322}
323
324void
325ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
326{
327    m_target_sp = target_sp;
328}
329
330void
331ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
332{
333    m_process_sp = process_sp;
334}
335
336void
337ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
338{
339    m_thread_sp = thread_sp;
340}
341
342void
343ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
344{
345    m_frame_sp = frame_sp;
346}
347
348void
349ExecutionContext::SetTargetPtr (Target* target)
350{
351    if (target)
352        m_target_sp = target->shared_from_this();
353    else
354        m_target_sp.reset();
355}
356
357void
358ExecutionContext::SetProcessPtr (Process *process)
359{
360    if (process)
361        m_process_sp = process->shared_from_this();
362    else
363        m_process_sp.reset();
364}
365
366void
367ExecutionContext::SetThreadPtr (Thread *thread)
368{
369    if (thread)
370        m_thread_sp = thread->shared_from_this();
371    else
372        m_thread_sp.reset();
373}
374
375void
376ExecutionContext::SetFramePtr (StackFrame *frame)
377{
378    if (frame)
379        m_frame_sp = frame->shared_from_this();
380    else
381        m_frame_sp.reset();
382}
383
384void
385ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process)
386{
387    m_target_sp = target_sp;
388    if (get_process && target_sp)
389        m_process_sp = target_sp->GetProcessSP();
390    else
391        m_process_sp.reset();
392    m_thread_sp.reset();
393    m_frame_sp.reset();
394}
395
396void
397ExecutionContext::SetContext (const lldb::ProcessSP &process_sp)
398{
399    m_process_sp = process_sp;
400    if (process_sp)
401        m_target_sp = process_sp->GetTarget().shared_from_this();
402    else
403        m_target_sp.reset();
404    m_thread_sp.reset();
405    m_frame_sp.reset();
406}
407
408void
409ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
410{
411    m_frame_sp.reset();
412    m_thread_sp = thread_sp;
413    if (thread_sp)
414    {
415        m_process_sp = thread_sp->GetProcess();
416        if (m_process_sp)
417            m_target_sp = m_process_sp->GetTarget().shared_from_this();
418        else
419            m_target_sp.reset();
420    }
421    else
422    {
423        m_target_sp.reset();
424        m_process_sp.reset();
425    }
426}
427
428void
429ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
430{
431    m_frame_sp = frame_sp;
432    if (frame_sp)
433    {
434        m_thread_sp = frame_sp->CalculateThread();
435        if (m_thread_sp)
436        {
437            m_process_sp = m_thread_sp->GetProcess();
438            if (m_process_sp)
439                m_target_sp = m_process_sp->GetTarget().shared_from_this();
440            else
441                m_target_sp.reset();
442        }
443        else
444        {
445            m_target_sp.reset();
446            m_process_sp.reset();
447        }
448    }
449    else
450    {
451        m_target_sp.reset();
452        m_process_sp.reset();
453        m_thread_sp.reset();
454    }
455}
456
457ExecutionContext &
458ExecutionContext::operator =(const ExecutionContext &rhs)
459{
460    if (this != &rhs)
461    {
462        m_target_sp  = rhs.m_target_sp;
463        m_process_sp = rhs.m_process_sp;
464        m_thread_sp  = rhs.m_thread_sp;
465        m_frame_sp   = rhs.m_frame_sp;
466    }
467    return *this;
468}
469
470bool
471ExecutionContext::operator ==(const ExecutionContext &rhs) const
472{
473    // Check that the frame shared pointers match, or both are valid and their stack
474    // IDs match since sometimes we get new objects that represent the same
475    // frame within a thread.
476    if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID()))
477    {
478        // Check that the thread shared pointers match, or both are valid and
479        // their thread IDs match since sometimes we get new objects that
480        // represent the same thread within a process.
481        if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID()))
482        {
483            // Processes and targets don't change much
484            return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
485        }
486    }
487    return false;
488}
489
490bool
491ExecutionContext::operator !=(const ExecutionContext &rhs) const
492{
493    return !(*this == rhs);
494}
495
496bool
497ExecutionContext::HasTargetScope () const
498{
499    return ((bool) m_target_sp
500            && m_target_sp->IsValid());
501}
502
503bool
504ExecutionContext::HasProcessScope () const
505{
506    return (HasTargetScope()
507            && ((bool) m_process_sp && m_process_sp->IsValid()));
508}
509
510bool
511ExecutionContext::HasThreadScope () const
512{
513    return (HasProcessScope()
514           && ((bool) m_thread_sp && m_thread_sp->IsValid()));
515}
516
517bool
518ExecutionContext::HasFrameScope () const
519{
520    return HasThreadScope() && m_frame_sp;
521}
522
523ExecutionContextRef::ExecutionContextRef() :
524    m_target_wp (),
525    m_process_wp (),
526    m_thread_wp (),
527    m_tid(LLDB_INVALID_THREAD_ID),
528    m_stack_id ()
529{
530}
531
532ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) :
533    m_target_wp (),
534    m_process_wp (),
535    m_thread_wp (),
536    m_tid(LLDB_INVALID_THREAD_ID),
537    m_stack_id ()
538{
539    if (exe_ctx)
540        *this = *exe_ctx;
541}
542
543ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
544    m_target_wp (),
545    m_process_wp (),
546    m_thread_wp (),
547    m_tid(LLDB_INVALID_THREAD_ID),
548    m_stack_id ()
549{
550    *this = exe_ctx;
551}
552
553
554ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
555    m_target_wp(),
556    m_process_wp(),
557    m_thread_wp(),
558    m_tid(LLDB_INVALID_THREAD_ID),
559    m_stack_id ()
560{
561    SetTargetPtr (target, adopt_selected);
562}
563
564
565
566
567ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
568    m_target_wp (rhs.m_target_wp),
569    m_process_wp(rhs.m_process_wp),
570    m_thread_wp (rhs.m_thread_wp),
571    m_tid       (rhs.m_tid),
572    m_stack_id  (rhs.m_stack_id)
573{
574}
575
576ExecutionContextRef &
577ExecutionContextRef::operator =(const ExecutionContextRef &rhs)
578{
579    if (this != &rhs)
580    {
581        m_target_wp  = rhs.m_target_wp;
582        m_process_wp = rhs.m_process_wp;
583        m_thread_wp  = rhs.m_thread_wp;
584        m_tid        = rhs.m_tid;
585        m_stack_id   = rhs.m_stack_id;
586    }
587    return *this;
588}
589
590ExecutionContextRef &
591ExecutionContextRef::operator =(const ExecutionContext &exe_ctx)
592{
593    m_target_wp = exe_ctx.GetTargetSP();
594    m_process_wp = exe_ctx.GetProcessSP();
595    lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP());
596    m_thread_wp = thread_sp;
597    if (thread_sp)
598        m_tid = thread_sp->GetID();
599    else
600        m_tid = LLDB_INVALID_THREAD_ID;
601    lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP());
602    if (frame_sp)
603        m_stack_id = frame_sp->GetStackID();
604    else
605        m_stack_id.Clear();
606    return *this;
607}
608
609void
610ExecutionContextRef::Clear()
611{
612    m_target_wp.reset();
613    m_process_wp.reset();
614    ClearThread();
615    ClearFrame();
616}
617
618ExecutionContextRef::~ExecutionContextRef()
619{
620}
621
622void
623ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
624{
625    m_target_wp = target_sp;
626}
627
628void
629ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp)
630{
631    if (process_sp)
632    {
633        m_process_wp = process_sp;
634        SetTargetSP (process_sp->GetTarget().shared_from_this());
635    }
636    else
637    {
638        m_process_wp.reset();
639        m_target_wp.reset();
640    }
641}
642
643void
644ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp)
645{
646    if (thread_sp)
647    {
648        m_thread_wp = thread_sp;
649        m_tid = thread_sp->GetID();
650        SetProcessSP (thread_sp->GetProcess());
651    }
652    else
653    {
654        ClearThread();
655        m_process_wp.reset();
656        m_target_wp.reset();
657    }
658}
659
660void
661ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
662{
663    if (frame_sp)
664    {
665        m_stack_id = frame_sp->GetStackID();
666        SetThreadSP (frame_sp->GetThread());
667    }
668    else
669    {
670        ClearFrame();
671        ClearThread();
672        m_process_wp.reset();
673        m_target_wp.reset();
674    }
675
676}
677
678void
679ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
680{
681    Clear();
682    if (target)
683    {
684        lldb::TargetSP target_sp (target->shared_from_this());
685        if (target_sp)
686        {
687            m_target_wp = target_sp;
688            if (adopt_selected)
689            {
690                lldb::ProcessSP process_sp (target_sp->GetProcessSP());
691                if (process_sp)
692                {
693                    m_process_wp = process_sp;
694                    if (process_sp)
695                    {
696                        // Only fill in the thread and frame if our process is stopped
697                        if (StateIsStoppedState (process_sp->GetState(), true))
698                        {
699                            lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
700                            if (!thread_sp)
701                                thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
702
703                            if (thread_sp)
704                            {
705                                SetThreadSP (thread_sp);
706                                lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
707                                if (!frame_sp)
708                                    frame_sp = thread_sp->GetStackFrameAtIndex(0);
709                                if (frame_sp)
710                                    SetFrameSP (frame_sp);
711                            }
712                        }
713                    }
714                }
715            }
716        }
717    }
718}
719
720void
721ExecutionContextRef::SetProcessPtr (Process *process)
722{
723    if (process)
724    {
725        SetProcessSP(process->shared_from_this());
726    }
727    else
728    {
729        m_process_wp.reset();
730        m_target_wp.reset();
731    }
732}
733
734void
735ExecutionContextRef::SetThreadPtr (Thread *thread)
736{
737    if (thread)
738    {
739        SetThreadSP (thread->shared_from_this());
740    }
741    else
742    {
743        ClearThread();
744        m_process_wp.reset();
745        m_target_wp.reset();
746    }
747}
748
749void
750ExecutionContextRef::SetFramePtr (StackFrame *frame)
751{
752    if (frame)
753        SetFrameSP (frame->shared_from_this());
754    else
755        Clear();
756}
757
758lldb::TargetSP
759ExecutionContextRef::GetTargetSP () const
760{
761    lldb::TargetSP target_sp(m_target_wp.lock());
762    if (target_sp && !target_sp->IsValid())
763        target_sp.reset();
764    return target_sp;
765}
766
767lldb::ProcessSP
768ExecutionContextRef::GetProcessSP () const
769{
770    lldb::ProcessSP process_sp(m_process_wp.lock());
771    if (process_sp && !process_sp->IsValid())
772        process_sp.reset();
773    return process_sp;
774}
775
776lldb::ThreadSP
777ExecutionContextRef::GetThreadSP () const
778{
779    lldb::ThreadSP thread_sp (m_thread_wp.lock());
780
781    if (m_tid != LLDB_INVALID_THREAD_ID)
782    {
783        // We check if the thread has been destroyed in cases where clients
784        // might still have shared pointer to a thread, but the thread is
785        // not valid anymore (not part of the process)
786        if (!thread_sp || !thread_sp->IsValid())
787        {
788            lldb::ProcessSP process_sp(GetProcessSP());
789            if (process_sp && process_sp->IsValid())
790            {
791                thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
792                m_thread_wp = thread_sp;
793            }
794        }
795    }
796
797    // Check that we aren't about to return an invalid thread sp.  We might return a NULL thread_sp,
798    // but don't return an invalid one.
799
800    if (thread_sp && !thread_sp->IsValid())
801        thread_sp.reset();
802
803    return thread_sp;
804}
805
806lldb::StackFrameSP
807ExecutionContextRef::GetFrameSP () const
808{
809    if (m_stack_id.IsValid())
810    {
811        lldb::ThreadSP thread_sp (GetThreadSP());
812        if (thread_sp)
813            return thread_sp->GetFrameWithStackID (m_stack_id);
814    }
815    return lldb::StackFrameSP();
816}
817
818ExecutionContext
819ExecutionContextRef::Lock () const
820{
821    return ExecutionContext(this);
822}
823
824
825