//===-- 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) {
  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;

    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();
}
