|
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