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