xref: /aosp_15_r20/external/cronet/base/apple/call_with_eh_frame.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/apple/call_with_eh_frame.h"
6 
7 #include <stdint.h>
8 #include <unwind.h>
9 
10 namespace base::apple {
11 
12 #if defined(__x86_64__) || defined(__aarch64__)
13 extern "C" _Unwind_Reason_Code __gxx_personality_v0(int,
14                                                     _Unwind_Action,
15                                                     uint64_t,
16                                                     struct _Unwind_Exception*,
17                                                     struct _Unwind_Context*);
18 
CxxPersonalityRoutine(int version,_Unwind_Action actions,uint64_t exception_class,struct _Unwind_Exception * exception_object,struct _Unwind_Context * context)19 _Unwind_Reason_Code CxxPersonalityRoutine(
20     int version,
21     _Unwind_Action actions,
22     uint64_t exception_class,
23     struct _Unwind_Exception* exception_object,
24     struct _Unwind_Context* context) {
25   // Unwinding is a two-phase process: phase one searches for an exception
26   // handler, and phase two performs cleanup. For phase one, this custom
27   // personality will terminate the search. For phase two, this should delegate
28   // back to the standard personality routine.
29 
30   if ((actions & _UA_SEARCH_PHASE) != 0) {
31     // Tell libunwind that this is the end of the stack. When it encounters the
32     // CallWithEHFrame, it will stop searching for an exception handler. The
33     // result is that no exception handler has been found higher on the stack,
34     // and any that are lower on the stack (e.g. in CFRunLoopRunSpecific), will
35     // now be skipped. Since this is reporting the end of the stack, and no
36     // exception handler will have been found, std::terminate() will be called.
37     return _URC_END_OF_STACK;
38   }
39 
40   return __gxx_personality_v0(version, actions, exception_class,
41                               exception_object, context);
42 }
43 #else   // !defined(__x86_64__) && !defined(__aarch64__)
44 // No implementation exists, so just call the block directly.
45 void CallWithEHFrame(void (^block)(void)) {
46   block();
47 }
48 #endif  // defined(__x86_64__) || defined(__aarch64__)
49 }  // namespace base::apple
50