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

#include "lldb/Symbol/UnwindPlan.h"

#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

bool
UnwindPlan::Row::RegisterLocation::operator == (const UnwindPlan::Row::RegisterLocation& rhs) const
{
    if (m_type == rhs.m_type)
    {
        switch (m_type)
        {
            case unspecified:
            case undefined:
            case same:
                return true;
                
            case atCFAPlusOffset:
            case isCFAPlusOffset:
                return m_location.offset == rhs.m_location.offset;

            case inOtherRegister:
                return m_location.reg_num == rhs.m_location.reg_num;
            
            case atDWARFExpression:
            case isDWARFExpression:
                if (m_location.expr.length == rhs.m_location.expr.length)
                    return !memcmp (m_location.expr.opcodes, rhs.m_location.expr.opcodes, m_location.expr.length);
                break;
        }
    }
    return false;
}

// This function doesn't copy the dwarf expression bytes; they must remain in allocated
// memory for the lifespan of this UnwindPlan object.
void
UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len)
{
    m_type = atDWARFExpression;
    m_location.expr.opcodes = opcodes;
    m_location.expr.length = len;
}

// This function doesn't copy the dwarf expression bytes; they must remain in allocated
// memory for the lifespan of this UnwindPlan object.
void
UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len)
{
    m_type = isDWARFExpression;
    m_location.expr.opcodes = opcodes;
    m_location.expr.length = len;
}

void
UnwindPlan::Row::RegisterLocation::Dump (Stream &s, const UnwindPlan* unwind_plan, const UnwindPlan::Row* row, Thread* thread, bool verbose) const
{
    switch (m_type)
    {
        case unspecified: 
            if (verbose)
                s.PutCString ("=<unspec>"); 
            else
                s.PutCString ("=!"); 
            break;
        case undefined: 
            if (verbose)
                s.PutCString ("=<undef>"); 
            else
                s.PutCString ("=?"); 
            break;
        case same: 
            s.PutCString ("= <same>"); 
            break;

        case atCFAPlusOffset: 
        case isCFAPlusOffset: 
            {
                s.PutChar('=');
                if (m_type == atCFAPlusOffset)
                    s.PutChar('[');
                s.Printf ("CFA%+d", m_location.offset);
                if (m_type == atCFAPlusOffset)
                    s.PutChar(']');
            }
            break;

        case inOtherRegister: 
            {
                const RegisterInfo *other_reg_info = nullptr;
                if (unwind_plan)
                    other_reg_info = unwind_plan->GetRegisterInfo (thread, m_location.reg_num);
                if (other_reg_info)
                    s.Printf ("=%s", other_reg_info->name); 
                else
                    s.Printf ("=reg(%u)", m_location.reg_num); 
            }
            break;

        case atDWARFExpression: 
        case isDWARFExpression: 
            {
                s.PutChar('=');
                if (m_type == atDWARFExpression)
                    s.PutCString("[dwarf-expr]");
                else
                    s.PutCString("dwarf-expr");
            }
            break;
        
    }
}

static void
DumpRegisterName (Stream &s, const UnwindPlan* unwind_plan, Thread *thread, uint32_t reg_num) {
    const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, reg_num);
    if (reg_info)
        s.PutCString (reg_info->name);
    else
        s.Printf ("reg(%u)", reg_num);
}

bool
UnwindPlan::Row::CFAValue::operator == (const UnwindPlan::Row::CFAValue& rhs) const
{
    if (m_type == rhs.m_type)
    {
        switch (m_type)
        {
            case unspecified:
                return true;

            case isRegisterPlusOffset:
                return m_value.reg.offset == rhs.m_value.reg.offset;

            case isRegisterDereferenced:
                return m_value.reg.reg_num == rhs.m_value.reg.reg_num;

            case isDWARFExpression:
                if (m_value.expr.length == rhs.m_value.expr.length)
                    return !memcmp (m_value.expr.opcodes, rhs.m_value.expr.opcodes, m_value.expr.length);
                break;
        }
    }
    return false;
}

void
UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan* unwind_plan, Thread* thread) const
{
    switch(m_type) {
    case isRegisterPlusOffset:
        DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
        s.Printf ("%+3d", m_value.reg.offset);
        break;
    case isRegisterDereferenced:
        s.PutChar ('[');
        DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
        s.PutChar (']');
        break;
    case isDWARFExpression:
        s.PutCString ("dwarf-expr");
        break;
    default:
        s.PutCString ("unspecified");
        break;
    }
}

void
UnwindPlan::Row::Clear ()
{
    m_cfa_value.SetUnspecified();
    m_offset = 0;
    m_register_locations.clear();
}

void
UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const
{
    if (base_addr != LLDB_INVALID_ADDRESS)
        s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
    else
        s.Printf ("%4" PRId64 ": CFA=", GetOffset());
            
    m_cfa_value.Dump(s, unwind_plan, thread);
    s.Printf(" => ");
    for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
    {
        DumpRegisterName(s, unwind_plan, thread, idx->first);
        const bool verbose = false;
        idx->second.Dump(s, unwind_plan, this, thread, verbose);
        s.PutChar (' ');
    }
    s.EOL();
}

UnwindPlan::Row::Row() :
    m_offset (0),
    m_cfa_value (),
    m_register_locations ()
{
}

bool
UnwindPlan::Row::GetRegisterInfo (uint32_t reg_num, UnwindPlan::Row::RegisterLocation& register_location) const
{
    collection::const_iterator pos = m_register_locations.find(reg_num);
    if (pos != m_register_locations.end())
    {
        register_location = pos->second;
        return true;
    }
    return false;
}

void
UnwindPlan::Row::RemoveRegisterInfo (uint32_t reg_num)
{
    collection::const_iterator pos = m_register_locations.find(reg_num);
    if (pos != m_register_locations.end())
    {
        m_register_locations.erase(pos);
    }
}

void
UnwindPlan::Row::SetRegisterInfo (uint32_t reg_num, const UnwindPlan::Row::RegisterLocation register_location)
{
    m_register_locations[reg_num] = register_location;
}

bool
UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
{
    if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
        return false;
    RegisterLocation reg_loc;
    reg_loc.SetAtCFAPlusOffset(offset);
    m_register_locations[reg_num] = reg_loc;
    return true;
}

bool
UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
{
    if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
        return false;
    RegisterLocation reg_loc;
    reg_loc.SetIsCFAPlusOffset(offset);
    m_register_locations[reg_num] = reg_loc;
    return true;
}

bool
UnwindPlan::Row::SetRegisterLocationToUndefined (uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
{
    collection::iterator pos = m_register_locations.find(reg_num);
    collection::iterator end = m_register_locations.end();
    
    if (pos != end)
    {
        if (!can_replace)
            return false;
        if (can_replace_only_if_unspecified && !pos->second.IsUnspecified())
            return false;
    }
    RegisterLocation reg_loc;
    reg_loc.SetUndefined();
    m_register_locations[reg_num] = reg_loc;
    return true;
}

bool
UnwindPlan::Row::SetRegisterLocationToUnspecified (uint32_t reg_num, bool can_replace)
{
    if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
        return false;
    RegisterLocation reg_loc;
    reg_loc.SetUnspecified();
    m_register_locations[reg_num] = reg_loc;
    return true;
}

bool
UnwindPlan::Row::SetRegisterLocationToRegister (uint32_t reg_num, 
                                                uint32_t other_reg_num,
                                                bool can_replace)
{
    if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
        return false;
    RegisterLocation reg_loc;
    reg_loc.SetInRegister(other_reg_num);
    m_register_locations[reg_num] = reg_loc;
    return true;
}

bool
UnwindPlan::Row::SetRegisterLocationToSame (uint32_t reg_num, bool must_replace)
{
    if (must_replace && m_register_locations.find(reg_num) == m_register_locations.end())
        return false;
    RegisterLocation reg_loc;
    reg_loc.SetSame();
    m_register_locations[reg_num] = reg_loc;
    return true;
}

bool
UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const
{
    return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value &&
        m_register_locations == rhs.m_register_locations;
}

void
UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp)
{
    if (m_row_list.empty() || m_row_list.back()->GetOffset() != row_sp->GetOffset())
        m_row_list.push_back(row_sp);
    else
        m_row_list.back() = row_sp;
}

void
UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp, bool replace_existing)
{
    collection::iterator it = m_row_list.begin();
    while (it != m_row_list.end()) {
        RowSP row = *it;
        if (row->GetOffset() >= row_sp->GetOffset())
            break;
        it++;
    }
    if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset())
        m_row_list.insert(it, row_sp);
    else if (replace_existing)
        *it = row_sp;
}

UnwindPlan::RowSP
UnwindPlan::GetRowForFunctionOffset (int offset) const
{
    RowSP row;
    if (!m_row_list.empty())
    {
        if (offset == -1)
            row = m_row_list.back();
        else
        {
            collection::const_iterator pos, end = m_row_list.end();
            for (pos = m_row_list.begin(); pos != end; ++pos)
            {
                if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
                    row = *pos;
                else
                    break;
            }
        }
    }
    return row;
}

bool
UnwindPlan::IsValidRowIndex (uint32_t idx) const
{
    return idx < m_row_list.size();
}

const UnwindPlan::RowSP
UnwindPlan::GetRowAtIndex (uint32_t idx) const
{
    if (idx < m_row_list.size())
        return m_row_list[idx];
    else
    {
        Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
        if (log)
            log->Printf ("error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index (number rows is %u)", idx, (uint32_t)m_row_list.size());
        return UnwindPlan::RowSP();
    }
}

const UnwindPlan::RowSP
UnwindPlan::GetLastRow () const
{
    if (m_row_list.empty())
    {
        Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
        if (log)
            log->Printf ("UnwindPlan::GetLastRow() when rows are empty");
        return UnwindPlan::RowSP();
    }
    return m_row_list.back();
}

int
UnwindPlan::GetRowCount () const
{
    return m_row_list.size ();
}

void
UnwindPlan::SetPlanValidAddressRange (const AddressRange& range)
{
   if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0)
       m_plan_valid_address_range = range;
}

bool
UnwindPlan::PlanValidAtAddress (Address addr)
{
    // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
    if (GetRowCount() == 0)
    {
        Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
        if (log)
        {
            StreamString s;
            if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
            {
                log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s' at address %s",
                             m_source_name.GetCString(), s.GetData());
            }
            else
            {
                log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
                             m_source_name.GetCString());
            }
        }
        return false;
    }

    // If the 0th Row of unwind instructions is missing, or if it doesn't provide
    // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan.
    if (GetRowAtIndex(0).get() == nullptr ||
            GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified)
    {
        Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
        if (log)
        {
            StreamString s;
            if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
            {
                log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s' at address %s",
                             m_source_name.GetCString(), s.GetData());
            }
            else
            {
                log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s'",
                             m_source_name.GetCString());
            }
        }
        return false;
    }

    if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0)
        return true;

    if (!addr.IsValid())
        return true;

    if (m_plan_valid_address_range.ContainsFileAddress (addr))
        return true;

    return false;
}

void
UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
{
    if (!m_source_name.IsEmpty())
    {
        s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString());
    }
    if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid())
    {
        TargetSP target_sp(thread->CalculateTarget());
        addr_t lsda_load_addr = m_lsda_address.GetLoadAddress (target_sp.get());
        addr_t personality_func_load_addr = m_personality_func_addr.GetLoadAddress (target_sp.get());
        
        if (lsda_load_addr != LLDB_INVALID_ADDRESS && personality_func_load_addr != LLDB_INVALID_ADDRESS)
        {
            s.Printf("LSDA address 0x%" PRIx64 ", personality routine is at address 0x%" PRIx64 "\n",
                     lsda_load_addr, personality_func_load_addr);
        }
    }
    s.Printf ("This UnwindPlan is sourced from the compiler: ");
    switch (m_plan_is_sourced_from_compiler)
    {
        case eLazyBoolYes:
            s.Printf ("yes.\n");
            break;
        case eLazyBoolNo:
            s.Printf ("no.\n");
            break;
        case eLazyBoolCalculate:
            s.Printf ("not specified.\n");
            break;
    }
    s.Printf ("This UnwindPlan is valid at all instruction locations: ");
    switch (m_plan_is_valid_at_all_instruction_locations)
    {
        case eLazyBoolYes:
            s.Printf ("yes.\n");
            break;
        case eLazyBoolNo:
            s.Printf ("no.\n");
            break;
        case eLazyBoolCalculate:
            s.Printf ("not specified.\n");
            break;
    }
    if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
    {
        s.PutCString ("Address range of this UnwindPlan: ");
        TargetSP target_sp(thread->CalculateTarget());
        m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
        s.EOL();
    }
    collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end();
    for (pos = begin; pos != end; ++pos)
    {
        s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
        (*pos)->Dump(s, this, thread, base_addr);
    }
}

void
UnwindPlan::SetSourceName (const char *source)
{
    m_source_name = ConstString (source);
}

ConstString
UnwindPlan::GetSourceName () const
{
    return m_source_name;
}

const RegisterInfo *
UnwindPlan::GetRegisterInfo (Thread* thread, uint32_t unwind_reg) const
{
    if (thread)
    {
        RegisterContext *reg_ctx = thread->GetRegisterContext().get();
        if (reg_ctx)
        {
            uint32_t reg;
            if (m_register_kind == eRegisterKindLLDB)
                reg = unwind_reg;
            else
                reg = reg_ctx->ConvertRegisterKindToRegisterNumber (m_register_kind, unwind_reg);
            if (reg != LLDB_INVALID_REGNUM)
                return reg_ctx->GetRegisterInfoAtIndex (reg);
        }
    }
    return nullptr;
}
    
