|
11 | 11 | // Note, however, that we run on lots older linuxes, as well as cross
|
12 | 12 | // compiling from a newer linux to an older linux, so we also have a
|
13 | 13 | // fallback implementation to use as well.
|
| 14 | +#[allow(unexpected_cfgs)] |
14 | 15 | #[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox"))]
|
15 | 16 | pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
16 | 17 | use crate::mem;
|
17 | 18 | use crate::sys_common::thread_local_dtor::register_dtor_fallback;
|
18 | 19 |
|
| 20 | + /// This is necessary because the __cxa_thread_atexit_impl implementation |
| 21 | + /// std links to by default may be a C or C++ implementation that was not |
| 22 | + /// compiled using the Clang integer normalization option. |
| 23 | + #[cfg(not(sanitizer_cfi_normalize_integers))] |
| 24 | + #[cfi_encoding = "i"] |
| 25 | + #[repr(transparent)] |
| 26 | + pub struct c_int(pub libc::c_int); |
| 27 | + |
19 | 28 | extern "C" {
|
20 | 29 | #[linkage = "extern_weak"]
|
21 | 30 | static __dso_handle: *mut u8;
|
22 | 31 | #[linkage = "extern_weak"]
|
23 |
| - static __cxa_thread_atexit_impl: *const libc::c_void; |
| 32 | + fn __cxa_thread_atexit_impl( |
| 33 | + dtor: unsafe extern "C" fn(*mut libc::c_void), |
| 34 | + arg: *mut libc::c_void, |
| 35 | + dso_handle: *mut libc::c_void, |
| 36 | + ) -> c_int; |
| 37 | + } |
| 38 | + |
| 39 | + // __cxa_thread_atexit_impl may be null because of the extern_weak linkage |
| 40 | + fn is_null(f: *mut libc::c_void) -> bool { |
| 41 | + f.is_null() |
24 | 42 | }
|
25 |
| - if !__cxa_thread_atexit_impl.is_null() { |
26 |
| - type F = unsafe extern "C" fn( |
27 |
| - dtor: unsafe extern "C" fn(*mut u8), |
28 |
| - arg: *mut u8, |
29 |
| - dso_handle: *mut u8, |
30 |
| - ) -> libc::c_int; |
31 |
| - mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)( |
32 |
| - dtor, |
33 |
| - t, |
34 |
| - &__dso_handle as *const _ as *mut _, |
35 |
| - ); |
| 43 | + |
| 44 | + if !is_null(__cxa_thread_atexit_impl as *mut libc::c_void) { |
| 45 | + unsafe { |
| 46 | + __cxa_thread_atexit_impl( |
| 47 | + mem::transmute::< |
| 48 | + unsafe extern "C" fn(*mut u8), |
| 49 | + unsafe extern "C" fn(*mut libc::c_void), |
| 50 | + >(dtor), |
| 51 | + t.cast(), |
| 52 | + &__dso_handle as *const _ as *mut _, |
| 53 | + ); |
| 54 | + } |
36 | 55 | return;
|
37 | 56 | }
|
38 | 57 | register_dtor_fallback(t, dtor);
|
|
0 commit comments