Skip to content

Commit be11de0

Browse files
wangrunji0408GabrielMajeri
authored andcommitted
Implement alignment for allocator
1 parent 4c4049e commit be11de0

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

src/alloc.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,33 @@ pub fn exit_boot_services() {
5252
/// Only valid for as long as the UEFI boot services are available.
5353
pub struct Allocator;
5454

55+
#[allow(clippy::cast_ptr_alignment)]
5556
unsafe impl GlobalAlloc for Allocator {
5657
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
5758
let mem_ty = MemoryType::LOADER_DATA;
5859
let size = layout.size();
5960
let align = layout.align();
6061

61-
// TODO: add support for other alignments.
6262
if align > 8 {
63-
// Unsupported alignment for allocation, UEFI can only allocate 8-byte aligned addresses
64-
ptr::null_mut()
63+
// allocate more space for alignment
64+
let ptr = if let Ok(ptr) = boot_services()
65+
.as_ref()
66+
.allocate_pool(mem_ty, size + align)
67+
.warning_as_error()
68+
{
69+
ptr
70+
} else {
71+
return ptr::null_mut();
72+
};
73+
// calculate align offset
74+
let mut offset = ptr.align_offset(align);
75+
if offset == 0 {
76+
offset = align;
77+
}
78+
let return_ptr = ptr.add(offset);
79+
// store allocated pointer before the struct
80+
(return_ptr as *mut *mut u8).sub(1).write(ptr);
81+
return_ptr
6582
} else {
6683
boot_services()
6784
.as_ref()
@@ -71,7 +88,10 @@ unsafe impl GlobalAlloc for Allocator {
7188
}
7289
}
7390

74-
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
91+
unsafe fn dealloc(&self, mut ptr: *mut u8, layout: Layout) {
92+
if layout.align() > 8 {
93+
ptr = (ptr as *const *mut u8).sub(1).read();
94+
}
7595
boot_services()
7696
.as_ref()
7797
.free_pool(ptr)

uefi-test-runner/src/boot/memory.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub fn test(bt: &BootServices) {
99

1010
allocate_pages(bt);
1111
vec_alloc();
12+
alloc_alignment();
1213
memmove(bt);
1314

1415
memory_map(bt);
@@ -47,6 +48,17 @@ fn vec_alloc() {
4748
assert_eq!(values[..], [-5, 0, 4, 16, 23], "Failed to sort vector");
4849
}
4950

51+
// Simple test to ensure our custom allocator works with correct alignment.
52+
fn alloc_alignment() {
53+
info!("Allocating a structure with alignment to 0x100");
54+
55+
#[repr(align(0x100))]
56+
struct Block([u8; 0x100]);
57+
58+
let value = vec![Block([1; 0x100])];
59+
assert_eq!(value.as_ptr() as usize % 0x100, 0, "Wrong alignment");
60+
}
61+
5062
// Test that the `memmove` / `memset` functions work.
5163
fn memmove(bt: &BootServices) {
5264
info!("Testing the `memmove` / `memset` functions");

0 commit comments

Comments
 (0)