//===-- ThreadPlanStepThrough.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/ThreadPlanStepThrough.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanStepThrough: If the current instruction is a trampoline, step
// through it If it is the beginning of the prologue of a function, step
// through that as well.
// FIXME: At present only handles DYLD trampolines.
//----------------------------------------------------------------------

ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread,
                                             StackID &m_stack_id,
                                             bool stop_others)
    : ThreadPlan(ThreadPlan::eKindStepThrough,
                 "Step through trampolines and prologues", thread,
                 eVoteNoOpinion, eVoteNoOpinion),
      m_start_address(0), m_backstop_bkpt_id(LLDB_INVALID_BREAK_ID),
      m_backstop_addr(LLDB_INVALID_ADDRESS), m_return_stack_id(m_stack_id),
      m_stop_others(stop_others) {
  LookForPlanToStepThroughFromCurrentPC();

  // If we don't get a valid step through plan, don't bother to set up a
  // backstop.
  if (m_sub_plan_sp) {
    m_start_address = GetThread().GetRegisterContext()->GetPC(0);

    // We are going to return back to the concrete frame 1, we might pass by
    // some inlined code that we're in the middle of by doing this, but it's
    // easier than trying to figure out where the inlined code might return to.

    StackFrameSP return_frame_sp = m_thread.GetFrameWithStackID(m_stack_id);

    if (return_frame_sp) {
      m_backstop_addr = return_frame_sp->GetFrameCodeAddress().GetLoadAddress(
          m_thread.CalculateTarget().get());
      Breakpoint *return_bp =
          m_thread.GetProcess()
              ->GetTarget()
              .CreateBreakpoint(m_backstop_addr, true, false)
              .get();

      if (return_bp != nullptr) {
        if (return_bp->IsHardware() && !return_bp->HasResolvedLocations())
          m_could_not_resolve_hw_bp = true;
        return_bp->SetThreadID(m_thread.GetID());
        m_backstop_bkpt_id = return_bp->GetID();
        return_bp->SetBreakpointKind("step-through-backstop");
      }
      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
      if (log) {
        log->Printf("Setting backstop breakpoint %d at address: 0x%" PRIx64,
                    m_backstop_bkpt_id, m_backstop_addr);
      }
    }
  }
}

ThreadPlanStepThrough::~ThreadPlanStepThrough() { ClearBackstopBreakpoint(); }

void ThreadPlanStepThrough::DidPush() {
  if (m_sub_plan_sp)
    PushPlan(m_sub_plan_sp);
}

void ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC() {
  DynamicLoader *loader = m_thread.GetProcess()->GetDynamicLoader();
  if (loader)
    m_sub_plan_sp =
        loader->GetStepThroughTrampolinePlan(m_thread, m_stop_others);

  // If that didn't come up with anything, try the ObjC runtime plugin:
  if (!m_sub_plan_sp.get()) {
    ObjCLanguageRuntime *objc_runtime =
        m_thread.GetProcess()->GetObjCLanguageRuntime();
    if (objc_runtime)
      m_sub_plan_sp =
          objc_runtime->GetStepThroughTrampolinePlan(m_thread, m_stop_others);

    CPPLanguageRuntime *cpp_runtime =
        m_thread.GetProcess()->GetCPPLanguageRuntime();

    // If the ObjC runtime did not provide us with a step though plan then if we
    // have it check the C++ runtime for a step though plan.
    if (!m_sub_plan_sp.get() && cpp_runtime)
      m_sub_plan_sp =
          cpp_runtime->GetStepThroughTrampolinePlan(m_thread, m_stop_others);
  }

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
  if (log) {
    lldb::addr_t current_address = GetThread().GetRegisterContext()->GetPC(0);
    if (m_sub_plan_sp) {
      StreamString s;
      m_sub_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
      log->Printf("Found step through plan from 0x%" PRIx64 ": %s",
                  current_address, s.GetData());
    } else {
      log->Printf("Couldn't find step through plan from address 0x%" PRIx64 ".",
                  current_address);
    }
  }
}

void ThreadPlanStepThrough::GetDescription(Stream *s,
                                           lldb::DescriptionLevel level) {
  if (level == lldb::eDescriptionLevelBrief)
    s->Printf("Step through");
  else {
    s->PutCString("Stepping through trampoline code from: ");
    s->Address(m_start_address, sizeof(addr_t));
    if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) {
      s->Printf(" with backstop breakpoint ID: %d at address: ",
                m_backstop_bkpt_id);
      s->Address(m_backstop_addr, sizeof(addr_t));
    } else
      s->PutCString(" unable to set a backstop breakpoint.");
  }
}

bool ThreadPlanStepThrough::ValidatePlan(Stream *error) {
  if (m_could_not_resolve_hw_bp) {
    if (error)
      error->PutCString(
          "Could not create hardware breakpoint for thread plan.");
    return false;
  }

  if (m_backstop_bkpt_id == LLDB_INVALID_BREAK_ID) {
    if (error)
      error->PutCString("Could not create backstop breakpoint.");
    return false;
  }

  if (!m_sub_plan_sp.get()) {
    if (error)
      error->PutCString("Does not have a subplan.");
    return false;
  }

  return true;
}

bool ThreadPlanStepThrough::DoPlanExplainsStop(Event *event_ptr) {
  // If we have a sub-plan, it will have been asked first if we explain the
  // stop, and we won't get asked.  The only time we would be the one directly
  // asked this question is if we hit our backstop breakpoint.

  return HitOurBackstopBreakpoint();
}

bool ThreadPlanStepThrough::ShouldStop(Event *event_ptr) {
  // If we've already marked ourselves done, then we're done...
  if (IsPlanComplete())
    return true;

  // First, did we hit the backstop breakpoint?
  if (HitOurBackstopBreakpoint()) {
    SetPlanComplete(true);
    return true;
  }

  // If we don't have a sub-plan, then we're also done (can't see how we would
  // ever get here without a plan, but just in case.

  if (!m_sub_plan_sp) {
    SetPlanComplete();
    return true;
  }

  // If the current sub plan is not done, we don't want to stop.  Actually, we
  // probably won't ever get here in this state, since we generally won't get
  // asked any questions if out current sub-plan is not done...
  if (!m_sub_plan_sp->IsPlanComplete())
    return false;

  // If our current sub plan failed, then let's just run to our backstop.  If
  // we can't do that then just stop.
  if (!m_sub_plan_sp->PlanSucceeded()) {
    if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) {
      m_sub_plan_sp.reset();
      return false;
    } else {
      SetPlanComplete(false);
      return true;
    }
  }

  // Next see if there is a specific step through plan at our current pc (these
  // might chain, for instance stepping through a dylib trampoline to the objc
  // dispatch function...)
  LookForPlanToStepThroughFromCurrentPC();
  if (m_sub_plan_sp) {
    PushPlan(m_sub_plan_sp);
    return false;
  } else {
    SetPlanComplete();
    return true;
  }
}

bool ThreadPlanStepThrough::StopOthers() { return m_stop_others; }

StateType ThreadPlanStepThrough::GetPlanRunState() { return eStateRunning; }

bool ThreadPlanStepThrough::DoWillResume(StateType resume_state,
                                         bool current_plan) {
  return true;
}

bool ThreadPlanStepThrough::WillStop() { return true; }

void ThreadPlanStepThrough::ClearBackstopBreakpoint() {
  if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) {
    m_thread.GetProcess()->GetTarget().RemoveBreakpointByID(m_backstop_bkpt_id);
    m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID;
    m_could_not_resolve_hw_bp = false;
  }
}

bool ThreadPlanStepThrough::MischiefManaged() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));

  if (!IsPlanComplete()) {
    return false;
  } else {
    if (log)
      log->Printf("Completed step through step plan.");

    ClearBackstopBreakpoint();
    ThreadPlan::MischiefManaged();
    return true;
  }
}

bool ThreadPlanStepThrough::HitOurBackstopBreakpoint() {
  StopInfoSP stop_info_sp(m_thread.GetStopInfo());
  if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
    break_id_t stop_value = (break_id_t)stop_info_sp->GetValue();
    BreakpointSiteSP cur_site_sp =
        m_thread.GetProcess()->GetBreakpointSiteList().FindByID(stop_value);
    if (cur_site_sp &&
        cur_site_sp->IsBreakpointAtThisSite(m_backstop_bkpt_id)) {
      StackID cur_frame_zero_id =
          m_thread.GetStackFrameAtIndex(0)->GetStackID();

      if (cur_frame_zero_id == m_return_stack_id) {
        Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
        if (log)
          log->PutCString("ThreadPlanStepThrough hit backstop breakpoint.");
        return true;
      }
    }
  }
  return false;
}
