//===-- UnwindMacOSXFrameBackchain.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/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ArchSpec.h"

#include "RegisterContextMacOSXFrameBackchain.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain(Thread &thread)
    : Unwind(thread), m_cursors() {}

uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
  if (m_cursors.empty()) {
    ExecutionContext exe_ctx(m_thread.shared_from_this());
    Target *target = exe_ctx.GetTargetPtr();
    if (target) {
      const ArchSpec &target_arch = target->GetArchitecture();
      // Frame zero should always be supplied by the thread...
      exe_ctx.SetFrameSP(m_thread.GetStackFrameAtIndex(0));

      if (target_arch.GetAddressByteSize() == 8)
        GetStackFrameData_x86_64(exe_ctx);
      else
        GetStackFrameData_i386(exe_ctx);
    }
  }
  return m_cursors.size();
}

bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(
    uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) {
  const uint32_t frame_count = GetFrameCount();
  if (idx < frame_count) {
    if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
      return false;
    if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS)
      return false;

    pc = m_cursors[idx].pc;
    cfa = m_cursors[idx].fp;
    behaves_like_zeroth_frame = (idx == 0);

    return true;
  }
  return false;
}

lldb::RegisterContextSP
UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame(StackFrame *frame) {
  lldb::RegisterContextSP reg_ctx_sp;
  uint32_t concrete_idx = frame->GetConcreteFrameIndex();
  const uint32_t frame_count = GetFrameCount();
  if (concrete_idx < frame_count)
    reg_ctx_sp = std::make_shared<RegisterContextMacOSXFrameBackchain>(
        m_thread, concrete_idx, m_cursors[concrete_idx]);
  return reg_ctx_sp;
}

size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
    const ExecutionContext &exe_ctx) {
  m_cursors.clear();

  StackFrame *first_frame = exe_ctx.GetFramePtr();

  Process *process = exe_ctx.GetProcessPtr();
  if (process == nullptr)
    return 0;

  struct Frame_i386 {
    uint32_t fp;
    uint32_t pc;
  };

  RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
  assert(reg_ctx);

  Cursor cursor;
  cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
  cursor.fp = reg_ctx->GetFP(0);

  Frame_i386 frame = {static_cast<uint32_t>(cursor.fp),
                      static_cast<uint32_t>(cursor.pc)};

  m_cursors.push_back(cursor);

  const size_t k_frame_size = sizeof(frame);
  Status error;
  while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
    // Read both the FP and PC (8 bytes)
    if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
        k_frame_size)
      break;
    if (frame.pc >= 0x1000) {
      cursor.pc = frame.pc;
      cursor.fp = frame.fp;
      m_cursors.push_back(cursor);
    }
  }
  if (!m_cursors.empty()) {
    lldb::addr_t first_frame_pc = m_cursors.front().pc;
    if (first_frame_pc != LLDB_INVALID_ADDRESS) {
      const SymbolContextItem resolve_scope =
          eSymbolContextModule | eSymbolContextCompUnit |
          eSymbolContextFunction | eSymbolContextSymbol;

      SymbolContext first_frame_sc(
          first_frame->GetSymbolContext(resolve_scope));
      const AddressRange *addr_range_ptr = nullptr;
      AddressRange range;
      if (first_frame_sc.function)
        addr_range_ptr = &first_frame_sc.function->GetAddressRange();
      else if (first_frame_sc.symbol) {
        range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
        range.SetByteSize(first_frame_sc.symbol->GetByteSize());
        addr_range_ptr = &range;
      }

      if (addr_range_ptr) {
        if (first_frame->GetFrameCodeAddress() ==
            addr_range_ptr->GetBaseAddress()) {
          // We are at the first instruction, so we can recover the previous PC
          // by dereferencing the SP
          lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
          // Read the real second frame return address into frame.pc
          if (first_frame_sp &&
              process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
                                  error) == sizeof(frame.pc)) {
            cursor.fp = m_cursors.front().fp;
            cursor.pc = frame.pc; // Set the new second frame PC

            // Insert the second frame
            m_cursors.insert(m_cursors.begin() + 1, cursor);

            m_cursors.front().fp = first_frame_sp;
          }
        }
      }
    }
  }
  //    uint32_t i=0;
  //    printf("      PC                 FP\n");
  //    printf("      ------------------ ------------------ \n");
  //    for (i=0; i<m_cursors.size(); ++i)
  //    {
  //        printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i,
  //        m_cursors[i].pc, m_cursors[i].fp);
  //    }
  return m_cursors.size();
}

size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
    const ExecutionContext &exe_ctx) {
  m_cursors.clear();

  Process *process = exe_ctx.GetProcessPtr();
  if (process == nullptr)
    return 0;

  StackFrame *first_frame = exe_ctx.GetFramePtr();

  struct Frame_x86_64 {
    uint64_t fp;
    uint64_t pc;
  };

  RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
  assert(reg_ctx);

  Cursor cursor;
  cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
  cursor.fp = reg_ctx->GetFP(0);

  Frame_x86_64 frame = {cursor.fp, cursor.pc};

  m_cursors.push_back(cursor);
  Status error;
  const size_t k_frame_size = sizeof(frame);
  while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
    // Read both the FP and PC (16 bytes)
    if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
        k_frame_size)
      break;

    if (frame.pc >= 0x1000) {
      cursor.pc = frame.pc;
      cursor.fp = frame.fp;
      m_cursors.push_back(cursor);
    }
  }
  if (!m_cursors.empty()) {
    lldb::addr_t first_frame_pc = m_cursors.front().pc;
    if (first_frame_pc != LLDB_INVALID_ADDRESS) {
      const SymbolContextItem resolve_scope =
          eSymbolContextModule | eSymbolContextCompUnit |
          eSymbolContextFunction | eSymbolContextSymbol;

      SymbolContext first_frame_sc(
          first_frame->GetSymbolContext(resolve_scope));
      const AddressRange *addr_range_ptr = nullptr;
      AddressRange range;
      if (first_frame_sc.function)
        addr_range_ptr = &first_frame_sc.function->GetAddressRange();
      else if (first_frame_sc.symbol) {
        range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
        range.SetByteSize(first_frame_sc.symbol->GetByteSize());
        addr_range_ptr = &range;
      }

      if (addr_range_ptr) {
        if (first_frame->GetFrameCodeAddress() ==
            addr_range_ptr->GetBaseAddress()) {
          // We are at the first instruction, so we can recover the previous PC
          // by dereferencing the SP
          lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
          // Read the real second frame return address into frame.pc
          if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
                                  error) == sizeof(frame.pc)) {
            cursor.fp = m_cursors.front().fp;
            cursor.pc = frame.pc; // Set the new second frame PC

            // Insert the second frame
            m_cursors.insert(m_cursors.begin() + 1, cursor);

            m_cursors.front().fp = first_frame_sp;
          }
        }
      }
    }
  }
  return m_cursors.size();
}
