130fdc8d8SChris Lattner //===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner 
1130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
1230fdc8d8SChris Lattner 
1330fdc8d8SChris Lattner // C Includes
1430fdc8d8SChris Lattner // C++ Includes
1530fdc8d8SChris Lattner // Other libraries and framework includes
1630fdc8d8SChris Lattner // Project includes
1730fdc8d8SChris Lattner #include "lldb/lldb-private-log.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Log.h"
1930fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2030fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2230fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner using namespace lldb;
2630fdc8d8SChris Lattner using namespace lldb_private;
2730fdc8d8SChris Lattner 
2830fdc8d8SChris Lattner //----------------------------------------------------------------------
2930fdc8d8SChris Lattner // ThreadPlanStepInstruction: Step over the current instruction
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner ThreadPlanStepInstruction::ThreadPlanStepInstruction
3330fdc8d8SChris Lattner (
3430fdc8d8SChris Lattner     Thread &thread,
3530fdc8d8SChris Lattner     bool step_over,
3630fdc8d8SChris Lattner     bool stop_other_threads,
3730fdc8d8SChris Lattner     Vote stop_vote,
3830fdc8d8SChris Lattner     Vote run_vote
3930fdc8d8SChris Lattner ) :
40*b01e742aSJim Ingham     ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote),
4130fdc8d8SChris Lattner     m_instruction_addr (0),
4230fdc8d8SChris Lattner     m_step_over (step_over),
4330fdc8d8SChris Lattner     m_stack_depth(0),
44*b01e742aSJim Ingham     m_stop_other_threads (stop_other_threads){
4530fdc8d8SChris Lattner     m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
4630fdc8d8SChris Lattner     m_stack_depth = m_thread.GetStackFrameCount();
4730fdc8d8SChris Lattner }
4830fdc8d8SChris Lattner 
4930fdc8d8SChris Lattner ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
5030fdc8d8SChris Lattner {
5130fdc8d8SChris Lattner }
5230fdc8d8SChris Lattner 
5330fdc8d8SChris Lattner void
5430fdc8d8SChris Lattner ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
5530fdc8d8SChris Lattner {
5630fdc8d8SChris Lattner     if (level == lldb::eDescriptionLevelBrief)
5730fdc8d8SChris Lattner     {
5830fdc8d8SChris Lattner         if (m_step_over)
5930fdc8d8SChris Lattner             s->Printf ("instruction step over");
6030fdc8d8SChris Lattner         else
6130fdc8d8SChris Lattner             s->Printf ("instruction step into");
6230fdc8d8SChris Lattner     }
6330fdc8d8SChris Lattner     else
6430fdc8d8SChris Lattner     {
6530fdc8d8SChris Lattner         s->Printf ("Stepping one instruction past ");
6630fdc8d8SChris Lattner         s->Address(m_instruction_addr, sizeof (addr_t));
6730fdc8d8SChris Lattner         if (m_step_over)
6830fdc8d8SChris Lattner             s->Printf(" stepping over calls");
6930fdc8d8SChris Lattner         else
7030fdc8d8SChris Lattner             s->Printf(" stepping into calls");
7130fdc8d8SChris Lattner     }
7230fdc8d8SChris Lattner }
7330fdc8d8SChris Lattner 
7430fdc8d8SChris Lattner bool
7530fdc8d8SChris Lattner ThreadPlanStepInstruction::ValidatePlan (Stream *error)
7630fdc8d8SChris Lattner {
7730fdc8d8SChris Lattner     // Since we read the instruction we're stepping over from the thread,
7830fdc8d8SChris Lattner     // this plan will always work.
7930fdc8d8SChris Lattner     return true;
8030fdc8d8SChris Lattner }
8130fdc8d8SChris Lattner 
8230fdc8d8SChris Lattner bool
8330fdc8d8SChris Lattner ThreadPlanStepInstruction::PlanExplainsStop ()
8430fdc8d8SChris Lattner {
8530fdc8d8SChris Lattner     Thread::StopInfo info;
8630fdc8d8SChris Lattner     if (m_thread.GetStopInfo (&info))
8730fdc8d8SChris Lattner     {
8830fdc8d8SChris Lattner         StopReason reason = info.GetStopReason();
8930fdc8d8SChris Lattner         if (reason == eStopReasonTrace || reason ==eStopReasonNone)
9030fdc8d8SChris Lattner             return true;
9130fdc8d8SChris Lattner         else
9230fdc8d8SChris Lattner             return false;
9330fdc8d8SChris Lattner     }
9430fdc8d8SChris Lattner     return false;
9530fdc8d8SChris Lattner }
9630fdc8d8SChris Lattner 
9730fdc8d8SChris Lattner bool
9830fdc8d8SChris Lattner ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
9930fdc8d8SChris Lattner {
10030fdc8d8SChris Lattner     if (m_step_over)
10130fdc8d8SChris Lattner     {
10230fdc8d8SChris Lattner         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
10330fdc8d8SChris Lattner         if (m_thread.GetStackFrameCount() <= m_stack_depth)
10430fdc8d8SChris Lattner         {
10530fdc8d8SChris Lattner             if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
10630fdc8d8SChris Lattner             {
10730fdc8d8SChris Lattner                 SetPlanComplete();
10830fdc8d8SChris Lattner                 return true;
10930fdc8d8SChris Lattner             }
11030fdc8d8SChris Lattner             else
11130fdc8d8SChris Lattner                 return false;
11230fdc8d8SChris Lattner         }
11330fdc8d8SChris Lattner         else
11430fdc8d8SChris Lattner         {
11530fdc8d8SChris Lattner             // We've stepped in, step back out again:
11630fdc8d8SChris Lattner             StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
11730fdc8d8SChris Lattner             if (return_frame)
11830fdc8d8SChris Lattner             {
11930fdc8d8SChris Lattner                 if (log)
12030fdc8d8SChris Lattner                 {
12130fdc8d8SChris Lattner                     StreamString s;
12230fdc8d8SChris Lattner                     s.PutCString ("Stepped in to: ");
12330fdc8d8SChris Lattner                     addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess());
12430fdc8d8SChris Lattner                     s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize());
12530fdc8d8SChris Lattner                     s.PutCString (" stepping out to: ");
12630fdc8d8SChris Lattner                     addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess());
12730fdc8d8SChris Lattner                     s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize());
12830fdc8d8SChris Lattner                     log->Printf("%s.", s.GetData());
12930fdc8d8SChris Lattner                 }
13030fdc8d8SChris Lattner                 m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion);
13130fdc8d8SChris Lattner                 return false;
13230fdc8d8SChris Lattner             }
13330fdc8d8SChris Lattner             else
13430fdc8d8SChris Lattner             {
13530fdc8d8SChris Lattner                 if (log)
13630fdc8d8SChris Lattner                     log->Printf("Could not find previous frame, stopping.");
13730fdc8d8SChris Lattner                 SetPlanComplete();
13830fdc8d8SChris Lattner                 return true;
13930fdc8d8SChris Lattner             }
14030fdc8d8SChris Lattner 
14130fdc8d8SChris Lattner         }
14230fdc8d8SChris Lattner 
14330fdc8d8SChris Lattner     }
14430fdc8d8SChris Lattner     else
14530fdc8d8SChris Lattner     {
14630fdc8d8SChris Lattner         if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
14730fdc8d8SChris Lattner         {
14830fdc8d8SChris Lattner             SetPlanComplete();
14930fdc8d8SChris Lattner             return true;
15030fdc8d8SChris Lattner         }
15130fdc8d8SChris Lattner         else
15230fdc8d8SChris Lattner             return false;
15330fdc8d8SChris Lattner     }
15430fdc8d8SChris Lattner }
15530fdc8d8SChris Lattner 
15630fdc8d8SChris Lattner bool
15730fdc8d8SChris Lattner ThreadPlanStepInstruction::StopOthers ()
15830fdc8d8SChris Lattner {
15930fdc8d8SChris Lattner     return m_stop_other_threads;
16030fdc8d8SChris Lattner }
16130fdc8d8SChris Lattner 
16230fdc8d8SChris Lattner StateType
16330fdc8d8SChris Lattner ThreadPlanStepInstruction::RunState ()
16430fdc8d8SChris Lattner {
16530fdc8d8SChris Lattner     return eStateStepping;
16630fdc8d8SChris Lattner }
16730fdc8d8SChris Lattner 
16830fdc8d8SChris Lattner bool
16930fdc8d8SChris Lattner ThreadPlanStepInstruction::WillStop ()
17030fdc8d8SChris Lattner {
17130fdc8d8SChris Lattner     return true;
17230fdc8d8SChris Lattner }
17330fdc8d8SChris Lattner 
17430fdc8d8SChris Lattner bool
17530fdc8d8SChris Lattner ThreadPlanStepInstruction::MischiefManaged ()
17630fdc8d8SChris Lattner {
17730fdc8d8SChris Lattner     if (IsPlanComplete())
17830fdc8d8SChris Lattner     {
17930fdc8d8SChris Lattner         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
18030fdc8d8SChris Lattner         if (log)
18130fdc8d8SChris Lattner             log->Printf("Completed single instruction step plan.");
18230fdc8d8SChris Lattner         ThreadPlan::MischiefManaged ();
18330fdc8d8SChris Lattner         return true;
18430fdc8d8SChris Lattner     }
18530fdc8d8SChris Lattner     else
18630fdc8d8SChris Lattner     {
18730fdc8d8SChris Lattner         return false;
18830fdc8d8SChris Lattner     }
18930fdc8d8SChris Lattner }
19030fdc8d8SChris Lattner 
191