1
Fork 0

Fix MinGW termination callbacks not being invoked

This commit is contained in:
Amanieu d'Antras 2020-03-05 14:34:25 +00:00
parent 8e3467c215
commit 04f24b7c69

View file

@ -60,37 +60,36 @@ pub mod eh_frames {
} }
// Unwind info registration/deregistration routines. // Unwind info registration/deregistration routines.
// See the docs of `unwind` module in libstd. // See the docs of libpanic_unwind.
extern "C" { extern "C" {
fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8); fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8);
fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8); fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8);
} }
unsafe fn init() { unsafe extern "C" fn init() {
// register unwind info on module startup // register unwind info on module startup
rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8); rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
} }
unsafe fn uninit() { unsafe extern "C" fn uninit() {
// unregister on shutdown // unregister on shutdown
rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8); rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8);
} }
// MSVC-specific init/uninit routine registration // MinGW-specific init/uninit routine registration
pub mod ms_init { pub mod mingw_init {
// .CRT$X?? sections are roughly analogous to ELF's .init_array and .fini_array, // MinGW's startup objects (crt0.o / dllcrt0.o) will invoke global constructors in the
// except that they exploit the fact that linker will sort them alphabitically, // .ctors and .dtors sections on startup and exit. In the case of DLLs, this is done when
// so e.g., sections with names between .CRT$XIA and .CRT$XIZ are guaranteed to be // the DLL is loaded and unloaded.
// placed between those two, without requiring any ordering of objects on the linker //
// command line. // The linker will sort the sections, which ensures that our callbacks are located at the
// Note that ordering of same-named sections from different objects is not guaranteed. // end of the list. Since constructors are run in reverse order, this ensures that our
// Since .CRT$XIA contains init array's header symbol, which must always come first, // callbacks are the first and last ones executed.
// we place our initialization callback into .CRT$XIB.
#[link_section = ".CRT$XIB"] // .CRT$XI? : C initialization callbacks #[link_section = ".ctors.65535"] // .ctors.* : C initialization callbacks
pub static P_INIT: unsafe fn() = super::init; pub static P_INIT: unsafe extern "C" fn() = super::init;
#[link_section = ".CRT$XTY"] // .CRT$XT? : C termination callbacks #[link_section = ".dtors.65535"] // .dtors.* : C termination callbacks
pub static P_UNINIT: unsafe fn() = super::uninit; pub static P_UNINIT: unsafe extern "C" fn() = super::uninit;
} }
} }