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

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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_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()) {
      Host::SystemLog(Host::eSystemLogError, "error: Invalid offset "
                                             "encountered in compact unwind "
                                             "info, skipping\n");
      // 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;
}
