|
1 |
| -/// Hook into .init_array to enable LSE atomic operations at startup, if |
2 |
| -/// supported. |
3 |
| -#[cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "compiler-builtins-c")))] |
| 1 | +/// Enable LSE atomic operations at startup, if supported. |
| 2 | +/// |
| 3 | +/// Linker sections are based on what [`ctor`] does, with priorities to run slightly before user |
| 4 | +/// code: |
| 5 | +/// |
| 6 | +/// - Apple uses the section `__mod_init_func`, `mod_init_funcs` is needed to set |
| 7 | +/// `S_MOD_INIT_FUNC_POINTERS`. There doesn't seem to be a way to indicate priorities. |
| 8 | +/// - Windows uses `.CRT$XCT`, which is run before user constructors (these should use `.CRT$XCU`). |
| 9 | +/// - ELF uses `.init_array` with a priority of 90, which runs before our `ARGV_INIT_ARRAY` |
| 10 | +/// initializer (priority 99). Both are within the 0-100 implementation-reserved range, per docs |
| 11 | +/// for the [`prio-ctor-dtor`] warning, and this matches compiler-rt's `CONSTRUCTOR_PRIORITY`. |
| 12 | +/// |
| 13 | +/// To save startup time, the initializer is only run if outline atomic routines from |
| 14 | +/// compiler-builtins may be used. If LSE is known to be available then the calls are never |
| 15 | +/// emitted, and if we build the C intrinsics then it has its own initializer using the symbol |
| 16 | +/// `__aarch64_have_lse_atomics`. |
| 17 | +/// |
| 18 | +/// [`ctor`]: https://github.com/mmastrac/rust-ctor/blob/63382b833ddcbfb8b064f4e86bfa1ed4026ff356/shared/src/macros/mod.rs#L522-L534 |
| 19 | +/// [`prio-ctor-dtor`]: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html |
| 20 | +#[cfg(all( |
| 21 | + target_arch = "aarch64", |
| 22 | + target_feature = "outline-atomics", |
| 23 | + not(target_feature = "lse"), |
| 24 | + not(feature = "compiler-builtins-c"), |
| 25 | +))] |
4 | 26 | #[used]
|
5 |
| -#[unsafe(link_section = ".init_array.90")] |
| 27 | +#[cfg_attr(target_vendor = "apple", unsafe(link_section = "__DATA,__mod_init_func,mod_init_funcs"))] |
| 28 | +#[cfg_attr(target_os = "windows", unsafe(link_section = ".CRT$XCT"))] |
| 29 | +#[cfg_attr( |
| 30 | + not(any(target_vendor = "apple", target_os = "windows")), |
| 31 | + unsafe(link_section = ".init_array.90") |
| 32 | +)] |
6 | 33 | static RUST_LSE_INIT: extern "C" fn() = {
|
7 | 34 | extern "C" fn init_lse() {
|
8 | 35 | use crate::arch;
|
|
0 commit comments