//===-- CompactUnwindInfo.cpp -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


// C Includes
// C++ Includes
#include <algorithm>

#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/CompactUnwindInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

#include "llvm/Support/MathExtras.h"

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;

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

            Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
            if (log && log->GetVerbose())
            {
                StreamString strm;
                addr.Dump (&strm, NULL, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize());
                log->Printf ("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.GetHeaderAddress().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)
            {
                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 == false)
    {
        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.reset (new DataBufferHeap (m_section_sp->GetByteSize(), 0));
            Error 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;
        ArchSpec arch;
        if (m_objfile.GetArchitecture (arch))
        {
            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.GetHeaderAddress().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 == true)
    {
        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_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress();
                unwind_info.lsda_address.ResolveAddressUsingFileSections (objfile_header_file_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_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress();
                        unwind_info.personality_ptr_address.ResolveAddressUsingFileSections (objfile_header_file_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_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress();
                unwind_info.lsda_address.ResolveAddressUsingFileSections (objfile_header_file_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_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress();
                        unwind_info.personality_ptr_address.ResolveAddressUsingFileSections (objfile_header_file_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.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);
                        Error 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] == false)
                        {
                            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.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);
                        Error 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] == false)
                        {
                            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.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.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;
}


