Teach bindgen about sparse annotations
geofft opened this issue · comments
In include/linux/compiler_types.h there are annotations for the Sparse static type checker like
#ifdef __CHECKER__
# define __user __attribute__((noderef, address_space(1)))
# define __kernel __attribute__((address_space(0)))
# define __must_hold(x) __attribute__((context(x,1,1)))
# define __acquires(x) __attribute__((context(x,0,1)))
# define __releases(x) __attribute__((context(x,1,0)))
# define __percpu __attribute__((noderef, address_space(3)))
# define __rcu __attribute__((noderef, address_space(4)))
# define __private __attribute__((noderef))
They're used in ways like
struct task_struct {
struct task_struct __rcu *parent;
};
struct file_operations {
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
};
It would be awesome if we could #define
them in a way that bindgen could pass to Rust, such that you couldn't dereference a __rcu
or __user
pointer directly (note the noderef
definition in sparse) and ideally so that there's a defined constructor from an __rcu
raw pointer to an Rcu<T>
or whatever but not from other raw pointers.
I'm also curious about the locking stuff, though that seems to be for what locks are expected to be held/acquired/released when you call a function, not for describing locks on data.
Apparently Clang supports __attribute__((annotate("some arbitrary text here")))
and assigns no meaning of it. If that gets through to the level that bindgen is looking at, we can probably teach bindgen to newtype the user/percpu/rcu/private pointers so they can't be dereferenced.