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

#include "lldb/Target/ThreadPlanStepOverRange.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes

#include "lldb/lldb-private-log.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;


//----------------------------------------------------------------------
// 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
) :
    ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others),
    m_first_resume(true)
{
}

ThreadPlanStepOverRange::~ThreadPlanStepOverRange ()
{
}

void
ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    if (level == lldb::eDescriptionLevelBrief)
        s->Printf("step over");
    else
    {
        s->Printf ("stepping through range (stepping over functions): ");
        DumpRanges(s);    
    }
}

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;

    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);
        }
        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 = 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 == 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
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();

        switch (reason)
        {
        case eStopReasonTrace:
            return_value = true;
            break;
        case eStopReasonBreakpoint:
            if (NextRangeBreakpointExplainsStop(stop_info_sp))
                return_value = true;
            else
                return_value = false;
            break;
        case eStopReasonWatchpoint:
        case eStopReasonSignal:
        case eStopReasonException:
        case eStopReasonExec:
        case eStopReasonThreadExiting:
        default:
            if (log)
                log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
            return_value = false;
            break;
        }
    }
    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().AsCString();
                            else
                                name = "<unknown-notinlined>";
                            
                            s.Printf ("Stepping over inlined function \"%s\" in inlined stack: ", name);
                            DumpRanges(&s);
                            log->PutCString(s.GetData());
                        }
                    }
                    
                }
            }
        }
    }
    
    return true;
}
