Skip to content

Commit 41e42cf

Browse files
committed
builder: cleanup large build function
1 parent cda8237 commit 41e42cf

File tree

2 files changed

+108
-85
lines changed

2 files changed

+108
-85
lines changed

multiboot2-header/src/builder/header.rs

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,11 @@ impl HeaderBuilder {
159159
}
160160

161161
/// Constructs the bytes for a valid Multiboot2 header with the given properties.
162-
pub fn build(self) -> HeaderBytes {
162+
pub fn build(mut self) -> HeaderBytes {
163163
const ALIGN: usize = 8;
164164

165+
// PHASE 1/3: Prepare Vector
166+
165167
// We allocate more than necessary so that we can ensure an correct
166168
// alignment within this data.
167169
let alloc_len = self.expected_len() + 7;
@@ -179,44 +181,12 @@ impl HeaderBuilder {
179181
let offset = bytes.as_ptr().align_offset(ALIGN);
180182
bytes.extend([0].repeat(offset));
181183

182-
Self::build_add_bytes(
183-
&mut bytes,
184-
// important that we write the correct expected length into the header!
185-
&Multiboot2BasicHeader::new(self.arch, self.expected_len() as u32).struct_as_bytes(),
186-
false,
187-
);
184+
// -----------------------------------------------
185+
// PHASE 2/3: Add Tags
186+
self.build_add_tags(&mut bytes);
188187

189-
if let Some(irs) = self.information_request_tag {
190-
Self::build_add_bytes(&mut bytes, &irs.build(), false)
191-
}
192-
if let Some(tag) = self.address_tag.as_ref() {
193-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
194-
}
195-
if let Some(tag) = self.entry_tag.as_ref() {
196-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
197-
}
198-
if let Some(tag) = self.console_tag.as_ref() {
199-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
200-
}
201-
if let Some(tag) = self.framebuffer_tag.as_ref() {
202-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
203-
}
204-
if let Some(tag) = self.module_align_tag.as_ref() {
205-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
206-
}
207-
if let Some(tag) = self.efi_bs_tag.as_ref() {
208-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
209-
}
210-
if let Some(tag) = self.efi_32_tag.as_ref() {
211-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
212-
}
213-
if let Some(tag) = self.efi_64_tag.as_ref() {
214-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
215-
}
216-
if let Some(tag) = self.relocatable_tag.as_ref() {
217-
Self::build_add_bytes(&mut bytes, &tag.struct_as_bytes(), false)
218-
}
219-
Self::build_add_bytes(&mut bytes, &EndHeaderTag::new().struct_as_bytes(), true);
188+
// -----------------------------------------------
189+
// PHASE 3/3: Finalize Vector
220190

221191
// Ensure that the vector has the same length as it's capacity. This is
222192
// important so that miri doesn't complain that the boxed memory is
@@ -244,6 +214,48 @@ impl HeaderBuilder {
244214
HeaderBytes { offset, bytes }
245215
}
246216

217+
/// Helper method that adds all the tags to the given vector.
218+
fn build_add_tags(&mut self, bytes: &mut Vec<u8>) {
219+
Self::build_add_bytes(
220+
bytes,
221+
// important that we write the correct expected length into the header!
222+
&Multiboot2BasicHeader::new(self.arch, self.expected_len() as u32).struct_as_bytes(),
223+
false,
224+
);
225+
226+
if let Some(irs) = self.information_request_tag.take() {
227+
Self::build_add_bytes(bytes, &irs.build(), false)
228+
}
229+
if let Some(tag) = self.address_tag.as_ref() {
230+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
231+
}
232+
if let Some(tag) = self.entry_tag.as_ref() {
233+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
234+
}
235+
if let Some(tag) = self.console_tag.as_ref() {
236+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
237+
}
238+
if let Some(tag) = self.framebuffer_tag.as_ref() {
239+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
240+
}
241+
if let Some(tag) = self.module_align_tag.as_ref() {
242+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
243+
}
244+
if let Some(tag) = self.efi_bs_tag.as_ref() {
245+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
246+
}
247+
if let Some(tag) = self.efi_32_tag.as_ref() {
248+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
249+
}
250+
if let Some(tag) = self.efi_64_tag.as_ref() {
251+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
252+
}
253+
if let Some(tag) = self.relocatable_tag.as_ref() {
254+
Self::build_add_bytes(bytes, &tag.struct_as_bytes(), false)
255+
}
256+
Self::build_add_bytes(bytes, &EndHeaderTag::new().struct_as_bytes(), true);
257+
}
258+
247259
// clippy thinks this can be a const fn but the compiler denies it
248260
#[allow(clippy::missing_const_for_fn)]
249261
pub fn information_request_tag(

multiboot2/src/builder/information.rs

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)