blob: 71ec18fa97f8014c6b85ad5ae87afbfaa8b70b4a [file] [log] [blame]
Greg Clayton643ee732010-08-04 01:40:35 +00001//===-- StopInfoMachException.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "StopInfoMachException.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/ArchSpec.h"
17#include "lldb/Core/StreamString.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/RegisterContext.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Target/Thread.h"
22#include "lldb/Target/ThreadPlan.h"
23#include "lldb/Target/UnixSignals.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
28const char *
29StopInfoMachException::GetDescription ()
30{
31 if (m_description.empty() && m_value != 0)
32 {
Greg Clayton940b1032011-02-23 00:35:02 +000033 const llvm::Triple::ArchType cpu = m_thread.GetProcess().GetTarget().GetArchitecture().GetMachine();
Greg Clayton643ee732010-08-04 01:40:35 +000034
35 const char *exc_desc = NULL;
36 const char *code_label = "code";
37 const char *code_desc = NULL;
38 const char *subcode_label = "subcode";
39 const char *subcode_desc = NULL;
40 switch (m_value)
41 {
42 case 1: // EXC_BAD_ACCESS
43 exc_desc = "EXC_BAD_ACCESS";
44 subcode_label = "address";
45 switch (cpu)
46 {
Greg Clayton940b1032011-02-23 00:35:02 +000047 case llvm::Triple::arm:
Greg Clayton643ee732010-08-04 01:40:35 +000048 switch (m_exc_code)
49 {
50 case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
51 case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
52 }
53 break;
54
Greg Clayton940b1032011-02-23 00:35:02 +000055 case llvm::Triple::ppc:
56 case llvm::Triple::ppc64:
Greg Clayton643ee732010-08-04 01:40:35 +000057 switch (m_exc_code)
58 {
59 case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
60 case 0x102: code_desc = "EXC_PPC_BADSPACE"; break;
61 case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break;
62 }
63 break;
64
65 default:
66 break;
67 }
68 break;
69
70 case 2: // EXC_BAD_INSTRUCTION
71 exc_desc = "EXC_BAD_INSTRUCTION";
72 switch (cpu)
73 {
Greg Clayton940b1032011-02-23 00:35:02 +000074 case llvm::Triple::x86:
75 case llvm::Triple::x86_64:
Greg Clayton643ee732010-08-04 01:40:35 +000076 if (m_exc_code == 1)
77 code_desc = "EXC_I386_INVOP";
78 break;
79
Greg Clayton940b1032011-02-23 00:35:02 +000080 case llvm::Triple::ppc:
81 case llvm::Triple::ppc64:
Greg Clayton643ee732010-08-04 01:40:35 +000082 switch (m_exc_code)
83 {
84 case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break;
85 case 2: code_desc = "EXC_PPC_UNIPL_INST"; break;
86 case 3: code_desc = "EXC_PPC_PRIVINST"; break;
87 case 4: code_desc = "EXC_PPC_PRIVREG"; break;
88 case 5: code_desc = "EXC_PPC_TRACE"; break;
89 case 6: code_desc = "EXC_PPC_PERFMON"; break;
90 }
91 break;
92
Greg Clayton940b1032011-02-23 00:35:02 +000093 case llvm::Triple::arm:
Greg Clayton643ee732010-08-04 01:40:35 +000094 if (m_exc_code == 1)
95 code_desc = "EXC_ARM_UNDEFINED";
96 break;
97
98 default:
99 break;
100 }
101 break;
102
103 case 3: // EXC_ARITHMETIC
104 exc_desc = "EXC_ARITHMETIC";
105 switch (cpu)
106 {
Greg Clayton940b1032011-02-23 00:35:02 +0000107 case llvm::Triple::x86:
108 case llvm::Triple::x86_64:
Greg Clayton643ee732010-08-04 01:40:35 +0000109 switch (m_exc_code)
110 {
111 case 1: code_desc = "EXC_I386_DIV"; break;
112 case 2: code_desc = "EXC_I386_INTO"; break;
113 case 3: code_desc = "EXC_I386_NOEXT"; break;
114 case 4: code_desc = "EXC_I386_EXTOVR"; break;
115 case 5: code_desc = "EXC_I386_EXTERR"; break;
116 case 6: code_desc = "EXC_I386_EMERR"; break;
117 case 7: code_desc = "EXC_I386_BOUND"; break;
118 case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
119 }
120 break;
121
Greg Clayton940b1032011-02-23 00:35:02 +0000122 case llvm::Triple::ppc:
123 case llvm::Triple::ppc64:
Greg Clayton643ee732010-08-04 01:40:35 +0000124 switch (m_exc_code)
125 {
126 case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
127 case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
128 case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
129 case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
130 case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
131 case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
132 case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
133 }
134 break;
135
136 default:
137 break;
138 }
139 break;
140
141 case 4: // EXC_EMULATION
142 exc_desc = "EXC_EMULATION";
143 break;
144
145
146 case 5: // EXC_SOFTWARE
147 exc_desc = "EXC_SOFTWARE";
148 if (m_exc_code == 0x10003)
149 {
150 subcode_desc = "EXC_SOFT_SIGNAL";
151 subcode_label = "signo";
152 }
153 break;
154
155 case 6: // EXC_BREAKPOINT
156 {
157 exc_desc = "EXC_BREAKPOINT";
158 switch (cpu)
159 {
Greg Clayton940b1032011-02-23 00:35:02 +0000160 case llvm::Triple::x86:
161 case llvm::Triple::x86_64:
Greg Clayton643ee732010-08-04 01:40:35 +0000162 switch (m_exc_code)
163 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000164 case 1: code_desc = "EXC_I386_SGL"; break;
165 case 2: code_desc = "EXC_I386_BPT"; break;
Greg Clayton643ee732010-08-04 01:40:35 +0000166 }
167 break;
168
Greg Clayton940b1032011-02-23 00:35:02 +0000169 case llvm::Triple::ppc:
170 case llvm::Triple::ppc64:
Greg Clayton643ee732010-08-04 01:40:35 +0000171 switch (m_exc_code)
172 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000173 case 1: code_desc = "EXC_PPC_BREAKPOINT"; break;
Greg Clayton643ee732010-08-04 01:40:35 +0000174 }
175 break;
176
Greg Clayton940b1032011-02-23 00:35:02 +0000177 case llvm::Triple::arm:
Greg Clayton643ee732010-08-04 01:40:35 +0000178 switch (m_exc_code)
179 {
Greg Clayton04d397c2011-05-23 18:04:09 +0000180 case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
181 case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000182 case 1: code_desc = "EXC_ARM_BREAKPOINT"; break;
Greg Clayton643ee732010-08-04 01:40:35 +0000183 }
184 break;
185
186 default:
187 break;
188 }
189 }
190 break;
191
192 case 7:
193 exc_desc = "EXC_SYSCALL";
194 break;
195
196 case 8:
197 exc_desc = "EXC_MACH_SYSCALL";
198 break;
199
200 case 9:
201 exc_desc = "EXC_RPC_ALERT";
202 break;
203
204 case 10:
205 exc_desc = "EXC_CRASH";
206 break;
207 }
208
209 StreamString strm;
210
211 if (exc_desc)
212 strm.PutCString(exc_desc);
213 else
214 strm.Printf("EXC_??? (%llu)", m_value);
215
216 if (m_exc_data_count >= 1)
217 {
218 if (code_desc)
219 strm.Printf(" (%s=%s", code_label, code_desc);
220 else
221 strm.Printf(" (%s=%llu", code_label, m_exc_code);
222 }
223
224 if (m_exc_data_count >= 2)
225 {
226 if (subcode_desc)
227 strm.Printf(", %s=%s", subcode_label, subcode_desc);
228 else
229 strm.Printf(", %s=0x%llx", subcode_label, m_exc_subcode);
230 }
231
232 if (m_exc_data_count > 0)
233 strm.PutChar(')');
234
235 m_description.swap (strm.GetString());
236 }
237 return m_description.c_str();
238}
239
240
241StopInfoSP
242StopInfoMachException::CreateStopReasonWithMachException
243(
244 Thread &thread,
245 uint32_t exc_type,
246 uint32_t exc_data_count,
247 uint64_t exc_code,
248 uint64_t exc_sub_code
249)
250{
251 if (exc_type != 0)
252 {
Greg Clayton940b1032011-02-23 00:35:02 +0000253 const llvm::Triple::ArchType cpu = thread.GetProcess().GetTarget().GetArchitecture().GetMachine();
Greg Clayton643ee732010-08-04 01:40:35 +0000254
255 switch (exc_type)
256 {
257 case 1: // EXC_BAD_ACCESS
258 break;
259
260 case 2: // EXC_BAD_INSTRUCTION
261 switch (cpu)
262 {
Greg Clayton940b1032011-02-23 00:35:02 +0000263 case llvm::Triple::ppc:
264 case llvm::Triple::ppc64:
Greg Clayton643ee732010-08-04 01:40:35 +0000265 switch (exc_code)
266 {
267 case 1: // EXC_PPC_INVALID_SYSCALL
268 case 2: // EXC_PPC_UNIPL_INST
269 case 3: // EXC_PPC_PRIVINST
270 case 4: // EXC_PPC_PRIVREG
271 break;
272 case 5: // EXC_PPC_TRACE
273 return StopInfo::CreateStopReasonToTrace (thread);
274 case 6: // EXC_PPC_PERFMON
275 break;
276 }
277 break;
278
279 default:
280 break;
281 }
282 break;
283
284 case 3: // EXC_ARITHMETIC
285 case 4: // EXC_EMULATION
286 break;
287
288 case 5: // EXC_SOFTWARE
289 if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
290 return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code);
291 break;
292
293 case 6: // EXC_BREAKPOINT
294 {
295 bool is_software_breakpoint = false;
296 switch (cpu)
297 {
Greg Clayton940b1032011-02-23 00:35:02 +0000298 case llvm::Triple::x86:
299 case llvm::Triple::x86_64:
Greg Clayton643ee732010-08-04 01:40:35 +0000300 if (exc_code == 1) // EXC_I386_SGL
301 {
Johnny Chen30e8d972011-09-08 20:52:34 +0000302 if (!exc_sub_code)
303 return StopInfo::CreateStopReasonToTrace(thread);
304
305 // It's a watchpoint, then.
306 lldb::WatchpointLocationSP wp_loc_sp =
307 thread.GetProcess().GetTarget().GetWatchpointLocationList().FindByAddress((lldb::addr_t)exc_sub_code);
308 if (wp_loc_sp)
309 return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_loc_sp->GetID());
Greg Clayton643ee732010-08-04 01:40:35 +0000310 }
311 else if (exc_code == 2) // EXC_I386_BPT
312 {
313 is_software_breakpoint = true;
314 }
315 break;
316
Greg Clayton940b1032011-02-23 00:35:02 +0000317 case llvm::Triple::ppc:
318 case llvm::Triple::ppc64:
Greg Clayton643ee732010-08-04 01:40:35 +0000319 is_software_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
320 break;
321
Greg Clayton940b1032011-02-23 00:35:02 +0000322 case llvm::Triple::arm:
Greg Clayton04d397c2011-05-23 18:04:09 +0000323 if (exc_code == 0x102)
324 {
325 // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS
326 return StopInfo::CreateStopReasonToTrace(thread);
327 }
328 else
329 is_software_breakpoint = exc_code == 1; // EXC_ARM_BREAKPOINT
Greg Clayton643ee732010-08-04 01:40:35 +0000330 break;
331
332 default:
333 break;
334 }
335
336 if (is_software_breakpoint)
337 {
338 addr_t pc = thread.GetRegisterContext()->GetPC();
339 lldb::BreakpointSiteSP bp_site_sp = thread.GetProcess().GetBreakpointSiteList().FindByAddress(pc);
340 if (bp_site_sp)
341 {
Jim Ingham11e95852010-10-22 23:28:32 +0000342 // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
343 // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
344 // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
Greg Clayton643ee732010-08-04 01:40:35 +0000345 if (bp_site_sp->ValidForThisThread (&thread))
346 return StopInfo::CreateStopReasonWithBreakpointSiteID (thread, bp_site_sp->GetID());
Jim Ingham11e95852010-10-22 23:28:32 +0000347 else
348 return StopInfoSP();
Greg Clayton643ee732010-08-04 01:40:35 +0000349 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000350 else if (cpu == llvm::Triple::arm)
351 {
352 return StopInfo::CreateStopReasonToTrace (thread);
353 }
Greg Clayton643ee732010-08-04 01:40:35 +0000354 }
355 }
356 break;
357
358 case 7: // EXC_SYSCALL
359 case 8: // EXC_MACH_SYSCALL
360 case 9: // EXC_RPC_ALERT
361 case 10: // EXC_CRASH
362 break;
363 }
364
365 return StopInfoSP(new StopInfoMachException (thread, exc_type, exc_data_count, exc_code, exc_sub_code));
366 }
367 return StopInfoSP();
368}