Last active
September 24, 2024 13:18
-
-
Save cpdt/99e359a099e390720411d4dbbc69f822 to your computer and use it in GitHub Desktop.
A minimal Rust file with no_std for sizecoding (4k, 8k, 64k, etc)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
#![no_main] | |
#![feature(core_intrinsics, lang_items, link_args, alloc, alloc_error_handler)] | |
#[allow(unused_attributes)] | |
#[link_args = "/NODEFAULTLIB /SUBSYSTEM:WINDOWS /SAFESEH:NO /DYNAMICBASE:NO /ENTRY:WinMainCRTStartup /LTCG support/msvcrt.lib"] | |
extern "C" {} | |
#[macro_use] | |
extern crate alloc; | |
use alloc::boxed::Box; | |
use core::alloc::{GlobalAlloc, Layout}; | |
use core::hint::unreachable_unchecked; | |
use winapi::um::heapapi::{GetProcessHeap, HeapAlloc, HeapFree}; | |
use winapi::um::processthreadsapi::ExitProcess; | |
struct SystemAllocator; | |
unsafe impl GlobalAlloc for SystemAllocator { | |
unsafe fn alloc(&self, layout: Layout) -> *mut u8 { | |
HeapAlloc(GetProcessHeap(), 0, layout.size()) as *mut _ | |
} | |
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { | |
// tbh in a 64k or lower you could probably get away with just leaking memory here | |
HeapFree(GetProcessHeap(), 0, ptr as *mut _); | |
} | |
} | |
#[global_allocator] | |
static ALLOC: SystemAllocator = SystemAllocator; | |
#[panic_handler] | |
#[no_mangle] | |
pub extern "C" fn panic(_info: &PanicInfo) -> ! { | |
// A small trick that can save some size - tell the optimizer that this point is unreachable, | |
// thereby allowing it to assume branches that panic never actually happen, which they | |
// shouldn't in a release build. Obviously very unsafe, so you probably don't want this in | |
// debug builds. | |
unsafe { | |
unreachable_unchecked(); | |
} | |
} | |
#[alloc_error_handler] | |
fn error_handler(_: core::alloc::Layout) -> ! { | |
// Same as above | |
unsafe { | |
unreachable_unchecked(); | |
} | |
} | |
#[lang = "eh_personality"] | |
extern "C" fn eh_personality() {} | |
fn exit_process(exit_code: u32) -> ! { | |
unsafe { | |
ExitProcess(exit_code); | |
unreachable_unchecked(); | |
} | |
} | |
#[no_mangle] | |
pub unsafe extern "C" fn WinMainCRTStartup() -> i32 { | |
// Do some stuff | |
// Note: returning from this function won't actually end the process, we need to call ExitProcess explicitly: | |
exit_process(0); | |
} | |
// Resolves a linker error when floating points are used | |
#[no_mangle] | |
pub static _fltused: i32 = 1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment