Skip to content

Replace the ioctl generation pipeline with bindgen clang_macro_fallback#182

Open
zRedShift wants to merge 1 commit intosunfishcode:mainfrom
zRedShift:clang-macro-fallback
Open

Replace the ioctl generation pipeline with bindgen clang_macro_fallback#182
zRedShift wants to merge 1 commit intosunfishcode:mainfrom
zRedShift:clang-macro-fallback

Conversation

@zRedShift
Copy link

Replace the ioctl generation pipeline with bindgen clang_macro_fallback

This removes the old gen/ioctl/generate.sh + list.c path and generates ioctl constants directly through bindgen.

The old setup depended on cross-compilers, qemu, and a hand-maintained ioctl list. The new one keeps everything in the normal bindgen flow by letting clang evaluate _IO/_IOR/_IOW/_IOWR macros during generation.

What changed

gen/modules/ioctl.h now includes the relevant UAPI headers directly.

For the ioctl module, bindgen runs twice:

  • once normally, which gives the plain #define constants
  • once with clang_macro_fallback(), which also evaluates function-like macros

The difference between those two outputs tells us which constants came from macro expansion. Those results are then filtered so we keep actual ioctls and drop the obvious non-ioctl fallout.

The generated ioctl names are also used as the blocklist for the other modules, replacing the old generated.txt.

Output changes

Compared to the currently shipped bindings:

  • no existing exported ioctl names are dropped
  • each architecture picks up a few hundred additional ioctls that were never listed in list.c
  • sparc, sparc64, and hexagon now get generated ioctl bindings instead of none
  • x32 gets 180 corrected values because the old pipeline used x86_64 layout assumptions
  • m68k gets 37 corrected values because of its alignment differences

There are also four compatibility definitions kept in gen/include/ioctl-addendum.h:

  • REISERFS_IOC_UNPACK
  • CM_IOCGATR
  • CM_IOSDBGLVL
  • MEYEIOC_SYNC

These came from headers that are no longer present in current kernel UAPI, but they were part of previously shipped bindings because the old generated ioctl.h had their values baked in. Keeping them here preserves the existing crate API.

Breaking changes

This should be released as 0.13.0.

Known breaking changes:

  • FIEMAP_MAX_OFFSET becomes i32 instead of u32 on 32-bit architectures. The bit pattern is unchanged, but the Rust type changes.
  • SIOCGSTAMP_OLD and SIOCGSTAMPNS_OLD move from net to ioctl
  • on mips, TCSANOW, TCSADRAIN, TCSAFLUSH, TIOCGETP, TIOCGLTC, TIOCSETN, TIOCSETP, and TIOCSLTC move from general to ioctl

Stub headers

A few minimal libc stubs were added under gen/include/ for -nostdinc generation:

  • sys/types.h
  • sys/time.h
  • sys/socket.h
  • empty stubs for stdlib.h, string.h, and sys/ioctl.h

Validation

I compared the generated ioctl exports against the currently shipped bindings to catch accidental removals and checked the expected value changes on x32 and m68k.

cargo test --all-features also passes.

Replace the generate.sh + list.c cross-compilation pipeline with
bindgen's clang_macro_fallback feature. This eliminates the need for
cross-compilers, qemu, and pre-generated ioctl text files.

A two-pass approach (with and without fallback) identifies function-like
macro results, which are then filtered by name prefix and value range to
separate real ioctls from non-ioctl macros (v4l2_fourcc, BLK_TC_ACT, etc.).
Object-like constants use plain prefix matching for legacy ioctl families.

Fixes x32 and m68k ioctl values that had incorrect struct sizes in the
old pipeline. Adds ~200-300 new ioctls per arch, and enables sparc and
hexagon which previously had no ioctl support.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant