//===-- UnwindLLDB.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/UnwindLLDB.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/RegisterContextUnwind.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;

UnwindLLDB::UnwindLLDB(Thread &thread)
    : Unwind(thread), m_frames(), m_unwind_complete(false),
      m_user_supplied_trap_handler_functions() {
  ProcessSP process_sp(thread.GetProcess());
  if (process_sp) {
    Args args;
    process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
    size_t count = args.GetArgumentCount();
    for (size_t i = 0; i < count; i++) {
      const char *func_name = args.GetArgumentAtIndex(i);
      m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));
    }
  }
}

uint32_t UnwindLLDB::DoGetFrameCount() {
  if (!m_unwind_complete) {
//#define DEBUG_FRAME_SPEED 1
#if DEBUG_FRAME_SPEED
#define FRAME_COUNT 10000
    using namespace std::chrono;
    auto time_value = steady_clock::now();
#endif
    if (!AddFirstFrame())
      return 0;

    ProcessSP process_sp(m_thread.GetProcess());
    ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;

    while (AddOneMoreFrame(abi)) {
#if DEBUG_FRAME_SPEED
      if ((m_frames.size() % FRAME_COUNT) == 0) {
        const auto now = steady_clock::now();
        const auto delta_t = now - time_value;
        printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
               duration<double, std::milli>(delta_t).count(),
               (float)FRAME_COUNT / duration<double>(delta_t).count());
        time_value = now;
      }
#endif
    }
  }
  return m_frames.size();
}

bool UnwindLLDB::AddFirstFrame() {
  if (m_frames.size() > 0)
    return true;

  ProcessSP process_sp(m_thread.GetProcess());
  ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;

  // First, set up the 0th (initial) frame
  CursorSP first_cursor_sp(new Cursor());
  RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind(
      m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));
  if (reg_ctx_sp.get() == nullptr)
    goto unwind_done;

  if (!reg_ctx_sp->IsValid())
    goto unwind_done;

  if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
    goto unwind_done;

  if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
    goto unwind_done;

  // Everything checks out, so release the auto pointer value and let the
  // cursor own it in its shared pointer
  first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
  m_frames.push_back(first_cursor_sp);

  // Update the Full Unwind Plan for this frame if not valid
  UpdateUnwindPlanForFirstFrameIfInvalid(abi);

  return true;

unwind_done:
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
  if (log) {
    LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
              m_thread.GetIndexID());
  }
  m_unwind_complete = true;
  return false;
}

UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
  assert(m_frames.size() != 0 &&
         "Get one more frame called with empty frame list");

  // If we've already gotten to the end of the stack, don't bother to try
  // again...
  if (m_unwind_complete)
    return nullptr;

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));

  CursorSP prev_frame = m_frames.back();
  uint32_t cur_idx = m_frames.size();

  CursorSP cursor_sp(new Cursor());
  RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind(
      m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));

  uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth();

  // We want to detect an unwind that cycles erroneously and stop backtracing.
  // Don't want this maximum unwind limit to be too low -- if you have a
  // backtrace with an "infinitely recursing" bug, it will crash when the stack
  // blows out and the first 35,000 frames are uninteresting - it's the top
  // most 5 frames that you actually care about.  So you can't just cap the
  // unwind at 10,000 or something. Realistically anything over around 200,000
  // is going to blow out the stack space. If we're still unwinding at that
  // point, we're probably never going to finish.
  if (cur_idx >= max_stack_depth) {
    LLDB_LOGF(log,
              "%*sFrame %d unwound too many frames, assuming unwind has "
              "gone astray, stopping.",
              cur_idx < 100 ? cur_idx : 100, "", cur_idx);
    return nullptr;
  }

  if (reg_ctx_sp.get() == nullptr) {
    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will
    // return false.
    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
      // TryFallbackUnwindPlan for prev_frame succeeded and updated
      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
      // still needs to be updated. Hence updating it.
      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
        return nullptr;

      return GetOneMoreFrame(abi);
    }

    LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.",
              cur_idx < 100 ? cur_idx : 100, "", cur_idx);
    return nullptr;
  }

  if (!reg_ctx_sp->IsValid()) {
    // We failed to get a valid RegisterContext. See if the regctx below this
    // on the stack has a fallback unwind plan it can use. Subsequent calls to
    // TryFallbackUnwindPlan() will return false.
    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
      // TryFallbackUnwindPlan for prev_frame succeeded and updated
      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
      // still needs to be updated. Hence updating it.
      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
        return nullptr;

      return GetOneMoreFrame(abi);
    }

    LLDB_LOGF(log,
              "%*sFrame %d invalid RegisterContext for this frame, "
              "stopping stack walk",
              cur_idx < 100 ? cur_idx : 100, "", cur_idx);
    return nullptr;
  }
  if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will
    // return false.
    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
      // TryFallbackUnwindPlan for prev_frame succeeded and updated
      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
      // still needs to be updated. Hence updating it.
      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
        return nullptr;

      return GetOneMoreFrame(abi);
    }

    LLDB_LOGF(log,
              "%*sFrame %d did not get CFA for this frame, stopping stack walk",
              cur_idx < 100 ? cur_idx : 100, "", cur_idx);
    return nullptr;
  }
  if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
    // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
    // have its (constructed) CFA aligned correctly -- don't do the abi
    // alignment check for these.
    if (!reg_ctx_sp->IsTrapHandlerFrame()) {
      // See if we can find a fallback unwind plan for THIS frame.  It may be
      // that the UnwindPlan we're using for THIS frame was bad and gave us a
      // bad CFA. If that's not it, then see if we can change the UnwindPlan
      // for the frame below us ("NEXT") -- see if using that other UnwindPlan
      // gets us a better unwind state.
      if (!reg_ctx_sp->TryFallbackUnwindPlan() ||
          !reg_ctx_sp->GetCFA(cursor_sp->cfa) ||
          !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
          // TryFallbackUnwindPlan for prev_frame succeeded and updated
          // reg_ctx_lldb_sp field of prev_frame. However, cfa field of
          // prev_frame still needs to be updated. Hence updating it.
          if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
            return nullptr;

          return GetOneMoreFrame(abi);
        }

        LLDB_LOGF(log,
                  "%*sFrame %d did not get a valid CFA for this frame, "
                  "stopping stack walk",
                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);
        return nullptr;
      } else {
        LLDB_LOGF(log,
                  "%*sFrame %d had a bad CFA value but we switched the "
                  "UnwindPlan being used and got one that looks more "
                  "realistic.",
                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);
      }
    }
  }
  if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will
    // return false.
    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
      // TryFallbackUnwindPlan for prev_frame succeeded and updated
      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
      // still needs to be updated. Hence updating it.
      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
        return nullptr;

      return GetOneMoreFrame(abi);
    }

    LLDB_LOGF(log,
              "%*sFrame %d did not get PC for this frame, stopping stack walk",
              cur_idx < 100 ? cur_idx : 100, "", cur_idx);
    return nullptr;
  }
  if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to
    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will
    // return false.
    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
      // TryFallbackUnwindPlan for prev_frame succeeded and updated
      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
      // still needs to be updated. Hence updating it.
      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
        return nullptr;

      return GetOneMoreFrame(abi);
    }

    LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk",
              cur_idx < 100 ? cur_idx : 100, "", cur_idx);
    return nullptr;
  }
  // Infinite loop where the current cursor is the same as the previous one...
  if (prev_frame->start_pc == cursor_sp->start_pc &&
      prev_frame->cfa == cursor_sp->cfa) {
    LLDB_LOGF(log,
              "th%d pc of this frame is the same as the previous frame and "
              "CFAs for both frames are identical -- stopping unwind",
              m_thread.GetIndexID());
    return nullptr;
  }

  cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
  return cursor_sp;
}

void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
  // This function is called for First Frame only.
  assert(m_frames.size() == 1 && "No. of cursor frames are not 1");

  bool old_m_unwind_complete = m_unwind_complete;
  CursorSP old_m_candidate_frame = m_candidate_frame;

  // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
  // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update
  // the cfa of Frame 0 (if required).
  AddOneMoreFrame(abi);

  // Remove all the frames added by above function as the purpose of using
  // above function was just to check whether Unwinder of Frame 0 works or not.
  for (uint32_t i = 1; i < m_frames.size(); i++)
    m_frames.pop_back();

  // Restore status after calling AddOneMoreFrame
  m_unwind_complete = old_m_unwind_complete;
  m_candidate_frame = old_m_candidate_frame;
  return;
}

bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));

  // Frame zero is a little different
  if (m_frames.empty())
    return false;

  // If we've already gotten to the end of the stack, don't bother to try
  // again...
  if (m_unwind_complete)
    return false;

  CursorSP new_frame = m_candidate_frame;
  if (new_frame == nullptr)
    new_frame = GetOneMoreFrame(abi);

  if (new_frame == nullptr) {
    LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
              m_thread.GetIndexID());
    m_unwind_complete = true;
    return false;
  }

  m_frames.push_back(new_frame);

  // If we can get one more frame further then accept that we get back a
  // correct frame.
  m_candidate_frame = GetOneMoreFrame(abi);
  if (m_candidate_frame)
    return true;

  // We can't go further from the frame returned by GetOneMore frame. Lets try
  // to get a different frame with using the fallback unwind plan.
  if (!m_frames[m_frames.size() - 2]
           ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
    // We don't have a valid fallback unwind plan. Accept the frame as it is.
    // This is a valid situation when we are at the bottom of the stack.
    return true;
  }

  // Remove the possibly incorrect frame from the frame list and try to add a
  // different one with the newly selected fallback unwind plan.
  m_frames.pop_back();
  CursorSP new_frame_v2 = GetOneMoreFrame(abi);
  if (new_frame_v2 == nullptr) {
    // We haven't got a new frame from the fallback unwind plan. Accept the
    // frame from the original unwind plan. This is a valid situation when we
    // are at the bottom of the stack.
    m_frames.push_back(new_frame);
    return true;
  }

  // Push the new frame to the list and try to continue from this frame. If we
  // can get a new frame then accept it as the correct one.
  m_frames.push_back(new_frame_v2);
  m_candidate_frame = GetOneMoreFrame(abi);
  if (m_candidate_frame) {
    // If control reached here then TryFallbackUnwindPlan had succeeded for
    // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next
    // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For
    // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already
    // updated during TryFallbackUnwindPlan call above. However, cfa field
    // still needs to be updated. Hence updating it here and then returning.
    return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
        m_frames[m_frames.size() - 2]->cfa);
  }

  // The new frame hasn't helped in unwinding. Fall back to the original one as
  // the default unwind plan is usually more reliable then the fallback one.
  m_frames.pop_back();
  m_frames.push_back(new_frame);
  return true;
}

bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc,
                                       bool &behaves_like_zeroth_frame) {
  if (m_frames.size() == 0) {
    if (!AddFirstFrame())
      return false;
  }

  ProcessSP process_sp(m_thread.GetProcess());
  ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;

  while (idx >= m_frames.size() && AddOneMoreFrame(abi))
    ;

  if (idx < m_frames.size()) {
    cfa = m_frames[idx]->cfa;
    pc = m_frames[idx]->start_pc;
    if (idx == 0) {
      // Frame zero always behaves like it.
      behaves_like_zeroth_frame = true;
    } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
      // This could be an asynchronous signal, thus the
      // pc might point to the interrupted instruction rather
      // than a post-call instruction
      behaves_like_zeroth_frame = true;
    } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
      // This frame may result from signal processing installing
      // a pointer to the first byte of a signal-return trampoline
      // in the return address slot of the frame below, so this
      // too behaves like the zeroth frame (i.e. the pc might not
      // be pointing just past a call in it)
      behaves_like_zeroth_frame = true;
    } else if (m_frames[idx]->reg_ctx_lldb_sp->BehavesLikeZerothFrame()) {
      behaves_like_zeroth_frame = true;
    } else {
      behaves_like_zeroth_frame = false;
    }
    return true;
  }
  return false;
}

lldb::RegisterContextSP
UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {
  lldb::RegisterContextSP reg_ctx_sp;
  uint32_t idx = frame->GetConcreteFrameIndex();

  if (idx == 0) {
    return m_thread.GetRegisterContext();
  }

  if (m_frames.size() == 0) {
    if (!AddFirstFrame())
      return reg_ctx_sp;
  }

  ProcessSP process_sp(m_thread.GetProcess());
  ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;

  while (idx >= m_frames.size()) {
    if (!AddOneMoreFrame(abi))
      break;
  }

  const uint32_t num_frames = m_frames.size();
  if (idx < num_frames) {
    Cursor *frame_cursor = m_frames[idx].get();
    reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
  }
  return reg_ctx_sp;
}

UnwindLLDB::RegisterContextLLDBSP
UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {
  RegisterContextLLDBSP reg_ctx_sp;
  if (frame_num < m_frames.size())
    reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
  return reg_ctx_sp;
}

bool UnwindLLDB::SearchForSavedLocationForRegister(
    uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
    uint32_t starting_frame_num, bool pc_reg) {
  int64_t frame_num = starting_frame_num;
  if (static_cast<size_t>(frame_num) >= m_frames.size())
    return false;

  // Never interrogate more than one level while looking for the saved pc
  // value. If the value isn't saved by frame_num, none of the frames lower on
  // the stack will have a useful value.
  if (pc_reg) {
    UnwindLLDB::RegisterSearchResult result;
    result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
        lldb_regnum, regloc);
    return result == UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }
  while (frame_num >= 0) {
    UnwindLLDB::RegisterSearchResult result;
    result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
        lldb_regnum, regloc);

    // We descended down to the live register context aka stack frame 0 and are
    // reading the value out of a live register.
    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
        regloc.type ==
            UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
      return true;
    }

    // If we have unwind instructions saying that register N is saved in
    // register M in the middle of the stack (and N can equal M here, meaning
    // the register was not used in this function), then change the register
    // number we're looking for to M and keep looking for a concrete  location
    // down the stack, or an actual value from a live RegisterContext at frame
    // 0.
    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
        regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister &&
        frame_num > 0) {
      result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
      lldb_regnum = regloc.location.register_number;
    }

    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
      return true;
    if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
      return false;
    frame_num--;
  }
  return false;
}
