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