//===-- ThreadPlanStepOverRange.cpp -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/ThreadPlanStepOverRange.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanStepOut.h"
#include "lldb/Target/ThreadPlanStepThrough.h"

using namespace lldb_private;
using namespace lldb;

uint32_t ThreadPlanStepOverRange::s_default_flag_values = 0;

//----------------------------------------------------------------------
// ThreadPlanStepOverRange: Step through a stack range, either stepping over or into
// based on the value of \a type.
//----------------------------------------------------------------------

ThreadPlanStepOverRange::ThreadPlanStepOverRange
(
    Thread &thread,
    const AddressRange &range,
    const SymbolContext &addr_context,
    lldb::RunMode stop_others,
    LazyBool step_out_avoids_code_without_debug_info
) :
    ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others),
    ThreadPlanShouldStopHere (this),
    m_first_resume(true)
{
    SetFlagsToDefault();
    SetupAvoidNoDebug(step_out_avoids_code_without_debug_info);
}

ThreadPlanStepOverRange::~ThreadPlanStepOverRange() = default;

void
ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    if (level == lldb::eDescriptionLevelBrief)
    {
        s->Printf("step over");
        return;
    }
    s->Printf ("Stepping over");
    bool printed_line_info = false;
    if (m_addr_context.line_entry.IsValid())
    {
        s->Printf (" line ");
        m_addr_context.line_entry.DumpStopContext (s, false);
        printed_line_info = true;
    }

    if (!printed_line_info || level == eDescriptionLevelVerbose)
    {
        s->Printf (" using ranges: ");
        DumpRanges(s);
    }

    s->PutChar('.');
}

void
ThreadPlanStepOverRange::SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info)
{
    bool avoid_nodebug = true;
    switch (step_out_avoids_code_without_debug_info)
    {
        case eLazyBoolYes:
            avoid_nodebug = true;
            break;
        case eLazyBoolNo:
            avoid_nodebug = false;
            break;
        case eLazyBoolCalculate:
            avoid_nodebug = m_thread.GetStepOutAvoidsNoDebug();
            break;
    }
    if (avoid_nodebug)
        GetFlags().Set (ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
    else
        GetFlags().Clear (ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
    // Step Over plans should always avoid no-debug on step in.  Seems like you shouldn't
    // have to say this, but a tail call looks more like a step in that a step out, so
    // we want to catch this case.
    GetFlags().Set (ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
}

bool
ThreadPlanStepOverRange::IsEquivalentContext(const SymbolContext &context)
{
    // 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...
    if (m_addr_context.comp_unit)
    {
        if (m_addr_context.comp_unit == context.comp_unit)
        {
            if (m_addr_context.function && m_addr_context.function == context.function)
            {
                if (m_addr_context.block && m_addr_context.block == context.block)
                    return true;
            }
        }
    }
    else if (m_addr_context.symbol && m_addr_context.symbol == context.symbol)
    {
        return true;
    }
    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 = (m_stop_others == lldb::eOnlyThisThread);
    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.QueueThreadPlanForStepOutNoShouldStop(false,
                                                                             nullptr,
                                                                             true,
                                                                             stop_others,
                                                                             eVoteNo,
                                                                             eVoteNoOpinion,
                                                                             0,
                                                                             true);
                break;
            }
            else
            {
                new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
                // If we found a way through, then we should stop recursing.
                if (new_plan_sp)
                    break;
            }
        }
    }
    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.original_file != m_addr_context.line_entry.original_file
                         && sc.comp_unit == m_addr_context.comp_unit
                         && sc.function == m_addr_context.function)
                    {
                        // Okay, find the next occurrence 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 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.original_file == line_entry.original_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.original_file == m_addr_context.line_entry.original_file)
                                        {
                                            const bool abort_other_plans = false;
                                            const RunMode stop_other_threads = RunMode::eAllThreads;
                                            lldb::addr_t cur_pc = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
                                            AddressRange step_range(cur_pc, next_line_address.GetLoadAddress(&GetTarget()) - cur_pc);
                                            
                                            new_plan_sp = m_thread.QueueThreadPlanForStepOverRange (abort_other_plans,
                                                                                                    step_range,
                                                                                                    sc,
                                                                                                    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 we haven't figured out something to do yet, then ask the ShouldStopHere callback:
    if (!new_plan_sp)
    {
        new_plan_sp = CheckShouldStopHereAndQueueStepOut (frame_order);
    }

    if (!new_plan_sp)
        m_no_more_plans = true;
    else
    {
        // Any new plan will be an implementation plan, so mark it private:
        new_plan_sp->SetPrivate(true);
        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
ThreadPlanStepOverRange::DoPlanExplainsStop (Event *event_ptr)
{
    // For crashes, breakpoint hits, signals, etc, let the base plan (or some plan above us)
    // handle the stop.  That way the user can see the stop, step around, and then when they
    // are done, continue and have their step complete.  The exception is if we've hit our
    // "run to next branch" breakpoint.
    // Note, unlike the step in range plan, we don't mark ourselves complete if we hit an
    // unexplained breakpoint/crash.
    
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
    bool return_value;
    
    if (stop_info_sp)
    {
        StopReason reason = stop_info_sp->GetStopReason();

        if (reason == eStopReasonTrace)
        {
            return_value = true;
        }
        else if (reason == eStopReasonBreakpoint)
        {
            return_value = NextRangeBreakpointExplainsStop(stop_info_sp);
        }
        else
        {
            if (log)
                log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
            return_value = false;
        }
    }
    else
        return_value = true;

    return return_value;
}

bool
ThreadPlanStepOverRange::DoWillResume (lldb::StateType resume_state, bool current_plan)
{
    if (resume_state != eStateSuspended && m_first_resume)
    {
        m_first_resume = false;
        if (resume_state == eStateStepping && current_plan)
        {
            // See if we are about to step over an inlined call in the middle of the inlined stack, if so figure
            // out its extents and reset our range to step over that.
            bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth();
            if (in_inlined_stack)
            {
                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
                if (log)
                    log->Printf ("ThreadPlanStepInRange::DoWillResume: adjusting range to the frame at inlined depth %d.",
                                 m_thread.GetCurrentInlinedDepth());
                StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0);
                if (stack_sp)
                {
                    Block *frame_block = stack_sp->GetFrameBlock();
                    lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
                    AddressRange my_range;
                    if (frame_block->GetRangeContainingLoadAddress(curr_pc, m_thread.GetProcess()->GetTarget(), my_range))
                    {
                        m_address_ranges.clear();
                        m_address_ranges.push_back(my_range);
                        if (log)
                        {
                            StreamString s;
                            const InlineFunctionInfo *inline_info = frame_block->GetInlinedFunctionInfo();
                            const char *name;
                            if (inline_info)
                                name = inline_info->GetName(frame_block->CalculateSymbolContextFunction()->GetLanguage()).AsCString();
                            else
                                name = "<unknown-notinlined>";
                            
                            s.Printf ("Stepping over inlined function \"%s\" in inlined stack: ", name);
                            DumpRanges(&s);
                            log->PutCString(s.GetData());
                        }
                    }
                    
                }
            }
        }
    }
    
    return true;
}
