fishinabarrel / linux-kernel-module-rust

Framework for writing Linux kernel modules in safe Rust
GNU General Public License v2.0
1.34k stars 119 forks source link

Create ABI compatibility check #203

Open geofft opened 5 years ago

geofft commented 5 years ago

To be extra sure that rustc + bindgen has the same idea about ABI as the C toolchain does, we should find a way to assert that the ABIs match each other. They usually do (and, I think, is guaranteed for clang kernels, excepting compiler bugs) but it's worth being sure.

For data structures, we need to check alignment and padding/layout, so the simple version of this is a Rust module that walks all the types that bindgen exported and sticks their alignment and member offsets in a data structure, plus a C module that does the same thing and compares against that data structure. A more advanced version would do this check at compile time, but it's easy enough to start by loading both modules into the kernel and having them check each other.

For functions, I think there's no way to ask things like "Which registers are these arguments passed in" from within C/Rust the way you can get data type alignments and offset, and I think there's no great way to do it from gdb either. so I think we need to parse debugging metadata like DWARF. (ORC appears to just be stack frame unwinding, it doesn't track arguments.) So this probably means picking a DWARF library (in any language) and comparing the two modules.

We should make this available for people to run on their own kernels and also throw it into CI. You only need to run the test once per built kernel + Rust toolchain version + version of this library, if you don't change the input to bindgen then you don't need to rerun it. (So, in practice, downstream users who have no changes to this library and are targeting a kernel we have in CI don't need to run it on their own.)

matu3ba commented 5 years ago

Stephen Kell is working on C/C++ semantics and DWARF. https://github.com/stephenrkell/liballocs I am pretty sure that would fit the use case and he has many papers on that. https://dl.acm.org/citation.cfm?doid=3302515.3290380

You could drop him a mail or so to see where that might go.

geofft commented 5 years ago

Thanks, that looks very relevant!

Also there's an LWN post today about ABI stability in stable kernel releases, mentioning use of libabigali: https://lwn.net/SubscriberLink/800452/f9ab71b575308a56/

I don't immediately see anything in a git grep of libabigali that looks at registers (things I'm worried about include, say, Rust passing something via the stack where C would pass it in a register - see e.g. https://github.com/rust-lang-nursery/nomicon/pull/8#issuecomment-291510444 - and also generally getting the choice of which register to use wrong with e.g. regparm), so it might not be the right tool for us. I haven't looked enough in DWARF to confirm that there is a right tool at all, but I assume DWARF must have this data.

matu3ba commented 4 years ago

@geofft The DWARF part should become relevant at a later point.