//===-- ArmUnwindInfo.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 <vector>

#include "Utility/ARM_DWARF_Registers.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Utility/Endian.h"

/*
 * Unwind information reader and parser for the ARM exception handling ABI
 *
 * Implemented based on:
 *     Exception Handling ABI for the ARM Architecture
 *     Document number: ARM IHI 0038A (current through ABI r2.09)
 *     Date of Issue: 25th January 2007, reissued 30th November 2012
 *     http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
 */

using namespace lldb;
using namespace lldb_private;

// Converts a prel31 value to lldb::addr_t with sign extension
static addr_t Prel31ToAddr(uint32_t prel31) {
  addr_t res = prel31;
  if (prel31 & (1 << 30))
    res |= 0xffffffff80000000ULL;
  return res;
}

ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a,
                                            uint32_t d)
    : file_address(f), address(a), data(d) {}

bool ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry &other) const {
  return address < other.address;
}

ArmUnwindInfo::ArmUnwindInfo(ObjectFile &objfile, SectionSP &arm_exidx,
                             SectionSP &arm_extab)
    : m_byte_order(objfile.GetByteOrder()), m_arm_exidx_sp(arm_exidx),
      m_arm_extab_sp(arm_extab) {
  objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data);
  objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data);

  addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress();

  offset_t offset = 0;
  while (m_arm_exidx_data.ValidOffset(offset)) {
    lldb::addr_t file_addr = exidx_base_addr + offset;
    lldb::addr_t addr = exidx_base_addr + (addr_t)offset +
                        Prel31ToAddr(m_arm_exidx_data.GetU32(&offset));
    uint32_t data = m_arm_exidx_data.GetU32(&offset);
    m_exidx_entries.emplace_back(file_addr, addr, data);
  }

  // Sort the entries in the exidx section. The entries should be sorted inside
  // the section but some old compiler isn't sorted them.
  llvm::sort(m_exidx_entries.begin(), m_exidx_entries.end());
}

ArmUnwindInfo::~ArmUnwindInfo() = default;

// Read a byte from the unwind instruction stream with the given offset. Custom
// function is required because have to red in order of significance within
// their containing word (most significant byte first) and in increasing word
// address order.
uint8_t ArmUnwindInfo::GetByteAtOffset(const uint32_t *data,
                                       uint16_t offset) const {
  uint32_t value = data[offset / 4];
  if (m_byte_order != endian::InlHostByteOrder())
    value = llvm::ByteSwap_32(value);
  return (value >> ((3 - (offset % 4)) * 8)) & 0xff;
}

uint64_t ArmUnwindInfo::GetULEB128(const uint32_t *data, uint16_t &offset,
                                   uint16_t max_offset) const {
  uint64_t result = 0;
  uint8_t shift = 0;
  while (offset < max_offset) {
    uint8_t byte = GetByteAtOffset(data, offset++);
    result |= (uint64_t)(byte & 0x7f) << shift;
    if ((byte & 0x80) == 0)
      break;
    shift += 7;
  }
  return result;
}

bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr,
                                  UnwindPlan &unwind_plan) {
  const uint32_t *data = (const uint32_t *)GetExceptionHandlingTableEntry(addr);
  if (data == nullptr)
    return false; // No unwind information for the function

  if (data[0] == 0x1)
    return false; // EXIDX_CANTUNWIND

  uint16_t byte_count = 0;
  uint16_t byte_offset = 0;
  if (data[0] & 0x80000000) {
    switch ((data[0] >> 24) & 0x0f) {
    case 0:
      byte_count = 4;
      byte_offset = 1;
      break;
    case 1:
    case 2:
      byte_count = 4 * ((data[0] >> 16) & 0xff) + 4;
      byte_offset = 2;
      break;
    default:
      // Unhandled personality routine index
      return false;
    }
  } else {
    byte_count = 4 * ((data[1] >> 24) & 0xff) + 8;
    byte_offset = 5;
  }

  uint8_t vsp_reg = dwarf_sp;
  int32_t vsp = 0;
  std::vector<std::pair<uint32_t, int32_t>>
      register_offsets; // register -> (offset from vsp_reg)

  while (byte_offset < byte_count) {
    uint8_t byte1 = GetByteAtOffset(data, byte_offset++);
    if ((byte1 & 0xc0) == 0x00) {
      // 00xxxxxx
      // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive
      vsp += ((byte1 & 0x3f) << 2) + 4;
    } else if ((byte1 & 0xc0) == 0x40) {
      // 01xxxxxx
      // vsp = vsp – (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive
      vsp -= ((byte1 & 0x3f) << 2) + 4;
    } else if ((byte1 & 0xf0) == 0x80) {
      if (byte_offset >= byte_count)
        return false;

      uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
      if (byte1 == 0x80 && byte2 == 0) {
        // 10000000 00000000
        // Refuse to unwind (for example, out of a cleanup) (see remark a)
        return false;
      } else {
        // 1000iiii iiiiiiii (i not all 0)
        // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see
        // remark b)
        uint16_t regs = ((byte1 & 0x0f) << 8) | byte2;
        for (uint8_t i = 0; i < 12; ++i) {
          if (regs & (1 << i)) {
            register_offsets.emplace_back(dwarf_r4 + i, vsp);
            vsp += 4;
          }
        }
      }
    } else if ((byte1 & 0xff) == 0x9d) {
      // 10011101
      // Reserved as prefix for ARM register to register moves
      return false;
    } else if ((byte1 & 0xff) == 0x9f) {
      // 10011111
      // Reserved as prefix for Intel Wireless MMX register to register moves
      return false;
    } else if ((byte1 & 0xf0) == 0x90) {
      // 1001nnnn (nnnn != 13,15)
      // Set vsp = r[nnnn]
      vsp_reg = dwarf_r0 + (byte1 & 0x0f);
    } else if ((byte1 & 0xf8) == 0xa0) {
      // 10100nnn
      // Pop r4-r[4+nnn]
      uint8_t n = byte1 & 0x7;
      for (uint8_t i = 0; i <= n; ++i) {
        register_offsets.emplace_back(dwarf_r4 + i, vsp);
        vsp += 4;
      }
    } else if ((byte1 & 0xf8) == 0xa8) {
      // 10101nnn
      // Pop r4-r[4+nnn], r14
      uint8_t n = byte1 & 0x7;
      for (uint8_t i = 0; i <= n; ++i) {
        register_offsets.emplace_back(dwarf_r4 + i, vsp);
        vsp += 4;
      }

      register_offsets.emplace_back(dwarf_lr, vsp);
      vsp += 4;
    } else if ((byte1 & 0xff) == 0xb0) {
      // 10110000
      // Finish (see remark c)
      break;
    } else if ((byte1 & 0xff) == 0xb1) {
      if (byte_offset >= byte_count)
        return false;

      uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
      if ((byte2 & 0xff) == 0x00) {
        // 10110001 00000000
        // Spare (see remark f)
        return false;
      } else if ((byte2 & 0xf0) == 0x00) {
        // 10110001 0000iiii (i not all 0)
        // Pop integer registers under mask {r3, r2, r1, r0}
        for (uint8_t i = 0; i < 4; ++i) {
          if (byte2 & (1 << i)) {
            register_offsets.emplace_back(dwarf_r0 + i, vsp);
            vsp += 4;
          }
        }
      } else {
        // 10110001 xxxxyyyy
        // Spare (xxxx != 0000)
        return false;
      }
    } else if ((byte1 & 0xff) == 0xb2) {
      // 10110010 uleb128
      // vsp = vsp + 0x204+ (uleb128 << 2)
      uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count);
      vsp += 0x204 + (uleb128 << 2);
    } else if ((byte1 & 0xff) == 0xb3) {
      // 10110011 sssscccc
      // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if)
      // by FSTMFDX (see remark d)
      if (byte_offset >= byte_count)
        return false;

      uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
      uint8_t s = (byte2 & 0xf0) >> 4;
      uint8_t c = (byte2 & 0x0f) >> 0;
      for (uint8_t i = 0; i <= c; ++i) {
        register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
        vsp += 8;
      }
      vsp += 4;
    } else if ((byte1 & 0xfc) == 0xb4) {
      // 101101nn
      // Spare (was Pop FPA)
      return false;
    } else if ((byte1 & 0xf8) == 0xb8) {
      // 10111nnn
      // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by
      // FSTMFDX (see remark d)
      uint8_t n = byte1 & 0x07;
      for (uint8_t i = 0; i <= n; ++i) {
        register_offsets.emplace_back(dwarf_d8 + i, vsp);
        vsp += 8;
      }
      vsp += 4;
    } else if ((byte1 & 0xf8) == 0xc0) {
      // 11000nnn (nnn != 6,7)
      // Intel Wireless MMX pop wR[10]-wR[10+nnn]

      // 11000110 sssscccc
      // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e)

      // 11000111 00000000
      // Spare

      // 11000111 0000iiii
      // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}

      // 11000111 xxxxyyyy
      // Spare (xxxx != 0000)

      return false;
    } else if ((byte1 & 0xff) == 0xc8) {
      // 11001000 sssscccc
      // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved
      // (as if) by FSTMFDD (see remarks d,e)
      if (byte_offset >= byte_count)
        return false;

      uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
      uint8_t s = (byte2 & 0xf0) >> 4;
      uint8_t c = (byte2 & 0x0f) >> 0;
      for (uint8_t i = 0; i <= c; ++i) {
        register_offsets.emplace_back(dwarf_d16 + s + i, vsp);
        vsp += 8;
      }
    } else if ((byte1 & 0xff) == 0xc9) {
      // 11001001 sssscccc
      // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if)
      // by FSTMFDD (see remark d)
      if (byte_offset >= byte_count)
        return false;

      uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
      uint8_t s = (byte2 & 0xf0) >> 4;
      uint8_t c = (byte2 & 0x0f) >> 0;
      for (uint8_t i = 0; i <= c; ++i) {
        register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
        vsp += 8;
      }
    } else if ((byte1 & 0xf8) == 0xc8) {
      // 11001yyy
      // Spare (yyy != 000, 001)
      return false;
    } else if ((byte1 & 0xf8) == 0xd0) {
      // 11010nnn
      // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by
      // FSTMFDD (see remark d)
      uint8_t n = byte1 & 0x07;
      for (uint8_t i = 0; i <= n; ++i) {
        register_offsets.emplace_back(dwarf_d8 + i, vsp);
        vsp += 8;
      }
    } else if ((byte1 & 0xc0) == 0xc0) {
      // 11xxxyyy Spare (xxx != 000, 001, 010)
      return false;
    } else {
      return false;
    }
  }

  UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
  row->SetOffset(0);
  row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);

  bool have_location_for_pc = false;
  for (const auto &offset : register_offsets) {
    have_location_for_pc |= offset.first == dwarf_pc;
    row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp,
                                              true);
  }

  if (!have_location_for_pc) {
    UnwindPlan::Row::RegisterLocation lr_location;
    if (row->GetRegisterInfo(dwarf_lr, lr_location))
      row->SetRegisterInfo(dwarf_pc, lr_location);
    else
      row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false);
  }

  unwind_plan.AppendRow(row);
  unwind_plan.SetSourceName("ARM.exidx unwind info");
  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
  unwind_plan.SetRegisterKind(eRegisterKindDWARF);

  return true;
}

const uint8_t *
ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address &addr) {
  auto it = std::upper_bound(m_exidx_entries.begin(), m_exidx_entries.end(),
                             ArmExidxEntry{0, addr.GetFileAddress(), 0});
  if (it == m_exidx_entries.begin())
    return nullptr;
  --it;

  if (it->data == 0x1)
    return nullptr; // EXIDX_CANTUNWIND

  if (it->data & 0x80000000)
    return (const uint8_t *)&it->data;

  addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data);
  return m_arm_extab_data.GetDataStart() +
         (data_file_addr - m_arm_extab_sp->GetFileAddress());
}
