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