Skip to content

Commit 829f379

Browse files
authored
Merge pull request #112 from rust-osdev/multiboot2-header-packed-n-fix
multiboot2-header: remove `packed(8)`
2 parents 13a38dd + 728d7b7 commit 829f379

18 files changed

+195
-71
lines changed

multiboot2-header/Changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CHANGELOG for crate `multiboot2-header`
22

3+
## v0.2.0 (2022-05-03)
4+
- **breaking** renamed `EntryHeaderTag` to `EntryAddressHeaderTag`
5+
36
## v0.1.1 (2022-05-02)
47
- fixed a bug that prevented the usage of the crate in `no_std` environments
58
- added a new default `builder`-feature to Cargo which requires the `alloc`-crate

multiboot2-header/src/address.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::mem::size_of;
66
/// other format. Required for legacy boot (BIOS).
77
/// Determines load addresses.
88
#[derive(Copy, Clone, Debug)]
9-
#[repr(C, packed(8))]
9+
#[repr(C)]
1010
pub struct AddressHeaderTag {
1111
typ: HeaderTagType,
1212
flags: HeaderTagFlag,
@@ -64,3 +64,16 @@ impl AddressHeaderTag {
6464
self.bss_end_addr
6565
}
6666
}
67+
68+
#[cfg(test)]
69+
mod tests {
70+
use crate::AddressHeaderTag;
71+
72+
#[test]
73+
fn test_assert_size() {
74+
assert_eq!(
75+
core::mem::size_of::<AddressHeaderTag>(),
76+
2 + 2 + 4 + 4 + 4 + 4 + 4
77+
);
78+
}
79+
}

multiboot2-header/src/builder/header.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use crate::builder::information_request::InformationRequestHeaderTagBuilder;
44
use crate::builder::traits::StructAsBytes;
55
use crate::HeaderTagISA;
66
use crate::{
7-
AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag, EntryEfi32HeaderTag,
8-
EntryEfi64HeaderTag, EntryHeaderTag, FramebufferHeaderTag, ModuleAlignHeaderTag,
9-
Multiboot2BasicHeader, RelocatableHeaderTag,
7+
AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
8+
EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
9+
ModuleAlignHeaderTag, Multiboot2BasicHeader, RelocatableHeaderTag,
1010
};
1111
use alloc::vec::Vec;
1212
use core::mem::size_of;
@@ -22,7 +22,7 @@ pub struct Multiboot2HeaderBuilder {
2222
// second
2323
address_tag: Option<AddressHeaderTag>,
2424
// third
25-
entry_tag: Option<EntryHeaderTag>,
25+
entry_tag: Option<EntryAddressHeaderTag>,
2626
// fourth
2727
console_tag: Option<ConsoleHeaderTag>,
2828
// fifth
@@ -86,7 +86,7 @@ impl Multiboot2HeaderBuilder {
8686
len += Self::size_or_up_aligned(size_of::<AddressHeaderTag>())
8787
}
8888
if self.entry_tag.is_some() {
89-
len += Self::size_or_up_aligned(size_of::<EntryHeaderTag>())
89+
len += Self::size_or_up_aligned(size_of::<EntryAddressHeaderTag>())
9090
}
9191
if self.console_tag.is_some() {
9292
len += Self::size_or_up_aligned(size_of::<ConsoleHeaderTag>())
@@ -192,7 +192,7 @@ impl Multiboot2HeaderBuilder {
192192
self.address_tag = Some(address_tag);
193193
self
194194
}
195-
pub const fn entry_tag(mut self, entry_tag: EntryHeaderTag) -> Self {
195+
pub const fn entry_tag(mut self, entry_tag: EntryAddressHeaderTag) -> Self {
196196
self.entry_tag = Some(entry_tag);
197197
self
198198
}

multiboot2-header/src/builder/traits.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Module for the helper trait [`StructAsBytes`].
22
33
use crate::{
4-
AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag, EntryEfi32HeaderTag,
5-
EntryEfi64HeaderTag, EntryHeaderTag, FramebufferHeaderTag, InformationRequestHeaderTag,
6-
ModuleAlignHeaderTag, Multiboot2BasicHeader, RelocatableHeaderTag,
4+
AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
5+
EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
6+
InformationRequestHeaderTag, ModuleAlignHeaderTag, Multiboot2BasicHeader, RelocatableHeaderTag,
77
};
88
use core::mem::size_of;
99

@@ -39,7 +39,7 @@ impl StructAsBytes for ConsoleHeaderTag {}
3939
impl StructAsBytes for EndHeaderTag {}
4040
impl StructAsBytes for EntryEfi32HeaderTag {}
4141
impl StructAsBytes for EntryEfi64HeaderTag {}
42-
impl StructAsBytes for EntryHeaderTag {}
42+
impl StructAsBytes for EntryAddressHeaderTag {}
4343
impl StructAsBytes for FramebufferHeaderTag {}
4444
impl StructAsBytes for InformationRequestHeaderTag<0> {}
4545
impl StructAsBytes for ModuleAlignHeaderTag {}

multiboot2-header/src/console.rs

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub enum ConsoleHeaderTagFlags {
1414
/// Tells that a console must be available in MBI.
1515
/// Only relevant for legacy BIOS.
1616
#[derive(Copy, Clone, Debug)]
17-
#[repr(C, packed(8))]
17+
#[repr(C)]
1818
pub struct ConsoleHeaderTag {
1919
typ: HeaderTagType,
2020
flags: HeaderTagFlag,
@@ -48,32 +48,10 @@ impl ConsoleHeaderTag {
4848

4949
#[cfg(test)]
5050
mod tests {
51-
use crate::{ConsoleHeaderTag, ConsoleHeaderTagFlags, HeaderTagFlag, HeaderTagType};
52-
use std::mem::size_of_val;
51+
use crate::ConsoleHeaderTag;
5352

54-
/// Checks if rust aligns the type correctly and still "pack" all properties.
55-
/// This test is necessary, because Rust doesn't support "packed" together with "align()" yet.
56-
/// It seems like "packed(N)" does the right thing tho.
57-
///
58-
/// This test is representative for all header tags, because all use the "packed(8)" attribute.
5953
#[test]
60-
fn test_alignment_and_size() {
61-
let tag = ConsoleHeaderTag::new(
62-
HeaderTagFlag::Required,
63-
ConsoleHeaderTagFlags::ConsoleRequired,
64-
);
65-
let ptr = get_ptr!(tag, ConsoleHeaderTag);
66-
let is_aligned = ptr % 8 == 0;
67-
assert!(is_aligned);
68-
// 2x u16, 2x u32
69-
assert_eq!(2 + 2 + 4 + 4, size_of_val(&tag));
70-
71-
assert_eq!(ptr + 0, get_field_ptr!(tag, typ, HeaderTagType));
72-
assert_eq!(ptr + 2, get_field_ptr!(tag, flags, HeaderTagFlag));
73-
assert_eq!(ptr + 4, get_field_ptr!(tag, size, u32));
74-
assert_eq!(
75-
ptr + 8,
76-
get_field_ptr!(tag, console_flags, ConsoleHeaderTagFlags)
77-
);
54+
fn test_assert_size() {
55+
assert_eq!(core::mem::size_of::<ConsoleHeaderTag>(), 2 + 2 + 4 + 4);
7856
}
7957
}

multiboot2-header/src/end.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::{HeaderTagFlag, HeaderTagType};
22
use core::mem::size_of;
33

4-
/// Terminates a list of optional tags
5-
/// in a Multiboot2 header.
4+
/// Terminates a list of optional tags in a Multiboot2 header.
65
#[derive(Copy, Clone, Debug)]
7-
#[repr(C, packed(8))]
6+
#[repr(C)]
87
pub struct EndHeaderTag {
98
// u16 value
109
typ: HeaderTagType,
@@ -32,3 +31,13 @@ impl EndHeaderTag {
3231
self.size
3332
}
3433
}
34+
35+
#[cfg(test)]
36+
mod tests {
37+
use crate::EndHeaderTag;
38+
39+
#[test]
40+
fn test_assert_size() {
41+
assert_eq!(core::mem::size_of::<EndHeaderTag>(), 2 + 2 + 4);
42+
}
43+
}

multiboot2-header/src/entry_header.rs renamed to multiboot2-header/src/entry_address.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,19 @@ use core::fmt::{Debug, Formatter};
44
use core::mem::size_of;
55

66
/// Specifies the physical address to which the boot loader should jump in
7-
/// order to start running the operating system.
8-
/// Not needed for ELF files.
7+
/// order to start running the operating system. Not needed for ELF files.
98
#[derive(Copy, Clone)]
10-
#[repr(C, packed(8))]
11-
pub struct EntryHeaderTag {
9+
#[repr(C)]
10+
pub struct EntryAddressHeaderTag {
1211
typ: HeaderTagType,
1312
flags: HeaderTagFlag,
1413
size: u32,
1514
entry_addr: u32,
1615
}
1716

18-
impl EntryHeaderTag {
17+
impl EntryAddressHeaderTag {
1918
pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
20-
EntryHeaderTag {
19+
EntryAddressHeaderTag {
2120
typ: HeaderTagType::EntryAddress,
2221
flags,
2322
size: size_of::<Self>() as u32,
@@ -39,13 +38,23 @@ impl EntryHeaderTag {
3938
}
4039
}
4140

42-
impl Debug for EntryHeaderTag {
41+
impl Debug for EntryAddressHeaderTag {
4342
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
44-
f.debug_struct("EntryHeaderTag")
43+
f.debug_struct("EntryAddressHeaderTag")
4544
.field("type", &{ self.typ })
4645
.field("flags", &{ self.flags })
4746
.field("size", &{ self.size })
4847
.field("entry_addr", &(self.entry_addr as *const u32))
4948
.finish()
5049
}
5150
}
51+
52+
#[cfg(test)]
53+
mod tests {
54+
use crate::EntryAddressHeaderTag;
55+
56+
#[test]
57+
fn test_assert_size() {
58+
assert_eq!(core::mem::size_of::<EntryAddressHeaderTag>(), 2 + 2 + 4 + 4);
59+
}
60+
}

multiboot2-header/src/entry_efi_32.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ use core::mem::size_of;
66
/// This tag is taken into account only on EFI i386 platforms when Multiboot2 image header
77
/// contains EFI boot services tag. Then entry point specified in ELF header and the entry address
88
/// tag of Multiboot2 header are ignored.
9+
///
10+
/// Technically, this is equivalent to the [`crate::EntryAddressHeaderTag`] but with a different
11+
/// [`crate::HeaderTagType`].
912
#[derive(Copy, Clone)]
10-
#[repr(C, packed(8))]
13+
#[repr(C)]
1114
pub struct EntryEfi32HeaderTag {
1215
typ: HeaderTagType,
1316
flags: HeaderTagFlag,
@@ -49,3 +52,13 @@ impl Debug for EntryEfi32HeaderTag {
4952
.finish()
5053
}
5154
}
55+
56+
#[cfg(test)]
57+
mod tests {
58+
use crate::EntryEfi32HeaderTag;
59+
60+
#[test]
61+
fn test_assert_size() {
62+
assert_eq!(core::mem::size_of::<EntryEfi32HeaderTag>(), 2 + 2 + 4 + 4);
63+
}
64+
}

multiboot2-header/src/entry_efi_64.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ use core::mem::size_of;
66
/// This tag is taken into account only on EFI amd64 platforms when Multiboot2 image header
77
/// contains EFI boot services tag. Then entry point specified in ELF header and the entry address
88
/// tag of Multiboot2 header are ignored.
9+
///
10+
/// Technically, this is equivalent to the [`crate::EntryAddressHeaderTag`] but with a different
11+
/// [`crate::HeaderTagType`].
912
#[derive(Copy, Clone)]
10-
#[repr(C, packed(8))]
13+
#[repr(C)]
1114
pub struct EntryEfi64HeaderTag {
1215
typ: HeaderTagType,
1316
flags: HeaderTagFlag,
@@ -49,3 +52,13 @@ impl Debug for EntryEfi64HeaderTag {
4952
.finish()
5053
}
5154
}
55+
56+
#[cfg(test)]
57+
mod tests {
58+
use crate::EntryEfi64HeaderTag;
59+
60+
#[test]
61+
fn test_assert_size() {
62+
assert_eq!(core::mem::size_of::<EntryEfi64HeaderTag>(), 2 + 2 + 4 + 4);
63+
}
64+
}

multiboot2-header/src/framebuffer.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::mem::size_of;
66
/// has framebuffer support. Note: This is only a
77
/// recommended mode. Only relevant on legacy BIOS.
88
#[derive(Copy, Clone, Debug)]
9-
#[repr(C, packed(8))]
9+
#[repr(C)]
1010
pub struct FramebufferHeaderTag {
1111
typ: HeaderTagType,
1212
flags: HeaderTagFlag,
@@ -47,3 +47,16 @@ impl FramebufferHeaderTag {
4747
self.depth
4848
}
4949
}
50+
51+
#[cfg(test)]
52+
mod tests {
53+
use crate::FramebufferHeaderTag;
54+
55+
#[test]
56+
fn test_assert_size() {
57+
assert_eq!(
58+
core::mem::size_of::<FramebufferHeaderTag>(),
59+
2 + 2 + 4 + 4 + 4 + 4
60+
);
61+
}
62+
}

multiboot2-header/src/header.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
2-
AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag, EntryEfi32HeaderTag,
3-
EntryEfi64HeaderTag, EntryHeaderTag, FramebufferHeaderTag, HeaderTag, HeaderTagISA,
4-
HeaderTagType, InformationRequestHeaderTag, RelocatableHeaderTag,
2+
AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
3+
EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
4+
HeaderTag, HeaderTagISA, HeaderTagType, InformationRequestHeaderTag, RelocatableHeaderTag,
55
};
66
use core::fmt::{Debug, Formatter};
77
use core::mem::size_of;
@@ -103,7 +103,7 @@ impl<'a> Debug for Multiboot2Header<'a> {
103103
/// The "basic" Multiboot2 header. This means only the properties, that are known during
104104
/// compile time. All other information are derived during runtime from the size property.
105105
#[derive(Copy, Clone)]
106-
#[repr(C, packed(8))]
106+
#[repr(C)]
107107
pub struct Multiboot2BasicHeader {
108108
/// Must be the value of [`MULTIBOOT2_HEADER_MAGIC`].
109109
header_magic: u32,
@@ -290,7 +290,7 @@ impl Debug for Multiboot2HeaderTagIter {
290290
let entry = &*(entry);
291291
debug.entry(entry);
292292
} else if typ == HeaderTagType::EntryAddress {
293-
let entry = t as *const EntryHeaderTag;
293+
let entry = t as *const EntryAddressHeaderTag;
294294
let entry = &*(entry);
295295
debug.entry(entry);
296296
} else if typ == HeaderTagType::ConsoleFlags {
@@ -324,3 +324,13 @@ impl Debug for Multiboot2HeaderTagIter {
324324
debug.finish()
325325
}
326326
}
327+
328+
#[cfg(test)]
329+
mod tests {
330+
use crate::Multiboot2BasicHeader;
331+
332+
#[test]
333+
fn test_assert_size() {
334+
assert_eq!(core::mem::size_of::<Multiboot2BasicHeader>(), 4 + 4 + 4 + 4);
335+
}
336+
}

multiboot2-header/src/information_request.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::mem::size_of;
88
/// Specifies what specific tag types the bootloader should provide
99
/// inside the mbi.
1010
#[derive(Copy, Clone)]
11-
#[repr(C, packed(8))]
11+
#[repr(C)]
1212
pub struct InformationRequestHeaderTag<const N: usize> {
1313
typ: HeaderTagType,
1414
flags: HeaderTagFlag,
@@ -130,3 +130,24 @@ impl<'a> Debug for InformationRequestHeaderTagIter<'a> {
130130
debug.finish()
131131
}
132132
}
133+
134+
#[cfg(test)]
135+
mod tests {
136+
use crate::InformationRequestHeaderTag;
137+
138+
#[test]
139+
fn test_assert_size() {
140+
assert_eq!(
141+
core::mem::size_of::<InformationRequestHeaderTag<0>>(),
142+
2 + 2 + 4 + 0 * 4
143+
);
144+
assert_eq!(
145+
core::mem::size_of::<InformationRequestHeaderTag<1>>(),
146+
2 + 2 + 4 + 1 * 4
147+
);
148+
assert_eq!(
149+
core::mem::size_of::<InformationRequestHeaderTag<2>>(),
150+
2 + 2 + 4 + 2 * 4
151+
);
152+
}
153+
}

0 commit comments

Comments
 (0)