Commit 4971df8572

antlilja <liljaanton2001@gmail.com>
2023-01-11 22:51:47
UEFI pool allocator changes
* Changed the interface to align with the new allocator interface. * Fixed bug where not enough memory was allocated for the header or to align the pointer.
1 parent 2a92b04
Changed files (1)
lib
std
lib/std/os/uefi/pool_allocator.zig
@@ -12,68 +12,59 @@ const UefiPoolAllocator = struct {
         return @intToPtr(*[*]align(8) u8, @ptrToInt(ptr) - @sizeOf(usize));
     }
 
-    fn alignedAlloc(len: usize, alignment: usize) ?[*]u8 {
-        var unaligned_ptr: [*]align(8) u8 = undefined;
-
-        if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, len, &unaligned_ptr) != .Success)
-            return null;
-
-        const unaligned_addr = @ptrToInt(unaligned_ptr);
-        const aligned_addr = mem.alignForward(unaligned_addr + @sizeOf(usize), alignment);
-
-        var aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr);
-        getHeader(aligned_ptr).* = unaligned_ptr;
-
-        return aligned_ptr;
-    }
-
-    fn alignedFree(ptr: [*]u8) void {
-        _ = uefi.system_table.boot_services.?.freePool(getHeader(ptr).*);
-    }
-
     fn alloc(
         _: *anyopaque,
         len: usize,
-        ptr_align: u29,
-        len_align: u29,
+        log2_ptr_align: u8,
         ret_addr: usize,
-    ) Allocator.Error![]u8 {
+    ) ?[*]u8 {
         _ = ret_addr;
 
         assert(len > 0);
-        assert(std.math.isPowerOfTwo(ptr_align));
 
-        var ptr = alignedAlloc(len, ptr_align) orelse return error.OutOfMemory;
+        const ptr_align = 1 << log2_ptr_align;
+
+        const metadata_len = mem.alignForward(@sizeOf(usize), ptr_align);
 
-        if (len_align == 0)
-            return ptr[0..len];
+        const full_len = metadata_len + len;
 
-        return ptr[0..mem.alignBackwardAnyAlign(len, len_align)];
+        var unaligned_ptr: [*]align(8) u8 = undefined;
+        if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, full_len, &unaligned_ptr) != .Success) return null;
+
+        const unaligned_addr = @ptrToInt(unaligned_ptr);
+        const aligned_addr = mem.alignForward(unaligned_addr + @sizeOf(usize), ptr_align);
+
+        var aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr);
+        getHeader(aligned_ptr).* = unaligned_ptr;
+
+        return aligned_ptr;
     }
 
     fn resize(
         _: *anyopaque,
         buf: []u8,
-        buf_align: u29,
+        log2_old_ptr_align: u8,
         new_len: usize,
-        len_align: u29,
         ret_addr: usize,
-    ) ?usize {
-        _ = buf_align;
+    ) bool {
         _ = ret_addr;
 
-        return if (new_len <= buf.len) mem.alignAllocLen(buf.len, new_len, len_align) else null;
+        if (new_len > buf.len) return false;
+
+        _ = mem.alignAllocLen(buf.len, new_len, log2_old_ptr_align);
+
+        return true;
     }
 
     fn free(
         _: *anyopaque,
         buf: []u8,
-        buf_align: u29,
+        log2_old_ptr_align: u8,
         ret_addr: usize,
     ) void {
-        _ = buf_align;
+        _ = log2_old_ptr_align;
         _ = ret_addr;
-        alignedFree(buf.ptr);
+        _ = uefi.system_table.boot_services.?.freePool(getHeader(buf.ptr).*);
     }
 };
 
@@ -105,49 +96,44 @@ const raw_pool_allocator_table = Allocator.VTable{
 fn uefi_alloc(
     _: *anyopaque,
     len: usize,
-    ptr_align: u29,
-    len_align: u29,
+    log2_ptr_align: u8,
     ret_addr: usize,
-) Allocator.Error![]u8 {
-    _ = len_align;
+) ?[*]u8 {
     _ = ret_addr;
 
-    std.debug.assert(ptr_align <= 8);
+    std.debug.assert(log2_ptr_align <= 3);
 
     var ptr: [*]align(8) u8 = undefined;
+    if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, len, &ptr) != .Success) return null;
 
-    if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, len, &ptr) != .Success) {
-        return error.OutOfMemory;
-    }
-
-    return ptr[0..len];
+    return ptr;
 }
 
 fn uefi_resize(
     _: *anyopaque,
     buf: []u8,
-    old_align: u29,
+    log2_old_ptr_align: u8,
     new_len: usize,
-    len_align: u29,
     ret_addr: usize,
-) ?usize {
-    _ = old_align;
+) bool {
     _ = ret_addr;
 
-    if (new_len <= buf.len) {
-        return mem.alignAllocLen(buf.len, new_len, len_align);
-    }
+    std.debug.assert(log2_old_ptr_align <= 3);
+
+    if (new_len > buf.len) return false;
+
+    _ = mem.alignAllocLen(buf.len, new_len, 8);
 
-    return null;
+    return true;
 }
 
 fn uefi_free(
     _: *anyopaque,
     buf: []u8,
-    buf_align: u29,
+    log2_old_ptr_align: u8,
     ret_addr: usize,
 ) void {
-    _ = buf_align;
+    _ = log2_old_ptr_align;
     _ = ret_addr;
     _ = uefi.system_table.boot_services.?.freePool(@alignCast(8, buf.ptr));
 }