Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

much improved debug output of BootInformation + enum TagType #76

Merged
merged 2 commits into from Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/elf_sections.rs
@@ -1,4 +1,5 @@
use header::Tag;
use core::fmt::{Formatter, Debug};

/// This tag contains section header table from an ELF kernel.
///
Expand Down Expand Up @@ -41,7 +42,7 @@ impl ElfSectionsTag {
/// }
/// }
/// ```
pub fn sections(&self) -> impl Iterator<Item = ElfSection> {
pub fn sections(&self) -> ElfSectionIter {
let string_section_offset = (self.get().shndx * self.get().entry_size) as isize;
let string_section_ptr =
unsafe { self.first_section().offset(string_section_offset) as *const _ };
Expand All @@ -64,7 +65,7 @@ impl ElfSectionsTag {
}

/// An iterator over some ELF sections.
#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct ElfSectionIter {
current_section: *const u8,
remaining_sections: u32,
Expand Down Expand Up @@ -96,6 +97,28 @@ impl Iterator for ElfSectionIter {
}
}

impl Debug for ElfSectionIter {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
let mut debug = f.debug_list();
self.clone().for_each(|ref e| {
debug.entry(e);
});
debug.finish()
}
}

impl Default for ElfSectionIter {
fn default() -> Self {
Self {
current_section: core::ptr::null(),
remaining_sections: 0,
entry_size: 0,
string_section: core::ptr::null(),
offset: 0
}
}
}

/// A single generic ELF Section.
#[derive(Debug)]
pub struct ElfSection {
Expand Down
88 changes: 85 additions & 3 deletions src/header.rs
@@ -1,13 +1,95 @@
use core::marker::PhantomData;
use core::fmt::{Debug, Formatter};
use core::cmp::Ordering;

#[derive(Clone, Copy, Debug)]
/// Possible Types of a [`Tag`]. The names and values are taken from the example C code
/// at the bottom of the Multiboot2 specification.
#[repr(u32)]
#[derive(Copy, Clone, Debug)]
pub enum TagType {
phip1611 marked this conversation as resolved.
Show resolved Hide resolved
End = 0,
Cmdline = 1,
BootLoaderName = 2,
Module = 3,
BasicMeminfo = 4,
Bootdev = 5,
Mmap = 6,
Vbe = 7,
Framebuffer = 8,
ElfSections = 9,
Apm = 10,
Efi32 = 11,
Efi64 = 12,
Smbios = 13,
/// Also called "AcpiOld" in other multiboot2 implementations.
AcpiV1 = 14,
/// Refers to version 2 and later of Acpi.
/// Also called "AcpiNew" in other multiboot2 implementations.
AcpiV2 = 15,
Network = 16,
EfiMmap = 17,
EfiBs = 18,
Efi32Ih = 19,
Efi64Ih = 20,
LoadBaseAddr = 21,
}

// each compare/equal direction must be implemented manually
impl PartialEq<u32> for TagType {
fn eq(&self, other: &u32) -> bool {
*self as u32 == *other
}
}

// each compare/equal direction must be implemented manually
impl PartialEq<TagType> for u32 {
fn eq(&self, other: &TagType) -> bool {
*self == *other as u32
}
}

impl PartialEq<TagType> for TagType {
fn eq(&self, other: &TagType) -> bool {
*self as u32 == *other as u32
}
}

impl PartialOrd<u32> for TagType {
fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
let num = *self as u32;
Some(
if num < *other {
Ordering::Less
} else if num == *other {
Ordering::Equal
} else {
Ordering::Greater
}
)
}
}

/// All tags that could passed via the Multiboot2 information structure to a payload/program/kernel.
/// Better not confuse this with the Multiboot2 header tags. They are something different.
#[derive(Clone, Copy)]
#[repr(C)]
pub struct Tag {
pub typ: u32,
// u32 value
pub typ: TagType,
pub size: u32,
// tag specific fields
}

impl Debug for Tag {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Tag")
.field("typ", &self.typ)
.field("typ (numeric)", &(self.typ as u32))
.field("size", &(self.size))
.finish()
}
}

#[derive(Clone, Debug)]
pub struct TagIter<'a> {
pub current: *const Tag,
Expand All @@ -28,7 +110,7 @@ impl<'a> Iterator for TagIter<'a> {

fn next(&mut self) -> Option<&'a Tag> {
match unsafe { &*self.current } {
&Tag { typ: 0, size: 8 } => None, // end tag
&Tag { typ: TagType::End, size: 8 } => None, // end tag
tag => {
// go to next tag
let mut tag_addr = self.current as usize;
Expand Down