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;