-
Notifications
You must be signed in to change notification settings - Fork 696
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_union_align produces wrong alignment when compiling for 32-bit #1983
Comments
Are you passing the right target to bindgen? For basically your test-case (with the typedefs removed): struct v4l2_buffer {
union {
unsigned offset;
unsigned long userptr;
struct v4l2_plane *planes;
int fd;
} m;
}; I get the expected: #[repr(C)]
#[derive(Copy, Clone)]
pub union v4l2_buffer__bindgen_ty_1 {
pub offset: ::std::os::raw::c_uint,
pub userptr: ::std::os::raw::c_ulong,
pub planes: *mut v4l2_plane,
pub fd: ::std::os::raw::c_int,
_bindgen_union_align: u32,
} If I run it with the right target:
|
In this case the alignment is redundant, so we should be able to detect this kind of case and remove it like we do for structs, though. |
#1984 should improve this significantly. |
Wow, I was completely oblivious of the fact you could pass #1984 is even better in that I could probably use the bindings for all cases with it. I guess we can close this issue, thanks a lot for the answer and quick fix! |
Due to rust-lang/rust-bindgen#1983 the bindings generated on a 64-bit machine won't work well with 32-bit targets. Work around this issue by generating 2 sets of bindings and selecting the correct one with #[cfg(target_pointer_width)].
I am using bindgen to generate Rust equivalents of C structures that are part of the Linux kernel ABI. These structures are defined in public headers and (unfortunately) have different a size and layout on 32-bit and 64-bit targets.
This works fine with bindgen for the most part, except when unions are involved. Consider the following struct:
bindgen generates the following code for it:
Note the
_bindgen_union_align
member. While the layout is perfectly correct for a 64-bit target (because the pointer andc_ulong
are the same size asu64
), when building for 32-bit the size of the union is also 8 bytes, while it should be just 4. This results in the kernel rejecting the ioctls because the passed argument is not of the expected size.If I just remove all the
_bindgen_union_align
from the generated bindings, the structures are now usable on both 64-bit and 32-bit, without any issue. The tests also keep passing on 64-bit (but not on 32-bit, due to issue #1213).I see several ways to solve this:
_bindgen_union_align
. While the C representation should just do the right thing (and in my case it does), I suspect they are here for a reason though.c_ulong
maybe?) for these cases.I am not sure what the correct way would be, but happy to gather some thoughts and maybe come with a patch for it?
The text was updated successfully, but these errors were encountered: