bool
ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
{
    if (m_step_over)
    {
        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (m_thread.GetStackFrameCount() <= m_stack_depth)
        {
            if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
            {
                SetPlanComplete();
                return true;
            }
            else
                return false;
        }
        else
        {
            // We've stepped in, step back out again:
            StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
            if (return_frame)
            {
                if (log)
                {
                    StreamString s;
                    s.PutCString ("Stepped in to: ");
                    addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
                    s.Address (stop_addr, m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
                    s.PutCString (" stepping out to: ");
                    addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
                    s.Address (return_addr, m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
                    log->Printf("%s.", s.GetData());
                }
                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
                return false;
            }
            else
            {
                if (log)
                    log->Printf("Could not find previous frame, stopping.");
                SetPlanComplete();
                return true;
            }

        }

    }
    else
    {
        if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
        {
            SetPlanComplete();
            return true;
        }
        else
            return false;
    }
}
bool
ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    if (log)
    {
        StreamString s;
        s.Address (m_thread.GetRegisterContext()->GetPC(), 
                   m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
        log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData());
    }
    
    // If we're out of the range but in the same frame or in our caller's frame
    // then we should stop.
    // When stepping out we only stop others if we are forcing running one thread.
    bool stop_others;
    if (m_stop_others == lldb::eOnlyThisThread)
        stop_others = true;
    else 
        stop_others = false;

    ThreadPlanSP new_plan_sp;
    
    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
    
    if (frame_order == eFrameCompareOlder)
    {
        // If we're in an older frame then we should stop.
        //
        // A caveat to this is if we think the frame is older but we're actually in a trampoline.
        // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
        // in a trampoline we think the frame is older because the trampoline confused the backtracer.
        // As below, we step through first, and then try to figure out how to get back out again.
        
        new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);

        if (new_plan_sp && log)
            log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
    }
    else if (frame_order == eFrameCompareYounger)
    {
        // Make sure we really are in a new frame.  Do that by unwinding and seeing if the
        // start function really is our start function...
        for(uint32_t i = 1;; ++i)
        {
            StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(i);
            if (!older_frame_sp) {
                // We can't unwind the next frame we should just get out of here & stop...
                break;
            }

            const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything);
            if (IsEquivalentContext(older_context))
            {
                new_plan_sp = m_thread.QueueThreadPlanForStepOut (false,
                                                           NULL,
                                                           true,
                                                           stop_others,
                                                           eVoteNo,
                                                           eVoteNoOpinion,
                                                           0);
                break;
            }
            else
            {
                new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
            }
        }
    }
    else
    {
        // If we're still in the range, keep going.
        if (InRange())
        {
            SetNextBranchBreakpoint();
            return false;
        }


        if (!InSymbol())
        {
            // This one is a little tricky.  Sometimes we may be in a stub or something similar,
            // in which case we need to get out of there.  But if we are in a stub then it's 
            // likely going to be hard to get out from here.  It is probably easiest to step into the
            // stub, and then it will be straight-forward to step out.        
            new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
        }
        else
        {
            // The current clang (at least through 424) doesn't always get the address range for the 
            // DW_TAG_inlined_subroutines right, so that when you leave the inlined range the line table says 
            // you are still in the source file of the inlining function.  This is bad, because now you are missing 
            // the stack frame for the function containing the inlining, and if you sensibly do "finish" to get
            // out of this function you will instead exit the containing function.
            // To work around this, we check whether we are still in the source file we started in, and if not assume
            // it is an error, and push a plan to get us out of this line and back to the containing file.

            if (m_addr_context.line_entry.IsValid())
            {
                SymbolContext sc;
                StackFrameSP frame_sp = m_thread.GetStackFrameAtIndex(0);
                sc = frame_sp->GetSymbolContext (eSymbolContextEverything);
                if (sc.line_entry.IsValid())
                {
                    if (sc.line_entry.file != m_addr_context.line_entry.file
                         && sc.comp_unit == m_addr_context.comp_unit
                         && sc.function == m_addr_context.function)
                    {
                        // Okay, find the next occurance of this file in the line table:
                        LineTable *line_table = m_addr_context.comp_unit->GetLineTable();
                        if (line_table)
                        {
                            Address cur_address = frame_sp->GetFrameCodeAddress();
                            uint32_t entry_idx;
                            LineEntry line_entry;
                            if (line_table->FindLineEntryByAddress (cur_address, line_entry, &entry_idx))
                            {
                                LineEntry next_line_entry;
                                bool step_past_remaining_inline = false;
                                if (entry_idx > 0)
                                {
                                    // We require the the previous line entry and the current line entry come
                                    // from the same file.
                                    // The other requirement is that the previous line table entry be part of an
                                    // inlined block, we don't want to step past cases where people have inlined
                                    // some code fragment by using #include <source-fragment.c> directly.
                                    LineEntry prev_line_entry;
                                    if (line_table->GetLineEntryAtIndex(entry_idx - 1, prev_line_entry)
                                        && prev_line_entry.file == line_entry.file)
                                    {
                                        SymbolContext prev_sc;
                                        Address prev_address = prev_line_entry.range.GetBaseAddress();
                                        prev_address.CalculateSymbolContext(&prev_sc);
                                        if (prev_sc.block)
                                        {
                                            Block *inlined_block = prev_sc.block->GetContainingInlinedBlock();
                                            if (inlined_block)
                                            {
                                                AddressRange inline_range;
                                                inlined_block->GetRangeContainingAddress(prev_address, inline_range);
                                                if (!inline_range.ContainsFileAddress(cur_address))
                                                {
                                                    
                                                    step_past_remaining_inline = true;
                                                }
                                                
                                            }
                                        }
                                    }
                                }
                                
                                if (step_past_remaining_inline)
                                {
                                    uint32_t look_ahead_step = 1;
                                    while (line_table->GetLineEntryAtIndex(entry_idx + look_ahead_step, next_line_entry))
                                    {
                                        // Make sure we haven't wandered out of the function we started from...
                                        Address next_line_address = next_line_entry.range.GetBaseAddress();
                                        Function *next_line_function = next_line_address.CalculateSymbolContextFunction();
                                        if (next_line_function != m_addr_context.function)
                                            break;
                                        
                                        if (next_line_entry.file == m_addr_context.line_entry.file)
                                        {
                                            const bool abort_other_plans = false;
                                            const bool stop_other_threads = false;
                                            new_plan_sp = m_thread.QueueThreadPlanForRunToAddress(abort_other_plans,
                                                                                               next_line_address,
                                                                                               stop_other_threads);
                                            break;
                                        }
                                        look_ahead_step++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
    ClearNextBranchBreakpoint();
    
    if (!new_plan_sp)
        m_no_more_plans = true;
    else
        m_no_more_plans = false;

    if (!new_plan_sp)
    {
        // For efficiencies sake, we know we're done here so we don't have to do this
        // calculation again in MischiefManaged.
        SetPlanComplete();
        return true;
    }
    else
        return false;
}
bool
ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    
    if (log)
    {
        StreamString s;
        s.Address (m_thread.GetRegisterContext()->GetPC(), 
                   m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
        log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
    }

    if (IsPlanComplete())
        return true;
        
    m_no_more_plans = false;
    if (m_sub_plan_sp && m_sub_plan_sp->IsPlanComplete())
    {
        if (!m_sub_plan_sp->PlanSucceeded())
        {
            SetPlanComplete();
            m_no_more_plans = true;
            return true;
        }
        else
            m_sub_plan_sp.reset();
    }
    
    if (m_virtual_step)
    {
        // If we've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
        // we're done.
        // FIXME - This can be both a step in and a step out.  Probably should record which in the m_virtual_step.
        m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(eFrameCompareYounger);
    }
    else
    {
        // Stepping through should be done running other threads in general, since we're setting a breakpoint and
        // continuing.  So only stop others if we are explicitly told to do so.
        
        bool stop_others;
        if (m_stop_others == lldb::eOnlyThisThread)
            stop_others = true;
        else
            stop_others = false;
            
        FrameComparison frame_order = CompareCurrentFrameToStartFrame();
        
        if (frame_order == eFrameCompareOlder || frame_order == eFrameCompareSameParent)
        {
            // If we're in an older frame then we should stop.
            //
            // A caveat to this is if we think the frame is older but we're actually in a trampoline.
            // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
            // in a trampoline we think the frame is older because the trampoline confused the backtracer.
            m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
            if (!m_sub_plan_sp)
            {
                // Otherwise check the ShouldStopHere for step out:
                m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);
                if (log)
                    log->Printf ("ShouldStopHere says we should step out of this frame.");
            }
            else if (log)
            {
                log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
            }

        }
        else if (frame_order == eFrameCompareEqual && InSymbol())
        {
            // If we are not in a place we should step through, we're done.
            // One tricky bit here is that some stubs don't push a frame, so we have to check
            // both the case of a frame that is younger, or the same as this frame.  
            // However, if the frame is the same, and we are still in the symbol we started
            // in, the we don't need to do this.  This first check isn't strictly necessary,
            // but it is more efficient.
            
            // If we're still in the range, keep going, either by running to the next branch breakpoint, or by
            // stepping.
            if (InRange())
            {
                SetNextBranchBreakpoint();
                return false;
            }
        
            SetPlanComplete();
            m_no_more_plans = true;
            return true;
        }
        
        // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
        ClearNextBranchBreakpoint();
        
        // We may have set the plan up above in the FrameIsOlder section:
        
        if (!m_sub_plan_sp)
            m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
        
        if (log)
        {
            if (m_sub_plan_sp)
                log->Printf ("Found a step through plan: %s", m_sub_plan_sp->GetName());
            else
                log->Printf ("No step through plan found.");
        }
        
        // If not, give the "should_stop" callback a chance to push a plan to get us out of here.
        // But only do that if we actually have stepped in.
        if (!m_sub_plan_sp && frame_order == eFrameCompareYounger)
            m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order);

        // If we've stepped in and we are going to stop here, check to see if we were asked to
        // run past the prologue, and if so do that.
        
        if (!m_sub_plan_sp && frame_order == eFrameCompareYounger && m_step_past_prologue)
        {
            lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
            if (curr_frame)
            {
                size_t bytes_to_skip = 0;
                lldb::addr_t curr_addr = m_thread.GetRegisterContext()->GetPC();
                Address func_start_address;
                
                SymbolContext sc = curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
                
                if (sc.function)
                {
                    func_start_address = sc.function->GetAddressRange().GetBaseAddress();
                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
                        bytes_to_skip = sc.function->GetPrologueByteSize();
                }
                else if (sc.symbol)
                {
                    func_start_address = sc.symbol->GetAddress();
                    if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
                        bytes_to_skip = sc.symbol->GetPrologueByteSize();
                }
                
                if (bytes_to_skip != 0)
                {
                    func_start_address.Slide (bytes_to_skip);
                    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
                    if (log)
                        log->Printf ("Pushing past prologue ");
                        
                    m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
                }
            }
        }
     }
    
     if (!m_sub_plan_sp)
     {
        m_no_more_plans = true;
        SetPlanComplete();
        return true;
    }
    else
    {
        m_no_more_plans = false;
        return false;
    }
}
bool
ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    if (log)
    {
        StreamString s;
        s.Address (m_thread.GetRegisterContext()->GetPC(), 
                   m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
        log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData());
    }
    
    // If we're out of the range but in the same frame or in our caller's frame
    // then we should stop.
    // When stepping out we only step if we are forcing running one thread.
    bool stop_others;
    if (m_stop_others == lldb::eOnlyThisThread)
        stop_others = true;
    else 
        stop_others = false;

    ThreadPlan* new_plan = NULL;
    
    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
    
    if (frame_order == eFrameCompareOlder)
    {
        // If we're in an older frame then we should stop.
        //
        // A caveat to this is if we think the frame is older but we're actually in a trampoline.
        // I'm going to make the assumption that you wouldn't RETURN to a trampoline.  So if we are
        // in a trampoline we think the frame is older because the trampoline confused the backtracer.
        // As below, we step through first, and then try to figure out how to get back out again.
        
        new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);

        if (new_plan != NULL && log)
            log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
    }
    else if (frame_order == eFrameCompareYounger)
    {
        // Make sure we really are in a new frame.  Do that by unwinding and seeing if the
        // start function really is our start function...
        StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1);
        
        // But if we can't even unwind one frame we should just get out of here & stop...
        if (older_frame_sp)
        {
            const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything);
            
            // Match as much as is specified in the m_addr_context:
            // This is a fairly loose sanity check.  Note, sometimes the target doesn't get filled
            // in so I left out the target check.  And sometimes the module comes in as the .o file from the
            // inlined range, so I left that out too...
            
            bool older_ctx_is_equivalent = true;
            if (m_addr_context.comp_unit)
            {
                if (m_addr_context.comp_unit == older_context.comp_unit)
                {
                    if (m_addr_context.function && m_addr_context.function == older_context.function)
                    {
                        if (m_addr_context.block && m_addr_context.block == older_context.block)
                        {
                            older_ctx_is_equivalent = true;
                        }
                    }
                }
            }
            else if (m_addr_context.symbol && m_addr_context.symbol == older_context.symbol)
            {
                older_ctx_is_equivalent = true;
            }
        
            if (older_ctx_is_equivalent)
            {
                new_plan = m_thread.QueueThreadPlanForStepOut (false, 
                                                           NULL, 
                                                           true, 
                                                           stop_others, 
                                                           eVoteNo, 
                                                           eVoteNoOpinion,
                                                           0);
            }
            else 
            {
                new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
                
            }
        }
    }
    else
    {
        // If we're still in the range, keep going.
        if (InRange())
        {
            SetNextBranchBreakpoint();
            return false;
        }


        if (!InSymbol())
        {
            // This one is a little tricky.  Sometimes we may be in a stub or something similar,
            // in which case we need to get out of there.  But if we are in a stub then it's 
            // likely going to be hard to get out from here.  It is probably easiest to step into the
            // stub, and then it will be straight-forward to step out.        
            new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
        }
    }

    // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
    ClearNextBranchBreakpoint();
    
    if (new_plan == NULL)
        m_no_more_plans = true;
    else
        m_no_more_plans = false;

    if (new_plan == NULL)
    {
        // For efficiencies sake, we know we're done here so we don't have to do this
        // calculation again in MischiefManaged.
        SetPlanComplete();
        return true;
    }
    else
        return false;
}
bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
  if (m_step_over) {
    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));

    StackFrameSP cur_frame_sp = m_thread.GetStackFrameAtIndex(0);
    if (!cur_frame_sp) {
      if (log)
        log->Printf(
            "ThreadPlanStepInstruction couldn't get the 0th frame, stopping.");
      SetPlanComplete();
      return true;
    }

    StackID cur_frame_zero_id = cur_frame_sp->GetStackID();

    if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id) {
      if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr) {
        if (--m_iteration_count <= 0) {
          SetPlanComplete();
          return true;
        } else {
          // We are still stepping, reset the start pc, and in case we've
          // stepped out,
          // reset the current stack id.
          SetUpState();
          return false;
        }
      } else
        return false;
    } else {
      // We've stepped in, step back out again:
      StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
      if (return_frame) {
        if (return_frame->GetStackID() != m_parent_frame_id ||
            m_start_has_symbol) {
          // next-instruction shouldn't step out of inlined functions.  But we
          // may have stepped into a
          // real function that starts with an inlined function, and we do want
          // to step out of that...

          if (cur_frame_sp->IsInlined()) {
            StackFrameSP parent_frame_sp =
                m_thread.GetFrameWithStackID(m_stack_id);

            if (parent_frame_sp &&
                parent_frame_sp->GetConcreteFrameIndex() ==
                    cur_frame_sp->GetConcreteFrameIndex()) {
              SetPlanComplete();
              if (log) {
                log->Printf("Frame we stepped into is inlined into the frame "
                            "we were stepping from, stopping.");
              }
              return true;
            }
          }

          if (log) {
            StreamString s;
            s.PutCString("Stepped in to: ");
            addr_t stop_addr =
                m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
            s.Address(stop_addr, m_thread.CalculateTarget()
                                     ->GetArchitecture()
                                     .GetAddressByteSize());
            s.PutCString(" stepping out to: ");
            addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
            s.Address(return_addr, m_thread.CalculateTarget()
                                       ->GetArchitecture()
                                       .GetAddressByteSize());
            log->Printf("%s.", s.GetData());
          }

          // StepInstruction should probably have the tri-state RunMode, but for
          // now it is safer to
          // run others.
          const bool stop_others = false;
          m_thread.QueueThreadPlanForStepOutNoShouldStop(
              false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0);
          return false;
        } else {
          if (log) {
            log->PutCString(
                "The stack id we are stepping in changed, but our parent frame "
                "did not when stepping from code with no symbols.  "
                "We are probably just confused about where we are, stopping.");
          }
          SetPlanComplete();
          return true;
        }
      } else {
        if (log)
          log->Printf("Could not find previous frame, stopping.");
        SetPlanComplete();
        return true;
      }
    }
  } else {
    lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(0);
    if (pc_addr != m_instruction_addr) {
      if (--m_iteration_count <= 0) {
        SetPlanComplete();
        return true;
      } else {
        // We are still stepping, reset the start pc, and in case we've stepped
        // in or out,
        // reset the current stack id.
        SetUpState();
        return false;
      }
    } else
      return false;
  }
}