From 497ba1cdf9f73d46275c446487db7b98b2a4203f Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 8 Aug 2024 17:18:57 +0100 Subject: [PATCH] [rust] use explicit `repr(C, packed)` instead of just `repr(packed)` `repr(packed)` only guarantees no internal padding, not that the fields will not be reordered. Signed-off-by: Gary Guo --- doc/rust_for_c_devs.md | 4 ++-- sw/host/opentitanlib/src/transport/hyperdebug/i2c.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/rust_for_c_devs.md b/doc/rust_for_c_devs.md index 6119d105d7203..9e4ab16fc0143 100644 --- a/doc/rust_for_c_devs.md +++ b/doc/rust_for_c_devs.md @@ -169,8 +169,8 @@ struct MyCStruct { ``` This is guaranteed to lay out fields in declaration order, adding padding for alignment. `#[repr(Rust)]` is the implicit default. -`#[repr(packed)]` is analogous to `__attribute__((packed))`, and will not produce any padding[^21]. -The alignment of the whole struct can be forced to a larger value using `#[repr(align(N))]`, similar to `_Alignas`. +`#[repr(C, packed)]` is analogous to `__attribute__((packed))`, and will not produce any padding[^21]. +The alignment of the whole struct can be forced to a larger value using `#[repr(C, align(N))]`, similar to `_Alignas`. Fields can be accessed using the same dot syntax as C: `my_struct.foo`, `my_struct.bar = 5;`. diff --git a/sw/host/opentitanlib/src/transport/hyperdebug/i2c.rs b/sw/host/opentitanlib/src/transport/hyperdebug/i2c.rs index f64942b18dc4d..725c20588d3c5 100644 --- a/sw/host/opentitanlib/src/transport/hyperdebug/i2c.rs +++ b/sw/host/opentitanlib/src/transport/hyperdebug/i2c.rs @@ -37,7 +37,7 @@ const USB_MAX_SIZE: usize = 64; /// (receiving at most 127 bytes). #[derive(AsBytes, FromBytes, FromZeroes, Debug)] #[allow(dead_code)] // Fields not explicitly read anywhere -#[repr(packed)] +#[repr(C, packed)] struct CmdTransferShort { encapsulation_header: u8, port: u8, @@ -51,7 +51,7 @@ struct CmdTransferShort { /// (receiving up to 32767 bytes). #[derive(AsBytes, FromBytes, FromZeroes, Debug)] #[allow(dead_code)] // Fields not explicitly read anywhere -#[repr(packed)] +#[repr(C, packed)] struct CmdTransferLong { encapsulation_header: u8, port: u8, @@ -66,7 +66,7 @@ struct CmdTransferLong { /// Wire format of USB packet containing I2C transaction response. #[derive(AsBytes, FromBytes, FromZeroes, Debug)] #[allow(dead_code)] // Reserved field not read anywhere -#[repr(packed)] +#[repr(C, packed)] struct RspTransfer { encapsulation_header: u8, status_code: u16, @@ -86,7 +86,7 @@ impl RspTransfer { #[derive(AsBytes, FromBytes, FromZeroes, Debug)] #[allow(dead_code)] // Fields not explicitly read anywhere -#[repr(packed)] +#[repr(C, packed)] struct CmdGetDeviceStatus { encapsulation_header: u8, port: u8, @@ -102,7 +102,7 @@ const I2C_DEVICE_CMD_PREPARE_READ_DATA: u8 = 0x01; const I2C_DEVICE_FLAG_STICKY: u8 = 0x80; #[derive(AsBytes, FromBytes, FromZeroes, Debug)] -#[repr(packed)] +#[repr(C, packed)] struct RspGetDeviceStatus { encapsulation_header: u8, struct_size: u16, @@ -126,7 +126,7 @@ impl RspGetDeviceStatus { #[derive(AsBytes, FromBytes, FromZeroes, Debug)] #[allow(dead_code)] // Fields not explicitly read anywhere -#[repr(packed)] +#[repr(C, packed)] struct CmdPrepareReadData { encapsulation_header: u8, port: u8,