Skip to content

Commit 8fbb126

Browse files
authored
system table can get debug-formatted (including boot and runtime services) (#248)
1 parent a1c61c8 commit 8fbb126

File tree

6 files changed

+218
-5
lines changed

6 files changed

+218
-5
lines changed

src/data_types/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use core::{ffi::c_void, mem::MaybeUninit};
66

77
/// Opaque handle to an UEFI entity (protocol, image...)
8-
#[derive(Clone, Copy)]
8+
#[derive(Clone, Copy, Debug)]
99
#[repr(transparent)]
1010
pub struct Handle(*mut c_void);
1111

src/proto/console/text/output.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::prelude::*;
22
use crate::proto::Protocol;
33
use crate::{unsafe_guid, CStr16, Char16, Completion, Result, Status};
44
use core::fmt;
5+
use core::fmt::{Debug, Formatter};
56

67
/// Interface for text-based output devices.
78
///
@@ -197,6 +198,35 @@ impl<'boot> fmt::Write for Output<'boot> {
197198
}
198199
}
199200

201+
impl<'boot> Debug for Output<'boot> {
202+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
203+
f.debug_struct("Output")
204+
.field("reset (fn ptr)", &(self.reset as *const u64))
205+
.field(
206+
"output_string (fn ptr)",
207+
&(self.output_string as *const u64),
208+
)
209+
.field("test_string (fn ptr)", &(self.test_string as *const u64))
210+
.field("query_mode (fn ptr)", &(self.query_mode as *const u64))
211+
.field("set_mode (fn ptr)", &(self.set_mode as *const u64))
212+
.field(
213+
"set_attribute (fn ptr)",
214+
&(self.set_attribute as *const u64),
215+
)
216+
.field("clear_screen (fn ptr)", &(self.clear_screen as *const u64))
217+
.field(
218+
"set_cursor_position (fn ptr)",
219+
&(self.set_cursor_position as *const u64),
220+
)
221+
.field(
222+
"enable_cursor (fn ptr)",
223+
&(self.enable_cursor as *const u64),
224+
)
225+
.field("data", &self.data)
226+
.finish()
227+
}
228+
}
229+
200230
/// The text mode (resolution) of the output device.
201231
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
202232
pub struct OutputMode {

src/table/boot.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use alloc_api::vec::Vec;
1111
use bitflags::bitflags;
1212
use core::cell::UnsafeCell;
1313
use core::ffi::c_void;
14+
use core::fmt::{Debug, Formatter};
1415
use core::mem::{self, MaybeUninit};
1516
use core::{ptr, slice};
1617

@@ -702,6 +703,132 @@ impl super::Table for BootServices {
702703
const SIGNATURE: u64 = 0x5652_4553_544f_4f42;
703704
}
704705

706+
impl Debug for BootServices {
707+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
708+
f.debug_struct("BootServices")
709+
.field("header", &self.header)
710+
.field("raise_tpl (fn ptr)", &(self.raise_tpl as *const usize))
711+
.field("restore_tpl (fn ptr)", &(self.restore_tpl as *const usize))
712+
.field(
713+
"allocate_pages (fn ptr)",
714+
&(self.allocate_pages as *const usize),
715+
)
716+
.field("free_pages (fn ptr)", &(self.free_pages as *const usize))
717+
.field(
718+
"get_memory_map (fn ptr)",
719+
&(self.get_memory_map as *const usize),
720+
)
721+
.field(
722+
"allocate_pool (fn ptr)",
723+
&(self.allocate_pool as *const usize),
724+
)
725+
.field("free_pool (fn ptr)", &(self.free_pool as *const usize))
726+
.field(
727+
"create_event (fn ptr)",
728+
&(self.create_event as *const usize),
729+
)
730+
.field("set_timer (fn ptr)", &(self.set_timer as *const usize))
731+
.field(
732+
"wait_for_event (fn ptr)",
733+
&(self.wait_for_event as *const usize),
734+
)
735+
.field("signal_event", &(self.signal_event as *const usize))
736+
.field("close_event", &(self.close_event as *const usize))
737+
.field("check_event", &(self.check_event as *const usize))
738+
.field(
739+
"install_protocol_interface",
740+
&(self.install_protocol_interface as *const usize),
741+
)
742+
.field(
743+
"reinstall_protocol_interface",
744+
&(self.reinstall_protocol_interface as *const usize),
745+
)
746+
.field(
747+
"uninstall_protocol_interface",
748+
&(self.uninstall_protocol_interface as *const usize),
749+
)
750+
.field(
751+
"handle_protocol (fn ptr)",
752+
&(self.handle_protocol as *const usize),
753+
)
754+
.field(
755+
"register_protocol_notify",
756+
&(self.register_protocol_notify as *const usize),
757+
)
758+
.field(
759+
"locate_handle (fn ptr)",
760+
&(self.locate_handle as *const usize),
761+
)
762+
.field(
763+
"locate_device_path (fn ptr)",
764+
&(self.locate_device_path as *const usize),
765+
)
766+
.field(
767+
"install_configuration_table",
768+
&(self.install_configuration_table as *const usize),
769+
)
770+
.field("load_image (fn ptr)", &(self.load_image as *const usize))
771+
.field("start_image (fn ptr)", &(self.start_image as *const usize))
772+
.field("exit", &(self.exit as *const usize))
773+
.field(
774+
"unload_image (fn ptr)",
775+
&(self.unload_image as *const usize),
776+
)
777+
.field(
778+
"exit_boot_services (fn ptr)",
779+
&(self.exit_boot_services as *const usize),
780+
)
781+
.field(
782+
"get_next_monotonic_count",
783+
&(self.get_next_monotonic_count as *const usize),
784+
)
785+
.field("stall (fn ptr)", &(self.stall as *const usize))
786+
.field(
787+
"set_watchdog_timer (fn ptr)",
788+
&(self.set_watchdog_timer as *const usize),
789+
)
790+
.field(
791+
"connect_controller",
792+
&(self.connect_controller as *const usize),
793+
)
794+
.field(
795+
"disconnect_controller",
796+
&(self.disconnect_controller as *const usize),
797+
)
798+
.field("open_protocol", &(self.open_protocol as *const usize))
799+
.field("close_protocol", &(self.close_protocol as *const usize))
800+
.field(
801+
"open_protocol_information",
802+
&(self.open_protocol_information as *const usize),
803+
)
804+
.field(
805+
"protocols_per_handle",
806+
&(self.protocols_per_handle as *const usize),
807+
)
808+
.field(
809+
"locate_handle_buffer",
810+
&(self.locate_handle_buffer as *const usize),
811+
)
812+
.field(
813+
"locate_protocol (fn ptr)",
814+
&(self.locate_protocol as *const usize),
815+
)
816+
.field(
817+
"install_multiple_protocol_interfaces",
818+
&(self.install_multiple_protocol_interfaces as *const usize),
819+
)
820+
.field(
821+
"uninstall_multiple_protocol_interfaces",
822+
&(self.uninstall_multiple_protocol_interfaces as *const usize),
823+
)
824+
.field("calculate_crc32", &(self.calculate_crc32 as *const usize))
825+
.field("copy_mem (fn ptr)", &(self.copy_mem as *const usize))
826+
.field("set_mem (fn ptr)", &(self.set_mem as *const usize))
827+
.field("create_event_ex", &(self.create_event_ex as *const usize))
828+
.finish()
829+
}
830+
}
831+
705832
newtype_enum! {
706833
/// Task priority level.
707834
///

src/table/header.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::Revision;
2+
use core::fmt::{Debug, Formatter};
23

34
/// All standard UEFI tables begin with a common header.
4-
#[derive(Debug)]
55
#[repr(C)]
66
pub struct Header {
77
/// Unique identifier for this table.
@@ -16,3 +16,14 @@ pub struct Header {
1616
/// Reserved field that must be set to 0.
1717
_reserved: u32,
1818
}
19+
20+
impl Debug for Header {
21+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
22+
f.debug_struct("Header")
23+
.field("signature", &(self.size as *const u64))
24+
.field("revision", &self.revision)
25+
.field("size", &self.size)
26+
.field("crc", &self.crc)
27+
.finish()
28+
}
29+
}

src/table/runtime.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{CStr16, Char16, Guid, Result, Status};
99
#[cfg(feature = "exts")]
1010
use alloc_api::{vec, vec::Vec};
1111
use bitflags::bitflags;
12-
use core::fmt::Formatter;
12+
use core::fmt::{Debug, Formatter};
1313
#[cfg(feature = "exts")]
1414
use core::mem;
1515
use core::mem::MaybeUninit;
@@ -250,6 +250,21 @@ impl super::Table for RuntimeServices {
250250
const SIGNATURE: u64 = 0x5652_4553_544e_5552;
251251
}
252252

253+
impl Debug for RuntimeServices {
254+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
255+
f.debug_struct("RuntimeServices")
256+
.field("header", &self.header)
257+
.field("get_time", &(self.get_time as *const u64))
258+
.field("set_time", &(self.set_time as *const u64))
259+
.field(
260+
"set_virtual_address_map",
261+
&(self.set_virtual_address_map as *const u64),
262+
)
263+
.field("reset", &(self.reset as *const u64))
264+
.finish()
265+
}
266+
}
267+
253268
/// The current time information
254269
#[derive(Copy, Clone)]
255270
#[repr(C)]

src/table/system.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use core::marker::PhantomData;
2-
use core::slice;
2+
use core::{ptr, slice};
33

44
use crate::proto::console::text;
55
use crate::{CStr16, Char16, Handle, Result, ResultExt, Status};
66

77
use super::boot::{BootServices, MemoryDescriptor};
88
use super::runtime::RuntimeServices;
99
use super::{cfg, Header, Revision};
10+
use core::fmt::{Debug, Formatter};
1011

1112
/// Marker trait used to provide different views of the UEFI System Table
1213
pub trait SystemTableView {}
@@ -41,6 +42,7 @@ impl SystemTableView for Runtime {}
4142
/// UEFI boot services in the eye of the Rust borrow checker) and a runtime view
4243
/// will be provided to replace it.
4344
#[repr(transparent)]
45+
#[derive(Debug)]
4446
pub struct SystemTable<View: SystemTableView> {
4547
table: &'static SystemTableImpl,
4648
_marker: PhantomData<View>,
@@ -186,6 +188,12 @@ impl SystemTable<Boot> {
186188
}
187189
}
188190

191+
impl Debug for SystemTable<Boot> {
192+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
193+
self.table.fmt(f)
194+
}
195+
}
196+
189197
// These parts of the SystemTable struct are only visible after exit from UEFI
190198
// boot services. They provide unsafe access to the UEFI runtime services, which
191199
// which were already available before but in safe form.
@@ -220,7 +228,7 @@ struct SystemTableImpl {
220228
runtime: &'static RuntimeServices,
221229
/// Boot services table.
222230
boot: *const BootServices,
223-
/// Number of entires in the configuration table.
231+
/// Number of entries in the configuration table.
224232
nr_cfg: usize,
225233
/// Pointer to beginning of the array.
226234
cfg_table: *const cfg::ConfigTableEntry,
@@ -229,3 +237,25 @@ struct SystemTableImpl {
229237
impl<View: SystemTableView> super::Table for SystemTable<View> {
230238
const SIGNATURE: u64 = 0x5453_5953_2049_4249;
231239
}
240+
241+
impl Debug for SystemTableImpl {
242+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
243+
f.debug_struct("UefiSystemTable")
244+
.field("header", &self.header)
245+
.field("fw_vendor", &(unsafe { CStr16::from_ptr(self.fw_vendor) }))
246+
.field("fw_revision", &self.fw_revision)
247+
.field("stdin_handle", &self.stdin_handle)
248+
.field("stdin", &self.stdin)
249+
.field("stdout_handle", &self.stdout_handle)
250+
.field("stdout", &self.stdout)
251+
.field("stderr_handle", &self.stderr_handle)
252+
.field("stderr", &self.stderr)
253+
.field("runtime", &self.runtime)
254+
// a little bit of extra work needed to call debug-fmt on the BootServices
255+
// instead of printing the raw pointer
256+
.field("boot", &(unsafe { ptr::read(self.boot) }))
257+
.field("nf_cfg", &self.nr_cfg)
258+
.field("cfg_table", &self.cfg_table)
259+
.finish()
260+
}
261+
}

0 commit comments

Comments
 (0)