1//===--------------------- Unwind_AppleExtras.cpp -------------------------===// 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//===----------------------------------------------------------------------===// 10 11#include "config.h" 12#include "AddressSpace.hpp" 13#include "DwarfParser.hpp" 14#include "unwind_ext.h" 15 16 17// private keymgr stuff 18#define KEYMGR_GCC3_DW2_OBJ_LIST 302 19extern "C" { 20 extern void _keymgr_set_and_unlock_processwide_ptr(int key, void *ptr); 21 extern void *_keymgr_get_and_lock_processwide_ptr(int key); 22} 23 24// undocumented libgcc "struct object" 25struct libgcc_object { 26 void *start; 27 void *unused1; 28 void *unused2; 29 void *fde; 30 unsigned long encoding; 31 void *fde_end; 32 libgcc_object *next; 33}; 34 35// undocumented libgcc "struct km_object_info" referenced by 36// KEYMGR_GCC3_DW2_OBJ_LIST 37struct libgcc_object_info { 38 libgcc_object *seen_objects; 39 libgcc_object *unseen_objects; 40 unsigned spare[2]; 41}; 42 43 44// static linker symbols to prevent wrong two level namespace for _Unwind symbols 45#if defined(__arm__) 46 #define NOT_HERE_BEFORE_5_0(sym) \ 47 extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \ 48 __attribute__((visibility("default"))) const char sym##_tmp30 = 0; \ 49 extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \ 50 __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \ 51 extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\ 52 __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \ 53 extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \ 54 __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \ 55 extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \ 56 __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \ 57 extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \ 58 __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \ 59 extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \ 60 __attribute__((visibility("default"))) const char sym##_tmp43 = 0; 61#elif defined(__arm64__) 62 #define NOT_HERE_BEFORE_10_6(sym) 63 #define NEVER_HERE(sym) 64#else 65 #define NOT_HERE_BEFORE_10_6(sym) \ 66 extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ 67 __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ 68 extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ 69 __attribute__((visibility("default"))) const char sym##_tmp5 = 0; 70 #define NEVER_HERE(sym) \ 71 extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ 72 __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ 73 extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ 74 __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \ 75 extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \ 76 __attribute__((visibility("default"))) const char sym##_tmp6 = 0; 77#endif 78 79 80#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) 81 82// 83// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in 84// earlier versions 85// 86NOT_HERE_BEFORE_10_6(_Unwind_DeleteException) 87NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE) 88NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind) 89NOT_HERE_BEFORE_10_6(_Unwind_GetGR) 90NOT_HERE_BEFORE_10_6(_Unwind_GetIP) 91NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData) 92NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart) 93NOT_HERE_BEFORE_10_6(_Unwind_RaiseException) 94NOT_HERE_BEFORE_10_6(_Unwind_Resume) 95NOT_HERE_BEFORE_10_6(_Unwind_SetGR) 96NOT_HERE_BEFORE_10_6(_Unwind_SetIP) 97NOT_HERE_BEFORE_10_6(_Unwind_Backtrace) 98NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction) 99NOT_HERE_BEFORE_10_6(_Unwind_GetCFA) 100NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase) 101NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase) 102NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow) 103NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) 104NOT_HERE_BEFORE_10_6(__register_frame) 105NOT_HERE_BEFORE_10_6(__deregister_frame) 106 107// 108// symbols in libSystem.dylib for compatibility, but we don't want any new code 109// using them 110// 111NEVER_HERE(__register_frame_info_bases) 112NEVER_HERE(__register_frame_info) 113NEVER_HERE(__register_frame_info_table_bases) 114NEVER_HERE(__register_frame_info_table) 115NEVER_HERE(__register_frame_table) 116NEVER_HERE(__deregister_frame_info) 117NEVER_HERE(__deregister_frame_info_bases) 118 119#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) 120 121 122 123 124#if defined(_LIBUNWIND_BUILD_SJLJ_APIS) 125// 126// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in 127// earlier versions 128// 129NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData) 130NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart) 131NOT_HERE_BEFORE_5_0(_Unwind_GetIP) 132NOT_HERE_BEFORE_5_0(_Unwind_SetGR) 133NOT_HERE_BEFORE_5_0(_Unwind_SetIP) 134NOT_HERE_BEFORE_5_0(_Unwind_DeleteException) 135NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register) 136NOT_HERE_BEFORE_5_0(_Unwind_GetGR) 137NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) 138NOT_HERE_BEFORE_5_0(_Unwind_GetCFA) 139NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume) 140NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException) 141NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow) 142NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister) 143 144#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) 145 146 147namespace libunwind { 148 149_LIBUNWIND_HIDDEN 150bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) { 151#if __MAC_OS_X_VERSION_MIN_REQUIRED 152 // lastly check for old style keymgr registration of dynamically generated 153 // FDEs acquire exclusive access to libgcc_object_info 154 libgcc_object_info *head = (libgcc_object_info *) 155 _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); 156 if (head != NULL) { 157 // look at each FDE in keymgr 158 for (libgcc_object *ob = head->unseen_objects; ob != NULL; ob = ob->next) { 159 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; 160 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; 161 const char *msg = CFI_Parser<LocalAddressSpace>::decodeFDE( 162 LocalAddressSpace::sThisAddressSpace, 163 (uintptr_t)ob->fde, &fdeInfo, &cieInfo); 164 if (msg == NULL) { 165 // Check if this FDE is for a function that includes the pc 166 if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) { 167 fde = (void*)fdeInfo.pcStart; 168 _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, 169 head); 170 return true; 171 } 172 } 173 } 174 } 175 // release libgcc_object_info 176 _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head); 177#else 178 (void)pc; 179 (void)fde; 180#endif 181 return false; 182} 183 184} 185 186 187#if !defined(FOR_DYLD) && defined(_LIBUNWIND_BUILD_SJLJ_APIS) 188 189#ifndef _LIBUNWIND_HAS_NO_THREADS 190 #include <System/pthread_machdep.h> 191#else 192 _Unwind_FunctionContext *fc_ = nullptr; 193#endif 194 195// Accessors to get get/set linked list of frames for sjlj based execeptions. 196_LIBUNWIND_HIDDEN 197struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() { 198#ifndef _LIBUNWIND_HAS_NO_THREADS 199 return (struct _Unwind_FunctionContext *) 200 _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key); 201#else 202 return fc_; 203#endif 204} 205 206_LIBUNWIND_HIDDEN 207void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) { 208#ifndef _LIBUNWIND_HAS_NO_THREADS 209 _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc); 210#else 211 fc_ = fc; 212#endif 213} 214#endif 215