aboutsummaryrefslogtreecommitdiff
path: root/lib/std/builtin.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-18 14:16:30 -0500
committerGitHub <noreply@github.com>2022-02-18 14:16:30 -0500
commit2c24bf2f79af8d258956d3169e0c64ac8e71e51d (patch)
tree961a8deb2a18ecc384ed1ce6ad84196e18410975 /lib/std/builtin.zig
parent60bb1d4e1c262ff36c18cefe974aa2f773483af4 (diff)
parentff6ece3811a1cb44a90986d543d1583a40629edf (diff)
downloadzig-2c24bf2f79af8d258956d3169e0c64ac8e71e51d.tar.gz
zig-2c24bf2f79af8d258956d3169e0c64ac8e71e51d.zip
Merge pull request #10604 from fifty-six/master
std/os/uefi: additional improvements/fixes
Diffstat (limited to 'lib/std/builtin.zig')
-rw-r--r--lib/std/builtin.zig47
1 files changed, 46 insertions, 1 deletions
diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig
index 39e849fb5e..ad6b5f052b 100644
--- a/lib/std/builtin.zig
+++ b/lib/std/builtin.zig
@@ -758,7 +758,52 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
std.os.abort();
},
.uefi => {
- // TODO look into using the debug info and logging helpful messages
+ const uefi = std.os.uefi;
+
+ const ExitData = struct {
+ pub fn create_exit_data(exit_msg: []const u8, exit_size: *usize) ![*:0]u16 {
+ // Need boot services for pool allocation
+ if (uefi.system_table.boot_services == null) {
+ return error.BootServicesUnavailable;
+ }
+
+ // ExitData buffer must be allocated using boot_services.allocatePool
+ var utf16: []u16 = try uefi.raw_pool_allocator.alloc(u16, 256);
+ errdefer uefi.raw_pool_allocator.free(utf16);
+
+ if (exit_msg.len > 255) {
+ return error.MessageTooLong;
+ }
+
+ var fmt: [256]u8 = undefined;
+ var slice = try std.fmt.bufPrint(&fmt, "\r\nerr: {s}\r\n", .{exit_msg});
+
+ var len = try std.unicode.utf8ToUtf16Le(utf16, slice);
+
+ utf16[len] = 0;
+
+ exit_size.* = 256;
+
+ return @ptrCast([*:0]u16, utf16.ptr);
+ }
+ };
+
+ var exit_size: usize = 0;
+ var exit_data = ExitData.create_exit_data(msg, &exit_size) catch null;
+
+ if (exit_data) |data| {
+ if (uefi.system_table.std_err) |out| {
+ _ = out.setAttribute(uefi.protocols.SimpleTextOutputProtocol.red);
+ _ = out.outputString(data);
+ _ = out.setAttribute(uefi.protocols.SimpleTextOutputProtocol.white);
+ }
+ }
+
+ if (uefi.system_table.boot_services) |bs| {
+ _ = bs.exit(uefi.handle, .Aborted, exit_size, exit_data);
+ }
+
+ // Didn't have boot_services, just fallback to whatever.
std.os.abort();
},
else => {