@@ -63,8 +63,8 @@ pub use memory_map::{
63
63
pub use module:: { ModuleIter , ModuleTag } ;
64
64
pub use rsdp:: { RsdpV1Tag , RsdpV2Tag } ;
65
65
pub use smbios:: SmbiosTag ;
66
- use tag_type:: TagIter ;
67
66
pub use tag_type:: { EndTag , Tag , TagType , TagTypeId } ;
67
+ use tag_type:: { TagIter , TagIterMut } ;
68
68
pub use vbe_info:: {
69
69
VBECapabilities , VBEControlInfo , VBEDirectColorAttributes , VBEField , VBEInfoTag ,
70
70
VBEMemoryModel , VBEModeAttributes , VBEModeInfo , VBEWindowAttributes ,
@@ -276,6 +276,11 @@ impl BootInformation {
276
276
self . get_tag :: < MemoryMapTag , _ > ( TagType :: Mmap )
277
277
}
278
278
279
+ /// Search for the Memory map tag, return a mutable reference.
280
+ pub fn memory_map_tag_mut ( & mut self ) -> Option < & mut MemoryMapTag > {
281
+ self . get_tag_mut :: < MemoryMapTag , _ > ( TagType :: Mmap )
282
+ }
283
+
279
284
/// Get an iterator of all module tags.
280
285
pub fn module_tags ( & self ) -> ModuleIter {
281
286
module:: module_iter ( self . tags ( ) )
@@ -427,9 +432,23 @@ impl BootInformation {
427
432
. map ( |tag| tag. cast_tag :: < TagT > ( ) )
428
433
}
429
434
435
+ fn get_tag_mut < TagT : TagTrait + ?Sized , TagType : Into < TagTypeId > > (
436
+ & mut self ,
437
+ typ : TagType ,
438
+ ) -> Option < & mut TagT > {
439
+ let typ = typ. into ( ) ;
440
+ self . tags_mut ( )
441
+ . find ( |tag| tag. typ == typ)
442
+ . map ( |tag| tag. cast_tag_mut :: < TagT > ( ) )
443
+ }
444
+
430
445
fn tags ( & self ) -> TagIter {
431
446
TagIter :: new ( unsafe { self . inner . offset ( 1 ) } as * const _ )
432
447
}
448
+
449
+ fn tags_mut ( & mut self ) -> TagIterMut {
450
+ TagIterMut :: new ( unsafe { self . inner . offset ( 1 ) } as * mut _ )
451
+ }
433
452
}
434
453
435
454
impl BootInformationInner {
@@ -567,6 +586,19 @@ pub trait TagTrait: Pointee {
567
586
let ptr = ptr_meta:: from_raw_parts ( ptr, Self :: dst_size ( tag) ) ;
568
587
& * ptr
569
588
}
589
+
590
+ /// Creates a mutable reference to a (dynamically sized) tag type in a safe way.
591
+ /// DST tags need to implement a proper [`Self::dst_size`] implementation.
592
+ ///
593
+ /// # Safety
594
+ /// Callers must be sure that the "size" field of the provided [`Tag`] is
595
+ /// sane and the underlying memory valid. The implementation of this trait
596
+ /// **must have** a correct [`Self::dst_size`] implementation.
597
+ unsafe fn from_base_tag_mut < ' a > ( tag : & mut Tag ) -> & ' a mut Self {
598
+ let ptr = tag as * mut _ as * mut ( ) ;
599
+ let ptr = ptr_meta:: from_raw_parts_mut ( ptr, Self :: dst_size ( tag) ) ;
600
+ & mut * ptr
601
+ }
570
602
}
571
603
572
604
// All sized tags automatically have a Pointee implementation where
0 commit comments