rust-lang / rust-lang/rust-bindgen

structure layout using __aligned__ attribute is incorrect

Open
#867 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug I-bogus-codegen
Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

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
$ bindgen input.h
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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with input.h based on linux/target_core_user.h using bindgen input.h, then inspect bindgen's handling of __aligned__ on packed structs. Compare the generated tcmu_mailbox layout with the C offsets, especially cmd_tail at offset 64; done means the Rust binding places the field at the same offset.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp, rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.