Commit d072acda authored by Gary Guo's avatar Gary Guo Committed by Miguel Ojeda
Browse files

rust: use custom FFI integer types



Currently FFI integer types are defined in libcore. This commit creates
the `ffi` crate and asks bindgen to use that crate for FFI integer types
instead of `core::ffi`.

This commit is preparatory and no type changes are made in this commit
yet.

Signed-off-by: default avatarGary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240913213041.395655-4-gary@garyguo.net


[ Added `rustdoc`, `rusttest` and KUnit tests support. Rebased on top of
  `rust-next` (e.g. migrated more `core::ffi` cases). Reworded crate
  docs slightly and formatted. - Miguel ]
Signed-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent 2fd6f55c
Loading
Loading
Loading
Loading
+26 −13
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
# Where to place rustdoc generated documentation
rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc

obj-$(CONFIG_RUST) += core.o compiler_builtins.o
obj-$(CONFIG_RUST) += core.o compiler_builtins.o ffi.o
always-$(CONFIG_RUST) += exports_core_generated.h

# Missing prototypes are expected in the helpers since these are exported
@@ -103,10 +103,13 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE
rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE
	+$(call if_changed,rustdoc)

rustdoc-kernel: private rustc_target_flags = \
rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE
	+$(call if_changed,rustdoc)

rustdoc-kernel: private rustc_target_flags = --extern ffi \
    --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
    --extern bindings --extern uapi
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \
    rustdoc-compiler_builtins $(obj)/libmacros.so \
    $(obj)/bindings.o FORCE
	+$(call if_changed,rustdoc)
@@ -124,12 +127,15 @@ quiet_cmd_rustc_test_library = RUSTC TL $<
rusttestlib-build_error: $(src)/build_error.rs FORCE
	+$(call if_changed,rustc_test_library)

rusttestlib-ffi: $(src)/ffi.rs FORCE
	+$(call if_changed,rustc_test_library)

rusttestlib-macros: private rustc_target_flags = --extern proc_macro
rusttestlib-macros: private rustc_test_library_proc = yes
rusttestlib-macros: $(src)/macros/lib.rs FORCE
	+$(call if_changed,rustc_test_library)

rusttestlib-kernel: private rustc_target_flags = \
rusttestlib-kernel: private rustc_target_flags = --extern ffi \
    --extern build_error --extern macros \
    --extern bindings --extern uapi
rusttestlib-kernel: $(src)/kernel/lib.rs \
@@ -137,10 +143,12 @@ rusttestlib-kernel: $(src)/kernel/lib.rs \
    $(obj)/libmacros.so $(obj)/bindings.o FORCE
	+$(call if_changed,rustc_test_library)

rusttestlib-bindings: $(src)/bindings/lib.rs FORCE
rusttestlib-bindings: private rustc_target_flags = --extern ffi
rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE
	+$(call if_changed,rustc_test_library)

rusttestlib-uapi: $(src)/uapi/lib.rs FORCE
rusttestlib-uapi: private rustc_target_flags = --extern ffi
rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE
	+$(call if_changed,rustc_test_library)

quiet_cmd_rustdoc_test = RUSTDOC T $<
@@ -160,7 +168,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
	mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
	OBJTREE=$(abspath $(objtree)) \
	$(RUSTDOC) --test $(rust_flags) \
		-L$(objtree)/$(obj) --extern kernel \
		-L$(objtree)/$(obj) --extern ffi --extern kernel \
		--extern build_error --extern macros \
		--extern bindings --extern uapi \
		--no-run --crate-name kernel -Zunstable-options \
@@ -198,9 +206,9 @@ rusttest-macros: $(src)/macros/lib.rs \
	+$(call if_changed,rustc_test)
	+$(call if_changed,rustdoc_test)

rusttest-kernel: private rustc_target_flags = \
rusttest-kernel: private rustc_target_flags = --extern ffi \
    --extern build_error --extern macros --extern bindings --extern uapi
rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-kernel \
rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \
    rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
    rusttestlib-uapi FORCE
	+$(call if_changed,rustc_test)
@@ -273,7 +281,7 @@ bindgen_c_flags_final = $(bindgen_c_flags_lto) -fno-builtin -D__BINDGEN__
quiet_cmd_bindgen = BINDGEN $@
      cmd_bindgen = \
	$(BINDGEN) $< $(bindgen_target_flags) \
		--use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \
		--use-core --with-derive-default --ctypes-prefix ffi --no-layout-tests \
		--no-debug '.*' --enable-function-attribute-detection \
		-o $@ -- $(bindgen_c_flags_final) -DMODULE \
		$(bindgen_target_cflags) $(bindgen_target_extra)
@@ -401,18 +409,23 @@ $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
$(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE
	+$(call if_changed_rule,rustc_library)

$(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE
	+$(call if_changed_rule,rustc_library)

$(obj)/bindings.o: private rustc_target_flags = --extern ffi
$(obj)/bindings.o: $(src)/bindings/lib.rs \
    $(obj)/compiler_builtins.o \
    $(obj)/ffi.o \
    $(obj)/bindings/bindings_generated.rs \
    $(obj)/bindings/bindings_helpers_generated.rs FORCE
	+$(call if_changed_rule,rustc_library)

$(obj)/uapi.o: private rustc_target_flags = --extern ffi
$(obj)/uapi.o: $(src)/uapi/lib.rs \
    $(obj)/compiler_builtins.o \
    $(obj)/ffi.o \
    $(obj)/uapi/uapi_generated.rs FORCE
	+$(call if_changed_rule,rustc_library)

$(obj)/kernel.o: private rustc_target_flags = \
$(obj)/kernel.o: private rustc_target_flags = --extern ffi \
    --extern build_error --extern macros --extern bindings --extern uapi
$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \
    $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE

rust/ffi.rs

0 → 100644
+13 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

//! Foreign function interface (FFI) types.
//!
//! This crate provides mapping from C primitive types to Rust ones.
//!
//! The Rust [`core`] crate provides [`core::ffi`], which maps integer types to the platform default
//! C ABI. The kernel does not use [`core::ffi`], so it can customise the mapping that deviates from
//! the platform default.

#![no_std]

pub use core::ffi::*;
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ fn aligned_size(new_layout: Layout) -> usize {
///
/// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
struct ReallocFunc(
    unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void,
    unsafe extern "C" fn(*const crate::ffi::c_void, usize, u32) -> *mut crate::ffi::c_void,
);

impl ReallocFunc {
+2 −2
Original line number Diff line number Diff line
@@ -24,10 +24,10 @@

extern "C" {
    #[link_name = "aligned_alloc"]
    fn libc_aligned_alloc(align: usize, size: usize) -> *mut core::ffi::c_void;
    fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void;

    #[link_name = "free"]
    fn libc_free(ptr: *mut core::ffi::c_void);
    fn libc_free(ptr: *mut crate::ffi::c_void);
}

// SAFETY:
+6 −6
Original line number Diff line number Diff line
@@ -355,17 +355,17 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A>
{
    type Borrowed<'a> = &'a T;

    fn into_foreign(self) -> *const core::ffi::c_void {
    fn into_foreign(self) -> *const crate::ffi::c_void {
        Box::into_raw(self) as _
    }

    unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
    unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
        // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
        // call to `Self::into_foreign`.
        unsafe { Box::from_raw(ptr as _) }
    }

    unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T {
    unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T {
        // SAFETY: The safety requirements of this method ensure that the object remains alive and
        // immutable for the duration of 'a.
        unsafe { &*ptr.cast() }
@@ -378,18 +378,18 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>>
{
    type Borrowed<'a> = Pin<&'a T>;

    fn into_foreign(self) -> *const core::ffi::c_void {
    fn into_foreign(self) -> *const crate::ffi::c_void {
        // SAFETY: We are still treating the box as pinned.
        Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _
    }

    unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self {
    unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self {
        // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
        // call to `Self::into_foreign`.
        unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) }
    }

    unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> {
    unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> {
        // SAFETY: The safety requirements for this function ensure that the object is still alive,
        // so it is safe to dereference the raw pointer.
        // The safety requirements of `from_foreign` also ensure that the object remains alive for
Loading