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

#include "StopInfoMachException.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/UnixSignals.h"

using namespace lldb;
using namespace lldb_private;
    
const char *
StopInfoMachException::GetDescription ()
{
    if (m_description.empty() && m_value != 0)
    {
        ExecutionContext exe_ctx (m_thread_wp.lock());
        Target *target = exe_ctx.GetTargetPtr();
        const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;

        const char *exc_desc = NULL;
        const char *code_label = "code";
        const char *code_desc = NULL;
        const char *subcode_label = "subcode";
        const char *subcode_desc = NULL;
        switch (m_value)
        {
        case 1: // EXC_BAD_ACCESS
            exc_desc = "EXC_BAD_ACCESS";
            subcode_label = "address";
            switch (cpu)
            {
            case llvm::Triple::x86:
            case llvm::Triple::x86_64:
                switch (m_exc_code)
                {
                case 0xd: code_desc = "EXC_I386_GPFLT"; m_exc_data_count = 1; break;
                }
                break;
            case llvm::Triple::arm:
            case llvm::Triple::thumb:
                switch (m_exc_code)
                {
                case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
                case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
                }
                break;

            case llvm::Triple::ppc:
            case llvm::Triple::ppc64:
                switch (m_exc_code)
                {
                case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
                case 0x102: code_desc = "EXC_PPC_BADSPACE";     break;
                case 0x103: code_desc = "EXC_PPC_UNALIGNED";    break;
                }
                break;

            default:
                break;
            }
            break;

        case 2: // EXC_BAD_INSTRUCTION
            exc_desc = "EXC_BAD_INSTRUCTION";
            switch (cpu)
            {
            case llvm::Triple::x86:
            case llvm::Triple::x86_64:
                if (m_exc_code == 1)
                    code_desc = "EXC_I386_INVOP";
                break;

            case llvm::Triple::ppc:
            case llvm::Triple::ppc64:
                switch (m_exc_code)
                {
                case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break; 
                case 2: code_desc = "EXC_PPC_UNIPL_INST"; break; 
                case 3: code_desc = "EXC_PPC_PRIVINST"; break; 
                case 4: code_desc = "EXC_PPC_PRIVREG"; break; 
                case 5: code_desc = "EXC_PPC_TRACE"; break; 
                case 6: code_desc = "EXC_PPC_PERFMON"; break; 
                }
                break;

            case llvm::Triple::arm:
            case llvm::Triple::thumb:
                if (m_exc_code == 1)
                    code_desc = "EXC_ARM_UNDEFINED";
                break;

            default:
                break;
            }
            break;

        case 3: // EXC_ARITHMETIC
            exc_desc = "EXC_ARITHMETIC";
            switch (cpu)
            {
            case llvm::Triple::x86:
            case llvm::Triple::x86_64:
                switch (m_exc_code)
                {
                case 1: code_desc = "EXC_I386_DIV"; break;
                case 2: code_desc = "EXC_I386_INTO"; break;
                case 3: code_desc = "EXC_I386_NOEXT"; break;
                case 4: code_desc = "EXC_I386_EXTOVR"; break;
                case 5: code_desc = "EXC_I386_EXTERR"; break;
                case 6: code_desc = "EXC_I386_EMERR"; break;
                case 7: code_desc = "EXC_I386_BOUND"; break;
                case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
                }
                break;

            case llvm::Triple::ppc:
            case llvm::Triple::ppc64:
                switch (m_exc_code)
                {
                case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
                case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
                case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
                case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
                case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
                case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
                case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
                }
                break;

            default:
                break;
            }
            break;

        case 4: // EXC_EMULATION
            exc_desc = "EXC_EMULATION";
            break;


        case 5: // EXC_SOFTWARE
            exc_desc = "EXC_SOFTWARE";
            if (m_exc_code == 0x10003)
            {
                subcode_desc = "EXC_SOFT_SIGNAL";
                subcode_label = "signo";
            }
            break;
        
        case 6: // EXC_BREAKPOINT
            {
                exc_desc = "EXC_BREAKPOINT";
                switch (cpu)
                {
                case llvm::Triple::x86:
                case llvm::Triple::x86_64:
                    switch (m_exc_code)
                    {
                    case 1: code_desc = "EXC_I386_SGL"; break;
                    case 2: code_desc = "EXC_I386_BPT"; break;
                    }
                    break;

                case llvm::Triple::ppc:
                case llvm::Triple::ppc64:
                    switch (m_exc_code)
                    {
                    case 1: code_desc = "EXC_PPC_BREAKPOINT"; break;
                    }
                    break;
                
                case llvm::Triple::arm:
                case llvm::Triple::thumb:
                    switch (m_exc_code)
                    {
                    case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
                    case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
                    case 1: code_desc = "EXC_ARM_BREAKPOINT"; break;
                    // FIXME temporary workaround, exc_code 0 does not really mean EXC_ARM_BREAKPOINT
                    case 0: code_desc = "EXC_ARM_BREAKPOINT"; break;
                    }
                    break;

                default:
                    break;
                }
            }
            break;

        case 7:
            exc_desc = "EXC_SYSCALL";
            break;

        case 8:
            exc_desc = "EXC_MACH_SYSCALL";
            break;

        case 9:
            exc_desc = "EXC_RPC_ALERT";
            break;

        case 10:
            exc_desc = "EXC_CRASH";
            break;
        case 11:
            exc_desc = "EXC_RESOURCE";
            break;
        case 12:
            exc_desc = "EXC_GUARD";
            break;
        }
        
        StreamString strm;

        if (exc_desc)
            strm.PutCString(exc_desc);
        else
            strm.Printf("EXC_??? (%" PRIu64 ")", m_value);

        if (m_exc_data_count >= 1)
        {
            if (code_desc)
                strm.Printf(" (%s=%s", code_label, code_desc);
            else
                strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
        }

        if (m_exc_data_count >= 2)
        {
            if (subcode_desc)
                strm.Printf(", %s=%s", subcode_label, subcode_desc);
            else
                strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
        }
        
        if (m_exc_data_count > 0)
            strm.PutChar(')');
        
        m_description.swap (strm.GetString());
    }
    return m_description.c_str();
}





StopInfoSP
StopInfoMachException::CreateStopReasonWithMachException 
(
    Thread &thread,
    uint32_t exc_type, 
    uint32_t exc_data_count,
    uint64_t exc_code,
    uint64_t exc_sub_code,
    uint64_t exc_sub_sub_code,
    bool pc_already_adjusted,
    bool adjust_pc_if_needed
)
{
    if (exc_type != 0)
    {
        uint32_t pc_decrement = 0;
        ExecutionContext exe_ctx (thread.shared_from_this());
        Target *target = exe_ctx.GetTargetPtr();
        const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;

        switch (exc_type)
        {
        case 1: // EXC_BAD_ACCESS
            break;

        case 2: // EXC_BAD_INSTRUCTION
            switch (cpu)
            {
            case llvm::Triple::ppc:
            case llvm::Triple::ppc64:
                switch (exc_code)
                {
                case 1: // EXC_PPC_INVALID_SYSCALL
                case 2: // EXC_PPC_UNIPL_INST
                case 3: // EXC_PPC_PRIVINST
                case 4: // EXC_PPC_PRIVREG
                    break;
                case 5: // EXC_PPC_TRACE
                    return StopInfo::CreateStopReasonToTrace (thread);
                case 6: // EXC_PPC_PERFMON
                    break;
                }
                break;

            default:
                break;
            }
            break;

        case 3: // EXC_ARITHMETIC
        case 4: // EXC_EMULATION
            break;

        case 5: // EXC_SOFTWARE
            if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
            {
                if (exc_sub_code == 5)
                {
                    // On MacOSX, a SIGTRAP can signify that a process has called
                    // exec, so we should check with our dynamic loader to verify.
                    ProcessSP process_sp (thread.GetProcess());
                    if (process_sp)
                    {
                        DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
                        if (dynamic_loader && dynamic_loader->ProcessDidExec())
                        {
                            // The program was re-exec'ed
                            return StopInfo::CreateStopReasonWithExec (thread);
                        }
//                        if (!process_did_exec)
//                        {
//                            // We have a SIGTRAP, make sure we didn't exec by checking
//                            // for the PC being at "_dyld_start"...
//                            lldb::StackFrameSP frame_sp (thread.GetStackFrameAtIndex(0));
//                            if (frame_sp)
//                            {
//                                const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
//                                if (symbol)
//                                {
//                                    if (symbol->GetName() == ConstString("_dyld_start"))
//                                        process_did_exec = true;
//                                }
//                            }
//                        }
                    }
                }
                return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code);
            }
            break;
        
        case 6: // EXC_BREAKPOINT
            {
                bool is_actual_breakpoint = false;
                bool is_trace_if_actual_breakpoint_missing = false;
                switch (cpu)
                {
                case llvm::Triple::x86:
                case llvm::Triple::x86_64:
                    if (exc_code == 1) // EXC_I386_SGL
                    {
                        if (!exc_sub_code)
                        {
                            // This looks like a plain trap.
                            // Have to check if there is a breakpoint here as well.  When you single-step onto a trap,
                            // the single step stops you not to trap.  Since we also do that check below, let's just use
                            // that logic.
                            is_actual_breakpoint = true;
                            is_trace_if_actual_breakpoint_missing = true;
                        }
                        else
                        {

                            // It's a watchpoint, then.
                            // The exc_sub_code indicates the data break address.
                            lldb::WatchpointSP wp_sp;
                            if (target)
                                wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
                            if (wp_sp && wp_sp->IsEnabled())
                            {
                                // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
                                // Set the hardware index if that's the case.
                                if (exc_data_count >=3)
                                    wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
                                return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
                            }
                        }
                    }
                    else if (exc_code == 2 ||   // EXC_I386_BPT
                             exc_code == 3)     // EXC_I386_BPTFLT
                    {
                        // KDP returns EXC_I386_BPTFLT for trace breakpoints
                        if (exc_code == 3)
                            is_trace_if_actual_breakpoint_missing = true;

                        is_actual_breakpoint = true;
                        if (!pc_already_adjusted)
                            pc_decrement = 1;
                    }
                    break;

                case llvm::Triple::ppc:
                case llvm::Triple::ppc64:
                    is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
                    break;
                
                case llvm::Triple::arm:
                case llvm::Triple::thumb:
                    if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
                    {
                        // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
                        // data break address from our watchpoint list.
                        lldb::WatchpointSP wp_sp;
                        if (target)
                            wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
                        if (wp_sp && wp_sp->IsEnabled())
                        {
                            // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
                            // Set the hardware index if that's the case.
                            if (exc_data_count >=3)
                                wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
                            return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
                        }
                        else
                        {
                            is_actual_breakpoint = true;
                            is_trace_if_actual_breakpoint_missing = true;
                        }
                    }
                    else if (exc_code == 1) // EXC_ARM_BREAKPOINT
                    {
                        is_actual_breakpoint = true;
                        is_trace_if_actual_breakpoint_missing = true;
                    }
                    else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel is currently returning this so accept it as indicating a breakpoint until the kernel is fixed
                    {
                        is_actual_breakpoint = true;
                        is_trace_if_actual_breakpoint_missing = true;
                    }
                    break;

                case llvm::Triple::aarch64:
                {
                    if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
                    {
                        // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 is set
                        return StopInfo::CreateStopReasonToTrace(thread);
                    }
                    if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
                    {
                        // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
                        // data break address from our watchpoint list.
                        lldb::WatchpointSP wp_sp;
                        if (target)
                            wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
                        if (wp_sp && wp_sp->IsEnabled())
                        {
                            // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
                            // Set the hardware index if that's the case.
                            if (exc_data_count >= 3)
                                wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
                            return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
                        }
                        // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS
                        if (thread.GetTemporaryResumeState() == eStateStepping)
                            return StopInfo::CreateStopReasonToTrace(thread);
                    }
                    // It looks like exc_sub_code has the 4 bytes of the instruction that triggered the 
                    // exception, i.e. our breakpoint opcode
                    is_actual_breakpoint = exc_code == 1;
                    break;
                }

                default:
                    break;
                }

                if (is_actual_breakpoint)
                {
                    RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
                    addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;

                    ProcessSP process_sp (thread.CalculateProcess());

                    lldb::BreakpointSiteSP bp_site_sp;
                    if (process_sp)
                        bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
                    if (bp_site_sp && bp_site_sp->IsEnabled())
                    {
                        // Update the PC if we were asked to do so, but only do
                        // so if we find a breakpoint that we know about cause
                        // this could be a trap instruction in the code
                        if (pc_decrement > 0 && adjust_pc_if_needed)
                            reg_ctx_sp->SetPC (pc);

                        // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
                        // we can just report no reason.  We don't need to worry about stepping over the breakpoint here, that
                        // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
                        // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
                        // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
                        // report the breakpoint regardless of the thread.
                        if (bp_site_sp->ValidForThisThread (&thread) || thread.GetProcess()->GetOperatingSystem () != NULL)
                            return StopInfo::CreateStopReasonWithBreakpointSiteID (thread, bp_site_sp->GetID());
                        else if (is_trace_if_actual_breakpoint_missing)
                            return StopInfo::CreateStopReasonToTrace (thread);
                        else
                            return StopInfoSP();
                    }

                    // Don't call this a trace if we weren't single stepping this thread.
                    if (is_trace_if_actual_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
                    {
                        return StopInfo::CreateStopReasonToTrace (thread);
                    }
                }
            }
            break;

        case 7:     // EXC_SYSCALL
        case 8:     // EXC_MACH_SYSCALL
        case 9:     // EXC_RPC_ALERT
        case 10:    // EXC_CRASH
            break;
        }
        
        return StopInfoSP(new StopInfoMachException (thread, exc_type, exc_data_count, exc_code, exc_sub_code));
    }
    return StopInfoSP();
}
