Skip to content

Commit 5831c85

Browse files
committed
multiboot2-header: streamline constructor
1 parent 4a73d8d commit 5831c85

File tree

7 files changed

+28
-42
lines changed

7 files changed

+28
-42
lines changed

multiboot2-header/Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- **BREAKING** bumped dependency to `[email protected]`
77
- **BREAKING** renamed `MULTIBOOT2_HEADER_MAGIC` to `MAGIC`
88
- **BREAKING** renamed `Multiboot2HeaderBuilder` to `HeaderBuilder`
9+
- **BREAKING** renamed `from_addr` to `load`. The function now consumes a ptr.
910
- added the optional `unstable` feature (requires nightly)
1011
- implement `core::error::Error` for `LoadError`
1112

multiboot2-header/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fn main() {
5252
.build();
5353

5454
// Cast bytes in vector to Multiboot2 information structure
55-
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr_bytes.as_ptr() as usize) };
55+
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr_bytes.as_ptr().cast()) };
5656
println!("{:#?}", mb2_hdr);
5757
}
5858
```

multiboot2-header/examples/minimal.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ fn main() {
2323
.build();
2424

2525
// Cast bytes in vector to Multiboot2 information structure
26-
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr_bytes.as_ptr() as usize) };
26+
let mb2_hdr = unsafe { Multiboot2Header::load(mb2_hdr_bytes.as_ptr().cast()) };
2727
println!("{:#?}", mb2_hdr);
2828
}

multiboot2-header/src/builder/header.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,8 @@ mod tests {
281281
println!("expected_len: {} bytes", builder.expected_len());
282282

283283
let mb2_hdr_data = builder.build();
284-
let mb2_hdr = mb2_hdr_data.as_ptr() as usize;
285-
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr) }
284+
let mb2_hdr = mb2_hdr_data.as_ptr().cast();
285+
let mb2_hdr = unsafe { Multiboot2Header::load(mb2_hdr) }
286286
.expect("the generated header to be loadable");
287287
println!("{:#?}", mb2_hdr);
288288
assert_eq!(

multiboot2-header/src/header.rs

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ pub const MAGIC: u32 = 0xe85250d6;
1616
/// by all tags (see [`crate::tags::HeaderTagType`]).
1717
/// Use this if you get a pointer to the header and just want
1818
/// to parse it. If you want to construct the type by yourself,
19-
/// please look at [`crate::builder::HeaderBuilder`].
19+
/// please look at [`crate::builder::HeaderBuilder`]..
20+
#[derive(Debug)]
2021
#[repr(transparent)]
21-
pub struct Multiboot2Header<'a> {
22-
inner: &'a Multiboot2BasicHeader,
23-
}
22+
pub struct Multiboot2Header<'a>(&'a Multiboot2BasicHeader);
2423

2524
impl<'a> Multiboot2Header<'a> {
2625
/// Public constructor for this type with various validations.
@@ -35,21 +34,23 @@ impl<'a> Multiboot2Header<'a> {
3534
/// # Safety
3635
/// This function may produce undefined behaviour, if the provided `addr` is not a valid
3736
/// Multiboot2 header pointer.
38-
// This function can be `const` on newer Rust versions.
39-
#[allow(clippy::missing_const_for_fn)]
40-
pub unsafe fn from_addr(addr: usize) -> Result<Self, LoadError> {
41-
if addr == 0 || addr % 8 != 0 {
37+
pub unsafe fn load(ptr: *const Multiboot2BasicHeader) -> Result<Self, LoadError> {
38+
// null or not aligned
39+
if ptr.is_null() || ptr.align_offset(8) != 0 {
4240
return Err(LoadError::InvalidAddress);
4341
}
44-
let ptr = addr as *const Multiboot2BasicHeader;
42+
4543
let reference = &*ptr;
44+
4645
if reference.header_magic() != MAGIC {
4746
return Err(LoadError::MagicNotFound);
4847
}
48+
4949
if !reference.verify_checksum() {
5050
return Err(LoadError::ChecksumMismatch);
5151
}
52-
Ok(Self { inner: reference })
52+
53+
Ok(Self(reference))
5354
}
5455

5556
/// Find the header in a given slice.
@@ -61,7 +62,7 @@ impl<'a> Multiboot2Header<'a> {
6162
/// If there is no header, it returns `None`.
6263
pub fn find_header(buffer: &[u8]) -> Result<Option<(&[u8], u32)>, LoadError> {
6364
if buffer.as_ptr().align_offset(4) != 0 {
64-
return Err(LoadError::InvalidAddress)
65+
return Err(LoadError::InvalidAddress);
6566
}
6667

6768
let mut windows = buffer[0..8192].windows(4);
@@ -104,27 +105,27 @@ impl<'a> Multiboot2Header<'a> {
104105

105106
/// Wrapper around [`Multiboot2BasicHeader::verify_checksum`].
106107
pub const fn verify_checksum(&self) -> bool {
107-
self.inner.verify_checksum()
108+
self.0.verify_checksum()
108109
}
109110
/// Wrapper around [`Multiboot2BasicHeader::header_magic`].
110111
pub const fn header_magic(&self) -> u32 {
111-
self.inner.header_magic()
112+
self.0.header_magic()
112113
}
113114
/// Wrapper around [`Multiboot2BasicHeader::arch`].
114115
pub const fn arch(&self) -> HeaderTagISA {
115-
self.inner.arch()
116+
self.0.arch()
116117
}
117118
/// Wrapper around [`Multiboot2BasicHeader::length`].
118119
pub const fn length(&self) -> u32 {
119-
self.inner.length()
120+
self.0.length()
120121
}
121122
/// Wrapper around [`Multiboot2BasicHeader::checksum`].
122123
pub const fn checksum(&self) -> u32 {
123-
self.inner.checksum()
124+
self.0.checksum()
124125
}
125126
/// Wrapper around [`Multiboot2BasicHeader::tag_iter`].
126127
pub fn iter(&self) -> Multiboot2HeaderTagIter {
127-
self.inner.tag_iter()
128+
self.0.tag_iter()
128129
}
129130
/// Wrapper around [`Multiboot2BasicHeader::calc_checksum`].
130131
pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
@@ -192,14 +193,6 @@ impl<'a> Multiboot2Header<'a> {
192193
}
193194
}
194195

195-
impl<'a> Debug for Multiboot2Header<'a> {
196-
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
197-
// For debug fmt we only output the inner field
198-
let reference = unsafe { &*(self.inner as *const Multiboot2BasicHeader) };
199-
Debug::fmt(reference, f)
200-
}
201-
}
202-
203196
/// Errors that can occur when parsing a header from a slice.
204197
/// See [`Multiboot2Header::find_header`].
205198
#[derive(Copy, Clone, Debug, derive_more::Display, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -217,9 +210,6 @@ pub enum LoadError {
217210
#[cfg(feature = "unstable")]
218211
impl core::error::Error for LoadError {}
219212

220-
/// **Use this only if you know what you do. You probably want to use
221-
/// [`Multiboot2Header`] instead.**
222-
///
223213
/// The "basic" Multiboot2 header. This means only the properties, that are known during
224214
/// compile time. All other information are derived during runtime from the size property.
225215
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -230,8 +220,8 @@ pub struct Multiboot2BasicHeader {
230220
arch: HeaderTagISA,
231221
length: u32,
232222
checksum: u32,
233-
// additional tags..
234-
// at minimum the end tag
223+
// Followed by dynamic amount of dynamically sized header tags.
224+
// At minimum, the end tag.
235225
}
236226

237227
impl Multiboot2BasicHeader {
@@ -259,7 +249,6 @@ impl Multiboot2BasicHeader {
259249
(0x100000000 - magic as u64 - arch as u64 - length as u64) as u32
260250
}
261251

262-
/// Returns
263252
pub const fn header_magic(&self) -> u32 {
264253
self.header_magic
265254
}

multiboot2-header/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
//! .build();
2626
//!
2727
//! // Cast bytes in vector to Multiboot2 information structure
28-
//! let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr_bytes.as_ptr() as usize) };
28+
//! let mb2_hdr = unsafe { Multiboot2Header::load(mb2_hdr_bytes.as_ptr().cast()) };
2929
//! println!("{:#?}", mb2_hdr);
3030
//!
3131
//! ```

multiboot2/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,8 @@ impl BootInformation<'_> {
204204
/// * The memory at `ptr` must not be modified after calling `load` or the
205205
/// program may observe unsynchronized mutation.
206206
pub unsafe fn load(ptr: *const u8) -> Result<Self, MbiLoadError> {
207-
if ptr.is_null() {
208-
return Err(MbiLoadError::IllegalAddress);
209-
}
210-
211-
// not aligned
212-
if ptr.align_offset(8) != 0 {
207+
// null or not aligned
208+
if ptr.is_null() || ptr.align_offset(8) != 0 {
213209
return Err(MbiLoadError::IllegalAddress);
214210
}
215211

0 commit comments

Comments
 (0)