authorgravatar for ybham6@gmail.comfifty-six <ybham6@gmail.com> 2022-01-13 05:23:39-05:00
committergravatar for ybham6@gmail.comfifty-six <ybham6@gmail.com> 2022-01-13 15:47:14-05:00
log649b872450689511ac3c5526d063c89fff7d898a
tree96b8f12fdf58f08f42ae03ed29639afcba054f40
parentea2df2601e81aa9e490459ad9c65b03de2be61d0

std/builtin: improve panic handler for uefi

Writes the panic message to stderr as well as passing it to boot_services.exit when boot_services is available.

1 files changed, 46 insertions(+), 1 deletions(-)

lib/std/builtin.zig+46-1
......@@ -769,7 +769,52 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
769769 std.os.abort();
770770 },
771771 .uefi => {
772 // TODO look into using the debug info and logging helpful messages
772 const uefi = std.os.uefi;
773
774 const ExitData = struct {
775 pub fn create_exit_data(exit_msg: []const u8, exit_size: *usize) ![*:0]u16 {
776 // Need boot services for pool allocation
777 if (uefi.system_table.boot_services == null) {
778 return error.BootServicesUnavailable;
779 }
780
781 // ExitData buffer must be allocated using boot_services.allocatePool
782 var utf16: []u16 = try uefi.raw_pool_allocator.alloc(u16, 256);
783 errdefer uefi.raw_pool_allocator.free(utf16);
784
785 if (exit_msg.len > 255) {
786 return error.MessageTooLong;
787 }
788
789 var fmt: [256]u8 = undefined;
790 var slice = try std.fmt.bufPrint(&fmt, "\r\nerr: {s}\r\n", .{exit_msg});
791
792 var len = try std.unicode.utf8ToUtf16Le(utf16, slice);
793
794 utf16[len] = 0;
795
796 exit_size.* = 256;
797
798 return @ptrCast([*:0]u16, utf16.ptr);
799 }
800 };
801
802 var exit_size: usize = 0;
803 var exit_data = ExitData.create_exit_data(msg, &exit_size) catch null;
804
805 if (exit_data) |data| {
806 if (uefi.system_table.std_err) |out| {
807 _ = out.setAttribute(uefi.protocols.SimpleTextOutputProtocol.red);
808 _ = out.outputString(data);
809 _ = out.setAttribute(uefi.protocols.SimpleTextOutputProtocol.white);
810 }
811 }
812
813 if (uefi.system_table.boot_services) |bs| {
814 _ = bs.exit(uefi.handle, .Aborted, exit_size, exit_data);
815 }
816
817 // Didn't have boot_services, just fallback to whatever.
773818 std.os.abort();
774819 },
775820 else => {