@@ -52,16 +52,33 @@ pub fn exit_boot_services() {
52
52
/// Only valid for as long as the UEFI boot services are available.
53
53
pub struct Allocator ;
54
54
55
+ #[ allow( clippy:: cast_ptr_alignment) ]
55
56
unsafe impl GlobalAlloc for Allocator {
56
57
unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
57
58
let mem_ty = MemoryType :: LOADER_DATA ;
58
59
let size = layout. size ( ) ;
59
60
let align = layout. align ( ) ;
60
61
61
- // TODO: add support for other alignments.
62
62
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
65
82
} else {
66
83
boot_services ( )
67
84
. as_ref ( )
@@ -71,7 +88,10 @@ unsafe impl GlobalAlloc for Allocator {
71
88
}
72
89
}
73
90
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
+ }
75
95
boot_services ( )
76
96
. as_ref ( )
77
97
. free_pool ( ptr)
0 commit comments