1 //===------------------------- UnwindLevel1.c -----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
9 // Implements C++ ABI Exception Handling Level 1 as documented at:
10 // http://mentorembedded.github.io/cxx-abi/abi-eh.html
13 //===----------------------------------------------------------------------===//
21 #include "libunwind.h"
25 #if _LIBUNWIND_BUILD_ZERO_COST_APIS && !LIBCXXABI_ARM_EHABI
27 static _Unwind_Reason_Code
28 unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
30 unw_init_local(&cursor1, uc);
32 // Walk each frame looking for a place to stop.
33 for (bool handlerNotFound = true; handlerNotFound;) {
35 // Ask libuwind to get next frame (skip over first which is
36 // _Unwind_RaiseException).
37 int stepResult = unw_step(&cursor1);
38 if (stepResult == 0) {
39 _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
40 "bottom => _URC_END_OF_STACK\n",
42 return _URC_END_OF_STACK;
43 } else if (stepResult < 0) {
44 _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
45 "_URC_FATAL_PHASE1_ERROR\n",
47 return _URC_FATAL_PHASE1_ERROR;
50 // See if frame has code to run (has personality routine).
51 unw_proc_info_t frameInfo;
53 if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
54 _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
55 "failed => _URC_FATAL_PHASE1_ERROR\n",
57 return _URC_FATAL_PHASE1_ERROR;
60 // When tracing, print state information.
61 if (_LIBUNWIND_TRACING_UNWINDING) {
62 char functionName[512];
64 if ((unw_get_proc_name(&cursor1, functionName, 512, &offset) !=
65 UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
66 strcpy(functionName, ".anonymous.");
68 unw_get_reg(&cursor1, UNW_REG_IP, &pc);
69 _LIBUNWIND_TRACE_UNWINDING(
70 "unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
71 "lsda=0x%llX, personality=0x%llX\n",
72 exception_object, pc, frameInfo.start_ip, functionName,
73 frameInfo.lsda, frameInfo.handler);
76 // If there is a personality routine, ask it if it will want to stop at
78 if (frameInfo.handler != 0) {
79 __personality_routine p =
80 (__personality_routine)(long)(frameInfo.handler);
81 _LIBUNWIND_TRACE_UNWINDING(
82 "unwind_phase1(ex_ojb=%p): calling personality function %p\n",
84 _Unwind_Reason_Code personalityResult =
85 (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
86 exception_object, (struct _Unwind_Context *)(&cursor1));
87 switch (personalityResult) {
88 case _URC_HANDLER_FOUND:
89 // found a catch clause or locals that need destructing in this frame
90 // stop search and remember stack pointer at the frame
91 handlerNotFound = false;
92 unw_get_reg(&cursor1, UNW_REG_SP, &sp);
93 exception_object->private_2 = (uintptr_t)sp;
94 _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
95 "_URC_HANDLER_FOUND \n",
97 return _URC_NO_REASON;
99 case _URC_CONTINUE_UNWIND:
100 _LIBUNWIND_TRACE_UNWINDING(
101 "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
103 // continue unwinding
107 // something went wrong
108 _LIBUNWIND_TRACE_UNWINDING(
109 "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
111 return _URC_FATAL_PHASE1_ERROR;
115 return _URC_NO_REASON;
119 static _Unwind_Reason_Code
120 unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
121 unw_cursor_t cursor2;
122 unw_init_local(&cursor2, uc);
124 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
126 // Walk each frame until we reach where search phase said to stop.
129 // Ask libuwind to get next frame (skip over first which is
130 // _Unwind_RaiseException).
131 int stepResult = unw_step(&cursor2);
132 if (stepResult == 0) {
133 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
134 "bottom => _URC_END_OF_STACK\n",
136 return _URC_END_OF_STACK;
137 } else if (stepResult < 0) {
138 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
139 "_URC_FATAL_PHASE1_ERROR\n",
141 return _URC_FATAL_PHASE2_ERROR;
144 // Get info about this frame.
146 unw_proc_info_t frameInfo;
147 unw_get_reg(&cursor2, UNW_REG_SP, &sp);
148 if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
149 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
150 "failed => _URC_FATAL_PHASE1_ERROR\n",
152 return _URC_FATAL_PHASE2_ERROR;
155 // When tracing, print state information.
156 if (_LIBUNWIND_TRACING_UNWINDING) {
157 char functionName[512];
159 if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
160 UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
161 strcpy(functionName, ".anonymous.");
162 _LIBUNWIND_TRACE_UNWINDING(
163 "unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, "
164 "lsda=0x%llX, personality=0x%llX\n",
165 exception_object, frameInfo.start_ip, functionName, sp,
166 frameInfo.lsda, frameInfo.handler);
169 // If there is a personality routine, tell it we are unwinding.
170 if (frameInfo.handler != 0) {
171 __personality_routine p =
172 (__personality_routine)(long)(frameInfo.handler);
173 _Unwind_Action action = _UA_CLEANUP_PHASE;
174 if (sp == exception_object->private_2) {
175 // Tell personality this was the frame it marked in phase 1.
176 action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME);
178 _Unwind_Reason_Code personalityResult =
179 (*p)(1, action, exception_object->exception_class, exception_object,
180 (struct _Unwind_Context *)(&cursor2));
181 switch (personalityResult) {
182 case _URC_CONTINUE_UNWIND:
183 // Continue unwinding
184 _LIBUNWIND_TRACE_UNWINDING(
185 "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
187 if (sp == exception_object->private_2) {
188 // Phase 1 said we would stop at this frame, but we did not...
189 _LIBUNWIND_ABORT("during phase1 personality function said it would "
190 "stop here, but now in phase2 it did not stop here");
193 case _URC_INSTALL_CONTEXT:
194 _LIBUNWIND_TRACE_UNWINDING(
195 "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
197 // Personality routine says to transfer control to landing pad.
198 // We may get control back if landing pad calls _Unwind_Resume().
199 if (_LIBUNWIND_TRACING_UNWINDING) {
201 unw_get_reg(&cursor2, UNW_REG_IP, &pc);
202 unw_get_reg(&cursor2, UNW_REG_SP, &sp);
203 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
204 "user code with ip=0x%llX, sp=0x%llX\n",
205 exception_object, pc, sp);
207 unw_resume(&cursor2);
208 // unw_resume() only returns if there was an error.
209 return _URC_FATAL_PHASE2_ERROR;
211 // Personality routine returned an unknown result code.
212 _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
214 return _URC_FATAL_PHASE2_ERROR;
219 // Clean up phase did not resume at the frame that the search phase
221 return _URC_FATAL_PHASE2_ERROR;
224 static _Unwind_Reason_Code
225 unwind_phase2_forced(unw_context_t *uc,
226 _Unwind_Exception *exception_object,
227 _Unwind_Stop_Fn stop, void *stop_parameter) {
228 unw_cursor_t cursor2;
229 unw_init_local(&cursor2, uc);
231 // Walk each frame until we reach where search phase said to stop
232 while (unw_step(&cursor2) > 0) {
234 // Update info about this frame.
235 unw_proc_info_t frameInfo;
236 if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
237 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
238 "failed => _URC_END_OF_STACK\n",
240 return _URC_FATAL_PHASE2_ERROR;
243 // When tracing, print state information.
244 if (_LIBUNWIND_TRACING_UNWINDING) {
245 char functionName[512];
247 if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
248 UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
249 strcpy(functionName, ".anonymous.");
250 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
251 "start_ip=0x%llX, func=%s, lsda=0x%llX, "
252 " personality=0x%llX\n",
253 exception_object, frameInfo.start_ip,
254 functionName, frameInfo.lsda,
258 // Call stop function at each frame.
259 _Unwind_Action action =
260 (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE);
261 _Unwind_Reason_Code stopResult =
262 (*stop)(1, action, exception_object->exception_class, exception_object,
263 (struct _Unwind_Context *)(&cursor2), stop_parameter);
264 _LIBUNWIND_TRACE_UNWINDING(
265 "unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
266 exception_object, stopResult);
267 if (stopResult != _URC_NO_REASON) {
268 _LIBUNWIND_TRACE_UNWINDING(
269 "unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n",
271 return _URC_FATAL_PHASE2_ERROR;
274 // If there is a personality routine, tell it we are unwinding.
275 if (frameInfo.handler != 0) {
276 __personality_routine p =
277 (__personality_routine)(long)(frameInfo.handler);
278 _LIBUNWIND_TRACE_UNWINDING(
279 "unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n",
280 exception_object, p);
281 _Unwind_Reason_Code personalityResult =
282 (*p)(1, action, exception_object->exception_class, exception_object,
283 (struct _Unwind_Context *)(&cursor2));
284 switch (personalityResult) {
285 case _URC_CONTINUE_UNWIND:
286 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
287 "personality returned _URC_CONTINUE_UNWIND\n",
289 // Destructors called, continue unwinding
291 case _URC_INSTALL_CONTEXT:
292 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
293 "personality returned _URC_INSTALL_CONTEXT\n",
295 // We may get control back if landing pad calls _Unwind_Resume().
296 unw_resume(&cursor2);
299 // Personality routine returned an unknown result code.
300 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
301 "personality returned %d, "
302 "_URC_FATAL_PHASE2_ERROR\n",
303 exception_object, personalityResult);
304 return _URC_FATAL_PHASE2_ERROR;
309 // Call stop function one last time and tell it we've reached the end
311 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
312 "function with _UA_END_OF_STACK\n",
314 _Unwind_Action lastAction =
315 (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
316 (*stop)(1, lastAction, exception_object->exception_class, exception_object,
317 (struct _Unwind_Context *)(&cursor2), stop_parameter);
319 // Clean up phase did not resume at the frame that the search phase said it
321 return _URC_FATAL_PHASE2_ERROR;
325 /// Called by __cxa_throw. Only returns if there is a fatal error.
326 _LIBUNWIND_EXPORT _Unwind_Reason_Code
327 _Unwind_RaiseException(_Unwind_Exception *exception_object) {
328 _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
333 // Mark that this is a non-forced unwind, so _Unwind_Resume()
334 // can do the right thing.
335 exception_object->private_1 = 0;
336 exception_object->private_2 = 0;
338 // phase 1: the search phase
339 _Unwind_Reason_Code phase1 = unwind_phase1(&uc, exception_object);
340 if (phase1 != _URC_NO_REASON)
343 // phase 2: the clean up phase
344 return unwind_phase2(&uc, exception_object);
349 /// When _Unwind_RaiseException() is in phase2, it hands control
350 /// to the personality function at each frame. The personality
351 /// may force a jump to a landing pad in that function, the landing
352 /// pad code may then call _Unwind_Resume() to continue with the
353 /// unwinding. Note: the call to _Unwind_Resume() is from compiler
354 /// geneated user code. All other _Unwind_* routines are called
355 /// by the C++ runtime __cxa_* routines.
357 /// Note: re-throwing an exception (as opposed to continuing the unwind)
358 /// is implemented by having the code call __cxa_rethrow() which
359 /// in turn calls _Unwind_Resume_or_Rethrow().
360 _LIBUNWIND_EXPORT void
361 _Unwind_Resume(_Unwind_Exception *exception_object) {
362 _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
366 if (exception_object->private_1 != 0)
367 unwind_phase2_forced(&uc, exception_object,
368 (_Unwind_Stop_Fn) exception_object->private_1,
369 (void *)exception_object->private_2);
371 unwind_phase2(&uc, exception_object);
373 // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
374 _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
380 /// Unwinds stack, calling "stop" function at each frame.
381 /// Could be used to implement longjmp().
382 _LIBUNWIND_EXPORT _Unwind_Reason_Code
383 _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
384 _Unwind_Stop_Fn stop, void *stop_parameter) {
385 _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
386 exception_object, stop);
390 // Mark that this is a forced unwind, so _Unwind_Resume() can do
392 exception_object->private_1 = (uintptr_t) stop;
393 exception_object->private_2 = (uintptr_t) stop_parameter;
396 return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter);
400 /// Called by personality handler during phase 2 to get LSDA for current frame.
401 _LIBUNWIND_EXPORT uintptr_t
402 _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
403 unw_cursor_t *cursor = (unw_cursor_t *)context;
404 unw_proc_info_t frameInfo;
405 uintptr_t result = 0;
406 if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
407 result = (uintptr_t)frameInfo.lsda;
408 _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p)"
409 "=> 0x%lX\n", context, result);
411 if (*((uint8_t *)result) != 0xFF)
412 _LIBUNWIND_DEBUG_LOG("lsda at 0x%lX does not start with 0xFF\n", result);
419 /// Called by personality handler during phase 2 to get register values.
420 _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
422 unw_cursor_t *cursor = (unw_cursor_t *)context;
424 unw_get_reg(cursor, index, &result);
425 _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%llX\n",
427 index, (uint64_t) result);
428 return (uintptr_t)result;
433 /// Called by personality handler during phase 2 to alter register values.
434 _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
435 uintptr_t new_value) {
436 _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, "
437 "value=0x%0llX)\n", context,
438 index, (uint64_t) new_value);
439 unw_cursor_t *cursor = (unw_cursor_t *)context;
440 unw_set_reg(cursor, index, new_value);
445 /// Called by personality handler during phase 2 to get instruction pointer.
446 _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
447 unw_cursor_t *cursor = (unw_cursor_t *)context;
449 unw_get_reg(cursor, UNW_REG_IP, &result);
450 _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%llX\n", context,
452 return (uintptr_t)result;
457 /// Called by personality handler during phase 2 to alter instruction pointer,
458 /// such as setting where the landing pad is, so _Unwind_Resume() will
459 /// start executing in the landing pad.
460 _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
461 uintptr_t new_value) {
462 _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0llX)\n",
463 context, (uint64_t) new_value);
464 unw_cursor_t *cursor = (unw_cursor_t *)context;
465 unw_set_reg(cursor, UNW_REG_IP, new_value);
469 /// Called by personality handler during phase 2 to find the start of the
471 _LIBUNWIND_EXPORT uintptr_t
472 _Unwind_GetRegionStart(struct _Unwind_Context *context) {
473 unw_cursor_t *cursor = (unw_cursor_t *)context;
474 unw_proc_info_t frameInfo;
475 uintptr_t result = 0;
476 if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
477 result = (uintptr_t)frameInfo.start_ip;
478 _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%lX\n",
484 /// Called by personality handler during phase 2 if a foreign exception
486 _LIBUNWIND_EXPORT void
487 _Unwind_DeleteException(_Unwind_Exception *exception_object) {
488 _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
490 if (exception_object->exception_cleanup != NULL)
491 (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
495 #endif // _LIBUNWIND_BUILD_ZERO_COST_APIS && !LIBCXXABI_ARM_EHABI