Skip to content

Commit 04f24b7

Browse files
committed
Fix MinGW termination callbacks not being invoked
1 parent 8e3467c commit 04f24b7

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

src/rtstartup/rsbegin.rs

+16-17
Original file line numberDiff line numberDiff line change
@@ -60,37 +60,36 @@ pub mod eh_frames {
6060
}
6161

6262
// Unwind info registration/deregistration routines.
63-
// See the docs of `unwind` module in libstd.
63+
// See the docs of libpanic_unwind.
6464
extern "C" {
6565
fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8);
6666
fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8);
6767
}
6868

69-
unsafe fn init() {
69+
unsafe extern "C" fn init() {
7070
// register unwind info on module startup
7171
rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
7272
}
7373

74-
unsafe fn uninit() {
74+
unsafe extern "C" fn uninit() {
7575
// unregister on shutdown
7676
rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
7777
}
7878

79-
// MSVC-specific init/uninit routine registration
80-
pub mod ms_init {
81-
// .CRT$X?? sections are roughly analogous to ELF's .init_array and .fini_array,
82-
// except that they exploit the fact that linker will sort them alphabitically,
83-
// so e.g., sections with names between .CRT$XIA and .CRT$XIZ are guaranteed to be
84-
// placed between those two, without requiring any ordering of objects on the linker
85-
// command line.
86-
// Note that ordering of same-named sections from different objects is not guaranteed.
87-
// Since .CRT$XIA contains init array's header symbol, which must always come first,
88-
// we place our initialization callback into .CRT$XIB.
79+
// MinGW-specific init/uninit routine registration
80+
pub mod mingw_init {
81+
// MinGW's startup objects (crt0.o / dllcrt0.o) will invoke global constructors in the
82+
// .ctors and .dtors sections on startup and exit. In the case of DLLs, this is done when
83+
// the DLL is loaded and unloaded.
84+
//
85+
// The linker will sort the sections, which ensures that our callbacks are located at the
86+
// end of the list. Since constructors are run in reverse order, this ensures that our
87+
// callbacks are the first and last ones executed.
8988

90-
#[link_section = ".CRT$XIB"] // .CRT$XI? : C initialization callbacks
91-
pub static P_INIT: unsafe fn() = super::init;
89+
#[link_section = ".ctors.65535"] // .ctors.* : C initialization callbacks
90+
pub static P_INIT: unsafe extern "C" fn() = super::init;
9291

93-
#[link_section = ".CRT$XTY"] // .CRT$XT? : C termination callbacks
94-
pub static P_UNINIT: unsafe fn() = super::uninit;
92+
#[link_section = ".dtors.65535"] // .dtors.* : C termination callbacks
93+
pub static P_UNINIT: unsafe extern "C" fn() = super::uninit;
9594
}
9695
}

0 commit comments

Comments
 (0)