//===-- ThreadPlanCallFunction.cpp ----------------------------------------===//
//
// 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/ThreadPlanCallFunction.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

// ThreadPlanCallFunction: Plan to call a single function
bool ThreadPlanCallFunction::ConstructorSetup(
    Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr,
    lldb::addr_t &function_load_addr) {
  SetIsControllingPlan(true);
  SetOkayToDiscard(false);
  SetPrivate(true);

  ProcessSP process_sp(thread.GetProcess());
  if (!process_sp)
    return false;

  abi = process_sp->GetABI().get();

  if (!abi)
    return false;

  Log *log = GetLog(LLDBLog::Step);

  SetBreakpoints();

  m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
  // If we can't read memory at the point of the process where we are planning
  // to put our function, we're not going to get any further...
  Status error;
  process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
  if (!error.Success()) {
    m_constructor_errors.Printf(
        "Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".",
        m_function_sp);
    LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
              m_constructor_errors.GetData());
    return false;
  }

  llvm::Expected<Address> start_address = GetTarget().GetEntryPointAddress();
  if (!start_address) {
    m_constructor_errors.Printf(
        "%s", llvm::toString(start_address.takeError()).c_str());
    LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
              m_constructor_errors.GetData());
    return false;
  }

  m_start_addr = *start_address;
  start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());

  // Checkpoint the thread state so we can restore it later.
  if (log && log->GetVerbose())
    ReportRegisterState("About to checkpoint thread before function call.  "
                        "Original register state was:");

  if (!thread.CheckpointThreadState(m_stored_thread_state)) {
    m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
                                "checkpoint thread state.");
    LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
              m_constructor_errors.GetData());
    return false;
  }
  function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());

  return true;
}

ThreadPlanCallFunction::ThreadPlanCallFunction(
    Thread &thread, const Address &function, const CompilerType &return_type,
    llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options)
    : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
                 eVoteNoOpinion, eVoteNoOpinion),
      m_valid(false), m_stop_other_threads(options.GetStopOthers()),
      m_unwind_on_error(options.DoesUnwindOnError()),
      m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
      m_debug_execution(options.GetDebug()),
      m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
      m_start_addr(), m_function_sp(0), m_subplan_sp(),
      m_cxx_language_runtime(nullptr), m_objc_language_runtime(nullptr),
      m_stored_thread_state(), m_real_stop_info_sp(), m_constructor_errors(),
      m_return_valobj_sp(), m_takedown_done(false),
      m_should_clear_objc_exception_bp(false),
      m_should_clear_cxx_exception_bp(false),
      m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
  lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
  lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
  ABI *abi = nullptr;

  if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
    return;

  if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
                               start_load_addr, args))
    return;

  ReportRegisterState("Function call was set up.  Register state was:");

  m_valid = true;
}

ThreadPlanCallFunction::ThreadPlanCallFunction(
    Thread &thread, const Address &function,
    const EvaluateExpressionOptions &options)
    : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
                 eVoteNoOpinion, eVoteNoOpinion),
      m_valid(false), m_stop_other_threads(options.GetStopOthers()),
      m_unwind_on_error(options.DoesUnwindOnError()),
      m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
      m_debug_execution(options.GetDebug()),
      m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
      m_start_addr(), m_function_sp(0), m_subplan_sp(),
      m_cxx_language_runtime(nullptr), m_objc_language_runtime(nullptr),
      m_stored_thread_state(), m_real_stop_info_sp(), m_constructor_errors(),
      m_return_valobj_sp(), m_takedown_done(false),
      m_should_clear_objc_exception_bp(false),
      m_should_clear_cxx_exception_bp(false),
      m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}

ThreadPlanCallFunction::~ThreadPlanCallFunction() {
  DoTakedown(PlanSucceeded());
}

void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
  Log *log = GetLog(LLDBLog::Step);
  if (log && log->GetVerbose()) {
    StreamString strm;
    RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();

    log->PutCString(message);

    RegisterValue reg_value;

    for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
         reg_idx < num_registers; ++reg_idx) {
      const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
      if (reg_ctx->ReadRegister(reg_info, reg_value)) {
        DumpRegisterValue(reg_value, strm, *reg_info, true, false,
                          eFormatDefault);
        strm.EOL();
      }
    }
    log->PutString(strm.GetString());
  }
}

void ThreadPlanCallFunction::DoTakedown(bool success) {
  Log *log = GetLog(LLDBLog::Step);
  Thread &thread = GetThread();

  if (!m_valid) {
    // If ConstructorSetup was succesfull but PrepareTrivialCall was not,
    // we will have a saved register state and potentially modified registers.
    // Restore those.
    if (m_stored_thread_state.register_backup_sp)
      if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
        LLDB_LOGF(
            log,
            "ThreadPlanCallFunction(%p): Failed to restore register state from "
            "invalid plan that contained a saved register state.",
            static_cast<void *>(this));

    // Don't call DoTakedown if we were never valid to begin with.
    LLDB_LOGF(log,
              "ThreadPlanCallFunction(%p): Log called on "
              "ThreadPlanCallFunction that was never valid.",
              static_cast<void *>(this));
    return;
  }

  if (!m_takedown_done) {
    if (success) {
      SetReturnValue();
    }
    LLDB_LOGF(log,
              "ThreadPlanCallFunction(%p): DoTakedown called for thread "
              "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
              static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
    m_takedown_done = true;
    m_stop_address =
        thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
    m_real_stop_info_sp = GetPrivateStopInfo();
    if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
      LLDB_LOGF(log,
                "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
                "register state",
                static_cast<void *>(this));
    }
    SetPlanComplete(success);
    ClearBreakpoints();
    if (log && log->GetVerbose())
      ReportRegisterState("Restoring thread state after function call.  "
                          "Restored register state:");
  } else {
    LLDB_LOGF(log,
              "ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
              "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
              static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
  }
}

void ThreadPlanCallFunction::DidPop() { DoTakedown(PlanSucceeded()); }

void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
  if (level == eDescriptionLevelBrief) {
    s->Printf("Function call thread plan");
  } else {
    s->Printf("Thread plan to call 0x%" PRIx64,
              m_function_addr.GetLoadAddress(&GetTarget()));
  }
}

bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
  if (!m_valid) {
    if (error) {
      if (m_constructor_errors.GetSize() > 0)
        error->PutCString(m_constructor_errors.GetString());
      else
        error->PutCString("Unknown error");
    }
    return false;
  }

  return true;
}

Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
  if (m_takedown_done || IsPlanComplete())
    return eVoteYes;
  else
    return ThreadPlan::ShouldReportStop(event_ptr);
}

bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
  Log *log(GetLog(LLDBLog::Step | LLDBLog::Process));
  m_real_stop_info_sp = GetPrivateStopInfo();

  // If our subplan knows why we stopped, even if it's done (which would
  // forward the question to us) we answer yes.
  if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
    SetPlanComplete();
    return true;
  }

  // Check if the breakpoint is one of ours.

  StopReason stop_reason;
  if (!m_real_stop_info_sp)
    stop_reason = eStopReasonNone;
  else
    stop_reason = m_real_stop_info_sp->GetStopReason();
  LLDB_LOG(log,
           "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - {0}.",
           Thread::StopReasonAsString(stop_reason));

  if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
    return true;

  // One more quirk here.  If this event was from Halt interrupting the target,
  // then we should not consider ourselves complete.  Return true to
  // acknowledge the stop.
  if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
    LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: The event is an "
                   "Interrupt, returning true.");
    return true;
  }
  // We control breakpoints separately from other "stop reasons."  So first,
  // check the case where we stopped for an internal breakpoint, in that case,
  // continue on. If it is not an internal breakpoint, consult
  // m_ignore_breakpoints.

  if (stop_reason == eStopReasonBreakpoint) {
    uint64_t break_site_id = m_real_stop_info_sp->GetValue();
    BreakpointSiteSP bp_site_sp;
    bp_site_sp = m_process.GetBreakpointSiteList().FindByID(break_site_id);
    if (bp_site_sp) {
      uint32_t num_owners = bp_site_sp->GetNumberOfConstituents();
      bool is_internal = true;
      for (uint32_t i = 0; i < num_owners; i++) {
        Breakpoint &bp = bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint();
        LLDB_LOGF(log,
                  "ThreadPlanCallFunction::PlanExplainsStop: hit "
                  "breakpoint %d while calling function",
                  bp.GetID());

        if (!bp.IsInternal()) {
          is_internal = false;
          break;
        }
      }
      if (is_internal) {
        LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop hit an "
                       "internal breakpoint, not stopping.");
        return false;
      }
    }

    if (m_ignore_breakpoints) {
      LLDB_LOGF(log,
                "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
                "breakpoints, overriding breakpoint stop info ShouldStop, "
                "returning true");
      m_real_stop_info_sp->OverrideShouldStop(false);
      return true;
    } else {
      LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: we are not "
                     "ignoring breakpoints, overriding breakpoint stop info "
                     "ShouldStop, returning true");
      m_real_stop_info_sp->OverrideShouldStop(true);
      return false;
    }
  } else if (!m_unwind_on_error) {
    // If we don't want to discard this plan, than any stop we don't understand
    // should be propagated up the stack.
    return false;
  } else {
    // If the subplan is running, any crashes are attributable to us. If we
    // want to discard the plan, then we say we explain the stop but if we are
    // going to be discarded, let whoever is above us explain the stop. But
    // don't discard the plan if the stop would restart itself (for instance if
    // it is a signal that is set not to stop.  Check that here first.  We just
    // say we explain the stop but aren't done and everything will continue on
    // from there.

    // Fork events are not handled by this plan — let them fall through
    // to ThreadPlanBase. DidFork is called via PerformAction when the
    // event is delivered.
    if (m_real_stop_info_sp) {
      StopReason reason = m_real_stop_info_sp->GetStopReason();
      if (reason == eStopReasonFork || reason == eStopReasonVFork ||
          reason == eStopReasonVForkDone)
        return false;
    }

    if (m_real_stop_info_sp &&
        m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
      SetPlanComplete(false);
      return m_subplan_sp ? m_unwind_on_error : false;
    } else
      return true;
  }
}

bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
  // We do some computation in DoPlanExplainsStop that may or may not set the
  // plan as complete. We need to do that here to make sure our state is
  // correct.
  DoPlanExplainsStop(event_ptr);

  if (IsPlanComplete()) {
    ReportRegisterState("Function completed.  Register state was:");
    return true;
  } else {
    return false;
  }
}

bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }

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

void ThreadPlanCallFunction::DidPush() {
  //#define SINGLE_STEP_EXPRESSIONS

  // Now set the thread state to "no reason" so we don't run with whatever
  // signal was outstanding... Wait till the plan is pushed so we aren't
  // changing the stop info till we're about to run.

  GetThread().SetStopInfoToNothing();

#ifndef SINGLE_STEP_EXPRESSIONS
  Thread &thread = GetThread();
  m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, m_start_addr, 
                                                          m_stop_other_threads);

  thread.QueueThreadPlan(m_subplan_sp, false);
  m_subplan_sp->SetPrivate(true);
#endif
}

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

bool ThreadPlanCallFunction::MischiefManaged() {
  Log *log = GetLog(LLDBLog::Step);

  if (IsPlanComplete()) {
    LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
              static_cast<void *>(this));

    ThreadPlan::MischiefManaged();
    return true;
  } else {
    return false;
  }
}

void ThreadPlanCallFunction::SetBreakpoints() {
  if (m_trap_exceptions) {
    m_cxx_language_runtime =
        m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus);
    m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC);

    if (m_cxx_language_runtime) {
      m_should_clear_cxx_exception_bp =
          !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
      m_cxx_language_runtime->SetExceptionBreakpoints();
    }
    if (m_objc_language_runtime) {
      m_should_clear_objc_exception_bp =
          !m_objc_language_runtime->ExceptionBreakpointsAreSet();
      m_objc_language_runtime->SetExceptionBreakpoints();
    }
  }
}

void ThreadPlanCallFunction::ClearBreakpoints() {
  if (m_trap_exceptions) {
    if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
      m_cxx_language_runtime->ClearExceptionBreakpoints();
    if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
      m_objc_language_runtime->ClearExceptionBreakpoints();
  }
}

bool ThreadPlanCallFunction::BreakpointsExplainStop() {
  StopInfoSP stop_info_sp = GetPrivateStopInfo();

  if (m_trap_exceptions) {
    if ((m_cxx_language_runtime &&
         m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
             stop_info_sp)) ||
        (m_objc_language_runtime &&
         m_objc_language_runtime->ExceptionBreakpointsExplainStop(
             stop_info_sp))) {
      Log *log = GetLog(LLDBLog::Step);
      LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
                     "exception breakpoint, setting plan complete.");

      SetPlanComplete(false);

      // If the user has set the ObjC language breakpoint, it would normally
      // get priority over our internal catcher breakpoint, but in this case we
      // can't let that happen, so force the ShouldStop here.
      stop_info_sp->OverrideShouldStop(true);
      return true;
    }
  }

  return false;
}

void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
  m_subplan_sp->SetStopOthers(new_value);
}

void ThreadPlanCallFunction::RestoreThreadState() {
  GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
}

void ThreadPlanCallFunction::SetReturnValue() {
  const ABI *abi = m_process.GetABI().get();
  if (abi && m_return_type.IsValid()) {
    const bool persistent = false;
    m_return_valobj_sp =
        abi->GetReturnValueObject(GetThread(), m_return_type, persistent);
  }
}
