]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
Merge llvm, clang, lld and lldb trunk r291274, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / POSIX / CrashReason.cpp
1 //===-- CrashReason.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 "CrashReason.h"
11
12 #include "llvm/Support/raw_ostream.h"
13
14 #include <sstream>
15
16 namespace {
17
18 void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
19   std::stringstream ss;
20   ss << " (fault address: 0x" << std::hex << addr << ")";
21   str += ss.str();
22 }
23
24 #if defined(si_lower) && defined(si_upper)
25 void AppendBounds(std::string &str, lldb::addr_t lower_bound,
26                   lldb::addr_t upper_bound, lldb::addr_t addr) {
27   llvm::raw_string_ostream stream(str);
28   if ((unsigned long)addr < lower_bound)
29     stream << ": lower bound violation ";
30   else
31     stream << ": upper bound violation ";
32   stream << "(fault address: 0x";
33   stream.write_hex(addr);
34   stream << ", lower bound: 0x";
35   stream.write_hex(lower_bound);
36   stream << ", upper bound: 0x";
37   stream.write_hex(upper_bound);
38   stream << ")";
39   stream.flush();
40 }
41 #endif
42
43 CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
44   assert(info.si_signo == SIGSEGV);
45
46   switch (info.si_code) {
47 #ifdef SI_KERNEL
48   case SI_KERNEL:
49     // Some platforms will occasionally send nonstandard spurious SI_KERNEL
50     // codes.
51     // One way to get this is via unaligned SIMD loads.
52     return CrashReason::eInvalidAddress; // for lack of anything better
53 #endif
54   case SEGV_MAPERR:
55     return CrashReason::eInvalidAddress;
56   case SEGV_ACCERR:
57     return CrashReason::ePrivilegedAddress;
58 #ifndef SEGV_BNDERR
59 #define SEGV_BNDERR 3
60 #endif
61   case SEGV_BNDERR:
62     return CrashReason::eBoundViolation;
63   }
64
65   assert(false && "unexpected si_code for SIGSEGV");
66   return CrashReason::eInvalidCrashReason;
67 }
68
69 CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
70   assert(info.si_signo == SIGILL);
71
72   switch (info.si_code) {
73   case ILL_ILLOPC:
74     return CrashReason::eIllegalOpcode;
75   case ILL_ILLOPN:
76     return CrashReason::eIllegalOperand;
77   case ILL_ILLADR:
78     return CrashReason::eIllegalAddressingMode;
79   case ILL_ILLTRP:
80     return CrashReason::eIllegalTrap;
81   case ILL_PRVOPC:
82     return CrashReason::ePrivilegedOpcode;
83   case ILL_PRVREG:
84     return CrashReason::ePrivilegedRegister;
85   case ILL_COPROC:
86     return CrashReason::eCoprocessorError;
87   case ILL_BADSTK:
88     return CrashReason::eInternalStackError;
89   }
90
91   assert(false && "unexpected si_code for SIGILL");
92   return CrashReason::eInvalidCrashReason;
93 }
94
95 CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
96   assert(info.si_signo == SIGFPE);
97
98   switch (info.si_code) {
99   case FPE_INTDIV:
100     return CrashReason::eIntegerDivideByZero;
101   case FPE_INTOVF:
102     return CrashReason::eIntegerOverflow;
103   case FPE_FLTDIV:
104     return CrashReason::eFloatDivideByZero;
105   case FPE_FLTOVF:
106     return CrashReason::eFloatOverflow;
107   case FPE_FLTUND:
108     return CrashReason::eFloatUnderflow;
109   case FPE_FLTRES:
110     return CrashReason::eFloatInexactResult;
111   case FPE_FLTINV:
112     return CrashReason::eFloatInvalidOperation;
113   case FPE_FLTSUB:
114     return CrashReason::eFloatSubscriptRange;
115   }
116
117   assert(false && "unexpected si_code for SIGFPE");
118   return CrashReason::eInvalidCrashReason;
119 }
120
121 CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
122   assert(info.si_signo == SIGBUS);
123
124   switch (info.si_code) {
125   case BUS_ADRALN:
126     return CrashReason::eIllegalAlignment;
127   case BUS_ADRERR:
128     return CrashReason::eIllegalAddress;
129   case BUS_OBJERR:
130     return CrashReason::eHardwareError;
131   }
132
133   assert(false && "unexpected si_code for SIGBUS");
134   return CrashReason::eInvalidCrashReason;
135 }
136 }
137
138 std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
139   std::string str;
140
141 // make sure that siginfo_t has the bound fields available.
142 #if defined(si_lower) && defined(si_upper)
143   if (reason == CrashReason::eBoundViolation) {
144     str = "signal SIGSEGV";
145     AppendBounds(str, reinterpret_cast<lldb::addr_t>(info.si_lower),
146                  reinterpret_cast<lldb::addr_t>(info.si_upper),
147                  reinterpret_cast<lldb::addr_t>(info.si_addr));
148     return str;
149   }
150 #endif
151
152   return GetCrashReasonString(reason,
153                               reinterpret_cast<lldb::addr_t>(info.si_addr));
154 }
155
156 std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
157   std::string str;
158
159   switch (reason) {
160   default:
161     assert(false && "invalid CrashReason");
162     break;
163
164   case CrashReason::eInvalidAddress:
165     str = "signal SIGSEGV: invalid address";
166     AppendFaultAddr(str, fault_addr);
167     break;
168   case CrashReason::ePrivilegedAddress:
169     str = "signal SIGSEGV: address access protected";
170     AppendFaultAddr(str, fault_addr);
171     break;
172   case CrashReason::eBoundViolation:
173     str = "signal SIGSEGV: bound violation";
174     break;
175   case CrashReason::eIllegalOpcode:
176     str = "signal SIGILL: illegal instruction";
177     break;
178   case CrashReason::eIllegalOperand:
179     str = "signal SIGILL: illegal instruction operand";
180     break;
181   case CrashReason::eIllegalAddressingMode:
182     str = "signal SIGILL: illegal addressing mode";
183     break;
184   case CrashReason::eIllegalTrap:
185     str = "signal SIGILL: illegal trap";
186     break;
187   case CrashReason::ePrivilegedOpcode:
188     str = "signal SIGILL: privileged instruction";
189     break;
190   case CrashReason::ePrivilegedRegister:
191     str = "signal SIGILL: privileged register";
192     break;
193   case CrashReason::eCoprocessorError:
194     str = "signal SIGILL: coprocessor error";
195     break;
196   case CrashReason::eInternalStackError:
197     str = "signal SIGILL: internal stack error";
198     break;
199   case CrashReason::eIllegalAlignment:
200     str = "signal SIGBUS: illegal alignment";
201     break;
202   case CrashReason::eIllegalAddress:
203     str = "signal SIGBUS: illegal address";
204     break;
205   case CrashReason::eHardwareError:
206     str = "signal SIGBUS: hardware error";
207     break;
208   case CrashReason::eIntegerDivideByZero:
209     str = "signal SIGFPE: integer divide by zero";
210     break;
211   case CrashReason::eIntegerOverflow:
212     str = "signal SIGFPE: integer overflow";
213     break;
214   case CrashReason::eFloatDivideByZero:
215     str = "signal SIGFPE: floating point divide by zero";
216     break;
217   case CrashReason::eFloatOverflow:
218     str = "signal SIGFPE: floating point overflow";
219     break;
220   case CrashReason::eFloatUnderflow:
221     str = "signal SIGFPE: floating point underflow";
222     break;
223   case CrashReason::eFloatInexactResult:
224     str = "signal SIGFPE: inexact floating point result";
225     break;
226   case CrashReason::eFloatInvalidOperation:
227     str = "signal SIGFPE: invalid floating point operation";
228     break;
229   case CrashReason::eFloatSubscriptRange:
230     str = "signal SIGFPE: invalid floating point subscript range";
231     break;
232   }
233
234   return str;
235 }
236
237 const char *CrashReasonAsString(CrashReason reason) {
238 #ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
239   // Just return the code in ascii for integration builds.
240   chcar str[8];
241   sprintf(str, "%d", reason);
242 #else
243   const char *str = nullptr;
244
245   switch (reason) {
246   case CrashReason::eInvalidCrashReason:
247     str = "eInvalidCrashReason";
248     break;
249
250   // SIGSEGV crash reasons.
251   case CrashReason::eInvalidAddress:
252     str = "eInvalidAddress";
253     break;
254   case CrashReason::ePrivilegedAddress:
255     str = "ePrivilegedAddress";
256     break;
257   case CrashReason::eBoundViolation:
258     str = "eBoundViolation";
259     break;
260
261   // SIGILL crash reasons.
262   case CrashReason::eIllegalOpcode:
263     str = "eIllegalOpcode";
264     break;
265   case CrashReason::eIllegalOperand:
266     str = "eIllegalOperand";
267     break;
268   case CrashReason::eIllegalAddressingMode:
269     str = "eIllegalAddressingMode";
270     break;
271   case CrashReason::eIllegalTrap:
272     str = "eIllegalTrap";
273     break;
274   case CrashReason::ePrivilegedOpcode:
275     str = "ePrivilegedOpcode";
276     break;
277   case CrashReason::ePrivilegedRegister:
278     str = "ePrivilegedRegister";
279     break;
280   case CrashReason::eCoprocessorError:
281     str = "eCoprocessorError";
282     break;
283   case CrashReason::eInternalStackError:
284     str = "eInternalStackError";
285     break;
286
287   // SIGBUS crash reasons:
288   case CrashReason::eIllegalAlignment:
289     str = "eIllegalAlignment";
290     break;
291   case CrashReason::eIllegalAddress:
292     str = "eIllegalAddress";
293     break;
294   case CrashReason::eHardwareError:
295     str = "eHardwareError";
296     break;
297
298   // SIGFPE crash reasons:
299   case CrashReason::eIntegerDivideByZero:
300     str = "eIntegerDivideByZero";
301     break;
302   case CrashReason::eIntegerOverflow:
303     str = "eIntegerOverflow";
304     break;
305   case CrashReason::eFloatDivideByZero:
306     str = "eFloatDivideByZero";
307     break;
308   case CrashReason::eFloatOverflow:
309     str = "eFloatOverflow";
310     break;
311   case CrashReason::eFloatUnderflow:
312     str = "eFloatUnderflow";
313     break;
314   case CrashReason::eFloatInexactResult:
315     str = "eFloatInexactResult";
316     break;
317   case CrashReason::eFloatInvalidOperation:
318     str = "eFloatInvalidOperation";
319     break;
320   case CrashReason::eFloatSubscriptRange:
321     str = "eFloatSubscriptRange";
322     break;
323   }
324 #endif
325
326   return str;
327 }
328
329 CrashReason GetCrashReason(const siginfo_t &info) {
330   switch (info.si_signo) {
331   case SIGSEGV:
332     return GetCrashReasonForSIGSEGV(info);
333   case SIGBUS:
334     return GetCrashReasonForSIGBUS(info);
335   case SIGFPE:
336     return GetCrashReasonForSIGFPE(info);
337   case SIGILL:
338     return GetCrashReasonForSIGILL(info);
339   }
340
341   assert(false && "unexpected signal");
342   return CrashReason::eInvalidCrashReason;
343 }