@@ -4,10 +4,12 @@ use crate::{
4
4
HeaderTagType , InformationRequestHeaderTag , ModuleAlignHeaderTag , RelocatableHeaderTag ,
5
5
TagIter ,
6
6
} ;
7
+ #[ cfg( feature = "unstable" ) ]
8
+ use core:: error:: Error ;
7
9
use core:: fmt:: { Debug , Formatter } ;
8
10
use core:: mem:: size_of;
9
11
use core:: ptr:: NonNull ;
10
- use multiboot2_common:: { DynSizedStructure , Header , Tag , ALIGNMENT } ;
12
+ use multiboot2_common:: { DynSizedStructure , Header , MemoryError , Tag , ALIGNMENT } ;
11
13
12
14
/// Magic value for a [`Multiboot2Header`], as defined by the spec.
13
15
pub const MAGIC : u32 = 0xe85250d6 ;
@@ -35,8 +37,8 @@ impl<'a> Multiboot2Header<'a> {
35
37
/// This function may produce undefined behaviour, if the provided `addr` is not a valid
36
38
/// Multiboot2 header pointer.
37
39
pub unsafe fn load ( ptr : * const Multiboot2BasicHeader ) -> Result < Self , LoadError > {
38
- let ptr = NonNull :: new ( ptr. cast_mut ( ) ) . ok_or ( LoadError :: InvalidAddress ) ?;
39
- let inner = DynSizedStructure :: ref_from_ptr ( ptr) . map_err ( |_e| LoadError :: TooSmall ) ?;
40
+ let ptr = NonNull :: new ( ptr. cast_mut ( ) ) . ok_or ( LoadError :: Memory ( MemoryError :: Null ) ) ?;
41
+ let inner = DynSizedStructure :: ref_from_ptr ( ptr) . map_err ( LoadError :: Memory ) ?;
40
42
let this = Self ( inner) ;
41
43
42
44
let header = this. 0 . header ( ) ;
@@ -58,7 +60,7 @@ impl<'a> Multiboot2Header<'a> {
58
60
/// If there is no header, it returns `None`.
59
61
pub fn find_header ( buffer : & [ u8 ] ) -> Result < Option < ( & [ u8 ] , u32 ) > , LoadError > {
60
62
if buffer. as_ptr ( ) . align_offset ( ALIGNMENT ) != 0 {
61
- return Err ( LoadError :: InvalidAddress ) ;
63
+ return Err ( LoadError :: Memory ( MemoryError :: WrongAlignment ) ) ;
62
64
}
63
65
64
66
let mut windows = buffer[ 0 ..8192 ] . windows ( 4 ) ;
@@ -70,7 +72,7 @@ impl<'a> Multiboot2Header<'a> {
70
72
if idx % 8 == 0 {
71
73
idx
72
74
} else {
73
- return Err ( LoadError :: InvalidAddress ) ;
75
+ return Err ( LoadError :: Memory ( MemoryError :: WrongAlignment ) ) ;
74
76
}
75
77
}
76
78
None => return Ok ( None ) ,
@@ -87,7 +89,7 @@ impl<'a> Multiboot2Header<'a> {
87
89
let header_length: usize = u32:: from_le_bytes (
88
90
windows
89
91
. next ( )
90
- . ok_or ( LoadError :: TooSmall ) ?
92
+ . ok_or ( LoadError :: Memory ( MemoryError :: MissingPadding ) ) ?
91
93
. try_into ( )
92
94
. unwrap ( ) , // 4 bytes are a u32
93
95
)
@@ -221,22 +223,28 @@ impl Debug for Multiboot2Header<'_> {
221
223
}
222
224
}
223
225
224
- /// Errors that can occur when parsing a header from a slice.
225
- /// See [`Multiboot2Header::find_header `].
226
+ /// Errors that occur when a chunk of memory can't be parsed as
227
+ /// [`Multiboot2Header`].
226
228
#[ derive( Copy , Clone , Debug , derive_more:: Display , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
227
229
pub enum LoadError {
228
- /// The checksum does not match the data .
230
+ /// The provided checksum does not match the expected value .
229
231
ChecksumMismatch ,
230
- /// The header is not properly 64-bit aligned (or a null pointer).
231
- InvalidAddress ,
232
232
/// The header does not contain the correct magic number.
233
233
MagicNotFound ,
234
- /// The header is truncated.
235
- TooSmall ,
234
+ /// The provided memory can't be parsed as [`Multiboot2Header`].
235
+ /// See [`MemoryError`].
236
+ Memory ( MemoryError ) ,
236
237
}
237
238
238
239
#[ cfg( feature = "unstable" ) ]
239
- impl core:: error:: Error for LoadError { }
240
+ impl Error for LoadError {
241
+ fn source ( & self ) -> Option < & ( dyn Error + ' static ) > {
242
+ match self {
243
+ Self :: Memory ( inner) => Some ( inner) ,
244
+ _ => None ,
245
+ }
246
+ }
247
+ }
240
248
241
249
/// The "basic" Multiboot2 header. This means only the properties, that are known during
242
250
/// compile time. All other information are derived during runtime from the size property.
0 commit comments