Skip to content

Instantly share code, notes, and snippets.

@cpdt
Last active Jul 14, 2022
Embed
What would you like to do?
A minimal Rust file with no_std for sizecoding (4k, 8k, 64k, etc)
#![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