diff options
author | Greg Clayton <gclayton@apple.com> | 2010-07-23 16:45:51 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2010-07-23 16:45:51 +0000 |
commit | 896dff661aaf11824b52fef5fccdb23600dfa9fb (patch) | |
tree | 49d0297d617fb66018df37fb3bbab5453ea6d19c /lldb/source/Target/Thread.cpp | |
parent | 2e00e3b12dcadf2446b51280c83732f72c1de7cb (diff) | |
download | bcm5719-llvm-896dff661aaf11824b52fef5fccdb23600dfa9fb.tar.gz bcm5719-llvm-896dff661aaf11824b52fef5fccdb23600dfa9fb.zip |
Centralized the Mach exception stop info code by adding it as a first
class citizen on the StopInfo class.
llvm-svn: 109235
Diffstat (limited to 'lldb/source/Target/Thread.cpp')
-rw-r--r-- | lldb/source/Target/Thread.cpp | 251 |
1 files changed, 250 insertions, 1 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 2cf64d1bf2e..35120905ac1 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/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 @@ Thread::StopInfo::SetStopDescription(const char *desc) } 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 @@ Thread::StopInfo::GetExceptionDataCount() const } 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; |