@@ -8,19 +8,18 @@ use core::convert::TryInto;
8
8
use core:: fmt:: { Debug , Formatter } ;
9
9
use core:: mem:: size_of;
10
10
11
- /// Magic value for a [`Multiboot2Header`], as defined in spec.
12
- pub const MULTIBOOT2_HEADER_MAGIC : u32 = 0xe85250d6 ;
11
+ /// Magic value for a [`Multiboot2Header`], as defined by the spec.
12
+ pub const MAGIC : u32 = 0xe85250d6 ;
13
13
14
14
/// Wrapper type around a pointer to the Multiboot2 header.
15
15
/// The Multiboot2 header is the [`Multiboot2BasicHeader`] followed
16
16
/// by all tags (see [`crate::tags::HeaderTagType`]).
17
17
/// Use this if you get a pointer to the header and just want
18
18
/// 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 ) ]
20
21
#[ repr( transparent) ]
21
- pub struct Multiboot2Header < ' a > {
22
- inner : & ' a Multiboot2BasicHeader ,
23
- }
22
+ pub struct Multiboot2Header < ' a > ( & ' a Multiboot2BasicHeader ) ;
24
23
25
24
impl < ' a > Multiboot2Header < ' a > {
26
25
/// Public constructor for this type with various validations.
@@ -35,37 +34,41 @@ impl<'a> Multiboot2Header<'a> {
35
34
/// # Safety
36
35
/// This function may produce undefined behaviour, if the provided `addr` is not a valid
37
36
/// 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 {
42
40
return Err ( LoadError :: InvalidAddress ) ;
43
41
}
44
- let ptr = addr as * const Multiboot2BasicHeader ;
42
+
45
43
let reference = & * ptr;
46
- if reference. header_magic ( ) != MULTIBOOT2_HEADER_MAGIC {
44
+
45
+ if reference. header_magic ( ) != MAGIC {
47
46
return Err ( LoadError :: MagicNotFound ) ;
48
47
}
48
+
49
49
if !reference. verify_checksum ( ) {
50
50
return Err ( LoadError :: ChecksumMismatch ) ;
51
51
}
52
- Ok ( Self { inner : reference } )
52
+
53
+ Ok ( Self ( reference) )
53
54
}
54
55
55
56
/// Find the header in a given slice.
56
57
///
57
58
/// If it succeeds, it returns a tuple consisting of the subslice containing
58
59
/// just the header and the index of the header in the given slice.
59
- /// If it fails (either because the header is not properply 64-bit aligned
60
+ /// If it fails (either because the header is not properly 64-bit aligned
60
61
/// or because it is truncated), it returns a [`LoadError`].
61
62
/// If there is no header, it returns `None`.
62
63
pub fn find_header ( buffer : & [ u8 ] ) -> Result < Option < ( & [ u8 ] , u32 ) > , LoadError > {
63
- // the magic is 32 bit aligned and inside the first 8192 bytes
64
- assert ! ( buffer. len( ) >= 8192 ) ;
64
+ if buffer. as_ptr ( ) . align_offset ( 4 ) != 0 {
65
+ return Err ( LoadError :: InvalidAddress ) ;
66
+ }
67
+
65
68
let mut windows = buffer[ 0 ..8192 ] . windows ( 4 ) ;
66
69
let magic_index = match windows. position ( |vals| {
67
70
u32:: from_le_bytes ( vals. try_into ( ) . unwrap ( ) ) // yes, there's 4 bytes here
68
- == MULTIBOOT2_HEADER_MAGIC
71
+ == MAGIC
69
72
} ) {
70
73
Some ( idx) => {
71
74
if idx % 8 == 0 {
@@ -102,27 +105,27 @@ impl<'a> Multiboot2Header<'a> {
102
105
103
106
/// Wrapper around [`Multiboot2BasicHeader::verify_checksum`].
104
107
pub const fn verify_checksum ( & self ) -> bool {
105
- self . inner . verify_checksum ( )
108
+ self . 0 . verify_checksum ( )
106
109
}
107
110
/// Wrapper around [`Multiboot2BasicHeader::header_magic`].
108
111
pub const fn header_magic ( & self ) -> u32 {
109
- self . inner . header_magic ( )
112
+ self . 0 . header_magic ( )
110
113
}
111
114
/// Wrapper around [`Multiboot2BasicHeader::arch`].
112
115
pub const fn arch ( & self ) -> HeaderTagISA {
113
- self . inner . arch ( )
116
+ self . 0 . arch ( )
114
117
}
115
118
/// Wrapper around [`Multiboot2BasicHeader::length`].
116
119
pub const fn length ( & self ) -> u32 {
117
- self . inner . length ( )
120
+ self . 0 . length ( )
118
121
}
119
122
/// Wrapper around [`Multiboot2BasicHeader::checksum`].
120
123
pub const fn checksum ( & self ) -> u32 {
121
- self . inner . checksum ( )
124
+ self . 0 . checksum ( )
122
125
}
123
126
/// Wrapper around [`Multiboot2BasicHeader::tag_iter`].
124
127
pub fn iter ( & self ) -> Multiboot2HeaderTagIter {
125
- self . inner . tag_iter ( )
128
+ self . 0 . tag_iter ( )
126
129
}
127
130
/// Wrapper around [`Multiboot2BasicHeader::calc_checksum`].
128
131
pub const fn calc_checksum ( magic : u32 , arch : HeaderTagISA , length : u32 ) -> u32 {
@@ -190,14 +193,6 @@ impl<'a> Multiboot2Header<'a> {
190
193
}
191
194
}
192
195
193
- impl < ' a > Debug for Multiboot2Header < ' a > {
194
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
195
- // For debug fmt we only output the inner field
196
- let reference = unsafe { & * ( self . inner as * const Multiboot2BasicHeader ) } ;
197
- Debug :: fmt ( reference, f)
198
- }
199
- }
200
-
201
196
/// Errors that can occur when parsing a header from a slice.
202
197
/// See [`Multiboot2Header::find_header`].
203
198
#[ derive( Copy , Clone , Debug , derive_more:: Display , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
@@ -215,28 +210,25 @@ pub enum LoadError {
215
210
#[ cfg( feature = "unstable" ) ]
216
211
impl core:: error:: Error for LoadError { }
217
212
218
- /// **Use this only if you know what you do. You probably want to use
219
- /// [`Multiboot2Header`] instead.**
220
- ///
221
213
/// The "basic" Multiboot2 header. This means only the properties, that are known during
222
214
/// compile time. All other information are derived during runtime from the size property.
223
215
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
224
216
#[ repr( C ) ]
225
217
pub struct Multiboot2BasicHeader {
226
- /// Must be the value of [`MULTIBOOT2_HEADER_MAGIC `].
218
+ /// Must be the value of [`MAGIC `].
227
219
header_magic : u32 ,
228
220
arch : HeaderTagISA ,
229
221
length : u32 ,
230
222
checksum : u32 ,
231
- // additional tags. .
232
- // at minimum the end tag
223
+ // Followed by dynamic amount of dynamically sized header tags.
224
+ // At minimum, the end tag.
233
225
}
234
226
235
227
impl Multiboot2BasicHeader {
236
228
#[ cfg( feature = "builder" ) ]
237
229
/// Constructor for the basic header.
238
230
pub ( crate ) const fn new ( arch : HeaderTagISA , length : u32 ) -> Self {
239
- let magic = MULTIBOOT2_HEADER_MAGIC ;
231
+ let magic = MAGIC ;
240
232
let checksum = Self :: calc_checksum ( magic, arch, length) ;
241
233
Multiboot2BasicHeader {
242
234
header_magic : magic,
@@ -257,7 +249,6 @@ impl Multiboot2BasicHeader {
257
249
( 0x100000000 - magic as u64 - arch as u64 - length as u64 ) as u32
258
250
}
259
251
260
- /// Returns
261
252
pub const fn header_magic ( & self ) -> u32 {
262
253
self . header_magic
263
254
}
0 commit comments