Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e1ca2c8

Browse files
committed
make_boxed: add tests for different alignments
1 parent 50f487c commit e1ca2c8

File tree

1 file changed

+55
-14
lines changed

1 file changed

+55
-14
lines changed

‎uefi/src/mem.rs‎

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ mod tests {
7575
use crate::ResultExt;
7676
use core::mem::{align_of, size_of};
7777

78+
/// Some simple dummy type to test [`make_boxed`].
7879
#[derive(Debug)]
7980
#[repr(C)]
8081
struct SomeData([u8; 4]);
@@ -85,53 +86,93 @@ mod tests {
8586
}
8687
}
8788

89+
/// Type wrapper that ensures an alignment of 16 for the underlying data.
90+
#[derive(Debug)]
91+
#[repr(C, align(16))]
92+
struct Align16<T>(T);
93+
94+
/// Version of [`SomeData`] that has an alignment of 16.
95+
type SomeDataAlign16 = Align16<SomeData>;
96+
97+
impl Align for SomeDataAlign16 {
98+
fn alignment() -> usize {
99+
align_of::<Self>()
100+
}
101+
}
102+
88103
/// Function that behaves like the other UEFI functions. It takes a
89104
/// mutable reference to a buffer memory that represents a [`SomeData`]
90105
/// instance.
91-
fn uefi_function_stub_read(buf: &mut [u8]) -> Result<&mut SomeData, Option<usize>> {
92-
if buf.len() < 4 {
93-
return Status::BUFFER_TOO_SMALL.into_with(|| panic!(), |_| Some(4));
106+
fn uefi_function_stub_read<Data: Align>(buf: &mut [u8]) -> Result<&mut Data, Option<usize>> {
107+
let required_size = size_of::<Data>();
108+
109+
if buf.len() < required_size {
110+
// We can use an zero-length buffer to find the required size.
111+
return Status::BUFFER_TOO_SMALL.into_with(|| panic!(), |_| Some(required_size));
94112
};
95113

114+
// assert alignment
115+
assert_eq!(
116+
buf.as_ptr() as usize % Data::alignment(),
117+
0,
118+
"The buffer must be correctly aligned!"
119+
);
120+
96121
buf[0] = 1;
97122
buf[1] = 2;
98123
buf[2] = 3;
99124
buf[3] = 4;
100125

101-
let data = unsafe { &mut *buf.as_mut_ptr().cast::<SomeData>() };
126+
let data = unsafe { &mut *buf.as_mut_ptr().cast::<Data>() };
102127

103128
Ok(data)
104129
}
105130

106-
// Some basic checks so that miri reports everything is fine.
131+
// Some basic sanity checks so that we can catch problems that miri would detect early.
107132
#[test]
108-
fn some_data_type_size_constraints() {
133+
fn test_some_data_type_size_constraints() {
109134
assert_eq!(size_of::<SomeData>(), 4);
110-
assert_eq!(align_of::<SomeData>(), 1);
135+
assert_eq!(SomeData::alignment(), 1);
136+
assert_eq!(
137+
size_of::<SomeDataAlign16>(),
138+
16,
139+
"The size must be 16 instead of 4, as in Rust the runtime size is a multiple of the alignment."
140+
);
141+
assert_eq!(SomeDataAlign16::alignment(), 16);
111142
}
112143

144+
// Tests `uefi_function_stub_read` which is the foundation for the `test_make_boxed_utility`
145+
// test.
113146
#[test]
114-
fn basic_stub_read() {
147+
fn test_basic_stub_read() {
115148
assert_eq!(
116-
uefi_function_stub_read(&mut []).status(),
149+
uefi_function_stub_read::<SomeData>(&mut []).status(),
117150
Status::BUFFER_TOO_SMALL
118151
);
119152
assert_eq!(
120-
*uefi_function_stub_read(&mut []).unwrap_err().data(),
153+
*uefi_function_stub_read::<SomeData>(&mut [])
154+
.unwrap_err()
155+
.data(),
121156
Some(4)
122157
);
123158

124159
let mut buf: [u8; 4] = [0; 4];
125-
let data = uefi_function_stub_read(&mut buf).unwrap();
160+
let data: &mut SomeData = uefi_function_stub_read(&mut buf).unwrap();
161+
assert_eq!(&data.0, &[1, 2, 3, 4]);
126162

127-
assert_eq!(&data.0, &[1, 2, 3, 4])
163+
let mut buf: Align16<[u8; 16]> = Align16([0; 16]);
164+
let data: &mut SomeDataAlign16 = uefi_function_stub_read(&mut buf.0).unwrap();
165+
assert_eq!(&data.0 .0, &[1, 2, 3, 4]);
128166
}
129167

130168
#[test]
131-
fn make_boxed_utility() {
169+
fn test_make_boxed_utility() {
132170
let fetch_data_fn = |buf| uefi_function_stub_read(buf);
133171
let data: Box<SomeData> = make_boxed(fetch_data_fn).unwrap();
172+
assert_eq!(&data.0, &[1, 2, 3, 4]);
134173

135-
assert_eq!(&data.0, &[1, 2, 3, 4])
174+
let fetch_data_fn = |buf| uefi_function_stub_read(buf);
175+
let data: Box<SomeDataAlign16> = make_boxed(fetch_data_fn).unwrap();
176+
assert_eq!(&data.0 .0, &[1, 2, 3, 4]);
136177
}
137178
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /