@@ -182,6 +182,8 @@ impl InformationBuilder {
182
182
pub fn build ( self ) -> BootInformationBytes {
183
183
const ALIGN : usize = 8 ;
184
184
185
+ // PHASE 1/3: Prepare Vector
186
+
185
187
// We allocate more than necessary so that we can ensure an correct
186
188
// alignment within this data.
187
189
let alloc_len = self . expected_len ( ) + 7 ;
@@ -199,90 +201,99 @@ impl InformationBuilder {
199
201
let offset = bytes. as_ptr ( ) . align_offset ( ALIGN ) ;
200
202
bytes. extend ( [ 0 ] . repeat ( offset) ) ;
201
203
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 > ) {
202
239
Self :: build_add_bytes (
203
- & mut bytes,
240
+ bytes,
204
241
// important that we write the correct expected length into the header!
205
242
& BootInformationHeader :: new ( self . expected_len ( ) as u32 ) . struct_as_bytes ( ) ,
206
243
false ,
207
244
) ;
208
-
209
245
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 )
211
247
}
212
248
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 )
214
250
}
215
251
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 )
217
253
}
218
254
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 )
220
256
}
221
257
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 )
223
259
}
224
260
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 )
226
262
}
227
263
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 )
229
265
}
230
266
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 )
232
268
}
233
269
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 )
235
271
}
236
272
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 )
238
274
}
239
275
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 )
241
277
}
242
278
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 )
244
280
}
245
281
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 )
247
283
}
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 )
250
286
}
251
287
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 )
253
289
}
254
290
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 )
256
292
}
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 )
259
295
}
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 ) ;
286
297
}
287
298
288
299
pub fn basic_memory_info_tag ( & mut self , basic_memory_info_tag : BasicMemoryInfoTag ) {
0 commit comments