Skip to content

Commit 8ee4860

Browse files
committed
rust: generate bindings for helpers
Helper functions are now only compiled if the wrapped function is not made directly available via bindgen. For the compiled helper functions, bindings for them are automatically generated via a second invocation to bindgen, and the corresponding binding will have its `rust_helper_` prefix removed, so Rust code can call `bindings::foo` regardless whether `foo` is directly exposed or exposed via a helper. Details about how this works: * `bindings_generated.rs` is first created via bindgen; * List of functions are extracted from `bindings_generated.rs` and a `rust_helper_foo` macro is generated for each function directly exposed this way; * `helpers.c` can then use C preprocessor to conditionally compile helpers only if they are not directly exposed. * bindgen invokes again to create bindings for `helpers.c`. * bindgen output is then postprocessed to remove the `rust_helper` prefix and add `#[link_name = ""]`. Signed-off-by: Gary Guo <[email protected]>
1 parent 7764b8c commit 8ee4860

15 files changed

+118
-136
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1835,10 +1835,10 @@ rusttest: prepare0
18351835
PHONY += rustfmt rustfmtcheck
18361836

18371837
rustfmt:
1838-
find $(srctree) -type f -name '*.rs' | xargs $(RUSTFMT)
1838+
find $(srctree) -type f -name '*.rs' | grep -v generated | xargs $(RUSTFMT)
18391839

18401840
rustfmtcheck:
1841-
find $(srctree) -type f -name '*.rs' | xargs $(RUSTFMT) --check
1841+
find $(srctree) -type f -name '*.rs' | grep -v generated | xargs $(RUSTFMT) --check
18421842

18431843
# IDE support targets
18441844
PHONY += rust-analyzer

drivers/android/process.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ use crate::{
3232
// TODO: Review this:
3333
// Lock order: Process::node_refs -> Process::inner -> Thread::inner
3434

35-
extern "C" {
36-
fn rust_helper_current_pid() -> c_types::c_int;
37-
}
38-
3935
pub(crate) struct AllocationInfo {
4036
/// Range within the allocation where we can find the offsets to the object descriptors.
4137
pub(crate) offsets: Range<usize>,
@@ -762,7 +758,7 @@ impl Process {
762758

763759
impl IoctlHandler for Process {
764760
fn write(&self, _file: &File, cmd: u32, reader: &mut UserSlicePtrReader) -> Result<i32> {
765-
let thread = self.get_thread(unsafe { rust_helper_current_pid() })?;
761+
let thread = self.get_thread(unsafe { bindings::current_pid() })?;
766762
match cmd {
767763
bindings::BINDER_SET_MAX_THREADS => self.set_max_threads(reader.read()?),
768764
bindings::BINDER_SET_CONTEXT_MGR => self.set_as_manager(None, &thread)?,
@@ -776,7 +772,7 @@ impl IoctlHandler for Process {
776772
}
777773

778774
fn read_write(&self, file: &File, cmd: u32, data: UserSlicePtr) -> Result<i32> {
779-
let thread = self.get_thread(unsafe { rust_helper_current_pid() })?;
775+
let thread = self.get_thread(unsafe { bindings::current_pid() })?;
780776
match cmd {
781777
bindings::BINDER_WRITE_READ => thread.write_read(data, file.is_blocking())?,
782778
bindings::BINDER_GET_NODE_DEBUG_INFO => self.get_node_debug_info(data)?,
@@ -913,7 +909,7 @@ impl FileOperations for Process {
913909
}
914910

915911
fn poll(&self, file: &File, table: &PollTable) -> Result<u32> {
916-
let thread = self.get_thread(unsafe { rust_helper_current_pid() })?;
912+
let thread = self.get_thread(unsafe { bindings::current_pid() })?;
917913
let (from_proc, mut mask) = thread.poll(file, table);
918914
if mask == 0 && from_proc && !self.inner.lock().work.is_empty() {
919915
mask |= bindings::POLLIN;

rust/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
bindings_generated.rs
4+
bindings_generated.h
5+
bindings_helpers_generated.rs
46
exports_*_generated.h
57
doc/
68
test/

rust/Makefile

+28-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extra-$(CONFIG_RUST) += exports_core_generated.h
55

66
extra-$(CONFIG_RUST) += libmacros.so
77

8-
extra-$(CONFIG_RUST) += bindings_generated.rs
8+
extra-$(CONFIG_RUST) += bindings_generated.rs bindings_helpers_generated.rs
99
obj-$(CONFIG_RUST) += alloc.o kernel.o
1010
extra-$(CONFIG_RUST) += exports_alloc_generated.h exports_kernel_generated.h
1111

@@ -21,7 +21,7 @@ RUSTDOC = rustdoc
2121

2222
quiet_cmd_rustdoc = RUSTDOC $(if $(filter --test,$(rustdoc_target_flags)),T, ) $(if $(rustdoc_host),H, ) $<
2323
cmd_rustdoc = \
24-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
24+
OBJTREE=$(abspath $(objtree)) \
2525
$(RUSTDOC) $(if $(rustdoc_host),,$(rustc_cross_flags)) \
2626
$(filter-out --emit=%, $(rustc_flags)) $(rustc_target_flags) $(rustdoc_target_flags) \
2727
-L $(objtree)/rust/$(if $(filter --test,$(rustdoc_target_flags)),test/) \
@@ -43,12 +43,13 @@ rustdoc-kernel: private rustc_target_flags = --extern alloc \
4343
--extern build_error \
4444
--extern macros=$(objtree)/rust/libmacros.so
4545
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-macros \
46-
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
46+
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs \
47+
$(objtree)/rust/bindings_helpers_generated.rs FORCE
4748
$(call if_changed,rustdoc)
4849

4950
quiet_cmd_rustc_test_library = RUSTC TL $<
5051
cmd_rustc_test_library = \
51-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
52+
OBJTREE=$(abspath $(objtree)) \
5253
$(RUSTC) $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rustc_flags))) \
5354
$(rustc_target_flags) --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \
5455
--out-dir $(objtree)/rust/test/ --cfg testlib \
@@ -66,7 +67,7 @@ rusttestlib-macros: $(srctree)/rust/macros/lib.rs FORCE
6667
# so for the moment we skip `-Cpanic=abort`.
6768
quiet_cmd_rustc_test = RUSTC T $<
6869
cmd_rustc_test = \
69-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
70+
OBJTREE=$(abspath $(objtree)) \
7071
$(RUSTC) --test $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rustc_flags))) \
7172
$(rustc_target_flags) --out-dir $(objtree)/rust/test \
7273
-L $(objtree)/rust/test/ --crate-name $(subst rusttest-,,$@) $<; \
@@ -134,12 +135,30 @@ quiet_cmd_bindgen = BINDGEN $@
134135
$(BINDGEN) $< $(shell grep -v '^\#\|^$$' $(srctree)/rust/bindgen_parameters) \
135136
--use-core --with-derive-default --ctypes-prefix c_types \
136137
--no-debug '.*' \
137-
--size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE
138+
--size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE; \
139+
sed -En 's/^.*pub fn ([a-zA-Z0-9_]*).*$$/\#define rust_helper_\1/pg' $@ \
140+
> $(patsubst %.rs,%.h,$@)
138141

139142
$(objtree)/rust/bindings_generated.rs: $(srctree)/rust/kernel/bindings_helper.h \
140143
$(srctree)/rust/bindgen_parameters FORCE
141144
$(call if_changed_dep,bindgen)
142145

146+
quiet_cmd_bindgen_helper = BINDGEN $@
147+
cmd_bindgen_helper = \
148+
$(BINDGEN) $< --blacklist-type '.*' --whitelist-var '' \
149+
--whitelist-function 'rust_helper_.*' \
150+
--use-core --with-derive-default --ctypes-prefix c_types \
151+
--no-debug '.*' \
152+
--size_t-is-usize -o $@ -- $(bindgen_c_flags_final) \
153+
-I$(objtree)/rust/ -DMODULE; \
154+
sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/\#[link_name="rust_helper_\1"]\n pub fn \1/g' $@
155+
156+
CFLAGS_helpers.o = -I$(objtree)/rust/
157+
158+
$(objtree)/rust/bindings_helpers_generated.rs: $(srctree)/rust/helpers.c \
159+
$(objtree)/rust/bindings_generated.rs FORCE
160+
$(call if_changed_dep,bindgen_helper)
161+
143162
quiet_cmd_exports = EXPORTS $@
144163
cmd_exports = \
145164
$(NM) -p --defined-only $< \
@@ -177,7 +196,7 @@ $(objtree)/rust/libmacros.so: $(srctree)/rust/macros/lib.rs \
177196

178197
quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
179198
cmd_rustc_library = \
180-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
199+
OBJTREE=$(abspath $(objtree)) \
181200
$(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \
182201
$(rustc_flags) $(rustc_cross_flags) $(rustc_target_flags) \
183202
--crate-type rlib --out-dir $(objtree)/rust/ -L $(objtree)/rust/ \
@@ -208,7 +227,8 @@ $(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
208227
--extern macros=$(objtree)/rust/libmacros.so
209228
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
210229
$(objtree)/rust/build_error.o \
211-
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
230+
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs \
231+
$(objtree)/rust/bindings_helpers_generated.rs FORCE
212232
$(call if_changed_dep,rustc_library)
213233

214234
# Targets that need to expand twice

rust/helpers.c

+49-13
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,39 @@
22

33
#include <linux/bug.h>
44
#include <linux/build_bug.h>
5-
#include <linux/uaccess.h>
6-
#include <linux/sched/signal.h>
7-
#include <linux/gfp.h>
8-
#include <linux/highmem.h>
9-
#include <linux/uio.h>
10-
#include <linux/errname.h>
11-
#include <linux/mutex.h>
5+
#include "kernel/bindings_helper.h"
6+
#include "bindings_generated.h"
127

8+
#ifndef rust_helper_BUG
139
void rust_helper_BUG(void)
1410
{
1511
BUG();
1612
}
13+
#endif
1714

15+
#ifndef rust_helper_copy_from_user
1816
unsigned long rust_helper_copy_from_user(void *to, const void __user *from, unsigned long n)
1917
{
2018
return copy_from_user(to, from, n);
2119
}
20+
#endif
2221

22+
#ifndef rust_helper_copy_to_user
2323
unsigned long rust_helper_copy_to_user(void __user *to, const void *from, unsigned long n)
2424
{
2525
return copy_to_user(to, from, n);
2626
}
27+
#endif
2728

29+
#ifndef rust_helper_clear_user
2830
unsigned long rust_helper_clear_user(void __user *to, unsigned long n)
2931
{
3032
return clear_user(to, n);
3133
}
34+
#endif
3235

33-
void rust_helper_spin_lock_init(spinlock_t *lock, const char *name,
36+
#ifndef rust_helper___spin_lock_init
37+
void rust_helper___spin_lock_init(spinlock_t *lock, const char *name,
3438
struct lock_class_key *key)
3539
{
3640
#ifdef CONFIG_DEBUG_SPINLOCK
@@ -39,96 +43,128 @@ void rust_helper_spin_lock_init(spinlock_t *lock, const char *name,
3943
spin_lock_init(lock);
4044
#endif
4145
}
42-
EXPORT_SYMBOL_GPL(rust_helper_spin_lock_init);
46+
EXPORT_SYMBOL_GPL(rust_helper___spin_lock_init);
47+
#endif
4348

49+
#ifndef rust_helper_spin_lock
4450
void rust_helper_spin_lock(spinlock_t *lock)
4551
{
4652
spin_lock(lock);
4753
}
4854
EXPORT_SYMBOL_GPL(rust_helper_spin_lock);
55+
#endif
4956

57+
#ifndef rust_helper_spin_unlock
5058
void rust_helper_spin_unlock(spinlock_t *lock)
5159
{
5260
spin_unlock(lock);
5361
}
5462
EXPORT_SYMBOL_GPL(rust_helper_spin_unlock);
63+
#endif
5564

65+
#ifndef rust_helper_init_wait
5666
void rust_helper_init_wait(struct wait_queue_entry *wq_entry)
5767
{
5868
init_wait(wq_entry);
5969
}
6070
EXPORT_SYMBOL_GPL(rust_helper_init_wait);
71+
#endif
6172

73+
#ifndef rust_helper_current_pid
6274
int rust_helper_current_pid(void)
6375
{
6476
return current->pid;
6577
}
6678
EXPORT_SYMBOL_GPL(rust_helper_current_pid);
79+
#endif
6780

81+
#ifndef rust_helper_signal_pending
6882
int rust_helper_signal_pending(void)
6983
{
7084
return signal_pending(current);
7185
}
7286
EXPORT_SYMBOL_GPL(rust_helper_signal_pending);
87+
#endif
7388

89+
#ifndef rust_helper_alloc_pages
7490
struct page *rust_helper_alloc_pages(gfp_t gfp_mask, unsigned int order)
7591
{
7692
return alloc_pages(gfp_mask, order);
7793
}
7894
EXPORT_SYMBOL_GPL(rust_helper_alloc_pages);
95+
#endif
7996

97+
#ifndef rust_helper_kamp
8098
void *rust_helper_kmap(struct page *page)
8199
{
82100
return kmap(page);
83101
}
84102
EXPORT_SYMBOL_GPL(rust_helper_kmap);
103+
#endif
85104

105+
#ifndef rust_helper_kunmap
86106
void rust_helper_kunmap(struct page *page)
87107
{
88108
return kunmap(page);
89109
}
90110
EXPORT_SYMBOL_GPL(rust_helper_kunmap);
111+
#endif
91112

113+
#ifndef rust_helper_cond_resched
92114
int rust_helper_cond_resched(void)
93115
{
94116
return cond_resched();
95117
}
96118
EXPORT_SYMBOL_GPL(rust_helper_cond_resched);
119+
#endif
97120

121+
#ifndef rust_helper_copy_from_iter
98122
size_t rust_helper_copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
99123
{
100124
return copy_from_iter(addr, bytes, i);
101125
}
102126
EXPORT_SYMBOL_GPL(rust_helper_copy_from_iter);
127+
#endif
103128

129+
#ifndef rust_helper_copy_to_iter
104130
size_t rust_helper_copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i)
105131
{
106132
return copy_to_iter(addr, bytes, i);
107133
}
108134
EXPORT_SYMBOL_GPL(rust_helper_copy_to_iter);
135+
#endif
109136

110-
bool rust_helper_is_err(__force const void *ptr)
137+
#ifndef rust_helper_IS_ERR
138+
bool rust_helper_IS_ERR(__force const void *ptr)
111139
{
112140
return IS_ERR(ptr);
113141
}
114-
EXPORT_SYMBOL_GPL(rust_helper_is_err);
142+
EXPORT_SYMBOL_GPL(rust_helper_IS_ERR);
143+
#endif
115144

116-
long rust_helper_ptr_err(__force const void *ptr)
145+
#ifndef rust_helper_PTR_ERR
146+
long rust_helper_PTR_ERR(__force const void *ptr)
117147
{
118148
return PTR_ERR(ptr);
119149
}
120-
EXPORT_SYMBOL_GPL(rust_helper_ptr_err);
150+
EXPORT_SYMBOL_GPL(rust_helper_PTR_ERR);
151+
#endif
121152

153+
#ifndef rust_helper_errname
122154
const char *rust_helper_errname(int err)
123155
{
124156
return errname(err);
125157
}
158+
EXPORT_SYMBOL_GPL(rust_helper_errname);
159+
#endif
126160

161+
#ifndef rust_helper_mutex_lock
127162
void rust_helper_mutex_lock(struct mutex *lock)
128163
{
129164
mutex_lock(lock);
130165
}
131166
EXPORT_SYMBOL_GPL(rust_helper_mutex_lock);
167+
#endif
132168

133169
/* We use bindgen's --size_t-is-usize option to bind the C size_t type
134170
* as the Rust usize type, so we can use it in contexts where Rust

rust/kernel/bindings.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
)]
2020
mod bindings_raw {
2121
use crate::c_types;
22-
include!(env!("RUST_BINDINGS_FILE"));
22+
include!(concat!(env!("OBJTREE"), "/rust/bindings_generated.rs"));
23+
include!(concat!(
24+
env!("OBJTREE"),
25+
"/rust/bindings_helpers_generated.rs"
26+
));
2327
}
2428
pub use bindings_raw::*;
2529

rust/kernel/bindings_helper.h

+3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
#include <linux/cdev.h>
44
#include <linux/errname.h>
55
#include <linux/fs.h>
6+
#include <linux/gfp.h>
7+
#include <linux/highmem.h>
68
#include <linux/module.h>
79
#include <linux/random.h>
10+
#include <linux/sched/signal.h>
811
#include <linux/slab.h>
912
#include <linux/sysctl.h>
1013
#include <linux/uaccess.h>

0 commit comments

Comments
 (0)