diff --git a/Cargo.lock b/Cargo.lock index 406ee5b1..65612c5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,7 +25,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.77", "unicode-xid", ] @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -117,9 +117,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -145,9 +145,9 @@ checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-xid" diff --git a/multiboot2-common/architecture.drawio.png b/multiboot2-common/architecture.drawio.png index a3d0e18c..de80e91e 100644 Binary files a/multiboot2-common/architecture.drawio.png and b/multiboot2-common/architecture.drawio.png differ diff --git a/multiboot2-common/architecture.drawio.xml b/multiboot2-common/architecture.drawio.xml index 1e87a57d..ab1dc7eb 100644 --- a/multiboot2-common/architecture.drawio.xml +++ b/multiboot2-common/architecture.drawio.xml @@ -1,160 +1,150 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - + - - + + - + - - + + - + - - + + - + - + - + - - + + - - + + - - + + - - + + - + - - + + - - - - - - - - - - - - + + - + - - + + - - - + + + - + - - + + - - - + + + - - + + @@ -164,8 +154,8 @@ - - + + @@ -175,8 +165,8 @@ - - + + @@ -185,31 +175,43 @@ - + - - + + - - + + - + - + - - + + - - + + - + + + + + + + + + + + + + diff --git a/multiboot2-common/src/bytes_ref.rs b/multiboot2-common/src/bytes_ref.rs index 99cdae5e..f2291408 100644 --- a/multiboot2-common/src/bytes_ref.rs +++ b/multiboot2-common/src/bytes_ref.rs @@ -8,8 +8,10 @@ use core::ops::Deref; /// Wraps a byte slice representing a Multiboot2 structure including an optional /// terminating padding, if necessary. /// -/// Instances of this type guarantee that the memory requirements promised in -/// the crates description are respected. +/// This type helps that casts to a specific tag from the underlying bytes are +/// either same-size casts or down-size casts, but never upsize-casts, which are +/// illegal and UB! Instances of this type guarantee that the memory +/// requirements promised in the crates description are respected. #[derive(Clone, Debug, PartialEq, Eq)] #[repr(transparent)] pub struct BytesRef<'a, H: Header> { diff --git a/multiboot2-common/src/lib.rs b/multiboot2-common/src/lib.rs index e26df689..d4ed7e18 100644 --- a/multiboot2-common/src/lib.rs +++ b/multiboot2-common/src/lib.rs @@ -267,6 +267,11 @@ pub trait Header: Clone + Sized + PartialEq + Eq + Debug { /// Further, there is a variable amount of payload bytes. Thus, this type can /// only exist on the heap or references to it can be made by cast via fat /// pointers. +/// +/// As there might be padding necessary for the proper Rust layout, +/// `size_of_val(&self)` might report additional padding bytes that are not +/// reflected by the actual payload. These additional padding bytes however +/// will be reflected in corresponding [`BytesRef`] instances. #[derive(Debug, PartialEq, Eq, ptr_meta::Pointee)] #[repr(C, align(8))] pub struct DynSizedStructure { @@ -334,14 +339,16 @@ impl DynSizedStructure { /// Performs a memory-safe same-size cast from the base-structure to a /// specific [`MaybeDynSized`]. The idea here is to cast the generic /// mostly semantic-free version to a specific type with fields that have - /// a semantic. + /// a clear semantic. /// /// The provided `T` of type [`MaybeDynSized`] might be may be sized type - /// or DST. This depends on the type. + /// or DST. This depends on the type. However, the source and the target + /// both will have the same actual payload size and the same + /// [`size_of_val`]. /// /// # Panic /// Panics if base assumptions are violated. For example, the - /// `T` of type [`MaybeDynSized`] must allow a proper casting to it. + /// `T` of type [`MaybeDynSized`] must allow proper same-size casting to it. /// /// # Safety /// This function is safe due to various sanity checks and the overall @@ -350,6 +357,8 @@ impl DynSizedStructure { /// # Panics /// This panics if there is a size mismatch. However, this should never be /// the case if all types follow their documented requirements. + /// + /// [`size_of_val`]: mem::size_of_val pub fn cast + ?Sized>(&self) -> &T { let base_ptr = ptr::addr_of!(*self); diff --git a/multiboot2-common/src/tag.rs b/multiboot2-common/src/tag.rs index 29a4da53..1501ede5 100644 --- a/multiboot2-common/src/tag.rs +++ b/multiboot2-common/src/tag.rs @@ -9,9 +9,15 @@ use ptr_meta::Pointee; /// casting a [`DynSizedStructure`] to sized or unsized structures using /// [`DynSizedStructure::cast`]. /// -/// Structs that are a DST must provide a **correct** -/// [`MaybeDynSized::dst_len`] implementation. Further, implementors **must** -/// use `#[repr(C)]`. +/// Structs that are a DST must provide a **correct** [`MaybeDynSized::dst_len`] +/// implementation. +/// +/// # ABI +/// Implementors **must** use `#[repr(C)]`. As there might be padding necessary +/// for the proper Rust layout, `size_of_val(&self)` might report additional +/// padding bytes that are not reflected by the actual payload. These additional +/// padding bytes however will be reflected in corresponding [`BytesRef`] +/// instances. /// /// [`ID`]: Tag::ID /// [`DynSizedStructure`]: crate::DynSizedStructure