-
Notifications
You must be signed in to change notification settings - Fork 700
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
Bindgen can't translate #pragma pack(n)
into #[repr(packed = "n")]
#537
Comments
Thanks for the bug report! I'm not super familiar with If we did support this, I think we would want to use |
I hope not! Abusing structs for serialisation purposes doesn't seem to be a good idea, and can cause problems. Unfortunately, I know of least one library which does this extensively.
bindgen is currently generating structs which have the wrong layout; this could also lead to some fairly strange behaviour. I think there are a number of ways you could go here:
Ah yes, you're right. |
I don't think we can even see I guess we can try to guess if we see the alignment is 1 and the relevant fields are packed when looking at their offsets, but... |
Hello, I'm having a similar issue on macOS 10.12.4. When generating the bindings for a header which includes "fcntl.h", the following struct is encountered: #pragma pack(4)
struct log2phys {
unsigned int l2p_flags; /* unused so far */
off_t l2p_contigbytes; /* F_LOG2PHYS: unused so far */
/* F_LOG2PHYS_EXT: IN: number of bytes to be queried */
/* OUT: number of contiguous bytes at this position */
off_t l2p_devoffset; /* F_LOG2PHYS: OUT: bytes into device */
/* F_LOG2PHYS_EXT: IN: bytes into file */
/* OUT: bytes into device */
};
#pragma pack() Rust-bindgen generates the following code: #[repr(C)]
#[derive(Debug, Copy)]
pub struct log2phys {
pub l2p_flags: ::std::os::raw::c_uint,
pub l2p_contigbytes: off_t,
pub l2p_devoffset: off_t,
}
#[test]
fn bindgen_test_layout_log2phys() {
assert_eq!(::std::mem::size_of::<log2phys>() , 20usize , concat ! (
"Size of: " , stringify ! ( log2phys ) ));
assert_eq! (::std::mem::align_of::<log2phys>() , 4usize , concat ! (
"Alignment of " , stringify ! ( log2phys ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const log2phys ) ) . l2p_flags as * const _ as
usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( log2phys ) , "::" ,
stringify ! ( l2p_flags ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const log2phys ) ) . l2p_contigbytes as * const
_ as usize } , 4usize , concat ! (
"Alignment of field: " , stringify ! ( log2phys ) , "::" ,
stringify ! ( l2p_contigbytes ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const log2phys ) ) . l2p_devoffset as * const _
as usize } , 12usize , concat ! (
"Alignment of field: " , stringify ! ( log2phys ) , "::" ,
stringify ! ( l2p_devoffset ) ));
} Some of these assertions are failing:
I don't know how helpful this is, but please let me know if I can supply more information. Thanks for making bindgen! |
I'm running into this same issue for osx/ios. Some of the system provided headers use Running: cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/
rg -c "^\s*#pragma\s*pack\(.*\d+\)" . | rg -v -N ":1$" Gives the count of
And there are many more headers with a single |
AFAICT, @emilo is right, and For this header #pragma pack(1)
struct foo { int x; }; we get this
|
Another version of this issue: struct AlignedToLess {
int i;
} __attribute__ ((packed,aligned(2))); |
Hmmm, reading http://llvm.org/viewvc/llvm-project?view=revision&revision=191345 (and the patch in http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130923/089367.html) I would assume that It appears |
On 10/19/2017 08:25 PM, Christian Legnitto wrote:> Hmmm, reading
http://llvm.org/viewvc/llvm-project?view=revision&revision=191345 I
would assume that packed should indeed be exposed by libclang?
Yup, __attribute__(packed) is exposed by libclang, but not pragma pack,
unfortunately.
|
This is a bandaid for rust-lang#537. It does *not* fix the underlying issue, which requires `#[repr(packed = "N")]` support in Rust. However, it does make sure that we don't generate type definitions with the wrong layout, or fail our generated layout tests.
I have a band-aid in #1136 It should make For |
#pragma pack(...)
#pragma pack(...)
#pragma pack(n)
into #[repr(packed = "n")]
This is a bandaid for rust-lang#537. It does *not* fix the underlying issue, which requires `#[repr(packed = "N")]` support in Rust. However, it does make sure that we don't generate type definitions with the wrong layout, or fail our generated layout tests.
Detect `#pragma pack(...)` and make `pack(n)` where `n > 1` opaque This is a bandaid for #537. It does *not* fix the underlying issue, which requires `#[repr(packed = "N")]` support in Rust. However, it does make sure that we don't generate type definitions with the wrong layout, or fail our generated layout tests. r? @emilio or @pepyakin
The PR for It would be great if Given that getting struct packing wrong is essentially undefined behavior, I'd wish that once the PR is merged it can be quickly stabilized. |
@fitzgen |
We can start doing that when the rust target = nightly now. I don't have time to write a PR myself, but I could review one. |
Given the header
bindgen generates
which uses
repr(C)
instead ofrepr(packed)
, and therefore has the wrong alignment:In fact, bindgen emits a warning to this effect:
Details
Steps to reproduce:
The text was updated successfully, but these errors were encountered: