1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- #![allow(unused_imports)]
- use core::intrinsics;
- // NOTE These functions are implemented using assembly because they using a custom
- // calling convention which can't be implemented using a normal Rust function
- // NOTE These functions are never mangled as they are not tested against compiler-rt
- // and mangling ___chkstk would break the `jmp ___chkstk` instruction in __alloca
- #[cfg(all(
- windows,
- target_env = "gnu",
- not(feature = "no-asm"),
- not(feature = "mangled-names")
- ))]
- #[naked]
- #[no_mangle]
- pub unsafe extern "C" fn ___chkstk_ms() {
- core::arch::asm!(
- "push %ecx",
- "push %eax",
- "cmp $0x1000,%eax",
- "lea 12(%esp),%ecx",
- "jb 1f",
- "2:",
- "sub $0x1000,%ecx",
- "test %ecx,(%ecx)",
- "sub $0x1000,%eax",
- "cmp $0x1000,%eax",
- "ja 2b",
- "1:",
- "sub %eax,%ecx",
- "test %ecx,(%ecx)",
- "pop %eax",
- "pop %ecx",
- "ret",
- options(noreturn, att_syntax)
- );
- }
- // FIXME: __alloca should be an alias to __chkstk
- #[cfg(all(
- windows,
- target_env = "gnu",
- not(feature = "no-asm"),
- not(feature = "mangled-names")
- ))]
- #[naked]
- #[no_mangle]
- pub unsafe extern "C" fn __alloca() {
- core::arch::asm!(
- "jmp ___chkstk", // Jump to ___chkstk since fallthrough may be unreliable"
- options(noreturn, att_syntax)
- );
- }
- #[cfg(all(
- windows,
- target_env = "gnu",
- not(feature = "no-asm"),
- not(feature = "mangled-names")
- ))]
- #[naked]
- #[no_mangle]
- pub unsafe extern "C" fn ___chkstk() {
- core::arch::asm!(
- "push %ecx",
- "cmp $0x1000,%eax",
- "lea 8(%esp),%ecx", // esp before calling this routine -> ecx
- "jb 1f",
- "2:",
- "sub $0x1000,%ecx",
- "test %ecx,(%ecx)",
- "sub $0x1000,%eax",
- "cmp $0x1000,%eax",
- "ja 2b",
- "1:",
- "sub %eax,%ecx",
- "test %ecx,(%ecx)",
- "lea 4(%esp),%eax", // load pointer to the return address into eax
- "mov %ecx,%esp", // install the new top of stack pointer into esp
- "mov -4(%eax),%ecx", // restore ecx
- "push (%eax)", // push return address onto the stack
- "sub %esp,%eax", // restore the original value in eax
- "ret",
- options(noreturn, att_syntax)
- );
- }
|