[PATCH 6.12.y 57/60] rust: fix size_t in bindgen prototypes of C builtins

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Gary Guo <gary@xxxxxxxxxxx>

commit 75c1fd41a671a0843b89d1526411a837a7163fa2 upstream.

Without `-fno-builtin`, for functions like memcpy/memmove (and many
others), bindgen seems to be using the clang-provided prototype. This
prototype is ABI-wise compatible, but the issue is that it does not have
the same information as the source code w.r.t. typedefs.

For example, bindgen generates the following:

    extern "C" {
        pub fn strlen(s: *const core::ffi::c_char) -> core::ffi::c_ulong;
    }

note that the return type is `c_ulong` (i.e. unsigned long), despite the
size_t-is-usize behavior (this is default, and we have not opted out
from it using --no-size_t-is-usize).

Similarly, memchr's size argument should be of type `__kernel_size_t`,
but bindgen generates `c_ulong` directly.

We want to ensure any `size_t` is translated to Rust `usize` so that we
can avoid having them be different type on 32-bit and 64-bit
architectures, and hence would require a lot of excessive type casts
when calling FFI functions.

I found that this bindgen behavior (which probably is caused by
libclang) can be disabled by `-fno-builtin`. Using the flag for compiled
code can result in less optimisation because compiler cannot assume
about their properties anymore, but this should not affect bindgen.

[ Trevor asked: "I wonder how reliable this behavior is. Maybe bindgen
  could do a better job controlling this, is there an open issue?".

  Gary replied: ..."apparently this is indeed the suggested approach in
  https://github.com/rust-lang/rust-bindgen/issues/1770";. - Miguel ]

Signed-off-by: Gary Guo <gary@xxxxxxxxxxx>
Link: https://lore.kernel.org/r/20240913213041.395655-2-gary@xxxxxxxxxxx
[ Formatted comment. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@xxxxxxxxxx>
---
 rust/Makefile | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/rust/Makefile b/rust/Makefile
index 5e7612f69cea..a6e80caa42c1 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -264,7 +264,11 @@ else
 bindgen_c_flags_lto = $(bindgen_c_flags)
 endif
 
-bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__
+# `-fno-builtin` is passed to avoid `bindgen` from using `clang` builtin
+# prototypes for functions like `memcpy` -- if this flag is not passed,
+# `bindgen`-generated prototypes use `c_ulong` or `c_uint` depending on
+# architecture instead of generating `usize`.
+bindgen_c_flags_final = $(bindgen_c_flags_lto) -fno-builtin -D__BINDGEN__
 
 # Each `bindgen` release may upgrade the list of Rust target versions. By
 # default, the highest stable release in their list is used. Thus we need to set
-- 
2.48.1





[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux