diff --git a/multiboot2-common/README.md b/multiboot2-common/README.md index ad043efb..5c6aa723 100644 --- a/multiboot2-common/README.md +++ b/multiboot2-common/README.md @@ -25,9 +25,13 @@ safely cast to the target type. ![Generic parsing flow overview](./parsing-flow-generic.drawio.png "Generic parsing flow overview: From raw bytes to specific structures") The next figure is like the previous figure, but shows a more specific parsing -flow by using types of the `multiboot2` crate. Green shows the raw memory. -Purple boxes refers to logic in `multiboot2-common`. Red components show structs -from the `multiboot2` crate. +flow by using example types of the `multiboot2` crate. Specifically, it shows +how the header structs for each multiboot2 structure, each implementing +the `Header` trait, are utilized as generic types to get the right size +information of the final type tag type. + +Green shows the raw memory, purple boxes refer to logic in `multiboot2-common`, +and red components show structs from the `multiboot2` crate. ![Specific parsing flow overview](./parsing-flow-specific.drawio.png "Specific parsing flow overview: From raw bytes to multiboot2 structures") diff --git a/multiboot2-common/parsing-flow-specific.drawio.png b/multiboot2-common/parsing-flow-specific.drawio.png index 6b39de11..072bfc90 100644 Binary files a/multiboot2-common/parsing-flow-specific.drawio.png and b/multiboot2-common/parsing-flow-specific.drawio.png differ diff --git a/multiboot2-common/parsing-flow-specific.drawio.xml b/multiboot2-common/parsing-flow-specific.drawio.xml index a984fdb4..5448e300 100644 --- a/multiboot2-common/parsing-flow-specific.drawio.xml +++ b/multiboot2-common/parsing-flow-specific.drawio.xml @@ -1,29 +1,29 @@ - + - + - + - - + + - + - + - + - - + + @@ -43,6 +43,11 @@ + + + + + @@ -76,11 +81,11 @@ - - + + - - + + @@ -96,24 +101,24 @@ - + - + - - + + - - + + - - + + @@ -121,13 +126,13 @@ - + - + @@ -152,12 +157,17 @@ - + + + + + + @@ -165,12 +175,12 @@ - + - - + + - + @@ -182,63 +192,51 @@ - + - - - - - - - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + @@ -246,10 +244,10 @@ - + - + @@ -260,19 +258,19 @@ - - + + - + - + - + @@ -295,10 +293,10 @@ - + - + @@ -306,6 +304,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/multiboot2-common/src/iter.rs b/multiboot2-common/src/iter.rs index 3c1a1dfb..775dedf8 100644 --- a/multiboot2-common/src/iter.rs +++ b/multiboot2-common/src/iter.rs @@ -7,11 +7,14 @@ use core::marker::PhantomData; use core::mem; /// Iterates over the tags (modelled by [`DynSizedStructure`]) of the underlying -/// byte slice. Each tag is expected to have the same common [`Header`]. +/// byte slice. Each tag is expected to have the same common [`Header`] with +/// the corresponding ABI guarantees. /// /// As the iterator emits elements of type [`DynSizedStructure`], users should -/// casted them to specific [`Tag`]s using [`DynSizedStructure::cast`] following -/// a user policy. This can for example happen on the basis of some ID. +/// cast them to specific [`Tag`]s using [`DynSizedStructure::cast`] following +/// a user-specific policy. This can for example happen on the basis of some ID. +/// +/// This iterator also emits end tags and doesn't treat them separately. /// /// This type ensures the memory safety guarantees promised by this crates /// documentation. @@ -30,6 +33,8 @@ pub struct TagIter<'a, H: Header> { impl<'a, H: Header> TagIter<'a, H> { /// Creates a new iterator. #[must_use] + // TODO we could take a BytesRef here, but the surrounding code should be + // bullet-proof enough. pub fn new(mem: &'a [u8]) -> Self { // Assert alignment. assert_eq!(mem.as_ptr().align_offset(ALIGNMENT), 0); diff --git a/multiboot2-common/src/tag.rs b/multiboot2-common/src/tag.rs index a57fc43f..8b1876e3 100644 --- a/multiboot2-common/src/tag.rs +++ b/multiboot2-common/src/tag.rs @@ -64,7 +64,7 @@ pub trait MaybeDynSized: Pointee { /// data, read the tag size from [`Self::header`] and create a sub slice. fn as_bytes(&self) -> BytesRef { let ptr = core::ptr::addr_of!(*self); - // Actual tag size, optionally with terminating padding. + // Actual tag size with optional terminating padding. let size = mem::size_of_val(self); let slice = unsafe { slice::from_raw_parts(ptr.cast::(), size) }; // Unwrap is fine as this type can't exist without the underlying memory diff --git a/multiboot2-header/src/entry_address.rs b/multiboot2-header/src/entry_address.rs index a4940e7b..852d481f 100644 --- a/multiboot2-header/src/entry_address.rs +++ b/multiboot2-header/src/entry_address.rs @@ -53,7 +53,7 @@ impl Debug for EntryAddressHeaderTag { .field("type", &self.typ()) .field("flags", &self.flags()) .field("size", &self.size()) - .field("entry_addr", &(self.entry_addr as *const u32)) + .field("entry_addr", &self.entry_addr) .finish() } } diff --git a/multiboot2-header/src/entry_efi_32.rs b/multiboot2-header/src/entry_efi_32.rs index 34a8d26f..1a40d559 100644 --- a/multiboot2-header/src/entry_efi_32.rs +++ b/multiboot2-header/src/entry_efi_32.rs @@ -62,7 +62,7 @@ impl Debug for EntryEfi32HeaderTag { .field("type", &self.typ()) .field("flags", &self.flags()) .field("size", &self.size()) - .field("entry_addr", &(self.entry_addr as *const u32)) + .field("entry_addr", &self.entry_addr) .finish() } } diff --git a/multiboot2-header/src/entry_efi_64.rs b/multiboot2-header/src/entry_efi_64.rs index 1a673496..28787254 100644 --- a/multiboot2-header/src/entry_efi_64.rs +++ b/multiboot2-header/src/entry_efi_64.rs @@ -62,7 +62,7 @@ impl Debug for EntryEfi64HeaderTag { .field("type", &self.typ()) .field("flags", &self.flags()) .field("size", &self.size()) - .field("entry_addr", &(self.entry_addr as *const u32)) + .field("entry_addr", &self.entry_addr) .finish() } } diff --git a/multiboot2-header/src/relocatable.rs b/multiboot2-header/src/relocatable.rs index 987030c7..9575f592 100644 --- a/multiboot2-header/src/relocatable.rs +++ b/multiboot2-header/src/relocatable.rs @@ -108,10 +108,10 @@ impl Debug for RelocatableHeaderTag { .field("flags", &self.flags()) .field("size", &self.size()) // trick to print this as hexadecimal pointer - .field("min_addr", &(self.min_addr as *const u32)) - .field("max_addr", &(self.max_addr as *const u32)) - .field("align", &{ self.align }) - .field("preference", &{ self.preference }) + .field("min_addr", &self.min_addr) + .field("max_addr", &self.max_addr) + .field("align", &self.align) + .field("preference", &self.preference) .finish() } } diff --git a/multiboot2/src/boot_information.rs b/multiboot2/src/boot_information.rs index 0bf40116..406ddb0c 100644 --- a/multiboot2/src/boot_information.rs +++ b/multiboot2/src/boot_information.rs @@ -132,6 +132,7 @@ impl<'a> BootInformation<'a> { /// Get the start address of the boot info. #[must_use] + // TODO deprecated and use pointers only (see provenance discussions) pub fn start_address(&self) -> usize { self.as_ptr() as usize } @@ -153,6 +154,7 @@ impl<'a> BootInformation<'a> { /// let end_addr = boot_info.start_address() + boot_info.total_size(); /// ``` #[must_use] + // TODO deprecated and use pointers only (see provenance discussions) pub fn end_address(&self) -> usize { self.start_address() + self.total_size() } diff --git a/multiboot2/src/elf_sections.rs b/multiboot2/src/elf_sections.rs index bfe66dda..5b23b160 100644 --- a/multiboot2/src/elf_sections.rs +++ b/multiboot2/src/elf_sections.rs @@ -134,7 +134,7 @@ impl<'a> Iterator for ElfSectionIter<'a> { } } -impl<'a> Debug for ElfSectionIter<'a> { +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| { @@ -183,7 +183,7 @@ struct ElfSectionInner64 { entry_size: u64, } -impl<'a> ElfSection<'a> { +impl ElfSection<'_> { /// Get the section type as a `ElfSectionType` enum variant. #[must_use] pub fn section_type(&self) -> ElfSectionType { diff --git a/multiboot2/src/framebuffer.rs b/multiboot2/src/framebuffer.rs index 78b5da0e..38b31793 100644 --- a/multiboot2/src/framebuffer.rs +++ b/multiboot2/src/framebuffer.rs @@ -319,7 +319,7 @@ pub enum FramebufferType<'a> { Text, } -impl<'a> FramebufferType<'a> { +impl FramebufferType<'_> { #[must_use] #[cfg(feature = "builder")] const fn id(&self) -> FramebufferTypeId { diff --git a/multiboot2/src/memory_map.rs b/multiboot2/src/memory_map.rs index a46feb67..2d633fd4 100644 --- a/multiboot2/src/memory_map.rs +++ b/multiboot2/src/memory_map.rs @@ -455,13 +455,13 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> { } } -impl<'a> ExactSizeIterator for EFIMemoryAreaIter<'a> { +impl ExactSizeIterator for EFIMemoryAreaIter<'_> { fn len(&self) -> usize { self.entries } } -impl<'a> Debug for EFIMemoryAreaIter<'a> { +impl Debug for EFIMemoryAreaIter<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_list(); let iter = self.clone(); diff --git a/multiboot2/src/module.rs b/multiboot2/src/module.rs index 73a334e1..aa7e30d4 100644 --- a/multiboot2/src/module.rs +++ b/multiboot2/src/module.rs @@ -123,7 +123,7 @@ impl<'a> Iterator for ModuleIter<'a> { } } -impl<'a> Debug for ModuleIter<'a> { +impl Debug for ModuleIter<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { let mut list = f.debug_list(); self.clone().for_each(|tag| {