]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / StopInfoMachException.cpp
1 //===-- 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/Breakpoint/Watchpoint.h"
17 #include "lldb/Symbol/Symbol.h"
18 #include "lldb/Target/DynamicLoader.h"
19 #include "lldb/Target/ExecutionContext.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/RegisterContext.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Thread.h"
24 #include "lldb/Target/ThreadPlan.h"
25 #include "lldb/Target/UnixSignals.h"
26 #include "lldb/Utility/StreamString.h"
27
28 using namespace lldb;
29 using namespace lldb_private;
30
31 const char *StopInfoMachException::GetDescription() {
32   if (m_description.empty() && m_value != 0) {
33     ExecutionContext exe_ctx(m_thread_wp.lock());
34     Target *target = exe_ctx.GetTargetPtr();
35     const llvm::Triple::ArchType cpu =
36         target ? target->GetArchitecture().GetMachine()
37                : llvm::Triple::UnknownArch;
38
39     const char *exc_desc = NULL;
40     const char *code_label = "code";
41     const char *code_desc = NULL;
42     const char *subcode_label = "subcode";
43     const char *subcode_desc = NULL;
44     switch (m_value) {
45     case 1: // EXC_BAD_ACCESS
46       exc_desc = "EXC_BAD_ACCESS";
47       subcode_label = "address";
48       switch (cpu) {
49       case llvm::Triple::x86:
50       case llvm::Triple::x86_64:
51         switch (m_exc_code) {
52         case 0xd:
53           code_desc = "EXC_I386_GPFLT";
54           m_exc_data_count = 1;
55           break;
56         }
57         break;
58       case llvm::Triple::arm:
59       case llvm::Triple::thumb:
60         switch (m_exc_code) {
61         case 0x101:
62           code_desc = "EXC_ARM_DA_ALIGN";
63           break;
64         case 0x102:
65           code_desc = "EXC_ARM_DA_DEBUG";
66           break;
67         }
68         break;
69
70       case llvm::Triple::ppc:
71       case llvm::Triple::ppc64:
72         switch (m_exc_code) {
73         case 0x101:
74           code_desc = "EXC_PPC_VM_PROT_READ";
75           break;
76         case 0x102:
77           code_desc = "EXC_PPC_BADSPACE";
78           break;
79         case 0x103:
80           code_desc = "EXC_PPC_UNALIGNED";
81           break;
82         }
83         break;
84
85       default:
86         break;
87       }
88       break;
89
90     case 2: // EXC_BAD_INSTRUCTION
91       exc_desc = "EXC_BAD_INSTRUCTION";
92       switch (cpu) {
93       case llvm::Triple::x86:
94       case llvm::Triple::x86_64:
95         if (m_exc_code == 1)
96           code_desc = "EXC_I386_INVOP";
97         break;
98
99       case llvm::Triple::ppc:
100       case llvm::Triple::ppc64:
101         switch (m_exc_code) {
102         case 1:
103           code_desc = "EXC_PPC_INVALID_SYSCALL";
104           break;
105         case 2:
106           code_desc = "EXC_PPC_UNIPL_INST";
107           break;
108         case 3:
109           code_desc = "EXC_PPC_PRIVINST";
110           break;
111         case 4:
112           code_desc = "EXC_PPC_PRIVREG";
113           break;
114         case 5:
115           code_desc = "EXC_PPC_TRACE";
116           break;
117         case 6:
118           code_desc = "EXC_PPC_PERFMON";
119           break;
120         }
121         break;
122
123       case llvm::Triple::arm:
124       case llvm::Triple::thumb:
125         if (m_exc_code == 1)
126           code_desc = "EXC_ARM_UNDEFINED";
127         break;
128
129       default:
130         break;
131       }
132       break;
133
134     case 3: // EXC_ARITHMETIC
135       exc_desc = "EXC_ARITHMETIC";
136       switch (cpu) {
137       case llvm::Triple::x86:
138       case llvm::Triple::x86_64:
139         switch (m_exc_code) {
140         case 1:
141           code_desc = "EXC_I386_DIV";
142           break;
143         case 2:
144           code_desc = "EXC_I386_INTO";
145           break;
146         case 3:
147           code_desc = "EXC_I386_NOEXT";
148           break;
149         case 4:
150           code_desc = "EXC_I386_EXTOVR";
151           break;
152         case 5:
153           code_desc = "EXC_I386_EXTERR";
154           break;
155         case 6:
156           code_desc = "EXC_I386_EMERR";
157           break;
158         case 7:
159           code_desc = "EXC_I386_BOUND";
160           break;
161         case 8:
162           code_desc = "EXC_I386_SSEEXTERR";
163           break;
164         }
165         break;
166
167       case llvm::Triple::ppc:
168       case llvm::Triple::ppc64:
169         switch (m_exc_code) {
170         case 1:
171           code_desc = "EXC_PPC_OVERFLOW";
172           break;
173         case 2:
174           code_desc = "EXC_PPC_ZERO_DIVIDE";
175           break;
176         case 3:
177           code_desc = "EXC_PPC_FLT_INEXACT";
178           break;
179         case 4:
180           code_desc = "EXC_PPC_FLT_ZERO_DIVIDE";
181           break;
182         case 5:
183           code_desc = "EXC_PPC_FLT_UNDERFLOW";
184           break;
185         case 6:
186           code_desc = "EXC_PPC_FLT_OVERFLOW";
187           break;
188         case 7:
189           code_desc = "EXC_PPC_FLT_NOT_A_NUMBER";
190           break;
191         }
192         break;
193
194       default:
195         break;
196       }
197       break;
198
199     case 4: // EXC_EMULATION
200       exc_desc = "EXC_EMULATION";
201       break;
202
203     case 5: // EXC_SOFTWARE
204       exc_desc = "EXC_SOFTWARE";
205       if (m_exc_code == 0x10003) {
206         subcode_desc = "EXC_SOFT_SIGNAL";
207         subcode_label = "signo";
208       }
209       break;
210
211     case 6: // EXC_BREAKPOINT
212     {
213       exc_desc = "EXC_BREAKPOINT";
214       switch (cpu) {
215       case llvm::Triple::x86:
216       case llvm::Triple::x86_64:
217         switch (m_exc_code) {
218         case 1:
219           code_desc = "EXC_I386_SGL";
220           break;
221         case 2:
222           code_desc = "EXC_I386_BPT";
223           break;
224         }
225         break;
226
227       case llvm::Triple::ppc:
228       case llvm::Triple::ppc64:
229         switch (m_exc_code) {
230         case 1:
231           code_desc = "EXC_PPC_BREAKPOINT";
232           break;
233         }
234         break;
235
236       case llvm::Triple::arm:
237       case llvm::Triple::thumb:
238         switch (m_exc_code) {
239         case 0x101:
240           code_desc = "EXC_ARM_DA_ALIGN";
241           break;
242         case 0x102:
243           code_desc = "EXC_ARM_DA_DEBUG";
244           break;
245         case 1:
246           code_desc = "EXC_ARM_BREAKPOINT";
247           break;
248         // FIXME temporary workaround, exc_code 0 does not really mean
249         // EXC_ARM_BREAKPOINT
250         case 0:
251           code_desc = "EXC_ARM_BREAKPOINT";
252           break;
253         }
254         break;
255
256       default:
257         break;
258       }
259     } break;
260
261     case 7:
262       exc_desc = "EXC_SYSCALL";
263       break;
264
265     case 8:
266       exc_desc = "EXC_MACH_SYSCALL";
267       break;
268
269     case 9:
270       exc_desc = "EXC_RPC_ALERT";
271       break;
272
273     case 10:
274       exc_desc = "EXC_CRASH";
275       break;
276     case 11:
277       exc_desc = "EXC_RESOURCE";
278       break;
279     case 12:
280       exc_desc = "EXC_GUARD";
281       break;
282     }
283
284     StreamString strm;
285
286     if (exc_desc)
287       strm.PutCString(exc_desc);
288     else
289       strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
290
291     if (m_exc_data_count >= 1) {
292       if (code_desc)
293         strm.Printf(" (%s=%s", code_label, code_desc);
294       else
295         strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
296     }
297
298     if (m_exc_data_count >= 2) {
299       if (subcode_desc)
300         strm.Printf(", %s=%s", subcode_label, subcode_desc);
301       else
302         strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
303     }
304
305     if (m_exc_data_count > 0)
306       strm.PutChar(')');
307
308     m_description = strm.GetString();
309   }
310   return m_description.c_str();
311 }
312
313 StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
314     Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
315     uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
316     bool pc_already_adjusted, bool adjust_pc_if_needed) {
317   if (exc_type != 0) {
318     uint32_t pc_decrement = 0;
319     ExecutionContext exe_ctx(thread.shared_from_this());
320     Target *target = exe_ctx.GetTargetPtr();
321     const llvm::Triple::ArchType cpu =
322         target ? target->GetArchitecture().GetMachine()
323                : llvm::Triple::UnknownArch;
324
325     switch (exc_type) {
326     case 1: // EXC_BAD_ACCESS
327       break;
328
329     case 2: // EXC_BAD_INSTRUCTION
330       switch (cpu) {
331       case llvm::Triple::ppc:
332       case llvm::Triple::ppc64:
333         switch (exc_code) {
334         case 1: // EXC_PPC_INVALID_SYSCALL
335         case 2: // EXC_PPC_UNIPL_INST
336         case 3: // EXC_PPC_PRIVINST
337         case 4: // EXC_PPC_PRIVREG
338           break;
339         case 5: // EXC_PPC_TRACE
340           return StopInfo::CreateStopReasonToTrace(thread);
341         case 6: // EXC_PPC_PERFMON
342           break;
343         }
344         break;
345
346       default:
347         break;
348       }
349       break;
350
351     case 3: // EXC_ARITHMETIC
352     case 4: // EXC_EMULATION
353       break;
354
355     case 5:                    // EXC_SOFTWARE
356       if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
357       {
358         if (exc_sub_code == 5) {
359           // On MacOSX, a SIGTRAP can signify that a process has called exec,
360           // so we should check with our dynamic loader to verify.
361           ProcessSP process_sp(thread.GetProcess());
362           if (process_sp) {
363             DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
364             if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
365               // The program was re-exec'ed
366               return StopInfo::CreateStopReasonWithExec(thread);
367             }
368             //                        if (!process_did_exec)
369             //                        {
370             //                            // We have a SIGTRAP, make sure we
371             //                            didn't exec by checking
372             //                            // for the PC being at
373             //                            "_dyld_start"...
374             //                            lldb::StackFrameSP frame_sp
375             //                            (thread.GetStackFrameAtIndex(0));
376             //                            if (frame_sp)
377             //                            {
378             //                                const Symbol *symbol =
379             //                                frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
380             //                                if (symbol)
381             //                                {
382             //                                    if (symbol->GetName() ==
383             //                                    ConstString("_dyld_start"))
384             //                                        process_did_exec = true;
385             //                                }
386             //                            }
387             //                        }
388           }
389         }
390         return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
391       }
392       break;
393
394     case 6: // EXC_BREAKPOINT
395     {
396       bool is_actual_breakpoint = false;
397       bool is_trace_if_actual_breakpoint_missing = false;
398       switch (cpu) {
399       case llvm::Triple::x86:
400       case llvm::Triple::x86_64:
401         if (exc_code == 1) // EXC_I386_SGL
402         {
403           if (!exc_sub_code) {
404             // This looks like a plain trap.
405             // Have to check if there is a breakpoint here as well.  When you
406             // single-step onto a trap, the single step stops you not to trap.
407             // Since we also do that check below, let's just use that logic.
408             is_actual_breakpoint = true;
409             is_trace_if_actual_breakpoint_missing = true;
410           } else {
411
412             // It's a watchpoint, then.
413             // The exc_sub_code indicates the data break address.
414             lldb::WatchpointSP wp_sp;
415             if (target)
416               wp_sp = target->GetWatchpointList().FindByAddress(
417                   (lldb::addr_t)exc_sub_code);
418             if (wp_sp && wp_sp->IsEnabled()) {
419               // Debugserver may piggyback the hardware index of the fired
420               // watchpoint in the exception data. Set the hardware index if
421               // that's the case.
422               if (exc_data_count >= 3)
423                 wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
424               return StopInfo::CreateStopReasonWithWatchpointID(thread,
425                                                                 wp_sp->GetID());
426             }
427           }
428         } else if (exc_code == 2 || // EXC_I386_BPT
429                    exc_code == 3)   // EXC_I386_BPTFLT
430         {
431           // KDP returns EXC_I386_BPTFLT for trace breakpoints
432           if (exc_code == 3)
433             is_trace_if_actual_breakpoint_missing = true;
434
435           is_actual_breakpoint = true;
436           if (!pc_already_adjusted)
437             pc_decrement = 1;
438         }
439         break;
440
441       case llvm::Triple::ppc:
442       case llvm::Triple::ppc64:
443         is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
444         break;
445
446       case llvm::Triple::arm:
447       case llvm::Triple::thumb:
448         if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
449         {
450           // It's a watchpoint, then, if the exc_sub_code indicates a
451           // known/enabled data break address from our watchpoint list.
452           lldb::WatchpointSP wp_sp;
453           if (target)
454             wp_sp = target->GetWatchpointList().FindByAddress(
455                 (lldb::addr_t)exc_sub_code);
456           if (wp_sp && wp_sp->IsEnabled()) {
457             // Debugserver may piggyback the hardware index of the fired
458             // watchpoint in the exception data. Set the hardware index if
459             // that's the case.
460             if (exc_data_count >= 3)
461               wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
462             return StopInfo::CreateStopReasonWithWatchpointID(thread,
463                                                               wp_sp->GetID());
464           } else {
465             is_actual_breakpoint = true;
466             is_trace_if_actual_breakpoint_missing = true;
467           }
468         } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
469         {
470           is_actual_breakpoint = true;
471           is_trace_if_actual_breakpoint_missing = true;
472         } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
473                                   // is currently returning this so accept it
474                                   // as indicating a breakpoint until the
475                                   // kernel is fixed
476         {
477           is_actual_breakpoint = true;
478           is_trace_if_actual_breakpoint_missing = true;
479         }
480         break;
481
482       case llvm::Triple::aarch64: {
483         if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
484         {
485           // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
486           // is set
487           is_actual_breakpoint = false;
488           is_trace_if_actual_breakpoint_missing = true;
489         }
490         if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
491         {
492           // It's a watchpoint, then, if the exc_sub_code indicates a
493           // known/enabled data break address from our watchpoint list.
494           lldb::WatchpointSP wp_sp;
495           if (target)
496             wp_sp = target->GetWatchpointList().FindByAddress(
497                 (lldb::addr_t)exc_sub_code);
498           if (wp_sp && wp_sp->IsEnabled()) {
499             // Debugserver may piggyback the hardware index of the fired
500             // watchpoint in the exception data. Set the hardware index if
501             // that's the case.
502             if (exc_data_count >= 3)
503               wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
504             return StopInfo::CreateStopReasonWithWatchpointID(thread,
505                                                               wp_sp->GetID());
506           }
507           // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
508           // EXC_BAD_ACCESS
509           if (thread.GetTemporaryResumeState() == eStateStepping)
510             return StopInfo::CreateStopReasonToTrace(thread);
511         }
512         // It looks like exc_sub_code has the 4 bytes of the instruction that
513         // triggered the exception, i.e. our breakpoint opcode
514         is_actual_breakpoint = exc_code == 1;
515         break;
516       }
517
518       default:
519         break;
520       }
521
522       if (is_actual_breakpoint) {
523         RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
524         addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
525
526         ProcessSP process_sp(thread.CalculateProcess());
527
528         lldb::BreakpointSiteSP bp_site_sp;
529         if (process_sp)
530           bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
531         if (bp_site_sp && bp_site_sp->IsEnabled()) {
532           // Update the PC if we were asked to do so, but only do so if we find
533           // a breakpoint that we know about cause this could be a trap
534           // instruction in the code
535           if (pc_decrement > 0 && adjust_pc_if_needed)
536             reg_ctx_sp->SetPC(pc);
537
538           // If the breakpoint is for this thread, then we'll report the hit,
539           // but if it is for another thread, we can just report no reason.  We
540           // don't need to worry about stepping over the breakpoint here, that
541           // will be taken care of when the thread resumes and notices that
542           // there's a breakpoint under the pc. If we have an operating system
543           // plug-in, we might have set a thread specific breakpoint using the
544           // operating system thread ID, so we can't make any assumptions about
545           // the thread ID so we must always report the breakpoint regardless
546           // of the thread.
547           if (bp_site_sp->ValidForThisThread(&thread) ||
548               thread.GetProcess()->GetOperatingSystem() != NULL)
549             return StopInfo::CreateStopReasonWithBreakpointSiteID(
550                 thread, bp_site_sp->GetID());
551           else if (is_trace_if_actual_breakpoint_missing)
552             return StopInfo::CreateStopReasonToTrace(thread);
553           else
554             return StopInfoSP();
555         }
556
557         // Don't call this a trace if we weren't single stepping this thread.
558         if (is_trace_if_actual_breakpoint_missing &&
559             thread.GetTemporaryResumeState() == eStateStepping) {
560           return StopInfo::CreateStopReasonToTrace(thread);
561         }
562       }
563     } break;
564
565     case 7:  // EXC_SYSCALL
566     case 8:  // EXC_MACH_SYSCALL
567     case 9:  // EXC_RPC_ALERT
568     case 10: // EXC_CRASH
569       break;
570     }
571
572     return StopInfoSP(new StopInfoMachException(
573         thread, exc_type, exc_data_count, exc_code, exc_sub_code));
574   }
575   return StopInfoSP();
576 }