Centralized the Mach exception stop info code by adding it as a first
class citizen on the StopInfo class. 



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@109235 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 2cf64d1..3512090 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -17,6 +17,7 @@
 #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/ThreadPlanCallFunction.h"
@@ -139,6 +140,254 @@
 }
 
 void
+Thread::StopInfo::SetStopReasonWithMachException 
+(
+    uint32_t exc_type, 
+    size_t exc_data_count, 
+    const addr_t *exc_data
+)
+{
+    assert (exc_data_count < LLDB_THREAD_MAX_STOP_EXC_DATA);
+    assert (m_thread != NULL);
+    m_reason = eStopReasonException;
+    m_details.exception.type = exc_type;
+    m_details.exception.data_count = exc_data_count;
+    for (size_t i=0; i<exc_data_count; ++i)
+        m_details.exception.data[i] = exc_data[i];
+
+    if (m_details.exception.type != 0)
+    {
+        ArchSpec::CPU cpu = m_thread->GetProcess().GetTarget().GetArchitecture().GetGenericCPUType();
+
+        bool exc_translated = false;
+        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_details.exception.type)
+        {
+        case 1: // EXC_BAD_ACCESS
+            exc_desc = "EXC_BAD_ACCESS";
+            subcode_label = "address";
+            switch (cpu)
+            {                        
+            case ArchSpec::eCPU_arm:
+                switch (m_details.exception.data[0])
+                {
+                case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
+                case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
+                }
+                break;
+
+            case ArchSpec::eCPU_ppc:
+            case ArchSpec::eCPU_ppc64:
+                switch (m_details.exception.data[0])
+                {
+                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 ArchSpec::eCPU_i386:
+            case ArchSpec::eCPU_x86_64:
+                if (m_details.exception.data[0] == 1)
+                    code_desc = "EXC_I386_INVOP";
+                break;
+
+            case ArchSpec::eCPU_ppc:
+            case ArchSpec::eCPU_ppc64:
+                switch (m_details.exception.data[0])
+                {
+                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: // EXC_PPC_TRACE
+                    SetStopReasonToTrace();
+                    exc_translated = true;
+                    break;
+                case 6: code_desc = "EXC_PPC_PERFMON"; break; 
+                }
+                break;
+
+            case ArchSpec::eCPU_arm:
+                if (m_details.exception.data[0] == 1)
+                    code_desc = "EXC_ARM_UNDEFINED";
+                break;
+
+            default:
+                break;
+            }
+            break;
+
+        case 3: // EXC_ARITHMETIC
+            exc_desc = "EXC_ARITHMETIC";
+            switch (cpu)
+            {
+            case ArchSpec::eCPU_i386:
+            case ArchSpec::eCPU_x86_64:
+                switch (m_details.exception.data[0])
+                {
+                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 ArchSpec::eCPU_ppc:
+            case ArchSpec::eCPU_ppc64:
+                switch (m_details.exception.data[0])
+                {
+                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_details.exception.data[0] == EXC_SOFT_SIGNAL && m_details.exception.data_count == 2)
+            {
+                SetStopReasonWithSignal(m_details.exception.data[1]);
+                exc_translated = true;
+            }
+            break;
+        
+        case 6:
+            {
+                exc_desc = "EXC_SOFTWARE";
+                bool is_software_breakpoint = false;
+                switch (cpu)
+                {
+                case ArchSpec::eCPU_i386:
+                case ArchSpec::eCPU_x86_64:
+                    if (m_details.exception.data[0] == 1) // EXC_I386_SGL
+                    {
+                        exc_translated = true;
+                        SetStopReasonToTrace ();
+                    }
+                    else if (m_details.exception.data[0] == 2) // EXC_I386_BPT
+                    {
+                        is_software_breakpoint = true;
+                    }
+                    break;
+
+                case ArchSpec::eCPU_ppc:
+                case ArchSpec::eCPU_ppc64:
+                    is_software_breakpoint = m_details.exception.data[0] == 1; // EXC_PPC_BREAKPOINT
+                    break;
+                
+                case ArchSpec::eCPU_arm:
+                    is_software_breakpoint = m_details.exception.data[0] == 1; // EXC_ARM_BREAKPOINT
+                    break;
+
+                default:
+                    break;
+                }
+
+                if (is_software_breakpoint)
+                {
+                    addr_t pc = m_thread->GetRegisterContext()->GetPC();
+                    lldb::BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
+                    if (bp_site_sp)
+                    {
+                        exc_translated = true;
+                        if (bp_site_sp->ValidForThisThread (m_thread))
+                        {
+                            Clear ();
+                            SetStopReasonWithBreakpointSiteID (bp_site_sp->GetID());
+                        }
+                        else
+                        {
+                            Clear ();
+                            SetStopReasonToNone();
+                        }
+
+                    }
+                }
+            }
+            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;
+        }
+        
+        if (!exc_translated)
+        {
+            StreamString desc_strm;
+
+            if (exc_desc)
+                desc_strm.PutCString(exc_desc);
+            else
+                desc_strm.Printf("EXC_??? (%u)", exc_type);
+
+            if (m_details.exception.data_count >= 1)
+            {
+                if (code_desc)
+                    desc_strm.Printf(" (%s=%s", code_label, code_desc);
+                else
+                    desc_strm.Printf(" (%s=%llu", code_label, exc_data[0]);
+            }
+
+            if (m_details.exception.data_count >= 2)
+            {
+                if (subcode_desc)
+                    desc_strm.Printf(", %s=%s", subcode_label, subcode_desc);
+                else
+                    desc_strm.Printf(", %s=0x%llx", subcode_label, exc_data[1]);
+            }
+            
+            if (m_details.exception.data_count > 0)
+                desc_strm.PutChar(')');
+            
+            SetStopDescription(desc_strm.GetString().c_str());
+        }
+    }
+}
+void
 Thread::StopInfo::SetThread (Thread* thread)
 {
     m_thread = thread;
@@ -227,7 +476,7 @@
 }
 
 void
-Thread::StopInfo::SetStopReasonWithException (uint32_t exc_type, size_t exc_data_count)
+Thread::StopInfo::SetStopReasonWithGenericException (uint32_t exc_type, size_t exc_data_count)
 {
     m_reason = eStopReasonException;
     m_details.exception.type = exc_type;