//===-- 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;
    DumpAddress(
        s.AsRawOstream(), m_thread.GetRegisterContext()->GetPC(),
        m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
    LLDB_LOGF(log, "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)
      LLDB_LOGF(log,
                "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));
        LLDB_LOGF(log,
                  "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;
}
