| #!/usr/bin/env fuchsia-vendored-python |
| # |
| # Copyright 2023 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import os |
| import sys |
| |
| # Add //build/rust to Python path so bindgen import works. |
| FUCHSIA_DIR = os.environ.get( |
| "FUCHSIA_DIR", |
| os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."), |
| ) |
| sys.path.append(os.path.join(FUCHSIA_DIR, "build", "rust")) |
| |
| from bindgen import Bindgen |
| |
| RELATIVE_SCRIPT_PATH = os.path.relpath(__file__, FUCHSIA_DIR) |
| |
| MODULE_DOC_COMMENT = f""" |
| //! WARNING - This file was auto generated by //{RELATIVE_SCRIPT_PATH}. |
| //! Do not modify this file. To re-generate, run the following command from the root of |
| //! your Fuchsia checkout: |
| //! |
| //! ./{RELATIVE_SCRIPT_PATH} |
| """ |
| |
| RAW_LINES = ( |
| MODULE_DOC_COMMENT |
| + """ |
| |
| use zerocopy::{IntoBytes, FromBytes, KnownLayout, Immutable}; |
| use crate::fscrypt_key_specifier; |
| |
| """ |
| ) |
| |
| for s in [8, 16, 144, 272]: |
| RAW_LINES += ( |
| """ |
| // SAFETY: The IntoBytes implementation is safe because the array size is a |
| // multiple of 8, so there is no padding. |
| unsafe impl IntoBytes for __BindgenOpaqueArray8<[u8; %dusize]> { |
| fn only_derive_is_allowed_to_implement_this_trait() { |
| } |
| } |
| """ |
| % s |
| ) |
| |
| PTR_TYPES = """ |
| #[repr(transparent)] |
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, IntoBytes, FromBytes, KnownLayout, Immutable)] |
| pub struct uaddr { |
| pub addr: u64, |
| } |
| |
| #[derive(Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd, IntoBytes, FromBytes, KnownLayout, Immutable)] |
| #[repr(transparent)] |
| pub struct uref<T> { |
| pub addr: uaddr, |
| _phantom: std::marker::PhantomData<T>, |
| } |
| |
| impl<T> Copy for uref<T> {} |
| |
| impl<T> Clone for uref<T> { |
| fn clone(&self) -> Self { |
| Self { addr: self.addr, _phantom: Default::default() } |
| } |
| } |
| |
| impl<T> From<uaddr> for uref<T> { |
| fn from(addr: uaddr) -> Self { |
| Self { addr, _phantom: Default::default() } |
| } |
| } |
| |
| #[repr(transparent)] |
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, IntoBytes, FromBytes, KnownLayout, Immutable)] |
| pub struct uaddr32 { |
| pub addr: u32, |
| } |
| |
| impl From<uaddr32> for uaddr { |
| fn from(addr32: uaddr32) -> Self { |
| Self { addr: addr32.addr.into() } |
| } |
| } |
| |
| impl TryFrom<uaddr> for uaddr32 { |
| type Error = (); |
| fn try_from(addr: uaddr) -> Result<Self, ()> { |
| Ok(Self { addr: addr.addr.try_into().map_err(|_| ())? }) |
| } |
| } |
| |
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, IntoBytes, FromBytes, KnownLayout, Immutable)] |
| #[repr(transparent)] |
| pub struct uref32<T> { |
| pub addr: uaddr32, |
| _phantom: std::marker::PhantomData<T>, |
| } |
| |
| impl<T> From<uaddr32> for uref32<T> { |
| fn from(addr: uaddr32) -> Self { |
| Self { addr, _phantom: Default::default() } |
| } |
| } |
| |
| impl<T> From<uaddr32> for uref<T> { |
| fn from(addr: uaddr32) -> Self { |
| Self { addr: addr.into(), _phantom: Default::default() } |
| } |
| } |
| |
| impl<T> From<uref32<T>> for uref<T> { |
| fn from(ur: uref32<T>) -> Self { |
| Self { addr: ur.addr.into(), _phantom: Default::default() } |
| } |
| } |
| |
| impl<T> TryFrom<uref<T>> for uref32<T> { |
| type Error = (); |
| fn try_from(ur: uref<T>) -> Result<Self, ()> { |
| Ok(Self { addr: ur.addr.try_into().map_err(|_| ())?, _phantom: Default::default() }) |
| } |
| } |
| """ |
| |
| # Tell bindgen not to produce records for these types. |
| OPAQUE_TYPES = [ |
| "group_filter.*", |
| "sigval", |
| "StdAtomic.*", |
| ] |
| |
| # Cross-architecture include paths (the ArchInfo class also has an arch-specific one to add). |
| INCLUDE_DIRS = [ |
| "third_party/android/platform/bionic/libc/kernel/uapi", |
| "third_party/android/platform/bionic/libc/kernel/android/uapi", |
| "src/starnix/lib/linux_uapi/stub", |
| ] |
| |
| STD_DERIVES = [ |
| "default", |
| ] |
| |
| # Additional traits that should be added to types matching the regexps. |
| AUTO_DERIVE_TRAITS = [ |
| ( |
| r"__BindgenBitfieldUnit", |
| ["Immutable", "IntoBytes", "KnownLayout", "FromBytes"], |
| ), |
| ( |
| r"__IncompleteArrayField", |
| ["Clone", "IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| ( |
| r"__BindgenUnionField", |
| ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| ( |
| r"__BindgenOpaqueArray$", |
| ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| ( |
| r"__BindgenOpaqueArray8$", |
| ["FromBytes", "KnownLayout", "Immutable"], |
| ), |
| ( |
| r"__sifields__bindgen_ty_(2|3|7)", |
| ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| ( |
| r"audit_status.*", |
| ["Copy", "Clone", "FromBytes", "IntoBytes", "KnownLayout", "Immutable"], |
| ), |
| (r"binder_fd_object.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| ( |
| r"binder_transaction_data__bindgen_ty_2__bindgen_ty_1", |
| ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| (r"binder_transaction_data.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| ( |
| r"bpf_attr__bindgen_ty_(1|3|5|6|7|8|9|10|11|12|13|16|17|18|19)(_.+)?$", |
| ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| (r"bpf_attr.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| ( |
| r"bpf_insn", |
| ["KnownLayout", "IntoBytes", "FromBytes", "Immutable", "PartialEq"], |
| ), |
| ( |
| r"bpf_prog", |
| ["Copy", "Clone", "IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| (r"bpf_sockopt", ["KnownLayout", "IntoBytes", "FromBytes", "Immutable"]), |
| (r"bpf_sock_addr", ["KnownLayout", "IntoBytes", "FromBytes", "Immutable"]), |
| (r"flat_binder_object.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| ( |
| r"usb_functionfs_event.*", |
| ["KnownLayout", "Clone", "IntoBytes", "FromBytes", "Immutable"], |
| ), |
| ( |
| r"fuse_dirent", |
| ["KnownLayout", "Clone", "IntoBytes", "FromBytes", "Immutable"], |
| ), |
| ( |
| r"fuse_open_out.*", |
| ["KnownLayout", "Clone", "IntoBytes", "FromBytes", "Immutable"], |
| ), |
| ( |
| r"fuse_open_out$", |
| ["Debug"], |
| ), |
| ( |
| r"fuse_in_header.*", |
| ["KnownLayout", "Clone", "IntoBytes", "FromBytes", "Immutable"], |
| ), |
| ( |
| r"fuse_in_header$", |
| ["Debug"], |
| ), |
| (r"ifreq.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"if_settings.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"in6_addr", ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"]), |
| (r"in6_pktinfo", ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"]), |
| (r"inotify_event", ["KnownLayout", "IntoBytes", "Immutable"]), |
| (r"dm_name_list", ["KnownLayout", "IntoBytes", "Immutable", "FromBytes"]), |
| ( |
| r"dm_target_versions", |
| ["KnownLayout", "IntoBytes", "Immutable", "FromBytes"], |
| ), |
| ( |
| r"fsverity_digest", |
| ["KnownLayout", "Clone", "IntoBytes", "Immutable", "FromBytes"], |
| ), |
| (r"fscrypt_add_key_arg", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"fscrypt_remove_key_arg", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"fscrypt_key_specifier", ["KnownLayout", "FromBytes", "Immutable"]), |
| ( |
| r"fscrypt_key_specifier__bindgen_ty_1", |
| ["KnownLayout", "FromBytes", "Immutable"], |
| ), |
| ( |
| r"input_event", |
| ["KnownLayout", "IntoBytes", "FromBytes", "Immutable", "PartialEq"], |
| ), |
| ( |
| r"input_id", |
| ["KnownLayout", "IntoBytes", "FromBytes", "Immutable", "PartialEq"], |
| ), |
| (r"ip6t_ip6", ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"]), |
| (r"ip6?t_entry", ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"]), |
| (r"ip6?t_reject*", ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"]), |
| (r"ip6?t_get_entries", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"ip6?t_replace", ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"]), |
| ( |
| r"__kernel_sigaction.*", |
| ["IntoBytes", "FromBytes", "KnownLayout", "Immutable"], |
| ), |
| (r"nf_.*", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"perf_event_attr", ["FromBytes", "Immutable"]), |
| (r"perf_event_mmap_page", ["IntoBytes", "Immutable"]), |
| (r"robust_list_head", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"robust_list", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"sigevent", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"sigval", ["KnownLayout", "IntoBytes", "FromBytes", "Immutable"]), |
| (r"__sk_buff", ["KnownLayout", "IntoBytes", "FromBytes", "Immutable"]), |
| (r"sockaddr_in", ["KnownLayout", "IntoBytes", "FromBytes", "Immutable"]), |
| (r"sockaddr_ll", ["KnownLayout", "IntoBytes", "FromBytes", "Immutable"]), |
| (r"sock_fprog", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"sysinfo", ["KnownLayout", "IntoBytes", "Immutable"]), |
| ( |
| r"timeval", |
| ["KnownLayout", "IntoBytes", "FromBytes", "Immutable", "PartialEq"], |
| ), |
| (r"xt_counters_info", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"xt_bpf_info_v1", ["KnownLayout", "FromBytes", "IntoBytes", "Immutable"]), |
| (r"xt_tproxy_target_info_v1", ["KnownLayout", "FromBytes", "Immutable"]), |
| (r"fastrpc_.*", ["IntoBytes, FromBytes, KnownLayout, Immutable"]), |
| (r"remote_.*", ["IntoBytes, FromBytes, KnownLayout, Immutable"]), |
| ( |
| r"ucred", |
| [ |
| "KnownLayout", |
| "IntoBytes", |
| "FromBytes", |
| "Immutable", |
| "Eq", |
| "PartialEq", |
| ], |
| ), |
| ( |
| r"cmsghdr", |
| [ |
| "KnownLayout", |
| "IntoBytes", |
| "FromBytes", |
| "Immutable", |
| "Eq", |
| "PartialEq", |
| ], |
| ), |
| ] |
| |
| # General replacements to apply to the contents of the file. These are tuples of |
| # compiled regular expressions + the thing to replace matches with. |
| REPLACEMENTS = [ |
| # Use CStr to represent constant C strings. The inputs look like: |
| # pub const FS_KEY_DESC_PREFIX: &[u8; 9usize] = b"fscrypt:\0"; |
| ( |
| r': &\[u8; [0-9]+(usize)?\] = b"(.*)\\0";\n', |
| ': &\'static std::ffi::CStr = c"\\2";\n', |
| ), |
| # Change `__IncompleteArrayField` representation to `transparent`, which is necessary to |
| # allow it to derive `IntoBytes`. |
| # TODO(https://github.com/google/zerocopy/issues/10): Remove this once zerocopy is updated |
| # to allow `IntoBytes` for generic structs with `repr(C)`. |
| ( |
| r"#\[repr\(C\)\]\n" |
| r"#\[derive\((([A-Za-z]+, )*[A-Za-z]+)\)\]\n" |
| r"pub struct (__IncompleteArrayField|__BindgenUnionField)", |
| """#[repr(transparent)] |
| #[derive(\\1)] |
| pub struct \\3""", |
| ), |
| # Add IntoBytes/FromBytes/KnownLayout/Immutable to every copyable struct regardless of |
| # name. |
| # TODO(https://github.com/rust-lang/rust-bindgen/issues/2170): |
| # Remove in favor of bindgen support for custom derives. |
| ( |
| r"\n#\[derive\(Debug, Default, Copy, Clone(, FromBytes)?\)\]\n", |
| "\n#[derive(Debug, Default, Copy, Clone, IntoBytes, FromBytes, KnownLayout, Immutable)]\n", |
| ), |
| ( |
| r"\n#\[derive\(Debug, Copy, Clone(, FromBytes)?\)\]\n", |
| "\n#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, KnownLayout, Immutable)]\n", |
| ), |
| # Convert atomic wrapper. |
| (r": StdAtomic([UI])(8|16|32|64)", ": std::sync::atomic::Atomic\\1\\2"), |
| # Remove __bindgen_missing from the start of constants defined in missing_includes.h |
| (r"const __bindgen_missing_([a-zA-Z_0-9]+)", "const \\1"), |
| # Convert atomic wrapper. |
| (r": StdAtomic([UI])(8|16|32|64)", ": std::sync::atomic::Atomic\\1\\2"), |
| # Remove __bindgen_missing from the start of constants defined in missing_includes.h |
| (r"const __bindgen_missing_([a-zA-Z_0-9]+)", "const \\1"), |
| # Workaround for https://github.com/rust-lang/rust-bindgen/issues/3068. |
| (r"pub __bindgen_padding_0: \[u8; 1844[0-9]+usize\],\n", ""), |
| ] |
| |
| REPLACEMENTS_PTR = [ |
| # Use uaddr/uref in place of pointers for compat with zerocopy traits. Because |
| # the target of the pointer is in userspace anyway, treating it as an opaque |
| # pointer is harmless. |
| (r"\*(const|mut) crate::types::c_void", "uaddr"), |
| ( |
| r'::std::option::Option<unsafe extern "C" fn\([a-zA-Z_0-9: ]*\)>', |
| "uaddr", |
| ), |
| (r"([:=]) \*(const|mut) ([a-z_][a-zA-Z_0-9:]*)", "\\1 uref<\\3>"), |
| ] |
| |
| ARCH32_REPLACEMENTS_PTR = [ |
| # Use uaddr/uref in place of pointers for compat with zerocopy traits. Because |
| # the target of the pointer is in userspace anyway, treating it as an opaque |
| # pointer is harmless. |
| # For arch32, we only use 64-bit width when dealing with AsBytes union |
| # padding. |
| (r"\*(const|mut) crate::types::arch32::c_void", "crate::uaddr32"), |
| ( |
| r'::std::option::Option<\s*unsafe extern "C" fn\([*a-zA-Z_0-9,:\s]*\),?\s*>', |
| "crate::uaddr32", |
| ), |
| (r"([:=]) \*(const|mut) ([a-z_][a-zA-Z_0-9:]*)", "\\1 crate::uref32<\\3>"), |
| ( |
| r"pub _u: __kernel_sigaction__bindgen_ty_1,", |
| "pub sa_handler: __sighandler_t,", |
| ), |
| ] |
| |
| |
| INPUT_FILE = "src/starnix/lib/linux_uapi/wrapper.h" |
| |
| NO_DEBUG_TYPES = [ |
| "__sifields__bindgen_ty_(2|3)", |
| ] |
| |
| NO_COPY_TYPES = [ |
| "StdAtomic.*", |
| ] |
| |
| # Bindgen offers limited support for union types. The fscrypt_key_specifier__bindgen_ty_1 union has |
| # three fields that bindgen defines to be three different sizes. As a result, the union is |
| # prevented from implementing the IntoBytes trait which prevents the larger fscrypt_add_key_arg |
| # struct from implementing IntoBytes. manual.rs adds the appropriate padding to the union fields |
| # so that it and thus fscrypt_add_key_arg can implement the IntoBytes trait. |
| TYPE_BLOCKLIST = [ |
| "fscrypt_key_specifier", |
| "fscrypt_key_specifier__bindgen_ty_1", |
| "fscrypt_add_key_arg", |
| "fscrypt_descriptor", |
| "fscrypt_identifier", |
| ] |
| |
| |
| class ArchInfo: |
| def __init__(self, name, clang_target, include): |
| self.name = name # Our internal arch name. |
| self.clang_target = clang_target # Clang "triple" name for this arch. |
| self.include = ( |
| include # Include directory for the arch-specific uapi files. |
| ) |
| |
| |
| ARCH_INFO = [ |
| ArchInfo( |
| "x86_64", |
| "x86_64-pc-linux-gnu", |
| "third_party/android/platform/bionic/libc/kernel/uapi/asm-x86", |
| ), |
| ArchInfo( |
| "arm64", |
| "aarch64-linux-gnu", |
| "third_party/android/platform/bionic/libc/kernel/uapi/asm-arm64", |
| ), |
| ArchInfo( |
| "arm", |
| "arm-linux-gnueabihf", |
| "third_party/android/platform/bionic/libc/kernel/uapi/asm-arm", |
| ), |
| ArchInfo( |
| "riscv64", |
| "riscv64-linux-gnu", |
| "third_party/android/platform/bionic/libc/kernel/uapi/asm-riscv", |
| ), |
| ] |
| |
| bindgen = Bindgen() |
| bindgen.opaque_types = OPAQUE_TYPES |
| bindgen.std_derives = STD_DERIVES |
| bindgen.set_auto_derive_traits(AUTO_DERIVE_TRAITS) |
| bindgen.ignore_functions = True |
| bindgen.type_blocklist = TYPE_BLOCKLIST |
| bindgen.no_debug_types = NO_DEBUG_TYPES |
| bindgen.no_copy_types = NO_COPY_TYPES |
| bindgen.enable_stdlib_include_dirs = False |
| bindgen.size_t_is_usize = False |
| |
| for arch in ARCH_INFO: |
| bindgen.raw_lines = RAW_LINES |
| if arch.name == "arm": |
| bindgen.c_types_prefix = "crate::types::arch32" |
| bindgen.set_replacements(REPLACEMENTS + ARCH32_REPLACEMENTS_PTR) |
| else: |
| bindgen.c_types_prefix = "crate::types" |
| bindgen.set_replacements(REPLACEMENTS + REPLACEMENTS_PTR) |
| bindgen.raw_lines += PTR_TYPES |
| bindgen.clang_target = arch.clang_target |
| bindgen.include_dirs = INCLUDE_DIRS + [arch.include] |
| rust_file = "src/starnix/lib/linux_uapi/src/" + arch.name + ".rs" |
| bindgen.run(INPUT_FILE, rust_file) |