@@ -44,6 +44,41 @@ fn get_memory_type() -> MemoryType {
4444 }
4545}
4646
47+ fn alloc_pool_aligned ( memory_type : MemoryType , size : usize , align : usize ) -> * mut u8 {
48+ // The requested alignment is greater than 8, but `allocate_pool` is
49+ // only guaranteed to provide eight-byte alignment. Allocate extra
50+ // space so that we can return an appropriately-aligned pointer
51+ // within the allocation.
52+ let full_alloc_ptr = boot:: allocate_pool ( memory_type, size + align) ;
53+ let full_alloc_ptr = if let Ok ( ptr) = full_alloc_ptr {
54+ ptr. as_ptr ( )
55+ } else {
56+ return ptr:: null_mut ( ) ;
57+ } ;
58+
59+ // Calculate the offset needed to get an aligned pointer within the
60+ // full allocation. If that offset is zero, increase it to `align`
61+ // so that we still have space to store the extra pointer described
62+ // below.
63+ let mut offset = full_alloc_ptr. align_offset ( align) ;
64+ if offset == 0 {
65+ offset = align;
66+ }
67+
68+ // Before returning the aligned allocation, store a pointer to the
69+ // full unaligned allocation in the bytes just before the aligned
70+ // allocation. We know we have at least eight bytes there due to
71+ // adding `align` to the memory allocation size. We also know the
72+ // write is appropriately aligned for a `*mut u8` pointer because
73+ // `align_ptr` is aligned, and alignments are always powers of two
74+ // (as enforced by the `Layout` type).
75+ unsafe {
76+ let aligned_ptr = full_alloc_ptr. add ( offset) ;
77+ ( aligned_ptr. cast :: < * mut u8 > ( ) ) . sub ( 1 ) . write ( full_alloc_ptr) ;
78+ aligned_ptr
79+ }
80+ }
81+
4782/// Allocator which uses the UEFI pool allocation functions.
4883///
4984/// The allocator can only be used as long as the UEFI boot services are
@@ -76,39 +111,7 @@ unsafe impl GlobalAlloc for Allocator {
76111 . unwrap_or ( ptr:: null_mut ( ) )
77112 }
78113 9 .. => {
79- // The requested alignment is greater than 8, but `allocate_pool` is
80- // only guaranteed to provide eight-byte alignment. Allocate extra
81- // space so that we can return an appropriately-aligned pointer
82- // within the allocation.
83- let full_alloc_ptr = boot:: allocate_pool ( memory_type, size + align) ;
84- let full_alloc_ptr = if let Ok ( ptr) = full_alloc_ptr
85- {
86- ptr. as_ptr ( )
87- } else {
88- return ptr:: null_mut ( ) ;
89- } ;
90-
91- // Calculate the offset needed to get an aligned pointer within the
92- // full allocation. If that offset is zero, increase it to `align`
93- // so that we still have space to store the extra pointer described
94- // below.
95- let mut offset = full_alloc_ptr. align_offset ( align) ;
96- if offset == 0 {
97- offset = align;
98- }
99-
100- // Before returning the aligned allocation, store a pointer to the
101- // full unaligned allocation in the bytes just before the aligned
102- // allocation. We know we have at least eight bytes there due to
103- // adding `align` to the memory allocation size. We also know the
104- // write is appropriately aligned for a `*mut u8` pointer because
105- // `align_ptr` is aligned, and alignments are always powers of two
106- // (as enforced by the `Layout` type).
107- unsafe {
108- let aligned_ptr = full_alloc_ptr. add ( offset) ;
109- ( aligned_ptr. cast :: < * mut u8 > ( ) ) . sub ( 1 ) . write ( full_alloc_ptr) ;
110- aligned_ptr
111- }
114+ alloc_pool_aligned ( memory_type, size, align)
112115 }
113116 }
114117 }
0 commit comments