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

#include <vector>

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

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

using namespace lldb;
using namespace lldb_private;

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

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

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

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

    addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress();

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

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

ArmUnwindInfo::~ArmUnwindInfo()
{
}

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

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

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

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

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

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

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

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

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

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

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

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

            // 11000111 00000000
            // Spare

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

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

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

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

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

    UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
    row->SetOffset(0);
    row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);
    
    bool have_location_for_pc = false;
    for (const auto& offset : register_offsets)
    {
        have_location_for_pc |= offset.first == dwarf_pc;
        row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp, true);
    }
    
    if (!have_location_for_pc)
    {
        UnwindPlan::Row::RegisterLocation lr_location;
        if (row->GetRegisterInfo(dwarf_lr, lr_location))
            row->SetRegisterInfo(dwarf_pc, lr_location);
        else
            row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false);
    }

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

    return true;
}

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

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

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

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