You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
workingjubilee opened this issue
Sep 16, 2021
· 0 comments
Labels
A-FFIArea: Foreign function interface (FFI)A-layoutArea: Memory layout of typesC-bugCategory: This is a bug.O-AArch64Armv8-A or later processors in AArch64 mode
I expected to see this happen: At least a warning about violating the Procedure Call Standard for the Arm 64-bit Architecture ("AAPCS64").
Instead, this happened: the code passed without rustc erroring (until rustc errored on finding I haven't installed the right linker yet). Concerning. Perhaps I am doing something wrong?
This came up during discussion of the Arm ABI and bitfields. In essence, as it was explained to me: #[repr(C)] and #[repr(packed)] are not really quite compatible since compilers have a lot of liberty to intepret things like __attribute__((__packed__)), which is, in any case, a compiler extension and not part of the C standard. As such, Arm actually explicitly disallows them in code that exposes an interface. Here we have some code which could do exactly that: return a type with an ABI-breaking combination of reprs.
To quote Arm (emphasis mine):
The AAPCS64 does not allow exported interfaces to contain packed structures or bit-fields. However a scheme for laying out packed bit-fields can be achieved by reducing the alignment, A, in the above rules to below that of the natural container type. ARMCC uses an alignment of A=8 in these cases, but GCC uses an alignment of A=1.
The varying alignment described here is itself an excellent example as to how #[repr(packed)] can be subject to differing interpretations between compilers, and would ideally have a limited amount of exposure to the logic outside a single compiler on any system. Of course, we don't have packed bitfields in Rust yet, but we do have packed structs!
This may fall under the improper_ctypes lint, however as it is apparently an explicit ABI violation on this architecture, something a bit more stern than just a warning does seem like it may be appropriate if we detect it "leaking out". It also does seem doubtful we can truly be inter-compiler consistent in cases where the ABI is any less specified than such a quite thorough algorithm. Of course, even on Arm, something like this may be required of a Rust programmer for interacting with legacy code that decides it is "too good" for the AAPCS anyways, though we might need additional hints for producing a proper layout (and ideally a better solution can be found).
The text was updated successfully, but these errors were encountered:
workingjubilee
added
A-FFI
Area: Foreign function interface (FFI)
O-Arm
Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state
C-bug
Category: This is a bug.
A-layout
Area: Memory layout of types
labels
Sep 16, 2021
workingjubilee
added
O-AArch64
Armv8-A or later processors in AArch64 mode
and removed
O-Arm
Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state
labels
Mar 18, 2022
A-FFIArea: Foreign function interface (FFI)A-layoutArea: Memory layout of typesC-bugCategory: This is a bug.O-AArch64Armv8-A or later processors in AArch64 mode
I tried this code with
rustc how-to-violate-an-abi.rs --target=aarch64-unknown-linux-gnu
:I expected to see this happen: At least a warning about violating the Procedure Call Standard for the Arm 64-bit Architecture ("AAPCS64").
Instead, this happened: the code passed without rustc erroring (until rustc errored on finding I haven't installed the right linker yet). Concerning. Perhaps I am doing something wrong?
Meta
rustc --version --verbose
:Details
This came up during discussion of the Arm ABI and bitfields. In essence, as it was explained to me:
#[repr(C)]
and#[repr(packed)]
are not really quite compatible since compilers have a lot of liberty to intepret things like__attribute__((__packed__))
, which is, in any case, a compiler extension and not part of the C standard. As such, Arm actually explicitly disallows them in code that exposes an interface. Here we have some code which could do exactly that: return a type with an ABI-breaking combination of reprs.To quote Arm (emphasis mine):
The varying alignment described here is itself an excellent example as to how
#[repr(packed)]
can be subject to differing interpretations between compilers, and would ideally have a limited amount of exposure to the logic outside a single compiler on any system. Of course, we don't have packed bitfields in Rust yet, but we do have packed structs!This may fall under the
improper_ctypes
lint, however as it is apparently an explicit ABI violation on this architecture, something a bit more stern than just a warning does seem like it may be appropriate if we detect it "leaking out". It also does seem doubtful we can truly be inter-compiler consistent in cases where the ABI is any less specified than such a quite thorough algorithm. Of course, even on Arm, something like this may be required of a Rust programmer for interacting with legacy code that decides it is "too good" for the AAPCS anyways, though we might need additional hints for producing a proper layout (and ideally a better solution can be found).The text was updated successfully, but these errors were encountered: