31
31
//! The mechanism of registering a static initializer with the CRT is
32
32
//! documented in
33
33
//! [CRT Initialization](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-160).
34
- //! It works by contributing a global symbol to the `.CRT$XCU ` section.
34
+ //! It works by contributing a global symbol to the `.CRT$XIU ` section.
35
35
//! The linker builds a table of all static initializer functions.
36
36
//! The CRT startup code then iterates that table, calling each
37
37
//! initializer function.
38
38
//!
39
+ //! This originally used the C++ initializer section `.CRT$XCU`. However, this
40
+ //! risks being run after user code that inserts their own initializers.
41
+ //! Instead the C initializer section `CRT$XIU` is used. Function placed here
42
+ //! are run earlier than the C++ initializers.
43
+ //!
39
44
//! # **WARNING!!*
40
45
//! The environment that a static initializer function runs in is highly
41
46
//! constrained. There are **many** restrictions on what static initializers
49
54
//! * call any Rust function or CRT function that touches any static
50
55
//! (global) state.
51
56
52
- use crate :: ffi:: { c_void, CStr } ;
57
+ use crate :: ffi:: { c_int , c_void, CStr } ;
53
58
use crate :: ptr:: NonNull ;
54
59
use crate :: sys:: c;
55
60
@@ -86,8 +91,8 @@ pub(crate) const fn const_cstr_from_bytes(bytes: &'static [u8]) -> &'static CStr
86
91
}
87
92
88
93
#[ used]
89
- #[ link_section = ".CRT$XCU " ]
90
- static INIT_TABLE_ENTRY : unsafe extern "C" fn ( ) = init;
94
+ #[ link_section = ".CRT$XIU " ]
95
+ static INIT_TABLE_ENTRY : unsafe extern "C" fn ( ) -> c_int = init;
91
96
92
97
/// This is where the magic preloading of symbols happens.
93
98
///
@@ -96,7 +101,7 @@ static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
96
101
///
97
102
/// Therefore, this is limited to `compat_fn_optional` functions which must be
98
103
/// preloaded and any functions which may be more time sensitive, even for the first call.
99
- unsafe extern "C" fn init ( ) {
104
+ unsafe extern "C" fn init ( ) -> c_int {
100
105
// There is no locking here. This code is executed before main() is entered, and
101
106
// is guaranteed to be single-threaded.
102
107
//
@@ -116,6 +121,9 @@ unsafe extern "C" fn init() {
116
121
// Preloading this means getting a precise time will be as fast as possible.
117
122
c:: GetSystemTimePreciseAsFileTime :: preload ( kernel32) ;
118
123
}
124
+
125
+ // Returns zero for success and non-zero for error.
126
+ 0
119
127
}
120
128
121
129
/// Represents a loaded module.
0 commit comments