//===-- ThreadPlanStepOverRange.cpp -----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/ThreadPlanStepOverRange.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"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.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) {
  auto PrintFailureIfAny = [&]() {
    if (m_status.Success())
      return;
    s->Printf(" failed (%s)", m_status.AsCString());
  };

  if (level == lldb::eDescriptionLevelBrief) {
    s->Printf("step over");
    PrintFailureIfAny();
    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);
  }

  PrintFailureIfAny();

  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)
      return false;
    if (m_addr_context.function) {
      if (m_addr_context.function != context.function)
        return false;
      // It is okay to return to a different block of a straight function, we
      // only have to be more careful if returning from one inlined block to
      // another.
      if (m_addr_context.block->GetInlinedFunctionInfo() == nullptr &&
          context.block->GetInlinedFunctionInfo() == nullptr)
        return true;
      return m_addr_context.block == context.block;
    }
  }
  // Fall back to symbol if we have no decision from comp_unit/function/block.
  return m_addr_context.symbol && m_addr_context.symbol == context.symbol;
}

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, m_status);

    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,
            m_status, true);
        break;
      } else {
        new_plan_sp = m_thread.QueueThreadPlanForStepThrough(
            m_stack_id, false, stop_others, m_status);
        // 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, m_status);
    } 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,
                          m_status);
                      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, m_status);
  }

  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(m_status.Success());
    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->PutString(s.GetString());
            }
          }
        }
      }
    }
  }

  return true;
}
