@@ -182,6 +182,8 @@ impl InformationBuilder {
182182 pub fn build ( self ) -> BootInformationBytes {
183183 const ALIGN : usize = 8 ;
184184
185+ // PHASE 1/3: Prepare Vector
186+
185187 // We allocate more than necessary so that we can ensure an correct
186188 // alignment within this data.
187189 let alloc_len = self . expected_len ( ) + 7 ;
@@ -199,90 +201,99 @@ impl InformationBuilder {
199201 let offset = bytes. as_ptr ( ) . align_offset ( ALIGN ) ;
200202 bytes. extend ( [ 0 ] . repeat ( offset) ) ;
201203
204+ // -----------------------------------------------
205+ // PHASE 2/3: Add Tags
206+ self . build_add_tags ( & mut bytes) ;
207+
208+ // -----------------------------------------------
209+ // PHASE 3/3: Finalize Vector
210+
211+ // Ensure that the vector has the same length as it's capacity. This is
212+ // important so that miri doesn't complain that the boxed memory is
213+ // smaller than the original allocation.
214+ bytes. extend ( [ 0 ] . repeat ( bytes. capacity ( ) - bytes. len ( ) ) ) ;
215+
216+ assert_eq ! (
217+ alloc_ptr,
218+ bytes. as_ptr( ) ,
219+ "Vector was reallocated. Alignment of MBI probably broken!"
220+ ) ;
221+ assert_eq ! (
222+ bytes[ 0 ..offset] . iter( ) . sum:: <u8 >( ) ,
223+ 0 ,
224+ "The offset to alignment area should be zero."
225+ ) ;
226+
227+ // Construct a box from a vec without `into_boxed_slice`. The latter
228+ // calls `shrink` on the allocator, which might reallocate this memory.
229+ // We don't want that!
230+ let bytes = unsafe { Box :: from_raw ( bytes. leak ( ) ) } ;
231+
232+ assert_eq ! ( bytes. len( ) , alloc_len) ;
233+
234+ BootInformationBytes { offset, bytes }
235+ }
236+
237+ /// Helper method that adds all the tags to the given vector.
238+ fn build_add_tags ( & self , bytes : & mut Vec < u8 > ) {
202239 Self :: build_add_bytes (
203- & mut bytes,
240+ bytes,
204241 // important that we write the correct expected length into the header!
205242 & BootInformationHeader :: new ( self . expected_len ( ) as u32 ) . struct_as_bytes ( ) ,
206243 false ,
207244 ) ;
208-
209245 if let Some ( tag) = self . basic_memory_info_tag . as_ref ( ) {
210- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
246+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
211247 }
212248 if let Some ( tag) = self . boot_loader_name_tag . as_ref ( ) {
213- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
249+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
214250 }
215251 if let Some ( tag) = self . command_line_tag . as_ref ( ) {
216- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
252+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
217253 }
218254 if let Some ( tag) = self . efisdt32_tag . as_ref ( ) {
219- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
255+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
220256 }
221257 if let Some ( tag) = self . efisdt64_tag . as_ref ( ) {
222- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
258+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
223259 }
224260 if let Some ( tag) = self . efi_boot_services_not_exited_tag . as_ref ( ) {
225- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
261+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
226262 }
227263 if let Some ( tag) = self . efi_image_handle32 . as_ref ( ) {
228- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
264+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
229265 }
230266 if let Some ( tag) = self . efi_image_handle64 . as_ref ( ) {
231- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
267+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
232268 }
233269 if let Some ( tag) = self . efi_memory_map_tag . as_ref ( ) {
234- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
270+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
235271 }
236272 if let Some ( tag) = self . elf_sections_tag . as_ref ( ) {
237- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
273+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
238274 }
239275 if let Some ( tag) = self . framebuffer_tag . as_ref ( ) {
240- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
276+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
241277 }
242278 if let Some ( tag) = self . image_load_addr . as_ref ( ) {
243- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
279+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
244280 }
245281 if let Some ( tag) = self . memory_map_tag . as_ref ( ) {
246- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
282+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
247283 }
248- for tag in self . module_tags {
249- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
284+ for tag in & self . module_tags {
285+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
250286 }
251287 if let Some ( tag) = self . rsdp_v1_tag . as_ref ( ) {
252- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
288+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
253289 }
254290 if let Some ( tag) = self . rsdp_v2_tag . as_ref ( ) {
255- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
291+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
256292 }
257- for tag in self . smbios_tags {
258- Self :: build_add_bytes ( & mut bytes, & tag. struct_as_bytes ( ) , false )
293+ for tag in & self . smbios_tags {
294+ Self :: build_add_bytes ( bytes, & tag. struct_as_bytes ( ) , false )
259295 }
260- Self :: build_add_bytes ( & mut bytes, & EndTag :: default ( ) . struct_as_bytes ( ) , true ) ;
261-
262- // Ensure that the vector has the same length as it's capacity. This is
263- // important so that miri doesn't complain that the boxed memory is
264- // smaller than the original allocation.
265- bytes. extend ( [ 0 ] . repeat ( bytes. capacity ( ) - bytes. len ( ) ) ) ;
266-
267- assert_eq ! (
268- alloc_ptr,
269- bytes. as_ptr( ) ,
270- "Vector was reallocated. Alignment of MBI probably broken!"
271- ) ;
272- assert_eq ! (
273- bytes[ 0 ..offset] . iter( ) . sum:: <u8 >( ) ,
274- 0 ,
275- "The offset to alignment area should be zero."
276- ) ;
277-
278- // Construct a box from a vec without `into_boxed_slice`. The latter
279- // calls `shrink` on the allocator, which might reallocate this memory.
280- // We don't want that!
281- let bytes = unsafe { Box :: from_raw ( bytes. leak ( ) ) } ;
282-
283- assert_eq ! ( bytes. len( ) , alloc_len) ;
284-
285- BootInformationBytes { offset, bytes }
296+ Self :: build_add_bytes ( bytes, & EndTag :: default ( ) . struct_as_bytes ( ) , true ) ;
286297 }
287298
288299 pub fn basic_memory_info_tag ( & mut self , basic_memory_info_tag : BasicMemoryInfoTag ) {
0 commit comments