]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libunwind/src/UnwindLevel1.c
MFC r345805: Unify SCSI_STATUS_BUSY retry handling with other cases.
[FreeBSD/FreeBSD.git] / contrib / libunwind / src / UnwindLevel1.c
1 //===------------------------- UnwindLevel1.c -----------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 // Implements C++ ABI Exception Handling Level 1 as documented at:
10 //      http://mentorembedded.github.io/cxx-abi/abi-eh.html
11 // using libunwind
12 //
13 //===----------------------------------------------------------------------===//
14
15 // ARM EHABI does not specify _Unwind_{Get,Set}{GR,IP}().  Thus, we are
16 // defining inline functions to delegate the function calls to
17 // _Unwind_VRS_{Get,Set}().  However, some applications might declare the
18 // function protetype directly (instead of including <unwind.h>), thus we need
19 // to export these functions from libunwind.so as well.
20 #define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 1
21
22 #include <inttypes.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "libunwind.h"
30 #include "unwind.h"
31 #include "config.h"
32
33 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
34
35 #ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
36
37 static _Unwind_Reason_Code
38 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
39   unw_init_local(cursor, uc);
40
41   // Walk each frame looking for a place to stop.
42   bool handlerNotFound = true;
43   while (handlerNotFound) {
44     // Ask libunwind to get next frame (skip over first which is
45     // _Unwind_RaiseException).
46     int stepResult = unw_step(cursor);
47     if (stepResult == 0) {
48       _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
49                                  "bottom => _URC_END_OF_STACK",
50                                  (void *)exception_object);
51       return _URC_END_OF_STACK;
52     } else if (stepResult < 0) {
53       _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
54                                  "_URC_FATAL_PHASE1_ERROR",
55                                  (void *)exception_object);
56       return _URC_FATAL_PHASE1_ERROR;
57     }
58
59     // See if frame has code to run (has personality routine).
60     unw_proc_info_t frameInfo;
61     unw_word_t sp;
62     if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
63       _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
64                                  "failed => _URC_FATAL_PHASE1_ERROR",
65                                  (void *)exception_object);
66       return _URC_FATAL_PHASE1_ERROR;
67     }
68
69     // When tracing, print state information.
70     if (_LIBUNWIND_TRACING_UNWINDING) {
71       char functionBuf[512];
72       const char *functionName = functionBuf;
73       unw_word_t offset;
74       if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
75                              &offset) != UNW_ESUCCESS) ||
76           (frameInfo.start_ip + offset > frameInfo.end_ip))
77         functionName = ".anonymous.";
78       unw_word_t pc;
79       unw_get_reg(cursor, UNW_REG_IP, &pc);
80       _LIBUNWIND_TRACE_UNWINDING(
81           "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR
82           ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "",
83           (void *)exception_object, pc, frameInfo.start_ip, functionName,
84           frameInfo.lsda, frameInfo.handler);
85     }
86
87     // If there is a personality routine, ask it if it will want to stop at
88     // this frame.
89     if (frameInfo.handler != 0) {
90       __personality_routine p =
91           (__personality_routine)(uintptr_t)(frameInfo.handler);
92       _LIBUNWIND_TRACE_UNWINDING(
93           "unwind_phase1(ex_ojb=%p): calling personality function %p",
94           (void *)exception_object, (void *)(uintptr_t)p);
95       _Unwind_Reason_Code personalityResult =
96           (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
97                exception_object, (struct _Unwind_Context *)(cursor));
98       switch (personalityResult) {
99       case _URC_HANDLER_FOUND:
100         // found a catch clause or locals that need destructing in this frame
101         // stop search and remember stack pointer at the frame
102         handlerNotFound = false;
103         unw_get_reg(cursor, UNW_REG_SP, &sp);
104         exception_object->private_2 = (uintptr_t)sp;
105         _LIBUNWIND_TRACE_UNWINDING(
106             "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
107             (void *)exception_object);
108         return _URC_NO_REASON;
109
110       case _URC_CONTINUE_UNWIND:
111         _LIBUNWIND_TRACE_UNWINDING(
112             "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
113             (void *)exception_object);
114         // continue unwinding
115         break;
116
117       default:
118         // something went wrong
119         _LIBUNWIND_TRACE_UNWINDING(
120             "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
121             (void *)exception_object);
122         return _URC_FATAL_PHASE1_ERROR;
123       }
124     }
125   }
126   return _URC_NO_REASON;
127 }
128
129
130 static _Unwind_Reason_Code
131 unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
132   unw_init_local(cursor, uc);
133
134   _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
135                              (void *)exception_object);
136
137   // Walk each frame until we reach where search phase said to stop.
138   while (true) {
139
140     // Ask libunwind to get next frame (skip over first which is
141     // _Unwind_RaiseException).
142     int stepResult = unw_step(cursor);
143     if (stepResult == 0) {
144       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
145                                  "bottom => _URC_END_OF_STACK",
146                                  (void *)exception_object);
147       return _URC_END_OF_STACK;
148     } else if (stepResult < 0) {
149       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
150                                  "_URC_FATAL_PHASE1_ERROR",
151                                  (void *)exception_object);
152       return _URC_FATAL_PHASE2_ERROR;
153     }
154
155     // Get info about this frame.
156     unw_word_t sp;
157     unw_proc_info_t frameInfo;
158     unw_get_reg(cursor, UNW_REG_SP, &sp);
159     if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
160       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
161                                  "failed => _URC_FATAL_PHASE1_ERROR",
162                                  (void *)exception_object);
163       return _URC_FATAL_PHASE2_ERROR;
164     }
165
166     // When tracing, print state information.
167     if (_LIBUNWIND_TRACING_UNWINDING) {
168       char functionBuf[512];
169       const char *functionName = functionBuf;
170       unw_word_t offset;
171       if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
172                              &offset) != UNW_ESUCCESS) ||
173           (frameInfo.start_ip + offset > frameInfo.end_ip))
174         functionName = ".anonymous.";
175       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR
176                                  ", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR
177                                  ", personality=0x%" PRIxPTR,
178                                  (void *)exception_object, frameInfo.start_ip,
179                                  functionName, sp, frameInfo.lsda,
180                                  frameInfo.handler);
181     }
182
183     // If there is a personality routine, tell it we are unwinding.
184     if (frameInfo.handler != 0) {
185       __personality_routine p =
186           (__personality_routine)(uintptr_t)(frameInfo.handler);
187       _Unwind_Action action = _UA_CLEANUP_PHASE;
188       if (sp == exception_object->private_2) {
189         // Tell personality this was the frame it marked in phase 1.
190         action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME);
191       }
192        _Unwind_Reason_Code personalityResult =
193           (*p)(1, action, exception_object->exception_class, exception_object,
194                (struct _Unwind_Context *)(cursor));
195       switch (personalityResult) {
196       case _URC_CONTINUE_UNWIND:
197         // Continue unwinding
198         _LIBUNWIND_TRACE_UNWINDING(
199             "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
200             (void *)exception_object);
201         if (sp == exception_object->private_2) {
202           // Phase 1 said we would stop at this frame, but we did not...
203           _LIBUNWIND_ABORT("during phase1 personality function said it would "
204                            "stop here, but now in phase2 it did not stop here");
205         }
206         break;
207       case _URC_INSTALL_CONTEXT:
208         _LIBUNWIND_TRACE_UNWINDING(
209             "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
210             (void *)exception_object);
211         // Personality routine says to transfer control to landing pad.
212         // We may get control back if landing pad calls _Unwind_Resume().
213         if (_LIBUNWIND_TRACING_UNWINDING) {
214           unw_word_t pc;
215           unw_get_reg(cursor, UNW_REG_IP, &pc);
216           unw_get_reg(cursor, UNW_REG_SP, &sp);
217           _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
218                                      "user code with ip=0x%" PRIxPTR
219                                      ", sp=0x%" PRIxPTR,
220                                      (void *)exception_object, pc, sp);
221         }
222         unw_resume(cursor);
223         // unw_resume() only returns if there was an error.
224         return _URC_FATAL_PHASE2_ERROR;
225       default:
226         // Personality routine returned an unknown result code.
227         _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
228                              personalityResult);
229         return _URC_FATAL_PHASE2_ERROR;
230       }
231     }
232   }
233
234   // Clean up phase did not resume at the frame that the search phase
235   // said it would...
236   return _URC_FATAL_PHASE2_ERROR;
237 }
238
239 static _Unwind_Reason_Code
240 unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
241                      _Unwind_Exception *exception_object,
242                      _Unwind_Stop_Fn stop, void *stop_parameter) {
243   unw_init_local(cursor, uc);
244
245   // Walk each frame until we reach where search phase said to stop
246   while (unw_step(cursor) > 0) {
247
248     // Update info about this frame.
249     unw_proc_info_t frameInfo;
250     if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
251       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
252                                  "failed => _URC_END_OF_STACK",
253                                  (void *)exception_object);
254       return _URC_FATAL_PHASE2_ERROR;
255     }
256
257     // When tracing, print state information.
258     if (_LIBUNWIND_TRACING_UNWINDING) {
259       char functionBuf[512];
260       const char *functionName = functionBuf;
261       unw_word_t offset;
262       if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
263                              &offset) != UNW_ESUCCESS) ||
264           (frameInfo.start_ip + offset > frameInfo.end_ip))
265         functionName = ".anonymous.";
266       _LIBUNWIND_TRACE_UNWINDING(
267           "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR
268           ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
269           (void *)exception_object, frameInfo.start_ip, functionName,
270           frameInfo.lsda, frameInfo.handler);
271     }
272
273     // Call stop function at each frame.
274     _Unwind_Action action =
275         (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE);
276     _Unwind_Reason_Code stopResult =
277         (*stop)(1, action, exception_object->exception_class, exception_object,
278                 (struct _Unwind_Context *)(cursor), stop_parameter);
279     _LIBUNWIND_TRACE_UNWINDING(
280         "unwind_phase2_forced(ex_ojb=%p): stop function returned %d",
281         (void *)exception_object, stopResult);
282     if (stopResult != _URC_NO_REASON) {
283       _LIBUNWIND_TRACE_UNWINDING(
284           "unwind_phase2_forced(ex_ojb=%p): stopped by stop function",
285           (void *)exception_object);
286       return _URC_FATAL_PHASE2_ERROR;
287     }
288
289     // If there is a personality routine, tell it we are unwinding.
290     if (frameInfo.handler != 0) {
291       __personality_routine p =
292           (__personality_routine)(intptr_t)(frameInfo.handler);
293       _LIBUNWIND_TRACE_UNWINDING(
294           "unwind_phase2_forced(ex_ojb=%p): calling personality function %p",
295           (void *)exception_object, (void *)(uintptr_t)p);
296       _Unwind_Reason_Code personalityResult =
297           (*p)(1, action, exception_object->exception_class, exception_object,
298                (struct _Unwind_Context *)(cursor));
299       switch (personalityResult) {
300       case _URC_CONTINUE_UNWIND:
301         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
302                                    "personality returned "
303                                    "_URC_CONTINUE_UNWIND",
304                                    (void *)exception_object);
305         // Destructors called, continue unwinding
306         break;
307       case _URC_INSTALL_CONTEXT:
308         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
309                                    "personality returned "
310                                    "_URC_INSTALL_CONTEXT",
311                                    (void *)exception_object);
312         // We may get control back if landing pad calls _Unwind_Resume().
313         unw_resume(cursor);
314         break;
315       default:
316         // Personality routine returned an unknown result code.
317         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
318                                    "personality returned %d, "
319                                    "_URC_FATAL_PHASE2_ERROR",
320                                    (void *)exception_object, personalityResult);
321         return _URC_FATAL_PHASE2_ERROR;
322       }
323     }
324   }
325
326   // Call stop function one last time and tell it we've reached the end
327   // of the stack.
328   _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
329                              "function with _UA_END_OF_STACK",
330                              (void *)exception_object);
331   _Unwind_Action lastAction =
332       (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
333   (*stop)(1, lastAction, exception_object->exception_class, exception_object,
334           (struct _Unwind_Context *)(cursor), stop_parameter);
335
336   // Clean up phase did not resume at the frame that the search phase said it
337   // would.
338   return _URC_FATAL_PHASE2_ERROR;
339 }
340
341
342 /// Called by __cxa_throw.  Only returns if there is a fatal error.
343 _LIBUNWIND_EXPORT _Unwind_Reason_Code
344 _Unwind_RaiseException(_Unwind_Exception *exception_object) {
345   _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
346                        (void *)exception_object);
347   unw_context_t uc;
348   unw_cursor_t cursor;
349   unw_getcontext(&uc);
350
351   // Mark that this is a non-forced unwind, so _Unwind_Resume()
352   // can do the right thing.
353   exception_object->private_1 = 0;
354   exception_object->private_2 = 0;
355
356   // phase 1: the search phase
357   _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object);
358   if (phase1 != _URC_NO_REASON)
359     return phase1;
360
361   // phase 2: the clean up phase
362   return unwind_phase2(&uc, &cursor, exception_object);
363 }
364
365
366
367 /// When _Unwind_RaiseException() is in phase2, it hands control
368 /// to the personality function at each frame.  The personality
369 /// may force a jump to a landing pad in that function, the landing
370 /// pad code may then call _Unwind_Resume() to continue with the
371 /// unwinding.  Note: the call to _Unwind_Resume() is from compiler
372 /// geneated user code.  All other _Unwind_* routines are called
373 /// by the C++ runtime __cxa_* routines.
374 ///
375 /// Note: re-throwing an exception (as opposed to continuing the unwind)
376 /// is implemented by having the code call __cxa_rethrow() which
377 /// in turn calls _Unwind_Resume_or_Rethrow().
378 _LIBUNWIND_EXPORT void
379 _Unwind_Resume(_Unwind_Exception *exception_object) {
380   _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object);
381   unw_context_t uc;
382   unw_cursor_t cursor;
383   unw_getcontext(&uc);
384
385   if (exception_object->private_1 != 0)
386     unwind_phase2_forced(&uc, &cursor, exception_object,
387                          (_Unwind_Stop_Fn) exception_object->private_1,
388                          (void *)exception_object->private_2);
389   else
390     unwind_phase2(&uc, &cursor, exception_object);
391
392   // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
393   _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
394 }
395
396
397
398 /// Not used by C++.
399 /// Unwinds stack, calling "stop" function at each frame.
400 /// Could be used to implement longjmp().
401 _LIBUNWIND_EXPORT _Unwind_Reason_Code
402 _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
403                      _Unwind_Stop_Fn stop, void *stop_parameter) {
404   _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)",
405                        (void *)exception_object, (void *)(uintptr_t)stop);
406   unw_context_t uc;
407   unw_cursor_t cursor;
408   unw_getcontext(&uc);
409
410   // Mark that this is a forced unwind, so _Unwind_Resume() can do
411   // the right thing.
412   exception_object->private_1 = (uintptr_t) stop;
413   exception_object->private_2 = (uintptr_t) stop_parameter;
414
415   // do it
416   return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter);
417 }
418
419
420 /// Called by personality handler during phase 2 to get LSDA for current frame.
421 _LIBUNWIND_EXPORT uintptr_t
422 _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
423   unw_cursor_t *cursor = (unw_cursor_t *)context;
424   unw_proc_info_t frameInfo;
425   uintptr_t result = 0;
426   if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
427     result = (uintptr_t)frameInfo.lsda;
428   _LIBUNWIND_TRACE_API(
429       "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR,
430       (void *)context, result);
431   if (result != 0) {
432     if (*((uint8_t *)result) != 0xFF)
433       _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF",
434                            result);
435   }
436   return result;
437 }
438
439
440 /// Called by personality handler during phase 2 to find the start of the
441 /// function.
442 _LIBUNWIND_EXPORT uintptr_t
443 _Unwind_GetRegionStart(struct _Unwind_Context *context) {
444   unw_cursor_t *cursor = (unw_cursor_t *)context;
445   unw_proc_info_t frameInfo;
446   uintptr_t result = 0;
447   if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
448     result = (uintptr_t)frameInfo.start_ip;
449   _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR,
450                        (void *)context, result);
451   return result;
452 }
453
454 #endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
455
456 /// Called by personality handler during phase 2 if a foreign exception
457 // is caught.
458 _LIBUNWIND_EXPORT void
459 _Unwind_DeleteException(_Unwind_Exception *exception_object) {
460   _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
461                        (void *)exception_object);
462   if (exception_object->exception_cleanup != NULL)
463     (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
464                                            exception_object);
465 }
466
467 /// Called by personality handler during phase 2 to get register values.
468 _LIBUNWIND_EXPORT uintptr_t
469 _Unwind_GetGR(struct _Unwind_Context *context, int index) {
470   unw_cursor_t *cursor = (unw_cursor_t *)context;
471   unw_word_t result;
472   unw_get_reg(cursor, index, &result);
473   _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIxPTR,
474                        (void *)context, index, result);
475   return (uintptr_t)result;
476 }
477
478 /// Called by personality handler during phase 2 to alter register values.
479 _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
480                                      uintptr_t value) {
481   _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIxPTR
482                        ")",
483                        (void *)context, index, value);
484   unw_cursor_t *cursor = (unw_cursor_t *)context;
485   unw_set_reg(cursor, index, value);
486 }
487
488 /// Called by personality handler during phase 2 to get instruction pointer.
489 _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
490   unw_cursor_t *cursor = (unw_cursor_t *)context;
491   unw_word_t result;
492   unw_get_reg(cursor, UNW_REG_IP, &result);
493   _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR,
494                        (void *)context, result);
495   return (uintptr_t)result;
496 }
497
498 /// Called by personality handler during phase 2 to alter instruction pointer,
499 /// such as setting where the landing pad is, so _Unwind_Resume() will
500 /// start executing in the landing pad.
501 _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
502                                      uintptr_t value) {
503   _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")",
504                        (void *)context, value);
505   unw_cursor_t *cursor = (unw_cursor_t *)context;
506   unw_set_reg(cursor, UNW_REG_IP, value);
507 }
508
509 #endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)