rust-lang / rust-lang/rust-bindgen

Bitfield type generates a `packed` and `aligned` structure

Open
#2,688 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

Input C/C++ Header
struct _GumChainedPtr64Rebase
{
  guint64 target   : 36,
          high8    :  8,
          reserved :  7,
          next     : 12,
          bind     :  1;
};
Bindgen Invocation

    let bindings = bindgen::Builder::default().use_core();

    #[cfg(feature = "auto-download")]
    let bindings = bindings.clang_arg(format!("-I{include_dir}"));

    #[cfg(not(feature = "auto-download"))]
    let bindings = if std::env::var("DOCS_RS").is_ok() {
        bindings.clang_arg("-Iinclude")
    } else {
        bindings
    };

    let bindings = bindings
        .header_contents("gum.h", "#include \"frida-gum.h\"")
        .header("event_sink.h")
        .header("invocation_listener.h")
        .header("probe_listener.h")
        .header("stalker_observer.h")
        .header("stalker_params.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate_comments(false)
        .layout_tests(false)
        .generate()
        .unwrap();
Actual Results
#[repr(C, packed(4))]
#[repr(align(4))]
#[derive(Debug, Copy, Clone)]
pub struct _GumChainedPtr64Rebase {
    pub _bitfield_align_1: [u64; 0],
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>,
}
impl _GumChainedPtr64Rebase {
    #[inline]
    pub fn target(&self) -> guint64 {
        unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 36u8) as u64) }
    }
    #[inline]
    pub fn set_target(&mut self, val: guint64) {
        unsafe {
            let val: u64 = ::core::mem::transmute(val);
            self._bitfield_1.set(0usize, 36u8, val as u64)
        }
    }
    #[inline]
    pub fn high8(&self) -> guint64 {
        unsafe { ::core::mem::transmute(self._bitfield_1.get(36usize, 8u8) as u64) }
    }
    #[inline]
    pub fn set_high8(&mut self, val: guint64) {
        unsafe {
            let val: u64 = ::core::mem::transmute(val);
            self._bitfield_1.set(36usize, 8u8, val as u64)
        }
    }
    #[inline]
    pub fn reserved(&self) -> guint64 {
        unsafe { ::core::mem::transmute(self._bitfield_1.get(44usize, 7u8) as u64) }
    }
    #[inline]
    pub fn set_reserved(&mut self, val: guint64) {
        unsafe {
            let val: u64 = ::core::mem::transmute(val);
            self._bitfield_1.set(44usize, 7u8, val as u64)
        }
    }
    #[inline]
    pub fn next(&self) -> guint64 {
        unsafe { ::core::mem::transmute(self._bitfield_1.get(51usize, 12u8) as u64) }
    }
    #[inline]
    pub fn set_next(&mut self, val: guint64) {
        unsafe {
            let val: u64 = ::core::mem::transmute(val);
            self._bitfield_1.set(51usize, 12u8, val as u64)
        }
    }
    #[inline]
    pub fn bind(&self) -> guint64 {
        unsafe { ::core::mem::transmute(self._bitfield_1.get(63usize, 1u8) as u64) }
    }
    #[inline]
    pub fn set_bind(&mut self, val: guint64) {
        unsafe {
            let val: u64 = ::core::mem::transmute(val);
            self._bitfield_1.set(63usize, 1u8, val as u64)
        }
    }
    #[inline]
    pub fn new_bitfield_1(
        target: guint64,
        high8: guint64,
        reserved: guint64,
        next: guint64,
        bind: guint64,
    ) -> __BindgenBitfieldUnit<[u8; 8usize]> {
        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default();
        __bindgen_bitfield_unit.set(0usize, 36u8, {
            let target: u64 = unsafe { ::core::mem::transmute(target) };
            target as u64
        });
        __bindgen_bitfield_unit.set(36usize, 8u8, {
            let high8: u64 = unsafe { ::core::mem::transmute(high8) };
            high8 as u64
        });
        __bindgen_bitfield_unit.set(44usize, 7u8, {
            let reserved: u64 = unsafe { ::core::mem::transmute(reserved) };
            reserved as u64
        });
        __bindgen_bitfield_unit.set(51usize, 12u8, {
            let next: u64 = unsafe { ::core::mem::transmute(next) };
            next as u64
        });
        __bindgen_bitfield_unit.set(63usize, 1u8, {
            let bind: u64 = unsafe { ::core::mem::transmute(bind) };
            bind as u64
        });
        __bindgen_bitfield_unit
    }
}

and/or

error[E0587]: type has conflicting packed and align representation hints
     --> /home/runner/work/frida-rust/frida-rust/target/i686-unknown-linux-gnu/debug/build/frida-gum-sys-6002c29d0e45c6ce/out/bindings.rs:19668:1
      |
19668 | pub struct _GumChainedPtr64Rebase {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expected Results

A struct with either packed(x) or aligned(x) should be generated.

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

Start with the reported bindgen::Builder invocation and the generated bindings.rs entry for _GumChainedPtr64Rebase. Reproduce the bitfield input and verify that generation no longer emits conflicting packed and align representation hints, producing a struct with only the expected representation.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.