xref: /freebsd/contrib/llvm-project/libunwind/src/UnwindLevel1.c (revision 38a52bd3b5cac3da6f7f6eef3dd050e6aa08ebb3)
1 //===----------------------------------------------------------------------===//
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 "cet_unwind.h"
29 #include "config.h"
30 #include "libunwind.h"
31 #include "libunwind_ext.h"
32 #include "unwind.h"
33 
34 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
35 
36 #ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
37 
38 // When CET is enabled, each "call" instruction will push return address to
39 // CET shadow stack, each "ret" instruction will pop current CET shadow stack
40 // top and compare it with target address which program will return.
41 // In exception handing, some stack frames will be skipped before jumping to
42 // landing pad and we must adjust CET shadow stack accordingly.
43 // _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we
44 // directly jump to __libunwind_Registerts_x86/x86_64_jumpto instead of using
45 // a regular function call to avoid pushing to CET shadow stack again.
46 #if !defined(_LIBUNWIND_USE_CET)
47 #define __unw_phase2_resume(cursor, fn) __unw_resume((cursor))
48 #elif defined(_LIBUNWIND_TARGET_I386)
49 #define __unw_phase2_resume(cursor, fn)                                        \
50   do {                                                                         \
51     _LIBUNWIND_POP_CET_SSP((fn));                                              \
52     void *cetRegContext = __libunwind_cet_get_registers((cursor));             \
53     void *cetJumpAddress = __libunwind_cet_get_jump_target();                  \
54     __asm__ volatile("push %%edi\n\t"                                          \
55                      "sub $4, %%esp\n\t"                                       \
56                      "jmp *%%edx\n\t" :: "D"(cetRegContext),                   \
57                      "d"(cetJumpAddress));                                     \
58   } while (0)
59 #elif defined(_LIBUNWIND_TARGET_X86_64)
60 #define __unw_phase2_resume(cursor, fn)                                        \
61   do {                                                                         \
62     _LIBUNWIND_POP_CET_SSP((fn));                                              \
63     void *cetRegContext = __libunwind_cet_get_registers((cursor));             \
64     void *cetJumpAddress = __libunwind_cet_get_jump_target();                  \
65     __asm__ volatile("jmpq *%%rdx\n\t" :: "D"(cetRegContext),                  \
66                      "d"(cetJumpAddress));                                     \
67   } while (0)
68 #endif
69 
70 static _Unwind_Reason_Code
71 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
72   __unw_init_local(cursor, uc);
73 
74   // Walk each frame looking for a place to stop.
75   while (true) {
76     // Ask libunwind to get next frame (skip over first which is
77     // _Unwind_RaiseException).
78     int stepResult = __unw_step(cursor);
79     if (stepResult == 0) {
80       _LIBUNWIND_TRACE_UNWINDING(
81           "unwind_phase1(ex_ojb=%p): __unw_step() reached "
82           "bottom => _URC_END_OF_STACK",
83           (void *)exception_object);
84       return _URC_END_OF_STACK;
85     } else if (stepResult < 0) {
86       _LIBUNWIND_TRACE_UNWINDING(
87           "unwind_phase1(ex_ojb=%p): __unw_step failed => "
88           "_URC_FATAL_PHASE1_ERROR",
89           (void *)exception_object);
90       return _URC_FATAL_PHASE1_ERROR;
91     }
92 
93     // See if frame has code to run (has personality routine).
94     unw_proc_info_t frameInfo;
95     unw_word_t sp;
96     if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
97       _LIBUNWIND_TRACE_UNWINDING(
98           "unwind_phase1(ex_ojb=%p): __unw_get_proc_info "
99           "failed => _URC_FATAL_PHASE1_ERROR",
100           (void *)exception_object);
101       return _URC_FATAL_PHASE1_ERROR;
102     }
103 
104 #ifndef NDEBUG
105     // When tracing, print state information.
106     if (_LIBUNWIND_TRACING_UNWINDING) {
107       char functionBuf[512];
108       const char *functionName = functionBuf;
109       unw_word_t offset;
110       if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
111                                &offset) != UNW_ESUCCESS) ||
112           (frameInfo.start_ip + offset > frameInfo.end_ip))
113         functionName = ".anonymous.";
114       unw_word_t pc;
115       __unw_get_reg(cursor, UNW_REG_IP, &pc);
116       _LIBUNWIND_TRACE_UNWINDING(
117           "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR
118           ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "",
119           (void *)exception_object, pc, frameInfo.start_ip, functionName,
120           frameInfo.lsda, frameInfo.handler);
121     }
122 #endif
123 
124     // If there is a personality routine, ask it if it will want to stop at
125     // this frame.
126     if (frameInfo.handler != 0) {
127       _Unwind_Personality_Fn p =
128           (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler);
129       _LIBUNWIND_TRACE_UNWINDING(
130           "unwind_phase1(ex_ojb=%p): calling personality function %p",
131           (void *)exception_object, (void *)(uintptr_t)p);
132       _Unwind_Reason_Code personalityResult =
133           (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
134                exception_object, (struct _Unwind_Context *)(cursor));
135       switch (personalityResult) {
136       case _URC_HANDLER_FOUND:
137         // found a catch clause or locals that need destructing in this frame
138         // stop search and remember stack pointer at the frame
139         __unw_get_reg(cursor, UNW_REG_SP, &sp);
140         exception_object->private_2 = (uintptr_t)sp;
141         _LIBUNWIND_TRACE_UNWINDING(
142             "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
143             (void *)exception_object);
144         return _URC_NO_REASON;
145 
146       case _URC_CONTINUE_UNWIND:
147         _LIBUNWIND_TRACE_UNWINDING(
148             "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
149             (void *)exception_object);
150         // continue unwinding
151         break;
152 
153       default:
154         // something went wrong
155         _LIBUNWIND_TRACE_UNWINDING(
156             "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
157             (void *)exception_object);
158         return _URC_FATAL_PHASE1_ERROR;
159       }
160     }
161   }
162   return _URC_NO_REASON;
163 }
164 
165 
166 static _Unwind_Reason_Code
167 unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
168   __unw_init_local(cursor, uc);
169 
170   _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
171                              (void *)exception_object);
172 
173   // uc is initialized by __unw_getcontext in the parent frame. The first stack
174   // frame walked is unwind_phase2.
175   unsigned framesWalked = 1;
176   // Walk each frame until we reach where search phase said to stop.
177   while (true) {
178 
179     // Ask libunwind to get next frame (skip over first which is
180     // _Unwind_RaiseException).
181     int stepResult = __unw_step(cursor);
182     if (stepResult == 0) {
183       _LIBUNWIND_TRACE_UNWINDING(
184           "unwind_phase2(ex_ojb=%p): __unw_step() reached "
185           "bottom => _URC_END_OF_STACK",
186           (void *)exception_object);
187       return _URC_END_OF_STACK;
188     } else if (stepResult < 0) {
189       _LIBUNWIND_TRACE_UNWINDING(
190           "unwind_phase2(ex_ojb=%p): __unw_step failed => "
191           "_URC_FATAL_PHASE1_ERROR",
192           (void *)exception_object);
193       return _URC_FATAL_PHASE2_ERROR;
194     }
195 
196     // Get info about this frame.
197     unw_word_t sp;
198     unw_proc_info_t frameInfo;
199     __unw_get_reg(cursor, UNW_REG_SP, &sp);
200     if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
201       _LIBUNWIND_TRACE_UNWINDING(
202           "unwind_phase2(ex_ojb=%p): __unw_get_proc_info "
203           "failed => _URC_FATAL_PHASE1_ERROR",
204           (void *)exception_object);
205       return _URC_FATAL_PHASE2_ERROR;
206     }
207 
208 #ifndef NDEBUG
209     // When tracing, print state information.
210     if (_LIBUNWIND_TRACING_UNWINDING) {
211       char functionBuf[512];
212       const char *functionName = functionBuf;
213       unw_word_t offset;
214       if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
215                                &offset) != UNW_ESUCCESS) ||
216           (frameInfo.start_ip + offset > frameInfo.end_ip))
217         functionName = ".anonymous.";
218       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR
219                                  ", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR
220                                  ", personality=0x%" PRIxPTR,
221                                  (void *)exception_object, frameInfo.start_ip,
222                                  functionName, sp, frameInfo.lsda,
223                                  frameInfo.handler);
224     }
225 #endif
226 
227     ++framesWalked;
228     // If there is a personality routine, tell it we are unwinding.
229     if (frameInfo.handler != 0) {
230       _Unwind_Personality_Fn p =
231           (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler);
232       _Unwind_Action action = _UA_CLEANUP_PHASE;
233       if (sp == exception_object->private_2) {
234         // Tell personality this was the frame it marked in phase 1.
235         action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME);
236       }
237        _Unwind_Reason_Code personalityResult =
238           (*p)(1, action, exception_object->exception_class, exception_object,
239                (struct _Unwind_Context *)(cursor));
240       switch (personalityResult) {
241       case _URC_CONTINUE_UNWIND:
242         // Continue unwinding
243         _LIBUNWIND_TRACE_UNWINDING(
244             "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
245             (void *)exception_object);
246         if (sp == exception_object->private_2) {
247           // Phase 1 said we would stop at this frame, but we did not...
248           _LIBUNWIND_ABORT("during phase1 personality function said it would "
249                            "stop here, but now in phase2 it did not stop here");
250         }
251         break;
252       case _URC_INSTALL_CONTEXT:
253         _LIBUNWIND_TRACE_UNWINDING(
254             "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
255             (void *)exception_object);
256         // Personality routine says to transfer control to landing pad.
257         // We may get control back if landing pad calls _Unwind_Resume().
258         if (_LIBUNWIND_TRACING_UNWINDING) {
259           unw_word_t pc;
260           __unw_get_reg(cursor, UNW_REG_IP, &pc);
261           __unw_get_reg(cursor, UNW_REG_SP, &sp);
262           _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
263                                      "user code with ip=0x%" PRIxPTR
264                                      ", sp=0x%" PRIxPTR,
265                                      (void *)exception_object, pc, sp);
266         }
267 
268         __unw_phase2_resume(cursor, framesWalked);
269         // __unw_phase2_resume() only returns if there was an error.
270         return _URC_FATAL_PHASE2_ERROR;
271       default:
272         // Personality routine returned an unknown result code.
273         _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
274                              personalityResult);
275         return _URC_FATAL_PHASE2_ERROR;
276       }
277     }
278   }
279 
280   // Clean up phase did not resume at the frame that the search phase
281   // said it would...
282   return _URC_FATAL_PHASE2_ERROR;
283 }
284 
285 static _Unwind_Reason_Code
286 unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
287                      _Unwind_Exception *exception_object,
288                      _Unwind_Stop_Fn stop, void *stop_parameter) {
289   __unw_init_local(cursor, uc);
290 
291   // uc is initialized by __unw_getcontext in the parent frame. The first stack
292   // frame walked is unwind_phase2_forced.
293   unsigned framesWalked = 1;
294   // Walk each frame until we reach where search phase said to stop
295   while (__unw_step(cursor) > 0) {
296 
297     // Update info about this frame.
298     unw_proc_info_t frameInfo;
299     if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
300       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
301                                  "failed => _URC_END_OF_STACK",
302                                  (void *)exception_object);
303       return _URC_FATAL_PHASE2_ERROR;
304     }
305 
306 #ifndef NDEBUG
307     // When tracing, print state information.
308     if (_LIBUNWIND_TRACING_UNWINDING) {
309       char functionBuf[512];
310       const char *functionName = functionBuf;
311       unw_word_t offset;
312       if ((__unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
313                                &offset) != UNW_ESUCCESS) ||
314           (frameInfo.start_ip + offset > frameInfo.end_ip))
315         functionName = ".anonymous.";
316       _LIBUNWIND_TRACE_UNWINDING(
317           "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR
318           ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
319           (void *)exception_object, frameInfo.start_ip, functionName,
320           frameInfo.lsda, frameInfo.handler);
321     }
322 #endif
323 
324     // Call stop function at each frame.
325     _Unwind_Action action =
326         (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE);
327     _Unwind_Reason_Code stopResult =
328         (*stop)(1, action, exception_object->exception_class, exception_object,
329                 (struct _Unwind_Context *)(cursor), stop_parameter);
330     _LIBUNWIND_TRACE_UNWINDING(
331         "unwind_phase2_forced(ex_ojb=%p): stop function returned %d",
332         (void *)exception_object, stopResult);
333     if (stopResult != _URC_NO_REASON) {
334       _LIBUNWIND_TRACE_UNWINDING(
335           "unwind_phase2_forced(ex_ojb=%p): stopped by stop function",
336           (void *)exception_object);
337       return _URC_FATAL_PHASE2_ERROR;
338     }
339 
340     ++framesWalked;
341     // If there is a personality routine, tell it we are unwinding.
342     if (frameInfo.handler != 0) {
343       _Unwind_Personality_Fn p =
344           (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler);
345       _LIBUNWIND_TRACE_UNWINDING(
346           "unwind_phase2_forced(ex_ojb=%p): calling personality function %p",
347           (void *)exception_object, (void *)(uintptr_t)p);
348       _Unwind_Reason_Code personalityResult =
349           (*p)(1, action, exception_object->exception_class, exception_object,
350                (struct _Unwind_Context *)(cursor));
351       switch (personalityResult) {
352       case _URC_CONTINUE_UNWIND:
353         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
354                                    "personality returned "
355                                    "_URC_CONTINUE_UNWIND",
356                                    (void *)exception_object);
357         // Destructors called, continue unwinding
358         break;
359       case _URC_INSTALL_CONTEXT:
360         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
361                                    "personality returned "
362                                    "_URC_INSTALL_CONTEXT",
363                                    (void *)exception_object);
364         // We may get control back if landing pad calls _Unwind_Resume().
365         __unw_phase2_resume(cursor, framesWalked);
366         break;
367       default:
368         // Personality routine returned an unknown result code.
369         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
370                                    "personality returned %d, "
371                                    "_URC_FATAL_PHASE2_ERROR",
372                                    (void *)exception_object, personalityResult);
373         return _URC_FATAL_PHASE2_ERROR;
374       }
375     }
376   }
377 
378   // Call stop function one last time and tell it we've reached the end
379   // of the stack.
380   _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
381                              "function with _UA_END_OF_STACK",
382                              (void *)exception_object);
383   _Unwind_Action lastAction =
384       (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
385   (*stop)(1, lastAction, exception_object->exception_class, exception_object,
386           (struct _Unwind_Context *)(cursor), stop_parameter);
387 
388   // Clean up phase did not resume at the frame that the search phase said it
389   // would.
390   return _URC_FATAL_PHASE2_ERROR;
391 }
392 
393 
394 /// Called by __cxa_throw.  Only returns if there is a fatal error.
395 _LIBUNWIND_EXPORT _Unwind_Reason_Code
396 _Unwind_RaiseException(_Unwind_Exception *exception_object) {
397   _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
398                        (void *)exception_object);
399   unw_context_t uc;
400   unw_cursor_t cursor;
401   __unw_getcontext(&uc);
402 
403   // Mark that this is a non-forced unwind, so _Unwind_Resume()
404   // can do the right thing.
405   exception_object->private_1 = 0;
406   exception_object->private_2 = 0;
407 
408   // phase 1: the search phase
409   _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object);
410   if (phase1 != _URC_NO_REASON)
411     return phase1;
412 
413   // phase 2: the clean up phase
414   return unwind_phase2(&uc, &cursor, exception_object);
415 }
416 
417 
418 
419 /// When _Unwind_RaiseException() is in phase2, it hands control
420 /// to the personality function at each frame.  The personality
421 /// may force a jump to a landing pad in that function, the landing
422 /// pad code may then call _Unwind_Resume() to continue with the
423 /// unwinding.  Note: the call to _Unwind_Resume() is from compiler
424 /// geneated user code.  All other _Unwind_* routines are called
425 /// by the C++ runtime __cxa_* routines.
426 ///
427 /// Note: re-throwing an exception (as opposed to continuing the unwind)
428 /// is implemented by having the code call __cxa_rethrow() which
429 /// in turn calls _Unwind_Resume_or_Rethrow().
430 _LIBUNWIND_EXPORT void
431 _Unwind_Resume(_Unwind_Exception *exception_object) {
432   _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object);
433   unw_context_t uc;
434   unw_cursor_t cursor;
435   __unw_getcontext(&uc);
436 
437   if (exception_object->private_1 != 0)
438     unwind_phase2_forced(&uc, &cursor, exception_object,
439                          (_Unwind_Stop_Fn) exception_object->private_1,
440                          (void *)exception_object->private_2);
441   else
442     unwind_phase2(&uc, &cursor, exception_object);
443 
444   // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
445   _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
446 }
447 
448 
449 
450 /// Not used by C++.
451 /// Unwinds stack, calling "stop" function at each frame.
452 /// Could be used to implement longjmp().
453 _LIBUNWIND_EXPORT _Unwind_Reason_Code
454 _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
455                      _Unwind_Stop_Fn stop, void *stop_parameter) {
456   _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)",
457                        (void *)exception_object, (void *)(uintptr_t)stop);
458   unw_context_t uc;
459   unw_cursor_t cursor;
460   __unw_getcontext(&uc);
461 
462   // Mark that this is a forced unwind, so _Unwind_Resume() can do
463   // the right thing.
464   exception_object->private_1 = (uintptr_t) stop;
465   exception_object->private_2 = (uintptr_t) stop_parameter;
466 
467   // do it
468   return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter);
469 }
470 
471 
472 /// Called by personality handler during phase 2 to get LSDA for current frame.
473 _LIBUNWIND_EXPORT uintptr_t
474 _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
475   unw_cursor_t *cursor = (unw_cursor_t *)context;
476   unw_proc_info_t frameInfo;
477   uintptr_t result = 0;
478   if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
479     result = (uintptr_t)frameInfo.lsda;
480   _LIBUNWIND_TRACE_API(
481       "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR,
482       (void *)context, result);
483   if (result != 0) {
484     if (*((uint8_t *)result) != 0xFF)
485       _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF",
486                            result);
487   }
488   return result;
489 }
490 
491 
492 /// Called by personality handler during phase 2 to find the start of the
493 /// function.
494 _LIBUNWIND_EXPORT uintptr_t
495 _Unwind_GetRegionStart(struct _Unwind_Context *context) {
496   unw_cursor_t *cursor = (unw_cursor_t *)context;
497   unw_proc_info_t frameInfo;
498   uintptr_t result = 0;
499   if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
500     result = (uintptr_t)frameInfo.start_ip;
501   _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR,
502                        (void *)context, result);
503   return result;
504 }
505 
506 #endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
507 
508 /// Called by personality handler during phase 2 if a foreign exception
509 // is caught.
510 _LIBUNWIND_EXPORT void
511 _Unwind_DeleteException(_Unwind_Exception *exception_object) {
512   _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
513                        (void *)exception_object);
514   if (exception_object->exception_cleanup != NULL)
515     (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
516                                            exception_object);
517 }
518 
519 /// Called by personality handler during phase 2 to get register values.
520 _LIBUNWIND_EXPORT uintptr_t
521 _Unwind_GetGR(struct _Unwind_Context *context, int index) {
522   unw_cursor_t *cursor = (unw_cursor_t *)context;
523   unw_word_t result;
524   __unw_get_reg(cursor, index, &result);
525   _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIxPTR,
526                        (void *)context, index, result);
527   return (uintptr_t)result;
528 }
529 
530 /// Called by personality handler during phase 2 to alter register values.
531 _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
532                                      uintptr_t value) {
533   _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIxPTR
534                        ")",
535                        (void *)context, index, value);
536   unw_cursor_t *cursor = (unw_cursor_t *)context;
537   __unw_set_reg(cursor, index, value);
538 }
539 
540 /// Called by personality handler during phase 2 to get instruction pointer.
541 _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
542   unw_cursor_t *cursor = (unw_cursor_t *)context;
543   unw_word_t result;
544   __unw_get_reg(cursor, UNW_REG_IP, &result);
545   _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR,
546                        (void *)context, result);
547   return (uintptr_t)result;
548 }
549 
550 /// Called by personality handler during phase 2 to alter instruction pointer,
551 /// such as setting where the landing pad is, so _Unwind_Resume() will
552 /// start executing in the landing pad.
553 _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
554                                      uintptr_t value) {
555   _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")",
556                        (void *)context, value);
557   unw_cursor_t *cursor = (unw_cursor_t *)context;
558   __unw_set_reg(cursor, UNW_REG_IP, value);
559 }
560 
561 #endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
562