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