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 19 extern "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" 25 struct 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 37 struct 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 _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 // 86 NOT_HERE_BEFORE_10_6(_Unwind_DeleteException) 87 NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE) 88 NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind) 89 NOT_HERE_BEFORE_10_6(_Unwind_GetGR) 90 NOT_HERE_BEFORE_10_6(_Unwind_GetIP) 91 NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData) 92 NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart) 93 NOT_HERE_BEFORE_10_6(_Unwind_RaiseException) 94 NOT_HERE_BEFORE_10_6(_Unwind_Resume) 95 NOT_HERE_BEFORE_10_6(_Unwind_SetGR) 96 NOT_HERE_BEFORE_10_6(_Unwind_SetIP) 97 NOT_HERE_BEFORE_10_6(_Unwind_Backtrace) 98 NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction) 99 NOT_HERE_BEFORE_10_6(_Unwind_GetCFA) 100 NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase) 101 NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase) 102 NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow) 103 NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) 104 NOT_HERE_BEFORE_10_6(__register_frame) 105 NOT_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 // 111 NEVER_HERE(__register_frame_info_bases) 112 NEVER_HERE(__register_frame_info) 113 NEVER_HERE(__register_frame_info_table_bases) 114 NEVER_HERE(__register_frame_info_table) 115 NEVER_HERE(__register_frame_table) 116 NEVER_HERE(__deregister_frame_info) 117 NEVER_HERE(__deregister_frame_info_bases) 118 119 #endif // _LIBUNWIND_BUILD_ZERO_COST_APIS 120 121 122 123 124 #if _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 // 129 NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData) 130 NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart) 131 NOT_HERE_BEFORE_5_0(_Unwind_GetIP) 132 NOT_HERE_BEFORE_5_0(_Unwind_SetGR) 133 NOT_HERE_BEFORE_5_0(_Unwind_SetIP) 134 NOT_HERE_BEFORE_5_0(_Unwind_DeleteException) 135 NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register) 136 NOT_HERE_BEFORE_5_0(_Unwind_GetGR) 137 NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) 138 NOT_HERE_BEFORE_5_0(_Unwind_GetCFA) 139 NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume) 140 NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException) 141 NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow) 142 NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister) 143 144 #endif // _LIBUNWIND_BUILD_SJLJ_APIS 145 146 147 namespace libunwind { 148 149 _LIBUNWIND_HIDDEN 150 bool 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) && _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 197 struct _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 207 void __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