structure layout using aligned attribute is incorrect · Issue #867 · rust-lang/rust-bindgen (original) (raw)

Input C/C++ Header

The original header is linux kernel source header; linux/target_core_user.h.

#define ALIGN_SIZE 64 /* Should be enough for most CPUs */

typedef unsigned short __u16; typedef unsigned int __u32;

struct tcmu_mailbox { __u16 version; __u16 flags; __u32 cmdr_off; __u32 cmdr_size;

__u32 cmd_head;

/* Updated by user. On its own cacheline */
__u32 cmd_tail __attribute__((__aligned__(ALIGN_SIZE)));

} attribute((packed));

Bindgen Invocation

Actual Results

pub type __u16 = ::std::os::raw::c_ushort; pub type __u32 = ::std::os::raw::c_uint; #[repr(C, packed)] #[derive(Copy)] pub struct tcmu_mailbox { pub version: __u16, pub flags: __u16, pub cmdr_off: __u32, pub cmdr_size: __u32, pub cmd_head: __u32, pub cmd_tail: __u32, pub __bindgen_padding_0: [u8; 108usize], }

Expected Results

pub type __u16 = ::std::os::raw::c_ushort; pub type __u32 = ::std::os::raw::c_uint; #[repr(C, packed)] #[derive(Copy)] pub struct tcmu_mailbox { pub version: __u16, pub flags: __u16, pub cmdr_off: __u32, pub cmdr_size: __u32, pub cmd_head: __u32, pub __bindgen_padding_0: [u8; 48usize], pub cmd_tail: __u32, }

In C, the offset of cmd_tail is 64, so generated rust code should also have same offset.

To check offset, I wrote C code like as;

#include <stddef.h>
#include <stdio.h>
#include "mini.h"

int main(int n, char**v) {
    printf("version %ld\n", offsetof(struct tcmu_mailbox, version));
    printf("flags %ld\n", offsetof(struct tcmu_mailbox, flags));
    printf("cmdr_off %ld\n", offsetof(struct tcmu_mailbox, cmdr_off));
    printf("cmdr_size %ld\n", offsetof(struct tcmu_mailbox, cmdr_size));
    printf("cmd_head %ld\n", offsetof(struct tcmu_mailbox, cmd_head));
    printf("cmd_tail %ld\n", offsetof(struct tcmu_mailbox, cmd_tail));
}

The outpu is;

version 0
flags 2
cmdr_off 4
cmdr_size 8
cmd_head 12
cmd_tail 64