@@ -799,41 +799,55 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
799
799
.uefi = > {
800
800
const uefi = std .os .uefi ;
801
801
802
+ const Formatter = struct {
803
+ pub fn fmt (exit_msg : []const u8 , out : []u16 ) ! [:0 ]u16 {
804
+ var u8_buf : [256 ]u8 = undefined ;
805
+ const slice = try std .fmt .bufPrint (& u8_buf , "err: {s}\r \n " , .{exit_msg });
806
+ // We pass len - 1 because we need to add a null terminator after
807
+ const len = try std .unicode .utf8ToUtf16Le (out [0 .. out .len - 1 ], slice );
808
+
809
+ out [len ] = 0 ;
810
+
811
+ return out [0.. len :0 ];
812
+ }
813
+ };
814
+
802
815
const ExitData = struct {
803
- pub fn create_exit_data (exit_msg : [] const u8 , exit_size : * usize ) ! [* :0 ]u16 {
816
+ pub fn create_exit_data (exit_msg : [: 0 ] u16 , exit_size : * usize ) ! [* :0 ]u16 {
804
817
// Need boot services for pool allocation
805
818
if (uefi .system_table .boot_services == null ) {
806
819
return error .BootServicesUnavailable ;
807
820
}
808
821
809
- // ExitData buffer must be allocated using boot_services.allocatePool
810
- var utf16 : []u16 = try uefi .raw_pool_allocator .alloc (u16 , 256 );
811
- errdefer uefi .raw_pool_allocator .free (utf16 );
812
-
813
- if (exit_msg .len > 255 ) {
814
- return error .MessageTooLong ;
815
- }
816
-
817
- var fmt : [256 ]u8 = undefined ;
818
- const slice = try std .fmt .bufPrint (& fmt , "\r \n err: {s}\r \n " , .{exit_msg });
819
- const len = try std .unicode .utf8ToUtf16Le (utf16 , slice );
820
-
821
- utf16 [len ] = 0 ;
822
+ // ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220)
823
+ const exit_data : []u16 = try uefi .raw_pool_allocator .alloc (u16 , exit_msg .len + 1 );
822
824
823
- exit_size .* = 256 ;
825
+ @memcpy (exit_data [0 .. exit_msg .len + 1 ], exit_msg [0 .. exit_msg .len + 1 ]);
826
+ exit_size .* = exit_msg .len + 1 ;
824
827
825
- return @as ([* :0 ]u16 , @ptrCast (utf16 .ptr ));
828
+ return @as ([* :0 ]u16 , @ptrCast (exit_data .ptr ));
826
829
}
827
830
};
828
831
829
- var exit_size : usize = 0 ;
830
- const exit_data = ExitData . create_exit_data (msg , & exit_size ) catch null ;
832
+ var buf : [ 256 ] u16 = undefined ;
833
+ const utf16 = Formatter . fmt (msg , & buf ) catch null ;
831
834
832
- if (exit_data ) | data | {
833
- if (uefi .system_table .std_err ) | out | {
834
- _ = out .setAttribute (uefi .protocol .SimpleTextOutput .red );
835
- _ = out .outputString (data );
836
- _ = out .setAttribute (uefi .protocol .SimpleTextOutput .white );
835
+ var exit_size : usize = 0 ;
836
+ const exit_data = if (utf16 ) | u |
837
+ ExitData .create_exit_data (u , & exit_size ) catch null
838
+ else
839
+ null ;
840
+
841
+ if (utf16 ) | str | {
842
+ // Output to both std_err and con_out, as std_err is easier
843
+ // to read in stuff like QEMU at times, but, unlike con_out,
844
+ // isn't visible on actual hardware if directly booted into
845
+ inline for ([_ ]? * uefi.protocol.SimpleTextOutput { uefi .system_table .std_err , uefi .system_table .con_out }) | o | {
846
+ if (o ) | out | {
847
+ _ = out .setAttribute (uefi .protocol .SimpleTextOutput .red );
848
+ _ = out .outputString (str );
849
+ _ = out .setAttribute (uefi .protocol .SimpleTextOutput .white );
850
+ }
837
851
}
838
852
}
839
853
0 commit comments