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 #include "lldb/Target/ExecutionContextScope.h"
12 #include "lldb/Target/StackFrame.h"
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Target/Thread.h"
16 
17 using namespace lldb_private;
18 
19 ExecutionContext::ExecutionContext() :
20     m_target_sp (),
21     m_process_sp (),
22     m_thread_sp (),
23     m_frame_sp ()
24 {
25 }
26 
27 ExecutionContext::ExecutionContext (const ExecutionContext &rhs) :
28     m_target_sp(rhs.m_target_sp),
29     m_process_sp(rhs.m_process_sp),
30     m_thread_sp(rhs.m_thread_sp),
31     m_frame_sp(rhs.m_frame_sp)
32 {
33 }
34 
35 ExecutionContext::ExecutionContext (const lldb::TargetSP &target_sp, bool get_process) :
36     m_target_sp (),
37     m_process_sp (),
38     m_thread_sp (),
39     m_frame_sp ()
40 {
41     if (target_sp)
42         SetContext (target_sp, get_process);
43 }
44 
45 ExecutionContext::ExecutionContext (const lldb::ProcessSP &process_sp) :
46     m_target_sp (),
47     m_process_sp (),
48     m_thread_sp (),
49     m_frame_sp ()
50 {
51     if (process_sp)
52         SetContext (process_sp);
53 }
54 
55 ExecutionContext::ExecutionContext (const lldb::ThreadSP &thread_sp) :
56     m_target_sp (),
57     m_process_sp (),
58     m_thread_sp (),
59     m_frame_sp ()
60 {
61     if (thread_sp)
62         SetContext (thread_sp);
63 }
64 
65 ExecutionContext::ExecutionContext (const lldb::StackFrameSP &frame_sp) :
66     m_target_sp (),
67     m_process_sp (),
68     m_thread_sp (),
69     m_frame_sp ()
70 {
71     if (frame_sp)
72         SetContext (frame_sp);
73 }
74 
75 ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
76     m_target_sp (t->shared_from_this()),
77     m_process_sp (),
78     m_thread_sp (),
79     m_frame_sp ()
80 {
81     if (t && fill_current_process_thread_frame)
82     {
83         m_process_sp = t->GetProcessSP();
84         if (m_process_sp)
85         {
86             m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
87             if (m_thread_sp)
88                 m_frame_sp = m_thread_sp->GetSelectedFrame();
89         }
90     }
91 }
92 
93 ExecutionContext::ExecutionContext(Process* process, Thread *thread, StackFrame *frame) :
94     m_target_sp (),
95     m_process_sp (process->shared_from_this()),
96     m_thread_sp (thread->shared_from_this()),
97     m_frame_sp (frame->shared_from_this())
98 {
99     if (process)
100         m_target_sp = process->GetTarget().shared_from_this();
101 }
102 
103 ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) :
104     m_target_sp (exe_ctx_ref.GetTargetSP()),
105     m_process_sp (exe_ctx_ref.GetProcessSP()),
106     m_thread_sp (exe_ctx_ref.GetThreadSP()),
107     m_frame_sp (exe_ctx_ref.GetFrameSP())
108 {
109 }
110 
111 ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr) :
112     m_target_sp (),
113     m_process_sp (),
114     m_thread_sp (),
115     m_frame_sp ()
116 {
117     if (exe_ctx_ref_ptr)
118     {
119         m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
120         m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
121         m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
122         m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
123     }
124 }
125 
126 ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) :
127     m_target_sp (),
128     m_process_sp (),
129     m_thread_sp (),
130     m_frame_sp ()
131 {
132     if (exe_scope_ptr)
133         exe_scope_ptr->CalculateExecutionContext (*this);
134 }
135 
136 ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
137 {
138     exe_scope_ref.CalculateExecutionContext (*this);
139 }
140 
141 void
142 ExecutionContext::Clear()
143 {
144     m_target_sp.reset();
145     m_process_sp.reset();
146     m_thread_sp.reset();
147     m_frame_sp.reset();
148 }
149 
150 ExecutionContext::~ExecutionContext()
151 {
152 }
153 
154 uint32_t
155 ExecutionContext::GetAddressByteSize() const
156 {
157     if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
158         m_target_sp->GetArchitecture().GetAddressByteSize();
159     if (m_process_sp)
160         m_process_sp->GetAddressByteSize();
161     return sizeof(void *);
162 }
163 
164 
165 
166 RegisterContext *
167 ExecutionContext::GetRegisterContext () const
168 {
169     if (m_frame_sp)
170         return m_frame_sp->GetRegisterContext().get();
171     else if (m_thread_sp)
172         return m_thread_sp->GetRegisterContext().get();
173     return NULL;
174 }
175 
176 Target *
177 ExecutionContext::GetTargetPtr () const
178 {
179     if (m_target_sp)
180         return m_target_sp.get();
181     if (m_process_sp)
182         return &m_process_sp->GetTarget();
183     return NULL;
184 }
185 
186 Process *
187 ExecutionContext::GetProcessPtr () const
188 {
189     if (m_process_sp)
190         return m_process_sp.get();
191     if (m_target_sp)
192         return m_target_sp->GetProcessSP().get();
193     return NULL;
194 }
195 
196 ExecutionContextScope *
197 ExecutionContext::GetBestExecutionContextScope () const
198 {
199     if (m_frame_sp)
200         return m_frame_sp.get();
201     if (m_thread_sp)
202         return m_thread_sp.get();
203     if (m_process_sp)
204         return m_process_sp.get();
205     return m_target_sp.get();
206 }
207 
208 Target &
209 ExecutionContext::GetTargetRef () const
210 {
211     assert (m_target_sp.get());
212     return *m_target_sp;
213 }
214 
215 Process &
216 ExecutionContext::GetProcessRef () const
217 {
218     assert (m_process_sp.get());
219     return *m_process_sp;
220 }
221 
222 Thread &
223 ExecutionContext::GetThreadRef () const
224 {
225     assert (m_thread_sp.get());
226     return *m_thread_sp;
227 }
228 
229 StackFrame &
230 ExecutionContext::GetFrameRef () const
231 {
232     assert (m_frame_sp.get());
233     return *m_frame_sp;
234 }
235 
236 void
237 ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
238 {
239     m_target_sp = target_sp;
240 }
241 
242 void
243 ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
244 {
245     m_process_sp = process_sp;
246 }
247 
248 void
249 ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
250 {
251     m_thread_sp = thread_sp;
252 }
253 
254 void
255 ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
256 {
257     m_frame_sp = frame_sp;
258 }
259 
260 void
261 ExecutionContext::SetTargetPtr (Target* target)
262 {
263     if (target)
264         m_target_sp = target->shared_from_this();
265     else
266         m_target_sp.reset();
267 }
268 
269 void
270 ExecutionContext::SetProcessPtr (Process *process)
271 {
272     if (process)
273         m_process_sp = process->shared_from_this();
274     else
275         m_process_sp.reset();
276 }
277 
278 void
279 ExecutionContext::SetThreadPtr (Thread *thread)
280 {
281     if (thread)
282         m_thread_sp = thread->shared_from_this();
283     else
284         m_thread_sp.reset();
285 }
286 
287 void
288 ExecutionContext::SetFramePtr (StackFrame *frame)
289 {
290     if (frame)
291         m_frame_sp = frame->shared_from_this();
292     else
293         m_frame_sp.reset();
294 }
295 
296 void
297 ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process)
298 {
299     m_target_sp = target_sp;
300     if (get_process && target_sp)
301         m_process_sp = target_sp->GetProcessSP();
302     else
303         m_process_sp.reset();
304     m_thread_sp.reset();
305     m_frame_sp.reset();
306 }
307 
308 void
309 ExecutionContext::SetContext (const lldb::ProcessSP &process_sp)
310 {
311     m_process_sp = process_sp;
312     if (process_sp)
313         m_target_sp = process_sp->GetTarget().shared_from_this();
314     else
315         m_target_sp.reset();
316     m_thread_sp.reset();
317     m_frame_sp.reset();
318 }
319 
320 void
321 ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
322 {
323     m_frame_sp.reset();
324     m_thread_sp = thread_sp;
325     if (thread_sp)
326     {
327         m_process_sp = thread_sp->GetProcess().shared_from_this();
328         if (m_process_sp)
329             m_target_sp = m_process_sp->GetTarget().shared_from_this();
330         else
331             m_target_sp.reset();
332     }
333     else
334     {
335         m_target_sp.reset();
336         m_process_sp.reset();
337     }
338 }
339 
340 void
341 ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
342 {
343     m_frame_sp = frame_sp;
344     if (frame_sp)
345     {
346         m_thread_sp = frame_sp->CalculateThread();
347         if (m_thread_sp)
348         {
349             m_process_sp = m_thread_sp->GetProcess().shared_from_this();
350             if (m_process_sp)
351                 m_target_sp = m_process_sp->GetTarget().shared_from_this();
352             else
353                 m_target_sp.reset();
354         }
355         else
356         {
357             m_target_sp.reset();
358             m_process_sp.reset();
359         }
360     }
361     else
362     {
363         m_target_sp.reset();
364         m_process_sp.reset();
365         m_thread_sp.reset();
366     }
367 }
368 
369 ExecutionContext &
370 ExecutionContext::operator =(const ExecutionContext &rhs)
371 {
372     if (this != &rhs)
373     {
374         m_target_sp  = rhs.m_target_sp;
375         m_process_sp = rhs.m_process_sp;
376         m_thread_sp  = rhs.m_thread_sp;
377         m_frame_sp   = rhs.m_frame_sp;
378     }
379     return *this;
380 }
381 
382 bool
383 ExecutionContext::operator ==(const ExecutionContext &rhs) const
384 {
385     // Check that the frame shared pointers match, or both are valid and their stack
386     // IDs match since sometimes we get new objects that represent the same
387     // frame within a thread.
388     if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID()))
389     {
390         // Check that the thread shared pointers match, or both are valid and
391         // their thread IDs match since sometimes we get new objects that
392         // represent the same thread within a process.
393         if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID()))
394         {
395             // Processes and targets don't change much
396             return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
397         }
398     }
399     return false;
400 }
401 
402 bool
403 ExecutionContext::operator !=(const ExecutionContext &rhs) const
404 {
405     return !(*this == rhs);
406 }
407 
408 
409 ExecutionContextRef::ExecutionContextRef() :
410     m_target_wp (),
411     m_process_wp (),
412     m_thread_wp (),
413     m_frame_wp (),
414     m_tid(LLDB_INVALID_THREAD_ID),
415     m_stack_id ()
416 {
417 }
418 
419 ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) :
420     m_target_wp (),
421     m_process_wp (),
422     m_thread_wp (),
423     m_frame_wp (),
424     m_tid(LLDB_INVALID_THREAD_ID),
425     m_stack_id ()
426 {
427     if (exe_ctx)
428         *this = *exe_ctx;
429 }
430 
431 ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
432     m_target_wp (),
433     m_process_wp (),
434     m_thread_wp (),
435     m_frame_wp (),
436     m_tid(LLDB_INVALID_THREAD_ID),
437     m_stack_id ()
438 {
439     *this = exe_ctx;
440 }
441 
442 
443 ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
444     m_target_wp(),
445     m_process_wp(),
446     m_thread_wp(),
447     m_frame_wp(),
448     m_tid(LLDB_INVALID_THREAD_ID),
449     m_stack_id ()
450 {
451     SetTargetPtr (target, adopt_selected);
452 }
453 
454 
455 
456 
457 ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
458     m_target_wp (rhs.m_target_wp),
459     m_process_wp(rhs.m_process_wp),
460     m_thread_wp (rhs.m_thread_wp),
461     m_frame_wp  (rhs.m_frame_wp),
462     m_tid       (rhs.m_tid),
463     m_stack_id  (rhs.m_stack_id)
464 {
465 }
466 
467 ExecutionContextRef &
468 ExecutionContextRef::operator =(const ExecutionContextRef &rhs)
469 {
470     if (this != &rhs)
471     {
472         m_target_wp  = rhs.m_target_wp;
473         m_process_wp = rhs.m_process_wp;
474         m_thread_wp  = rhs.m_thread_wp;
475         m_frame_wp   = rhs.m_frame_wp;
476         m_tid        = rhs.m_tid;
477         m_stack_id   = rhs.m_stack_id;
478     }
479     return *this;
480 }
481 
482 ExecutionContextRef &
483 ExecutionContextRef::operator =(const ExecutionContext &exe_ctx)
484 {
485     m_target_wp  = exe_ctx.GetTargetSP();
486     m_process_wp = exe_ctx.GetProcessSP();
487     SetThreadSP (exe_ctx.GetThreadSP());
488     SetFrameSP (exe_ctx.GetFrameSP());
489     return *this;
490 }
491 
492 void
493 ExecutionContextRef::Clear()
494 {
495     m_target_wp.reset();
496     m_process_wp.reset();
497     m_thread_wp.reset();
498     m_frame_wp.reset();
499     m_tid = LLDB_INVALID_THREAD_ID;
500     m_stack_id.Clear();
501 }
502 
503 ExecutionContextRef::~ExecutionContextRef()
504 {
505 }
506 
507 void
508 ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
509 {
510     m_target_wp = target_sp;
511 }
512 
513 void
514 ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp)
515 {
516     m_process_wp = process_sp;
517 }
518 
519 void
520 ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp)
521 {
522     m_thread_wp = thread_sp;
523     if (thread_sp)
524         m_tid = thread_sp->GetID();
525     else
526         m_tid = LLDB_INVALID_THREAD_ID;
527 }
528 
529 void
530 ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
531 {
532     m_frame_wp = frame_sp;
533     if (frame_sp)
534         m_stack_id = frame_sp->GetStackID();
535     else
536         m_stack_id.Clear();
537 }
538 
539 void
540 ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
541 {
542     Clear();
543     if (target)
544     {
545         lldb::TargetSP target_sp (target->shared_from_this());
546         if (target_sp)
547         {
548             m_target_wp = target_sp;
549             if (adopt_selected)
550             {
551                 lldb::ProcessSP process_sp (target_sp->GetProcessSP());
552                 if (process_sp)
553                 {
554                     m_process_wp = process_sp;
555                     if (process_sp)
556                     {
557                         lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
558                         if (!thread_sp)
559                             thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
560 
561                         if (thread_sp)
562                         {
563                             SetThreadSP (thread_sp);
564                             lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
565                             if (!frame_sp)
566                                 frame_sp = thread_sp->GetStackFrameAtIndex(0);
567                             if (frame_sp)
568                                 SetFrameSP (frame_sp);
569                         }
570                     }
571                 }
572             }
573         }
574     }
575 }
576 
577 void
578 ExecutionContextRef::SetProcessPtr (Process *process)
579 {
580     if (process)
581         m_process_wp = process->shared_from_this();
582     else
583         m_process_wp.reset();
584 }
585 
586 void
587 ExecutionContextRef::SetThreadPtr (Thread *thread)
588 {
589     if (thread)
590         m_thread_wp = thread->shared_from_this();
591     else
592         m_thread_wp.reset();
593 }
594 
595 void
596 ExecutionContextRef::SetFramePtr (StackFrame *frame)
597 {
598     if (frame)
599         m_frame_wp = frame->shared_from_this();
600     else
601         m_frame_wp.reset();
602 }
603 
604 
605 lldb::ThreadSP
606 ExecutionContextRef::GetThreadSP () const
607 {
608     lldb::ThreadSP thread_sp (m_thread_wp.lock());
609     if (!thread_sp && m_tid != LLDB_INVALID_THREAD_ID)
610     {
611         lldb::ProcessSP process_sp(GetProcessSP());
612         if (process_sp)
613         {
614             thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
615             m_thread_wp = thread_sp;
616         }
617     }
618     return thread_sp;
619 }
620 
621 lldb::StackFrameSP
622 ExecutionContextRef::GetFrameSP () const
623 {
624     lldb::StackFrameSP frame_sp (m_frame_wp.lock());
625     if (!frame_sp && m_stack_id.IsValid())
626     {
627         lldb::ThreadSP thread_sp (GetThreadSP());
628         if (thread_sp)
629         {
630             frame_sp = thread_sp->GetFrameWithStackID (m_stack_id);
631             m_frame_wp = frame_sp;
632         }
633     }
634     return frame_sp;
635 }
636 
637 ExecutionContext
638 ExecutionContextRef::Lock () const
639 {
640     return ExecutionContext(this);
641 }
642 
643 
644