|
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", target_os = "hurd"))] |
| 16 | +// FIXME: The Rust compiler currently omits weakly function definitions (i.e., |
| 17 | +// __cxa_thread_atexit_impl) and its metadata from LLVM IR. |
| 18 | +#[no_sanitize(cfi, kcfi)] |
15 | 19 | pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { |
16 | 20 | use crate::mem; |
17 | 21 | use crate::sys_common::thread_local_dtor::register_dtor_fallback; |
18 | 22 |
|
| 23 | + /// This is necessary because the __cxa_thread_atexit_impl implementation |
| 24 | + /// std links to by default may be a C or C++ implementation that was not |
| 25 | + /// compiled using the Clang integer normalization option. |
| 26 | + #[cfg(not(sanitizer_cfi_normalize_integers))] |
| 27 | + #[cfi_encoding = "i"] |
| 28 | + #[repr(transparent)] |
| 29 | + pub struct c_int(pub libc::c_int); |
| 30 | + |
19 | 31 | extern "C" { |
20 | 32 | #[linkage = "extern_weak"] |
21 | 33 | static __dso_handle: *mut u8; |
22 | 34 | #[linkage = "extern_weak"] |
23 | | - static __cxa_thread_atexit_impl: *const libc::c_void; |
| 35 | + static __cxa_thread_atexit_impl: Option< |
| 36 | + extern "C" fn( |
| 37 | + unsafe extern "C" fn(*mut libc::c_void), |
| 38 | + *mut libc::c_void, |
| 39 | + *mut libc::c_void, |
| 40 | + ) -> c_int, |
| 41 | + >; |
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 let Some(f) = __cxa_thread_atexit_impl { |
| 45 | + unsafe { |
| 46 | + f( |
| 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