diff options
| author | joboet <jonasboettiger@icloud.com> | 2024-07-23 16:10:08 +0200 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2024-08-27 11:58:19 +0200 |
| commit | d456814842e65a153a1de67960b892897a02ed14 (patch) | |
| tree | 2b7f252cd52ba3e785fedea291fe3f78c1edf206 /library/std/src/sys/alloc/uefi.rs | |
| parent | a60a9e567a7319b33619f6551dc29522c6f58687 (diff) | |
| download | rust-d456814842e65a153a1de67960b892897a02ed14.tar.gz rust-d456814842e65a153a1de67960b892897a02ed14.zip | |
std: move allocators to `sys`
Diffstat (limited to 'library/std/src/sys/alloc/uefi.rs')
| -rw-r--r-- | library/std/src/sys/alloc/uefi.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/library/std/src/sys/alloc/uefi.rs b/library/std/src/sys/alloc/uefi.rs new file mode 100644 index 00000000000..5221876e908 --- /dev/null +++ b/library/std/src/sys/alloc/uefi.rs @@ -0,0 +1,49 @@ +//! Global Allocator for UEFI. +//! Uses [r-efi-alloc](https://crates.io/crates/r-efi-alloc) + +use r_efi::protocols::loaded_image; + +use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::sync::OnceLock; +use crate::sys::pal::helpers; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + static EFI_MEMORY_TYPE: OnceLock<u32> = OnceLock::new(); + + // Return null pointer if boot services are not available + if crate::os::uefi::env::boot_services().is_none() { + return crate::ptr::null_mut(); + } + + // If boot services is valid then SystemTable is not null. + let system_table = crate::os::uefi::env::system_table().as_ptr().cast(); + + // Each loaded image has an image handle that supports `EFI_LOADED_IMAGE_PROTOCOL`. Thus, this + // will never fail. + let mem_type = EFI_MEMORY_TYPE.get_or_init(|| { + let protocol = helpers::image_handle_protocol::<loaded_image::Protocol>( + loaded_image::PROTOCOL_GUID, + ) + .unwrap(); + // Gives allocations the memory type that the data sections were loaded as. + unsafe { (*protocol.as_ptr()).image_data_type } + }); + + // The caller must ensure non-0 layout + unsafe { r_efi_alloc::raw::alloc(system_table, layout, *mem_type) } + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + // Do nothing if boot services are not available + if crate::os::uefi::env::boot_services().is_none() { + return; + } + + // If boot services is valid then SystemTable is not null. + let system_table = crate::os::uefi::env::system_table().as_ptr().cast(); + // The caller must ensure non-0 layout + unsafe { r_efi_alloc::raw::dealloc(system_table, ptr, layout) } + } +} |
