mirror of
https://github.com/rust-osdev/uefi-rs
synced 2026-08-26 18:26:05 -04:00
Merge pull request #2039 from rust-osdev/abi
replace ABI-related unit tests with const checks
This commit is contained in:
commit
ef8641b510
6 changed files with 50 additions and 49 deletions
|
|
@ -86,6 +86,14 @@ pub type VirtualAddress = u64;
|
|||
#[repr(transparent)]
|
||||
pub struct Boolean(pub u8);
|
||||
|
||||
// Ensure ABI guarantees for Boolean, as promised in [0].
|
||||
//
|
||||
// [0]: https://github.com/tianocore/edk2/blob/b0f43dd3fdec2363e3548ec31eb455dc1c4ac761/MdePkg/Include/X64/ProcessorBind.h#L192
|
||||
const _: () = {
|
||||
assert!(align_of::<Boolean>() == 1);
|
||||
assert!(size_of::<Boolean>() == 1);
|
||||
};
|
||||
|
||||
impl Boolean {
|
||||
/// [`Boolean`] representing `true`.
|
||||
///
|
||||
|
|
@ -169,12 +177,10 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
/// Test the properties promised in [0]. This also applies for the other
|
||||
/// architectures.
|
||||
/// Test the properties promised in [0] and convenient rusty conversions.
|
||||
///
|
||||
/// [0] https://github.com/tianocore/edk2/blob/b0f43dd3fdec2363e3548ec31eb455dc1c4ac761/MdePkg/Include/X64/ProcessorBind.h#L192
|
||||
fn test_boolean_abi() {
|
||||
assert_eq!(size_of::<Boolean>(), 1);
|
||||
fn test_boolean_conversions() {
|
||||
assert_eq!(Boolean::from(true).0, 1);
|
||||
assert_eq!(Boolean::from(false).0, 0);
|
||||
assert_eq!(Boolean::TRUE.0, 1);
|
||||
|
|
|
|||
|
|
@ -130,6 +130,20 @@ pub union IpAddress {
|
|||
pub v6: Ipv6Address,
|
||||
}
|
||||
|
||||
// Ensure ABI guarantees for IpAddress.
|
||||
const _: () = {
|
||||
#[repr(C, packed)]
|
||||
struct PackedHelper<T>(T);
|
||||
|
||||
assert!(align_of::<IpAddress>() == 4);
|
||||
assert!(size_of::<IpAddress>() == 16);
|
||||
|
||||
// The type must be usable in a packed struct, even when it is normally
|
||||
// 4 byte aligned.
|
||||
assert!(align_of::<PackedHelper<IpAddress>>() == 1);
|
||||
assert!(size_of::<PackedHelper<IpAddress>>() == 16);
|
||||
};
|
||||
|
||||
impl IpAddress {
|
||||
/// Zeroed variant where all bytes are guaranteed to be initialized to zero.
|
||||
pub const ZERO: Self = Self { addr: [0; 4] };
|
||||
|
|
@ -355,20 +369,6 @@ mod tests {
|
|||
assert_eq!(efi_mac_addr.into_ethernet_addr(), ethernet_octets);
|
||||
}
|
||||
|
||||
// Ensure that our IpAddress type can be put into a packed struct,
|
||||
// even when it is normally 4 byte aligned.
|
||||
#[test]
|
||||
fn test_efi_ip_address_abi() {
|
||||
#[repr(C, packed)]
|
||||
struct PackedHelper<T>(T);
|
||||
|
||||
assert_eq!(align_of::<IpAddress>(), 4);
|
||||
assert_eq!(size_of::<IpAddress>(), 16);
|
||||
|
||||
assert_eq!(align_of::<PackedHelper<IpAddress>>(), 1);
|
||||
assert_eq!(size_of::<PackedHelper<IpAddress>>(), 16);
|
||||
}
|
||||
|
||||
/// Tests the From-impls from the documentation.
|
||||
#[test]
|
||||
fn test_promised_from_impls() {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ pub struct DevicePathProtocol {
|
|||
// followed by payload (dynamically sized)
|
||||
}
|
||||
|
||||
// Ensure ABI guarantees for DevicePathProtocol. The struct is naturally
|
||||
// packed; thus, we don't need to explicitly specify `packed`.
|
||||
const _: () = {
|
||||
assert!(size_of::<DevicePathProtocol>() == 4);
|
||||
assert!(align_of::<DevicePathProtocol>() == 1);
|
||||
};
|
||||
|
||||
impl DevicePathProtocol {
|
||||
pub const GUID: Guid = guid!("09576e91-6d3f-11d2-8e39-00a0c969723b");
|
||||
|
||||
|
|
@ -300,16 +307,3 @@ pub struct DevicePathUtilitiesProtocol {
|
|||
impl DevicePathUtilitiesProtocol {
|
||||
pub const GUID: Guid = guid!("0379be4e-d706-437d-b037-edb82fb772a4");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Test that ensures the struct is packed. Thus, we don't need to
|
||||
/// explicitly specify `packed`.
|
||||
#[test]
|
||||
fn abi() {
|
||||
assert_eq!(size_of::<DevicePathProtocol>(), 4);
|
||||
assert_eq!(align_of::<DevicePathProtocol>(), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,17 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
// Some basic sanity checks of the helper types so that we can catch
|
||||
// problems early that miri would detect otherwise.
|
||||
const _: () = {
|
||||
assert!(size_of::<SomeData>() == 4);
|
||||
assert!(align_of::<SomeData>() == 1);
|
||||
// The size is 16 instead of 4, as in Rust the size is always a
|
||||
// multiple of the alignment.
|
||||
assert!(size_of::<SomeDataAlign16>() == 16);
|
||||
assert!(align_of::<SomeDataAlign16>() == 16);
|
||||
};
|
||||
|
||||
/// Function that behaves like the other UEFI functions. It takes a
|
||||
/// mutable reference to a buffer memory that represents a [`SomeData`]
|
||||
/// instance.
|
||||
|
|
@ -139,20 +150,6 @@ mod tests {
|
|||
Ok(data)
|
||||
}
|
||||
|
||||
// Some basic sanity checks so that we can catch problems early that miri would detect
|
||||
// otherwise.
|
||||
#[test]
|
||||
fn test_some_data_type_size_constraints() {
|
||||
assert_eq!(size_of::<SomeData>(), 4);
|
||||
assert_eq!(SomeData::alignment(), 1);
|
||||
assert_eq!(
|
||||
size_of::<SomeDataAlign16>(),
|
||||
16,
|
||||
"The size must be 16 instead of 4, as in Rust the runtime size is a multiple of the alignment."
|
||||
);
|
||||
assert_eq!(SomeDataAlign16::alignment(), 16);
|
||||
}
|
||||
|
||||
// Tests `uefi_function_stub_read` which is the foundation for the `test_make_boxed_utility`
|
||||
// test.
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -509,6 +509,10 @@ pub struct DevicePath {
|
|||
data: [u8],
|
||||
}
|
||||
|
||||
// References to the DST are transmuted from/to slice references; ensure
|
||||
// both have the same fat-pointer layout.
|
||||
const _: () = assert!(size_of::<&DevicePath>() == size_of::<&[u8]>());
|
||||
|
||||
impl ProtocolPointer for DevicePath {
|
||||
unsafe fn ptr_from_ffi(ptr: *const c_void) -> *const Self {
|
||||
// SAFETY: The memory is valid.
|
||||
|
|
@ -1119,9 +1123,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_to_owned() {
|
||||
// Relevant assertion to verify the transmute is fine.
|
||||
assert_eq!(size_of::<&DevicePath>(), size_of::<&[u8]>());
|
||||
|
||||
let raw_data = create_raw_device_path();
|
||||
// SAFETY: The memory is valid.
|
||||
let dp = unsafe { DevicePath::from_ffi_ptr(raw_data.as_ptr().cast()) };
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ pub struct PciIoAddress {
|
|||
pub ext_reg: u32,
|
||||
}
|
||||
|
||||
// The address is converted to/from a raw u64 value; ensure both have the
|
||||
// same size.
|
||||
const _: () = assert!(size_of::<PciIoAddress>() == size_of::<u64>());
|
||||
|
||||
impl PciIoAddress {
|
||||
/// Create address pointing to the device identified by `bus`, `dev` and `fun` ids.
|
||||
#[must_use]
|
||||
|
|
@ -170,7 +174,6 @@ mod tests {
|
|||
#[test]
|
||||
#[expect(clippy::unusual_byte_groupings)]
|
||||
fn test_pci_ioaddr_raw_conversion() {
|
||||
assert_eq!(size_of::<u64>(), size_of::<PciIoAddress>());
|
||||
let srcaddr = PciIoAddress {
|
||||
reg: 0x11,
|
||||
fun: 0x33,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue