Fix MinGW termination callbacks not being invoked
This commit is contained in:
parent
8e3467c215
commit
04f24b7c69
1 changed files with 16 additions and 17 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue