Skip to content

Commit e0bc758

Browse files
committed
multiboot2: improve debug output of BootInformation and ElfSections
1 parent a537d24 commit e0bc758

File tree

5 files changed

+48
-30
lines changed

5 files changed

+48
-30
lines changed

multiboot2/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- `BootInformation::elf_sections` is now deprecated and replaced by the newly
99
- added `BootInformation::elf_sections_tag`. On the returned type, you can call
1010
`.sections()` to iterate the sections
11+
- Fixed the debug output of `BootInformation`
1112

1213
## v0.23.0 (2024-09-17)
1314

multiboot2/src/boot_information.rs

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -428,50 +428,42 @@ impl<'a> BootInformation<'a> {
428428

429429
impl fmt::Debug for BootInformation<'_> {
430430
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431-
/// Limit how many Elf-Sections should be debug-formatted.
432-
/// Can be thousands of sections for a Rust binary => this is useless output.
433-
/// If the user really wants this, they should debug-format the field directly.
434-
const ELF_SECTIONS_LIMIT: usize = 7;
435-
436431
let mut debug = f.debug_struct("Multiboot2BootInformation");
437432
debug
438433
.field("start_address", &self.start_address())
439434
.field("end_address", &self.end_address())
440435
.field("total_size", &self.total_size())
441436
// now tags in alphabetical order
437+
.field("apm", &self.apm_tag())
442438
.field("basic_memory_info", &(self.basic_memory_info_tag()))
443439
.field("boot_loader_name", &self.boot_loader_name_tag())
444-
// .field("bootdev", &self.bootdev_tag())
440+
.field("bootdev", &self.bootdev_tag())
445441
.field("command_line", &self.command_line_tag())
446442
.field("efi_bs_not_exited", &self.efi_bs_not_exited_tag())
443+
.field("efi_ih32", &self.efi_ih32_tag())
444+
.field("efi_ih64", &self.efi_ih64_tag())
447445
.field("efi_memory_map", &self.efi_memory_map_tag())
448446
.field("efi_sdt32", &self.efi_sdt32_tag())
449447
.field("efi_sdt64", &self.efi_sdt64_tag())
450-
.field("efi_ih32", &self.efi_ih32_tag())
451-
.field("efi_ih64", &self.efi_ih64_tag());
452-
453-
// usually this is REALLY big (thousands of tags) => skip it here
454-
{
455-
let elf_sections_tag_entries_count =
456-
self.elf_sections().map(|x| x.count()).unwrap_or(0);
457-
458-
if elf_sections_tag_entries_count > ELF_SECTIONS_LIMIT {
459-
debug.field("elf_sections (count)", &elf_sections_tag_entries_count);
460-
} else {
461-
debug.field("elf_sections", &self.elf_sections());
462-
}
463-
}
464-
465-
debug
448+
.field("elf_sections", &self.elf_sections_tag())
466449
.field("framebuffer", &self.framebuffer_tag())
467450
.field("load_base_addr", &self.load_base_addr_tag())
468451
.field("memory_map", &self.memory_map_tag())
469452
.field("modules", &self.module_tags())
470-
// .field("network", &self.network_tag())
453+
.field("network", &self.network_tag())
471454
.field("rsdp_v1", &self.rsdp_v1_tag())
472455
.field("rsdp_v2", &self.rsdp_v2_tag())
473-
.field("smbios_tag", &self.smbios_tag())
474-
.field("vbe_info_tag", &self.vbe_info_tag())
456+
.field("smbios", &self.smbios_tag())
457+
.field("vbe_info", &self.vbe_info_tag())
458+
// computed fields
459+
.field("custom_tags_count", &{
460+
self.tags()
461+
.filter(|tag| {
462+
let id: TagType = tag.header().typ.into();
463+
matches!(id, TagType::Custom(_))
464+
})
465+
.count()
466+
})
475467
.finish()
476468
}
477469
}

multiboot2/src/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,5 +378,6 @@ mod tests {
378378
// Mainly a test for Miri.
379379
dbg!(tag.header(), tag.payload().len());
380380
}
381+
eprintln!("{info:#x?}")
381382
}
382383
}

multiboot2/src/elf_sections.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,23 +136,45 @@ impl<'a> Iterator for ElfSectionIter<'a> {
136136

137137
impl Debug for ElfSectionIter<'_> {
138138
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
139+
/// Limit how many Elf-Sections should be debug-formatted.
140+
/// Can be thousands of sections for a Rust binary => this is useless output.
141+
/// If the user really wants this, they should debug-format the field directly.
142+
const ELF_SECTIONS_LIMIT: usize = 7;
143+
139144
let mut debug = f.debug_list();
140-
self.clone().for_each(|ref e| {
145+
146+
self.clone().take(ELF_SECTIONS_LIMIT).for_each(|ref e| {
141147
debug.entry(e);
142148
});
149+
150+
if self.clone().len() > ELF_SECTIONS_LIMIT {
151+
debug.entry(&"...");
152+
}
153+
143154
debug.finish()
144155
}
145156
}
146157

147158
/// A single generic ELF Section.
148-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
159+
// TODO Shouldn't this be called ElfSectionPtrs, ElfSectionWrapper or so?
160+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
149161
pub struct ElfSection<'a> {
150162
inner: *const u8,
151163
string_section: *const u8,
152164
entry_size: u32,
153165
_phantom: PhantomData<&'a ()>,
154166
}
155167

168+
impl Debug for ElfSection<'_> {
169+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
170+
let inner = self.get();
171+
f.debug_struct("ElfSection")
172+
.field("inner", &inner)
173+
.field("string_section_ptr", &self.string_section)
174+
.finish()
175+
}
176+
}
177+
156178
#[derive(Clone, Copy, Debug)]
157179
#[repr(C, packed)]
158180
struct ElfSectionInner32 {
@@ -297,7 +319,7 @@ impl ElfSection<'_> {
297319
}
298320
}
299321

300-
trait ElfSectionInner {
322+
trait ElfSectionInner: Debug {
301323
fn name_index(&self) -> u32;
302324

303325
fn typ(&self) -> u32;

multiboot2/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,8 +1007,7 @@ mod tests {
10071007
]);
10081008
#[repr(C, align(8))]
10091009
struct StringBytes([u8; 11]);
1010-
let string_bytes: StringBytes =
1011-
StringBytes([0, 46, 115, 104, 115, 116, 114, 116, 97, 98, 0]);
1010+
let string_bytes: StringBytes = StringBytes(*b"\0.shstrtab\0");
10121011
let string_addr = string_bytes.0.as_ptr() as u64;
10131012
for i in 0..8 {
10141013
let offset = 108;
@@ -1019,6 +1018,9 @@ mod tests {
10191018
let addr = ptr as usize;
10201019
let bi = unsafe { BootInformation::load(ptr.cast()) };
10211020
let bi = bi.unwrap();
1021+
1022+
eprintln!("boot information with elf sections: {bi:#x?}");
1023+
10221024
assert_eq!(addr, bi.start_address());
10231025
assert_eq!(addr + bytes.0.len(), bi.end_address());
10241026
assert_eq!(bytes.0.len(), bi.total_size());

0 commit comments

Comments
 (0)