void pthread_cancel_init (void) { void *resume, *personality, *forcedunwind, *getcfa; void *handle; if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) return; handle = __libc_dlopen ("libgcc_s.so.1"); if (handle == NULL || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind")) == NULL || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL #ifdef ARCH_CANCEL_INIT || ARCH_CANCEL_INIT (handle) #endif ) __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); libgcc_s_resume = resume; libgcc_s_personality = personality; libgcc_s_forcedunwind = forcedunwind; libgcc_s_getcfa = getcfa; }
void __attribute_noinline__ pthread_cancel_init (void) { void *resume; void *personality; void *forcedunwind; void *getcfa; void *handle; if (__builtin_expect (libgcc_s_handle != NULL, 1)) { /* Force gcc to reload all values. */ asm volatile ("" ::: "memory"); return; } handle = __libc_dlopen (LIBGCC_S_SO); if (handle == NULL || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind")) == NULL || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL #ifdef ARCH_CANCEL_INIT || ARCH_CANCEL_INIT (handle) #endif ) __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); PTR_MANGLE (resume); libgcc_s_resume = resume; PTR_MANGLE (personality); libgcc_s_personality = personality; PTR_MANGLE (forcedunwind); libgcc_s_forcedunwind = forcedunwind; PTR_MANGLE (getcfa); libgcc_s_getcfa = getcfa; /* Make sure libgcc_s_handle is written last. Otherwise, pthread_cancel_init might return early even when the pointer the caller is interested in is not initialized yet. */ atomic_write_barrier (); libgcc_s_handle = handle; }