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
27
static _Unwind_Reason_Code
28
unwind_phase1(unw_context_t *uc, struct _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, struct _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 if 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
struct _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_PHASE1_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(struct _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(struct _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(struct _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(struct _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