Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No warning for violating AAPCS64 #89003

Open
workingjubilee opened this issue Sep 16, 2021 · 0 comments
Open

No warning for violating AAPCS64 #89003

workingjubilee opened this issue Sep 16, 2021 · 0 comments
Labels
A-FFI Area: Foreign function interface (FFI) A-layout Area: Memory layout of types C-bug Category: This is a bug. O-AArch64 Armv8-A or later processors in AArch64 mode

Comments

@workingjubilee
Copy link
Member

I tried this code with rustc how-to-violate-an-abi.rs --target=aarch64-unknown-linux-gnu:

#[repr(C, packed)]
pub struct PackedC {
    a: u8,
    b: u16,
}

#[no_mangle]
pub extern "C" fn exposed_illegal_struct(c: PackedC) -> PackedC {
    PackedC { a: c.a +1, b: c.b -1 } 
}

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:

rustc 1.57.0-nightly (51e514c0f 2021-09-12)
binary: rustc
commit-hash: 51e514c0fb4f9afcaae3b02dd9ccb93e15b30ef8
commit-date: 2021-09-12
host: x86_64-pc-windows-msvc
release: 1.57.0-nightly
LLVM version: 13.0.0

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 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).

@workingjubilee 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 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI) A-layout Area: Memory layout of types C-bug Category: This is a bug. O-AArch64 Armv8-A or later processors in AArch64 mode
Projects
None yet
Development

No branches or pull requests

1 participant