//===-- ArchitectureArm.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 "Plugins/Architecture/Arm/ArchitectureArm.h"
#include "Plugins/Process/Utility/ARMDefines.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ArchSpec.h"

using namespace lldb_private;
using namespace lldb;

ConstString ArchitectureArm::GetPluginNameStatic() {
  return ConstString("arm");
}

void ArchitectureArm::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                "Arm-specific algorithms",
                                &ArchitectureArm::Create);
}

void ArchitectureArm::Terminate() {
  PluginManager::UnregisterPlugin(&ArchitectureArm::Create);
}

std::unique_ptr<Architecture> ArchitectureArm::Create(const ArchSpec &arch) {
  if (arch.GetMachine() != llvm::Triple::arm)
    return nullptr;
  return std::unique_ptr<Architecture>(new ArchitectureArm());
}

ConstString ArchitectureArm::GetPluginName() { return GetPluginNameStatic(); }
uint32_t ArchitectureArm::GetPluginVersion() { return 1; }

void ArchitectureArm::OverrideStopInfo(Thread &thread) const {
  // We need to check if we are stopped in Thumb mode in a IT instruction and
  // detect if the condition doesn't pass. If this is the case it means we
  // won't actually execute this instruction. If this happens we need to clear
  // the stop reason to no thread plans think we are stopped for a reason and
  // the plans should keep going.
  //
  // We do this because when single stepping many ARM processes, debuggers
  // often use the BVR/BCR registers that says "stop when the PC is not equal
  // to its current value". This method of stepping means we can end up
  // stopping on instructions inside an if/then block that wouldn't get
  // executed. By fixing this we can stop the debugger from seeming like you
  // stepped through both the "if" _and_ the "else" clause when source level
  // stepping because the debugger stops regardless due to the BVR/BCR
  // triggering a stop.
  //
  // It also means we can set breakpoints on instructions inside an an if/then
  // block and correctly skip them if we use the BKPT instruction. The ARM and
  // Thumb BKPT instructions are unconditional even when executed in a Thumb IT
  // block.
  //
  // If your debugger inserts software traps in ARM/Thumb code, it will need to
  // use 16 and 32 bit instruction for 16 and 32 bit thumb instructions
  // respectively. If your debugger inserts a 16 bit thumb trap on top of a 32
  // bit thumb instruction for an opcode that is inside an if/then, it will
  // change the it/then to conditionally execute your
  // 16 bit trap and then cause your program to crash if it executes the
  // trailing 16 bits (the second half of the 32 bit thumb instruction you
  // partially overwrote).

  RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
  if (!reg_ctx_sp)
    return;

  const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
  if (cpsr == 0)
    return;

  // Read the J and T bits to get the ISETSTATE
  const uint32_t J = Bit32(cpsr, 24);
  const uint32_t T = Bit32(cpsr, 5);
  const uint32_t ISETSTATE = J << 1 | T;
  if (ISETSTATE == 0) {
// NOTE: I am pretty sure we want to enable the code below
// that detects when we stop on an instruction in ARM mode that is conditional
// and the condition doesn't pass. This can happen if you set a breakpoint on
// an instruction that is conditional. We currently will _always_ stop on the
// instruction which is bad. You can also run into this while single stepping
// and you could appear to run code in the "if" and in the "else" clause
// because it would stop at all of the conditional instructions in both. In
// such cases, we really don't want to stop at this location.
// I will check with the lldb-dev list first before I enable this.
#if 0
    // ARM mode: check for condition on instruction
    const addr_t pc = reg_ctx_sp->GetPC();
    Status error;
    // If we fail to read the opcode we will get UINT64_MAX as the result in
    // "opcode" which we can use to detect if we read a valid opcode.
    const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
    if (opcode <= UINT32_MAX)
    {
        const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
        if (!ARMConditionPassed(condition, cpsr))
        {
            // We ARE stopped on an ARM instruction whose condition doesn't
            // pass so this instruction won't get executed. Regardless of why
            // it stopped, we need to clear the stop info
            thread.SetStopInfo (StopInfoSP());
        }
    }
#endif
  } else if (ISETSTATE == 1) {
    // Thumb mode
    const uint32_t ITSTATE = Bits32(cpsr, 15, 10) << 2 | Bits32(cpsr, 26, 25);
    if (ITSTATE != 0) {
      const uint32_t condition = Bits32(ITSTATE, 7, 4);
      if (!ARMConditionPassed(condition, cpsr)) {
        // We ARE stopped in a Thumb IT instruction on an instruction whose
        // condition doesn't pass so this instruction won't get executed.
        // Regardless of why it stopped, we need to clear the stop info
        thread.SetStopInfo(StopInfoSP());
      }
    }
  }
}

addr_t ArchitectureArm::GetCallableLoadAddress(addr_t code_addr,
                                               AddressClass addr_class) const {
  bool is_alternate_isa = false;

  switch (addr_class) {
  case AddressClass::eData:
  case AddressClass::eDebug:
    return LLDB_INVALID_ADDRESS;
  case AddressClass::eCodeAlternateISA:
    is_alternate_isa = true;
    break;
  default: break;
  }

  if ((code_addr & 2u) || is_alternate_isa)
    return code_addr | 1u;
  return code_addr;
}

addr_t ArchitectureArm::GetOpcodeLoadAddress(addr_t opcode_addr,
                                             AddressClass addr_class) const {
  switch (addr_class) {
  case AddressClass::eData:
  case AddressClass::eDebug:
    return LLDB_INVALID_ADDRESS;
  default: break;
  }
  return opcode_addr & ~(1ull);
}
