//===-- CompactUnwindInfo.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/Symbol/CompactUnwindInfo.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

#include "llvm/Support/MathExtras.h"

#include <algorithm>
#include <memory>

using namespace lldb;
using namespace lldb_private;

namespace lldb_private {

// Constants from <mach-o/compact_unwind_encoding.h>

FLAGS_ANONYMOUS_ENUM(){
    UNWIND_IS_NOT_FUNCTION_START = 0x80000000, UNWIND_HAS_LSDA = 0x40000000,
    UNWIND_PERSONALITY_MASK = 0x30000000,
};

FLAGS_ANONYMOUS_ENUM(){
    UNWIND_X86_MODE_MASK = 0x0F000000,
    UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
    UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
    UNWIND_X86_MODE_STACK_IND = 0x03000000,
    UNWIND_X86_MODE_DWARF = 0x04000000,

    UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
    UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,

    UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
    UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
    UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
    UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,

    UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};

enum {
  UNWIND_X86_REG_NONE = 0,
  UNWIND_X86_REG_EBX = 1,
  UNWIND_X86_REG_ECX = 2,
  UNWIND_X86_REG_EDX = 3,
  UNWIND_X86_REG_EDI = 4,
  UNWIND_X86_REG_ESI = 5,
  UNWIND_X86_REG_EBP = 6,
};

FLAGS_ANONYMOUS_ENUM(){
    UNWIND_X86_64_MODE_MASK = 0x0F000000,
    UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
    UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
    UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
    UNWIND_X86_64_MODE_DWARF = 0x04000000,

    UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
    UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,

    UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
    UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
    UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
    UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,

    UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};

enum {
  UNWIND_X86_64_REG_NONE = 0,
  UNWIND_X86_64_REG_RBX = 1,
  UNWIND_X86_64_REG_R12 = 2,
  UNWIND_X86_64_REG_R13 = 3,
  UNWIND_X86_64_REG_R14 = 4,
  UNWIND_X86_64_REG_R15 = 5,
  UNWIND_X86_64_REG_RBP = 6,
};

FLAGS_ANONYMOUS_ENUM(){
    UNWIND_ARM64_MODE_MASK = 0x0F000000,
    UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
    UNWIND_ARM64_MODE_DWARF = 0x03000000,
    UNWIND_ARM64_MODE_FRAME = 0x04000000,

    UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
    UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
    UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
    UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
    UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
    UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
    UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
    UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
    UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,

    UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
    UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};

FLAGS_ANONYMOUS_ENUM(){
    UNWIND_ARM_MODE_MASK = 0x0F000000,
    UNWIND_ARM_MODE_FRAME = 0x01000000,
    UNWIND_ARM_MODE_FRAME_D = 0x02000000,
    UNWIND_ARM_MODE_DWARF = 0x04000000,

    UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,

    UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
    UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
    UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,

    UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
    UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
    UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
    UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
    UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,

    UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,

    UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
}

#ifndef UNWIND_SECOND_LEVEL_REGULAR
#define UNWIND_SECOND_LEVEL_REGULAR 2
#endif

#ifndef UNWIND_SECOND_LEVEL_COMPRESSED
#define UNWIND_SECOND_LEVEL_COMPRESSED 3
#endif

#ifndef UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET
#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
#endif

#ifndef UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX
#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry)                     \
  ((entry >> 24) & 0xFF)
#endif

#define EXTRACT_BITS(value, mask)                                              \
  ((value >>                                                                   \
    llvm::countTrailingZeros(static_cast<uint32_t>(mask), llvm::ZB_Width)) &   \
   (((1 << llvm::countPopulation(static_cast<uint32_t>(mask)))) - 1))

// constructor

CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP &section_sp)
    : m_objfile(objfile), m_section_sp(section_sp),
      m_section_contents_if_encrypted(), m_mutex(), m_indexes(),
      m_indexes_computed(eLazyBoolCalculate), m_unwindinfo_data(),
      m_unwindinfo_data_computed(false), m_unwind_header() {}

// destructor

CompactUnwindInfo::~CompactUnwindInfo() = default;

bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr,
                                      UnwindPlan &unwind_plan) {
  if (!IsValid(target.GetProcessSP())) {
    return false;
  }
  FunctionInfo function_info;
  if (GetCompactUnwindInfoForFunction(target, addr, function_info)) {
    // shortcut return for functions that have no compact unwind
    if (function_info.encoding == 0)
      return false;

    if (ArchSpec arch = m_objfile.GetArchitecture()) {

      Log *log = GetLog(LLDBLog::Unwind);
      if (log && log->GetVerbose()) {
        StreamString strm;
        addr.Dump(
            &strm, nullptr,
            Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments,
            Address::DumpStyle::DumpStyleFileAddress,
            arch.GetAddressByteSize());
        LLDB_LOGF(log, "Got compact unwind encoding 0x%x for function %s",
                  function_info.encoding, strm.GetData());
      }

      if (function_info.valid_range_offset_start != 0 &&
          function_info.valid_range_offset_end != 0) {
        SectionList *sl = m_objfile.GetSectionList();
        if (sl) {
          addr_t func_range_start_file_addr =
              function_info.valid_range_offset_start +
              m_objfile.GetBaseAddress().GetFileAddress();
          AddressRange func_range(func_range_start_file_addr,
                                  function_info.valid_range_offset_end -
                                      function_info.valid_range_offset_start,
                                  sl);
          unwind_plan.SetPlanValidAddressRange(func_range);
        }
      }

      if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
        return CreateUnwindPlan_x86_64(target, function_info, unwind_plan,
                                       addr);
      }
      if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
          arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
        return CreateUnwindPlan_arm64(target, function_info, unwind_plan, addr);
      }
      if (arch.GetTriple().getArch() == llvm::Triple::x86) {
        return CreateUnwindPlan_i386(target, function_info, unwind_plan, addr);
      }
      if (arch.GetTriple().getArch() == llvm::Triple::arm ||
          arch.GetTriple().getArch() == llvm::Triple::thumb) {
        return CreateUnwindPlan_armv7(target, function_info, unwind_plan, addr);
      }
    }
  }
  return false;
}

bool CompactUnwindInfo::IsValid(const ProcessSP &process_sp) {
  if (m_section_sp.get() == nullptr)
    return false;

  if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed)
    return true;

  ScanIndex(process_sp);

  return m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed;
}

void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed)
    return;

  // We can't read the index for some reason.
  if (m_indexes_computed == eLazyBoolNo) {
    return;
  }

  Log *log = GetLog(LLDBLog::Unwind);
  if (log)
    m_objfile.GetModule()->LogMessage(
        log, "Reading compact unwind first-level indexes");

  if (!m_unwindinfo_data_computed) {
    if (m_section_sp->IsEncrypted()) {
      // Can't get section contents of a protected/encrypted section until we
      // have a live process and can read them out of memory.
      if (process_sp.get() == nullptr)
        return;
      m_section_contents_if_encrypted =
          std::make_shared<DataBufferHeap>(m_section_sp->GetByteSize(), 0);
      Status error;
      if (process_sp->ReadMemory(
              m_section_sp->GetLoadBaseAddress(&process_sp->GetTarget()),
              m_section_contents_if_encrypted->GetBytes(),
              m_section_sp->GetByteSize(),
              error) == m_section_sp->GetByteSize() &&
          error.Success()) {
        m_unwindinfo_data.SetAddressByteSize(
            process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
        m_unwindinfo_data.SetByteOrder(
            process_sp->GetTarget().GetArchitecture().GetByteOrder());
        m_unwindinfo_data.SetData(m_section_contents_if_encrypted, 0);
      }
    } else {
      m_objfile.ReadSectionData(m_section_sp.get(), m_unwindinfo_data);
    }
    if (m_unwindinfo_data.GetByteSize() != m_section_sp->GetByteSize())
      return;
    m_unwindinfo_data_computed = true;
  }

  if (m_unwindinfo_data.GetByteSize() > 0) {
    offset_t offset = 0;

    // struct unwind_info_section_header
    // {
    // uint32_t    version;            // UNWIND_SECTION_VERSION
    // uint32_t    commonEncodingsArraySectionOffset;
    // uint32_t    commonEncodingsArrayCount;
    // uint32_t    personalityArraySectionOffset;
    // uint32_t    personalityArrayCount;
    // uint32_t    indexSectionOffset;
    // uint32_t    indexCount;

    m_unwind_header.version = m_unwindinfo_data.GetU32(&offset);
    m_unwind_header.common_encodings_array_offset =
        m_unwindinfo_data.GetU32(&offset);
    m_unwind_header.common_encodings_array_count =
        m_unwindinfo_data.GetU32(&offset);
    m_unwind_header.personality_array_offset =
        m_unwindinfo_data.GetU32(&offset);
    m_unwind_header.personality_array_count = m_unwindinfo_data.GetU32(&offset);
    uint32_t indexSectionOffset = m_unwindinfo_data.GetU32(&offset);

    uint32_t indexCount = m_unwindinfo_data.GetU32(&offset);

    if (m_unwind_header.common_encodings_array_offset >
            m_unwindinfo_data.GetByteSize() ||
        m_unwind_header.personality_array_offset >
            m_unwindinfo_data.GetByteSize() ||
        indexSectionOffset > m_unwindinfo_data.GetByteSize() ||
        offset > m_unwindinfo_data.GetByteSize()) {
      Debugger::ReportError(
          "Invalid offset encountered in compact unwind info, skipping");
      // don't trust anything from this compact_unwind section if it looks
      // blatantly invalid data in the header.
      m_indexes_computed = eLazyBoolNo;
      return;
    }

    // Parse the basic information from the indexes We wait to scan the second
    // level page info until it's needed

    // struct unwind_info_section_header_index_entry {
    //     uint32_t        functionOffset;
    //     uint32_t        secondLevelPagesSectionOffset;
    //     uint32_t        lsdaIndexArraySectionOffset;
    // };

    bool clear_address_zeroth_bit = false;
    if (ArchSpec arch = m_objfile.GetArchitecture()) {
      if (arch.GetTriple().getArch() == llvm::Triple::arm ||
          arch.GetTriple().getArch() == llvm::Triple::thumb)
        clear_address_zeroth_bit = true;
    }

    offset = indexSectionOffset;
    for (uint32_t idx = 0; idx < indexCount; idx++) {
      uint32_t function_offset =
          m_unwindinfo_data.GetU32(&offset); // functionOffset
      uint32_t second_level_offset =
          m_unwindinfo_data.GetU32(&offset); // secondLevelPagesSectionOffset
      uint32_t lsda_offset =
          m_unwindinfo_data.GetU32(&offset); // lsdaIndexArraySectionOffset

      if (second_level_offset > m_section_sp->GetByteSize() ||
          lsda_offset > m_section_sp->GetByteSize()) {
        m_indexes_computed = eLazyBoolNo;
      }

      if (clear_address_zeroth_bit)
        function_offset &= ~1ull;

      UnwindIndex this_index;
      this_index.function_offset = function_offset;
      this_index.second_level = second_level_offset;
      this_index.lsda_array_start = lsda_offset;

      if (m_indexes.size() > 0) {
        m_indexes[m_indexes.size() - 1].lsda_array_end = lsda_offset;
      }

      if (second_level_offset == 0) {
        this_index.sentinal_entry = true;
      }

      m_indexes.push_back(this_index);
    }
    m_indexes_computed = eLazyBoolYes;
  } else {
    m_indexes_computed = eLazyBoolNo;
  }
}

uint32_t CompactUnwindInfo::GetLSDAForFunctionOffset(uint32_t lsda_offset,
                                                     uint32_t lsda_count,
                                                     uint32_t function_offset) {
  // struct unwind_info_section_header_lsda_index_entry {
  //         uint32_t        functionOffset;
  //         uint32_t        lsdaOffset;
  // };

  offset_t first_entry = lsda_offset;
  uint32_t low = 0;
  uint32_t high = lsda_count;
  while (low < high) {
    uint32_t mid = (low + high) / 2;
    offset_t offset = first_entry + (mid * 8);
    uint32_t mid_func_offset =
        m_unwindinfo_data.GetU32(&offset); // functionOffset
    uint32_t mid_lsda_offset = m_unwindinfo_data.GetU32(&offset); // lsdaOffset
    if (mid_func_offset == function_offset) {
      return mid_lsda_offset;
    }
    if (mid_func_offset < function_offset) {
      low = mid + 1;
    } else {
      high = mid;
    }
  }
  return 0;
}

lldb::offset_t CompactUnwindInfo::BinarySearchRegularSecondPage(
    uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset,
    uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
  // typedef uint32_t compact_unwind_encoding_t;
  // struct unwind_info_regular_second_level_entry {
  //     uint32_t                    functionOffset;
  //     compact_unwind_encoding_t    encoding;

  offset_t first_entry = entry_page_offset;

  uint32_t low = 0;
  uint32_t high = entry_count;
  uint32_t last = high - 1;
  while (low < high) {
    uint32_t mid = (low + high) / 2;
    offset_t offset = first_entry + (mid * 8);
    uint32_t mid_func_offset =
        m_unwindinfo_data.GetU32(&offset); // functionOffset
    uint32_t next_func_offset = 0;
    if (mid < last) {
      offset = first_entry + ((mid + 1) * 8);
      next_func_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset
    }
    if (mid_func_offset <= function_offset) {
      if (mid == last || (next_func_offset > function_offset)) {
        if (entry_func_start_offset)
          *entry_func_start_offset = mid_func_offset;
        if (mid != last && entry_func_end_offset)
          *entry_func_end_offset = next_func_offset;
        return first_entry + (mid * 8);
      } else {
        low = mid + 1;
      }
    } else {
      high = mid;
    }
  }
  return LLDB_INVALID_OFFSET;
}

uint32_t CompactUnwindInfo::BinarySearchCompressedSecondPage(
    uint32_t entry_page_offset, uint32_t entry_count,
    uint32_t function_offset_to_find, uint32_t function_offset_base,
    uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
  offset_t first_entry = entry_page_offset;

  uint32_t low = 0;
  uint32_t high = entry_count;
  uint32_t last = high - 1;
  while (low < high) {
    uint32_t mid = (low + high) / 2;
    offset_t offset = first_entry + (mid * 4);
    uint32_t entry = m_unwindinfo_data.GetU32(&offset); // entry
    uint32_t mid_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry);
    mid_func_offset += function_offset_base;
    uint32_t next_func_offset = 0;
    if (mid < last) {
      offset = first_entry + ((mid + 1) * 4);
      uint32_t next_entry = m_unwindinfo_data.GetU32(&offset); // entry
      next_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(next_entry);
      next_func_offset += function_offset_base;
    }
    if (mid_func_offset <= function_offset_to_find) {
      if (mid == last || (next_func_offset > function_offset_to_find)) {
        if (entry_func_start_offset)
          *entry_func_start_offset = mid_func_offset;
        if (mid != last && entry_func_end_offset)
          *entry_func_end_offset = next_func_offset;
        return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry);
      } else {
        low = mid + 1;
      }
    } else {
      high = mid;
    }
  }

  return UINT32_MAX;
}

bool CompactUnwindInfo::GetCompactUnwindInfoForFunction(
    Target &target, Address address, FunctionInfo &unwind_info) {
  unwind_info.encoding = 0;
  unwind_info.lsda_address.Clear();
  unwind_info.personality_ptr_address.Clear();

  if (!IsValid(target.GetProcessSP()))
    return false;

  addr_t text_section_file_address = LLDB_INVALID_ADDRESS;
  SectionList *sl = m_objfile.GetSectionList();
  if (sl) {
    SectionSP text_sect = sl->FindSectionByType(eSectionTypeCode, true);
    if (text_sect.get()) {
      text_section_file_address = text_sect->GetFileAddress();
    }
  }
  if (text_section_file_address == LLDB_INVALID_ADDRESS)
    return false;

  addr_t function_offset =
      address.GetFileAddress() - m_objfile.GetBaseAddress().GetFileAddress();

  UnwindIndex key;
  key.function_offset = function_offset;

  std::vector<UnwindIndex>::const_iterator it;
  it = std::lower_bound(m_indexes.begin(), m_indexes.end(), key);
  if (it == m_indexes.end()) {
    return false;
  }

  if (it->function_offset != key.function_offset) {
    if (it != m_indexes.begin())
      --it;
  }

  if (it->sentinal_entry) {
    return false;
  }

  auto next_it = it + 1;
  if (next_it != m_indexes.end()) {
    // initialize the function offset end range to be the start of the next
    // index offset.  If we find an entry which is at the end of the index
    // table, this will establish the range end.
    unwind_info.valid_range_offset_end = next_it->function_offset;
  }

  offset_t second_page_offset = it->second_level;
  offset_t lsda_array_start = it->lsda_array_start;
  offset_t lsda_array_count = (it->lsda_array_end - it->lsda_array_start) / 8;

  offset_t offset = second_page_offset;
  uint32_t kind = m_unwindinfo_data.GetU32(
      &offset); // UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED

  if (kind == UNWIND_SECOND_LEVEL_REGULAR) {
    // struct unwind_info_regular_second_level_page_header {
    //     uint32_t    kind;    // UNWIND_SECOND_LEVEL_REGULAR
    //     uint16_t    entryPageOffset;
    //     uint16_t    entryCount;

    // typedef uint32_t compact_unwind_encoding_t;
    // struct unwind_info_regular_second_level_entry {
    //     uint32_t                    functionOffset;
    //     compact_unwind_encoding_t    encoding;

    uint16_t entry_page_offset =
        m_unwindinfo_data.GetU16(&offset);                    // entryPageOffset
    uint16_t entry_count = m_unwindinfo_data.GetU16(&offset); // entryCount

    offset_t entry_offset = BinarySearchRegularSecondPage(
        second_page_offset + entry_page_offset, entry_count, function_offset,
        &unwind_info.valid_range_offset_start,
        &unwind_info.valid_range_offset_end);
    if (entry_offset == LLDB_INVALID_OFFSET) {
      return false;
    }
    entry_offset += 4; // skip over functionOffset
    unwind_info.encoding = m_unwindinfo_data.GetU32(&entry_offset); // encoding
    if (unwind_info.encoding & UNWIND_HAS_LSDA) {
      SectionList *sl = m_objfile.GetSectionList();
      if (sl) {
        uint32_t lsda_offset = GetLSDAForFunctionOffset(
            lsda_array_start, lsda_array_count, function_offset);
        addr_t objfile_base_address =
            m_objfile.GetBaseAddress().GetFileAddress();
        unwind_info.lsda_address.ResolveAddressUsingFileSections(
            objfile_base_address + lsda_offset, sl);
      }
    }
    if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) {
      uint32_t personality_index =
          EXTRACT_BITS(unwind_info.encoding, UNWIND_PERSONALITY_MASK);

      if (personality_index > 0) {
        personality_index--;
        if (personality_index < m_unwind_header.personality_array_count) {
          offset_t offset = m_unwind_header.personality_array_offset;
          offset += 4 * personality_index;
          SectionList *sl = m_objfile.GetSectionList();
          if (sl) {
            uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset);
            addr_t objfile_base_address =
                m_objfile.GetBaseAddress().GetFileAddress();
            unwind_info.personality_ptr_address.ResolveAddressUsingFileSections(
                objfile_base_address + personality_offset, sl);
          }
        }
      }
    }
    return true;
  } else if (kind == UNWIND_SECOND_LEVEL_COMPRESSED) {
    // struct unwind_info_compressed_second_level_page_header {
    //     uint32_t    kind;    // UNWIND_SECOND_LEVEL_COMPRESSED
    //     uint16_t    entryPageOffset;         // offset from this 2nd lvl page
    //     idx to array of entries
    //                                          // (an entry has a function
    //                                          offset and index into the
    //                                          encodings)
    //                                          // NB function offset from the
    //                                          entry in the compressed page
    //                                          // must be added to the index's
    //                                          functionOffset value.
    //     uint16_t    entryCount;
    //     uint16_t    encodingsPageOffset;     // offset from this 2nd lvl page
    //     idx to array of encodings
    //     uint16_t    encodingsCount;

    uint16_t entry_page_offset =
        m_unwindinfo_data.GetU16(&offset);                    // entryPageOffset
    uint16_t entry_count = m_unwindinfo_data.GetU16(&offset); // entryCount
    uint16_t encodings_page_offset =
        m_unwindinfo_data.GetU16(&offset); // encodingsPageOffset
    uint16_t encodings_count =
        m_unwindinfo_data.GetU16(&offset); // encodingsCount

    uint32_t encoding_index = BinarySearchCompressedSecondPage(
        second_page_offset + entry_page_offset, entry_count, function_offset,
        it->function_offset, &unwind_info.valid_range_offset_start,
        &unwind_info.valid_range_offset_end);
    if (encoding_index == UINT32_MAX ||
        encoding_index >=
            encodings_count + m_unwind_header.common_encodings_array_count) {
      return false;
    }
    uint32_t encoding = 0;
    if (encoding_index < m_unwind_header.common_encodings_array_count) {
      offset = m_unwind_header.common_encodings_array_offset +
               (encoding_index * sizeof(uint32_t));
      encoding = m_unwindinfo_data.GetU32(
          &offset); // encoding entry from the commonEncodingsArray
    } else {
      uint32_t page_specific_entry_index =
          encoding_index - m_unwind_header.common_encodings_array_count;
      offset = second_page_offset + encodings_page_offset +
               (page_specific_entry_index * sizeof(uint32_t));
      encoding = m_unwindinfo_data.GetU32(
          &offset); // encoding entry from the page-specific encoding array
    }
    if (encoding == 0)
      return false;

    unwind_info.encoding = encoding;
    if (unwind_info.encoding & UNWIND_HAS_LSDA) {
      SectionList *sl = m_objfile.GetSectionList();
      if (sl) {
        uint32_t lsda_offset = GetLSDAForFunctionOffset(
            lsda_array_start, lsda_array_count, function_offset);
        addr_t objfile_base_address =
            m_objfile.GetBaseAddress().GetFileAddress();
        unwind_info.lsda_address.ResolveAddressUsingFileSections(
            objfile_base_address + lsda_offset, sl);
      }
    }
    if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) {
      uint32_t personality_index =
          EXTRACT_BITS(unwind_info.encoding, UNWIND_PERSONALITY_MASK);

      if (personality_index > 0) {
        personality_index--;
        if (personality_index < m_unwind_header.personality_array_count) {
          offset_t offset = m_unwind_header.personality_array_offset;
          offset += 4 * personality_index;
          SectionList *sl = m_objfile.GetSectionList();
          if (sl) {
            uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset);
            addr_t objfile_base_address =
                m_objfile.GetBaseAddress().GetFileAddress();
            unwind_info.personality_ptr_address.ResolveAddressUsingFileSections(
                objfile_base_address + personality_offset, sl);
          }
        }
      }
    }
    return true;
  }
  return false;
}

enum x86_64_eh_regnum {
  rax = 0,
  rdx = 1,
  rcx = 2,
  rbx = 3,
  rsi = 4,
  rdi = 5,
  rbp = 6,
  rsp = 7,
  r8 = 8,
  r9 = 9,
  r10 = 10,
  r11 = 11,
  r12 = 12,
  r13 = 13,
  r14 = 14,
  r15 = 15,
  rip = 16 // this is officially the Return Address register number, but close
           // enough
};

// Convert the compact_unwind_info.h register numbering scheme to
// eRegisterKindEHFrame (eh_frame) register numbering scheme.
uint32_t translate_to_eh_frame_regnum_x86_64(uint32_t unwind_regno) {
  switch (unwind_regno) {
  case UNWIND_X86_64_REG_RBX:
    return x86_64_eh_regnum::rbx;
  case UNWIND_X86_64_REG_R12:
    return x86_64_eh_regnum::r12;
  case UNWIND_X86_64_REG_R13:
    return x86_64_eh_regnum::r13;
  case UNWIND_X86_64_REG_R14:
    return x86_64_eh_regnum::r14;
  case UNWIND_X86_64_REG_R15:
    return x86_64_eh_regnum::r15;
  case UNWIND_X86_64_REG_RBP:
    return x86_64_eh_regnum::rbp;
  default:
    return LLDB_INVALID_REGNUM;
  }
}

bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target,
                                                FunctionInfo &function_info,
                                                UnwindPlan &unwind_plan,
                                                Address pc_or_function_start) {
  unwind_plan.SetSourceName("compact unwind info");
  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
  unwind_plan.SetRegisterKind(eRegisterKindEHFrame);

  unwind_plan.SetLSDAAddress(function_info.lsda_address);
  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);

  UnwindPlan::RowSP row(new UnwindPlan::Row);

  const int wordsize = 8;
  int mode = function_info.encoding & UNWIND_X86_64_MODE_MASK;
  switch (mode) {
  case UNWIND_X86_64_MODE_RBP_FRAME: {
    row->GetCFAValue().SetIsRegisterPlusOffset(
        translate_to_eh_frame_regnum_x86_64(UNWIND_X86_64_REG_RBP),
        2 * wordsize);
    row->SetOffset(0);
    row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rbp,
                                              wordsize * -2, true);
    row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rip,
                                              wordsize * -1, true);
    row->SetRegisterLocationToIsCFAPlusOffset(x86_64_eh_regnum::rsp, 0, true);

    uint32_t saved_registers_offset =
        EXTRACT_BITS(function_info.encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);

    uint32_t saved_registers_locations =
        EXTRACT_BITS(function_info.encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);

    saved_registers_offset += 2;

    for (int i = 0; i < 5; i++) {
      uint32_t regnum = saved_registers_locations & 0x7;
      switch (regnum) {
      case UNWIND_X86_64_REG_NONE:
        break;
      case UNWIND_X86_64_REG_RBX:
      case UNWIND_X86_64_REG_R12:
      case UNWIND_X86_64_REG_R13:
      case UNWIND_X86_64_REG_R14:
      case UNWIND_X86_64_REG_R15:
        row->SetRegisterLocationToAtCFAPlusOffset(
            translate_to_eh_frame_regnum_x86_64(regnum),
            wordsize * -saved_registers_offset, true);
        break;
      }
      saved_registers_offset--;
      saved_registers_locations >>= 3;
    }
    unwind_plan.AppendRow(row);
    return true;
  } break;

  case UNWIND_X86_64_MODE_STACK_IND: {
    // The clang in Xcode 6 is emitting incorrect compact unwind encodings for
    // this style of unwind.  It was fixed in llvm r217020. The clang in Xcode
    // 7 has this fixed.
    return false;
  } break;

  case UNWIND_X86_64_MODE_STACK_IMMD: {
    uint32_t stack_size = EXTRACT_BITS(function_info.encoding,
                                       UNWIND_X86_64_FRAMELESS_STACK_SIZE);
    uint32_t register_count = EXTRACT_BITS(
        function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
    uint32_t permutation = EXTRACT_BITS(
        function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);

    if (mode == UNWIND_X86_64_MODE_STACK_IND &&
        function_info.valid_range_offset_start != 0) {
      uint32_t stack_adjust = EXTRACT_BITS(
          function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);

      // offset into the function instructions; 0 == beginning of first
      // instruction
      uint32_t offset_to_subl_insn = EXTRACT_BITS(
          function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);

      SectionList *sl = m_objfile.GetSectionList();
      if (sl) {
        ProcessSP process_sp = target.GetProcessSP();
        if (process_sp) {
          Address subl_payload_addr(function_info.valid_range_offset_start, sl);
          subl_payload_addr.Slide(offset_to_subl_insn);
          Status error;
          uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
              subl_payload_addr.GetLoadAddress(&target), 4, 0, error);
          if (large_stack_size != 0 && error.Success()) {
            // Got the large stack frame size correctly - use it
            stack_size = large_stack_size + (stack_adjust * wordsize);
          } else {
            return false;
          }
        } else {
          return false;
        }
      } else {
        return false;
      }
    }

    int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND
                         ? stack_size
                         : stack_size * wordsize;
    row->GetCFAValue().SetIsRegisterPlusOffset(x86_64_eh_regnum::rsp, offset);

    row->SetOffset(0);
    row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rip,
                                              wordsize * -1, true);
    row->SetRegisterLocationToIsCFAPlusOffset(x86_64_eh_regnum::rsp, 0, true);

    if (register_count > 0) {

      // We need to include (up to) 6 registers in 10 bits. That would be 18
      // bits if we just used 3 bits per reg to indicate the order they're
      // saved on the stack.
      //
      // This is done with Lehmer code permutation, e.g. see
      // http://stackoverflow.com/questions/1506078/fast-permutation-number-
      // permutation-mapping-algorithms
      int permunreg[6] = {0, 0, 0, 0, 0, 0};

      // This decodes the variable-base number in the 10 bits and gives us the
      // Lehmer code sequence which can then be decoded.

      switch (register_count) {
      case 6:
        permunreg[0] = permutation / 120; // 120 == 5!
        permutation -= (permunreg[0] * 120);
        permunreg[1] = permutation / 24; // 24 == 4!
        permutation -= (permunreg[1] * 24);
        permunreg[2] = permutation / 6; // 6 == 3!
        permutation -= (permunreg[2] * 6);
        permunreg[3] = permutation / 2; // 2 == 2!
        permutation -= (permunreg[3] * 2);
        permunreg[4] = permutation; // 1 == 1!
        permunreg[5] = 0;
        break;
      case 5:
        permunreg[0] = permutation / 120;
        permutation -= (permunreg[0] * 120);
        permunreg[1] = permutation / 24;
        permutation -= (permunreg[1] * 24);
        permunreg[2] = permutation / 6;
        permutation -= (permunreg[2] * 6);
        permunreg[3] = permutation / 2;
        permutation -= (permunreg[3] * 2);
        permunreg[4] = permutation;
        break;
      case 4:
        permunreg[0] = permutation / 60;
        permutation -= (permunreg[0] * 60);
        permunreg[1] = permutation / 12;
        permutation -= (permunreg[1] * 12);
        permunreg[2] = permutation / 3;
        permutation -= (permunreg[2] * 3);
        permunreg[3] = permutation;
        break;
      case 3:
        permunreg[0] = permutation / 20;
        permutation -= (permunreg[0] * 20);
        permunreg[1] = permutation / 4;
        permutation -= (permunreg[1] * 4);
        permunreg[2] = permutation;
        break;
      case 2:
        permunreg[0] = permutation / 5;
        permutation -= (permunreg[0] * 5);
        permunreg[1] = permutation;
        break;
      case 1:
        permunreg[0] = permutation;
        break;
      }

      // Decode the Lehmer code for this permutation of the registers v.
      // http://en.wikipedia.org/wiki/Lehmer_code

      int registers[6] = {UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE,
                          UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE,
                          UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE};
      bool used[7] = {false, false, false, false, false, false, false};
      for (uint32_t i = 0; i < register_count; i++) {
        int renum = 0;
        for (int j = 1; j < 7; j++) {
          if (!used[j]) {
            if (renum == permunreg[i]) {
              registers[i] = j;
              used[j] = true;
              break;
            }
            renum++;
          }
        }
      }

      uint32_t saved_registers_offset = 1;
      saved_registers_offset++;

      for (int i = (sizeof(registers) / sizeof(int)) - 1; i >= 0; i--) {
        switch (registers[i]) {
        case UNWIND_X86_64_REG_NONE:
          break;
        case UNWIND_X86_64_REG_RBX:
        case UNWIND_X86_64_REG_R12:
        case UNWIND_X86_64_REG_R13:
        case UNWIND_X86_64_REG_R14:
        case UNWIND_X86_64_REG_R15:
        case UNWIND_X86_64_REG_RBP:
          row->SetRegisterLocationToAtCFAPlusOffset(
              translate_to_eh_frame_regnum_x86_64(registers[i]),
              wordsize * -saved_registers_offset, true);
          saved_registers_offset++;
          break;
        }
      }
    }
    unwind_plan.AppendRow(row);
    return true;
  } break;

  case UNWIND_X86_64_MODE_DWARF: {
    return false;
  } break;

  case 0: {
    return false;
  } break;
  }
  return false;
}

enum i386_eh_regnum {
  eax = 0,
  ecx = 1,
  edx = 2,
  ebx = 3,
  ebp = 4,
  esp = 5,
  esi = 6,
  edi = 7,
  eip = 8 // this is officially the Return Address register number, but close
          // enough
};

// Convert the compact_unwind_info.h register numbering scheme to
// eRegisterKindEHFrame (eh_frame) register numbering scheme.
uint32_t translate_to_eh_frame_regnum_i386(uint32_t unwind_regno) {
  switch (unwind_regno) {
  case UNWIND_X86_REG_EBX:
    return i386_eh_regnum::ebx;
  case UNWIND_X86_REG_ECX:
    return i386_eh_regnum::ecx;
  case UNWIND_X86_REG_EDX:
    return i386_eh_regnum::edx;
  case UNWIND_X86_REG_EDI:
    return i386_eh_regnum::edi;
  case UNWIND_X86_REG_ESI:
    return i386_eh_regnum::esi;
  case UNWIND_X86_REG_EBP:
    return i386_eh_regnum::ebp;
  default:
    return LLDB_INVALID_REGNUM;
  }
}

bool CompactUnwindInfo::CreateUnwindPlan_i386(Target &target,
                                              FunctionInfo &function_info,
                                              UnwindPlan &unwind_plan,
                                              Address pc_or_function_start) {
  unwind_plan.SetSourceName("compact unwind info");
  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
  unwind_plan.SetRegisterKind(eRegisterKindEHFrame);

  unwind_plan.SetLSDAAddress(function_info.lsda_address);
  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);

  UnwindPlan::RowSP row(new UnwindPlan::Row);

  const int wordsize = 4;
  int mode = function_info.encoding & UNWIND_X86_MODE_MASK;
  switch (mode) {
  case UNWIND_X86_MODE_EBP_FRAME: {
    row->GetCFAValue().SetIsRegisterPlusOffset(
        translate_to_eh_frame_regnum_i386(UNWIND_X86_REG_EBP), 2 * wordsize);
    row->SetOffset(0);
    row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::ebp,
                                              wordsize * -2, true);
    row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::eip,
                                              wordsize * -1, true);
    row->SetRegisterLocationToIsCFAPlusOffset(i386_eh_regnum::esp, 0, true);

    uint32_t saved_registers_offset =
        EXTRACT_BITS(function_info.encoding, UNWIND_X86_EBP_FRAME_OFFSET);

    uint32_t saved_registers_locations =
        EXTRACT_BITS(function_info.encoding, UNWIND_X86_EBP_FRAME_REGISTERS);

    saved_registers_offset += 2;

    for (int i = 0; i < 5; i++) {
      uint32_t regnum = saved_registers_locations & 0x7;
      switch (regnum) {
      case UNWIND_X86_REG_NONE:
        break;
      case UNWIND_X86_REG_EBX:
      case UNWIND_X86_REG_ECX:
      case UNWIND_X86_REG_EDX:
      case UNWIND_X86_REG_EDI:
      case UNWIND_X86_REG_ESI:
        row->SetRegisterLocationToAtCFAPlusOffset(
            translate_to_eh_frame_regnum_i386(regnum),
            wordsize * -saved_registers_offset, true);
        break;
      }
      saved_registers_offset--;
      saved_registers_locations >>= 3;
    }
    unwind_plan.AppendRow(row);
    return true;
  } break;

  case UNWIND_X86_MODE_STACK_IND:
  case UNWIND_X86_MODE_STACK_IMMD: {
    uint32_t stack_size =
        EXTRACT_BITS(function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
    uint32_t register_count = EXTRACT_BITS(
        function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
    uint32_t permutation = EXTRACT_BITS(
        function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);

    if (mode == UNWIND_X86_MODE_STACK_IND &&
        function_info.valid_range_offset_start != 0) {
      uint32_t stack_adjust = EXTRACT_BITS(function_info.encoding,
                                           UNWIND_X86_FRAMELESS_STACK_ADJUST);

      // offset into the function instructions; 0 == beginning of first
      // instruction
      uint32_t offset_to_subl_insn =
          EXTRACT_BITS(function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);

      SectionList *sl = m_objfile.GetSectionList();
      if (sl) {
        ProcessSP process_sp = target.GetProcessSP();
        if (process_sp) {
          Address subl_payload_addr(function_info.valid_range_offset_start, sl);
          subl_payload_addr.Slide(offset_to_subl_insn);
          Status error;
          uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
              subl_payload_addr.GetLoadAddress(&target), 4, 0, error);
          if (large_stack_size != 0 && error.Success()) {
            // Got the large stack frame size correctly - use it
            stack_size = large_stack_size + (stack_adjust * wordsize);
          } else {
            return false;
          }
        } else {
          return false;
        }
      } else {
        return false;
      }
    }

    int32_t offset =
        mode == UNWIND_X86_MODE_STACK_IND ? stack_size : stack_size * wordsize;
    row->GetCFAValue().SetIsRegisterPlusOffset(i386_eh_regnum::esp, offset);
    row->SetOffset(0);
    row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::eip,
                                              wordsize * -1, true);
    row->SetRegisterLocationToIsCFAPlusOffset(i386_eh_regnum::esp, 0, true);

    if (register_count > 0) {

      // We need to include (up to) 6 registers in 10 bits. That would be 18
      // bits if we just used 3 bits per reg to indicate the order they're
      // saved on the stack.
      //
      // This is done with Lehmer code permutation, e.g. see
      // http://stackoverflow.com/questions/1506078/fast-permutation-number-
      // permutation-mapping-algorithms
      int permunreg[6] = {0, 0, 0, 0, 0, 0};

      // This decodes the variable-base number in the 10 bits and gives us the
      // Lehmer code sequence which can then be decoded.

      switch (register_count) {
      case 6:
        permunreg[0] = permutation / 120; // 120 == 5!
        permutation -= (permunreg[0] * 120);
        permunreg[1] = permutation / 24; // 24 == 4!
        permutation -= (permunreg[1] * 24);
        permunreg[2] = permutation / 6; // 6 == 3!
        permutation -= (permunreg[2] * 6);
        permunreg[3] = permutation / 2; // 2 == 2!
        permutation -= (permunreg[3] * 2);
        permunreg[4] = permutation; // 1 == 1!
        permunreg[5] = 0;
        break;
      case 5:
        permunreg[0] = permutation / 120;
        permutation -= (permunreg[0] * 120);
        permunreg[1] = permutation / 24;
        permutation -= (permunreg[1] * 24);
        permunreg[2] = permutation / 6;
        permutation -= (permunreg[2] * 6);
        permunreg[3] = permutation / 2;
        permutation -= (permunreg[3] * 2);
        permunreg[4] = permutation;
        break;
      case 4:
        permunreg[0] = permutation / 60;
        permutation -= (permunreg[0] * 60);
        permunreg[1] = permutation / 12;
        permutation -= (permunreg[1] * 12);
        permunreg[2] = permutation / 3;
        permutation -= (permunreg[2] * 3);
        permunreg[3] = permutation;
        break;
      case 3:
        permunreg[0] = permutation / 20;
        permutation -= (permunreg[0] * 20);
        permunreg[1] = permutation / 4;
        permutation -= (permunreg[1] * 4);
        permunreg[2] = permutation;
        break;
      case 2:
        permunreg[0] = permutation / 5;
        permutation -= (permunreg[0] * 5);
        permunreg[1] = permutation;
        break;
      case 1:
        permunreg[0] = permutation;
        break;
      }

      // Decode the Lehmer code for this permutation of the registers v.
      // http://en.wikipedia.org/wiki/Lehmer_code

      int registers[6] = {UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE,
                          UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE,
                          UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE};
      bool used[7] = {false, false, false, false, false, false, false};
      for (uint32_t i = 0; i < register_count; i++) {
        int renum = 0;
        for (int j = 1; j < 7; j++) {
          if (!used[j]) {
            if (renum == permunreg[i]) {
              registers[i] = j;
              used[j] = true;
              break;
            }
            renum++;
          }
        }
      }

      uint32_t saved_registers_offset = 1;
      saved_registers_offset++;

      for (int i = (sizeof(registers) / sizeof(int)) - 1; i >= 0; i--) {
        switch (registers[i]) {
        case UNWIND_X86_REG_NONE:
          break;
        case UNWIND_X86_REG_EBX:
        case UNWIND_X86_REG_ECX:
        case UNWIND_X86_REG_EDX:
        case UNWIND_X86_REG_EDI:
        case UNWIND_X86_REG_ESI:
        case UNWIND_X86_REG_EBP:
          row->SetRegisterLocationToAtCFAPlusOffset(
              translate_to_eh_frame_regnum_i386(registers[i]),
              wordsize * -saved_registers_offset, true);
          saved_registers_offset++;
          break;
        }
      }
    }

    unwind_plan.AppendRow(row);
    return true;
  } break;

  case UNWIND_X86_MODE_DWARF: {
    return false;
  } break;
  }
  return false;
}

// DWARF register numbers from "DWARF for the ARM 64-bit Architecture (AArch64)"
// doc by ARM

enum arm64_eh_regnum {
  x19 = 19,
  x20 = 20,
  x21 = 21,
  x22 = 22,
  x23 = 23,
  x24 = 24,
  x25 = 25,
  x26 = 26,
  x27 = 27,
  x28 = 28,

  fp = 29,
  ra = 30,
  sp = 31,
  pc = 32,

  // Compact unwind encodes d8-d15 but we don't have eh_frame / dwarf reg #'s
  // for the 64-bit fp regs.  Normally in DWARF it's context sensitive - so it
  // knows it is fetching a 32- or 64-bit quantity from reg v8 to indicate s0
  // or d0 - but the unwinder is operating at a lower level and we'd try to
  // fetch 128 bits if we were told that v8 were stored on the stack...
  v8 = 72,
  v9 = 73,
  v10 = 74,
  v11 = 75,
  v12 = 76,
  v13 = 77,
  v14 = 78,
  v15 = 79,
};

enum arm_eh_regnum {
  arm_r0 = 0,
  arm_r1 = 1,
  arm_r2 = 2,
  arm_r3 = 3,
  arm_r4 = 4,
  arm_r5 = 5,
  arm_r6 = 6,
  arm_r7 = 7,
  arm_r8 = 8,
  arm_r9 = 9,
  arm_r10 = 10,
  arm_r11 = 11,
  arm_r12 = 12,

  arm_sp = 13,
  arm_lr = 14,
  arm_pc = 15,

  arm_d0 = 256,
  arm_d1 = 257,
  arm_d2 = 258,
  arm_d3 = 259,
  arm_d4 = 260,
  arm_d5 = 261,
  arm_d6 = 262,
  arm_d7 = 263,
  arm_d8 = 264,
  arm_d9 = 265,
  arm_d10 = 266,
  arm_d11 = 267,
  arm_d12 = 268,
  arm_d13 = 269,
  arm_d14 = 270,
};

bool CompactUnwindInfo::CreateUnwindPlan_arm64(Target &target,
                                               FunctionInfo &function_info,
                                               UnwindPlan &unwind_plan,
                                               Address pc_or_function_start) {
  unwind_plan.SetSourceName("compact unwind info");
  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
  unwind_plan.SetRegisterKind(eRegisterKindEHFrame);

  unwind_plan.SetLSDAAddress(function_info.lsda_address);
  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);

  UnwindPlan::RowSP row(new UnwindPlan::Row);

  const int wordsize = 8;
  int mode = function_info.encoding & UNWIND_ARM64_MODE_MASK;

  if (mode == UNWIND_ARM64_MODE_DWARF)
    return false;

  if (mode == UNWIND_ARM64_MODE_FRAMELESS) {
    row->SetOffset(0);

    uint32_t stack_size =
        (EXTRACT_BITS(function_info.encoding,
                      UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK)) *
        16;

    // Our previous Call Frame Address is the stack pointer plus the stack size
    row->GetCFAValue().SetIsRegisterPlusOffset(arm64_eh_regnum::sp, stack_size);

    // Our previous PC is in the LR
    row->SetRegisterLocationToRegister(arm64_eh_regnum::pc, arm64_eh_regnum::ra,
                                       true);

    unwind_plan.AppendRow(row);
    return true;
  }

  // Should not be possible
  if (mode != UNWIND_ARM64_MODE_FRAME)
    return false;

  // mode == UNWIND_ARM64_MODE_FRAME

  row->GetCFAValue().SetIsRegisterPlusOffset(arm64_eh_regnum::fp, 2 * wordsize);
  row->SetOffset(0);
  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::fp, wordsize * -2,
                                            true);
  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::pc, wordsize * -1,
                                            true);
  row->SetRegisterLocationToIsCFAPlusOffset(arm64_eh_regnum::sp, 0, true);

  int reg_pairs_saved_count = 1;

  uint32_t saved_register_bits = function_info.encoding & 0xfff;

  if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
    int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x19, cfa_offset,
                                              true);
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x20, cfa_offset,
                                              true);
    reg_pairs_saved_count++;
  }

  if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
    int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x21, cfa_offset,
                                              true);
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x22, cfa_offset,
                                              true);
    reg_pairs_saved_count++;
  }

  if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
    int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x23, cfa_offset,
                                              true);
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x24, cfa_offset,
                                              true);
    reg_pairs_saved_count++;
  }

  if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
    int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x25, cfa_offset,
                                              true);
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x26, cfa_offset,
                                              true);
    reg_pairs_saved_count++;
  }

  if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
    int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x27, cfa_offset,
                                              true);
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x28, cfa_offset,
                                              true);
    reg_pairs_saved_count++;
  }

  // If we use the v8-v15 regnums here, the unwinder will try to grab 128 bits
  // off the stack;
  // not sure if we have a good way to represent the 64-bitness of these saves.

  if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR) {
    reg_pairs_saved_count++;
  }
  if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR) {
    reg_pairs_saved_count++;
  }
  if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR) {
    reg_pairs_saved_count++;
  }
  if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR) {
    reg_pairs_saved_count++;
  }

  unwind_plan.AppendRow(row);
  return true;
}

bool CompactUnwindInfo::CreateUnwindPlan_armv7(Target &target,
                                               FunctionInfo &function_info,
                                               UnwindPlan &unwind_plan,
                                               Address pc_or_function_start) {
  unwind_plan.SetSourceName("compact unwind info");
  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
  unwind_plan.SetRegisterKind(eRegisterKindEHFrame);

  unwind_plan.SetLSDAAddress(function_info.lsda_address);
  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);

  UnwindPlan::RowSP row(new UnwindPlan::Row);

  const int wordsize = 4;
  int mode = function_info.encoding & UNWIND_ARM_MODE_MASK;

  if (mode == UNWIND_ARM_MODE_DWARF)
    return false;

  uint32_t stack_adjust = (EXTRACT_BITS(function_info.encoding,
                                        UNWIND_ARM_FRAME_STACK_ADJUST_MASK)) *
                          wordsize;

  row->GetCFAValue().SetIsRegisterPlusOffset(arm_r7,
                                             (2 * wordsize) + stack_adjust);
  row->SetOffset(0);
  row->SetRegisterLocationToAtCFAPlusOffset(
      arm_r7, (wordsize * -2) - stack_adjust, true);
  row->SetRegisterLocationToAtCFAPlusOffset(
      arm_pc, (wordsize * -1) - stack_adjust, true);
  row->SetRegisterLocationToIsCFAPlusOffset(arm_sp, 0, true);

  int cfa_offset = -stack_adjust - (2 * wordsize);

  uint32_t saved_register_bits = function_info.encoding & 0xff;

  if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r6, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r5, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r4, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r12, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r11, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r10, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r9, cfa_offset, true);
  }

  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8) {
    cfa_offset -= wordsize;
    row->SetRegisterLocationToAtCFAPlusOffset(arm_r8, cfa_offset, true);
  }

  if (mode == UNWIND_ARM_MODE_FRAME_D) {
    uint32_t d_reg_bits =
        EXTRACT_BITS(function_info.encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
    switch (d_reg_bits) {
    case 0:
      // vpush {d8}
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
      break;
    case 1:
      // vpush {d10}
      // vpush {d8}
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d10, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
      break;
    case 2:
      // vpush {d12}
      // vpush {d10}
      // vpush {d8}
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d12, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d10, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
      break;
    case 3:
      // vpush {d14}
      // vpush {d12}
      // vpush {d10}
      // vpush {d8}
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d14, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d12, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d10, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
      break;
    case 4:
      // vpush {d14}
      // vpush {d12}
      // sp = (sp - 24) & (-16);
      // vst   {d8, d9, d10}
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d14, cfa_offset, true);
      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d12, cfa_offset, true);

      // FIXME we don't have a way to represent reg saves at an specific
      // alignment short of
      // coming up with some DWARF location description.

      break;
    case 5:
      // vpush {d14}
      // sp = (sp - 40) & (-16);
      // vst   {d8, d9, d10, d11}
      // vst   {d12}

      cfa_offset -= 8;
      row->SetRegisterLocationToAtCFAPlusOffset(arm_d14, cfa_offset, true);

      // FIXME we don't have a way to represent reg saves at an specific
      // alignment short of
      // coming up with some DWARF location description.

      break;
    case 6:
      // sp = (sp - 56) & (-16);
      // vst   {d8, d9, d10, d11}
      // vst   {d12, d13, d14}

      // FIXME we don't have a way to represent reg saves at an specific
      // alignment short of
      // coming up with some DWARF location description.

      break;
    case 7:
      // sp = (sp - 64) & (-16);
      // vst   {d8, d9, d10, d11}
      // vst   {d12, d13, d14, d15}

      // FIXME we don't have a way to represent reg saves at an specific
      // alignment short of
      // coming up with some DWARF location description.

      break;
    }
  }

  unwind_plan.AppendRow(row);
  return true;
}
