diff --git a/Cargo.toml b/Cargo.toml index 5bc4b0d8..9df03b47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,6 @@ edition = "2018" bitflags = "1" [build-dependencies] -bindgen = "0.54" +bindgen = "0.56" cc = "1.0" shlex = "0.1" diff --git a/build.rs b/build.rs index 9358ad4c..f809c1c9 100644 --- a/build.rs +++ b/build.rs @@ -53,6 +53,14 @@ const OPAQUE_TYPES: &[&str] = &[ // and https://github.com/rust-lang/rust-bindgen/issues/1538 "desc_struct", "xregs_state", + "xsave_struct", +]; +const CLANG_ARGS_BLACKLIST: [&'static str; 5] = [ + "-maccumulate-outgoing-args", + "-mpreferred-stack-boundary=3", + "-mindirect-branch=thunk-extern", + "-mindirect-branch-register", + "-fconserve-stack", ]; fn handle_kernel_version_cfg(bindings_path: &PathBuf) { @@ -86,10 +94,25 @@ fn handle_kernel_version_cfg(bindings_path: &PathBuf) { } if major >= 4 { // We don't currently support anything older than 4.4 - for x in 4..=if major > 4 { 20 } else { minor } { + for x in 1..=if major > 4 { 20 } else { minor } { println!("cargo:rustc-cfg=kernel_4_{}_0_or_greater", x); } } + if major >= 3 { + for x in 1..=if major > 3 { 19 } else { minor } { + println!("cargo:rustc-cfg=kernel_3_{}_0_or_greater", x); + } + } +} + +fn handle_kernel_rhel_kabi(fs_ops_path: &PathBuf) { + let f = BufReader::new(fs::File::open(fs_ops_path).unwrap()); + for line in f.lines() { + if line.unwrap().contains("RH_KABI") { + println!("cargo:rustc-cfg=kernel_rh_kabi"); + break; + } + } } fn handle_kernel_symbols_cfg(symvers_path: &PathBuf) { @@ -153,6 +176,9 @@ fn main() { builder = builder.clang_arg(format!("--target={}", target)); for arg in kernel_args.iter() { + if CLANG_ARGS_BLACKLIST.contains(&arg.as_str()) { + continue; + } builder = builder.clang_arg(arg.clone()); } @@ -179,10 +205,12 @@ fn main() { .expect("Couldn't write bindings!"); handle_kernel_version_cfg(&out_path.join("bindings.rs")); + handle_kernel_rhel_kabi(&PathBuf::from(&kernel_dir).parent().unwrap().join("source/include/linux/fs.h")); handle_kernel_symbols_cfg(&PathBuf::from(&kernel_dir).join("Module.symvers")); let mut builder = cc::Build::new(); - builder.compiler(env::var("CC").unwrap_or_else(|_| "clang".to_string())); + let compiler = env::var("CC").unwrap_or_else(|_| "clang".to_string()); + builder.compiler(&compiler); builder.target(&target); builder.warnings(false); println!("cargo:rerun-if-changed=src/helpers.c"); @@ -190,5 +218,8 @@ fn main() { for arg in kernel_args.iter() { builder.flag(&arg); } + if &compiler == "gcc" { + builder.flag("-fno-pie"); + } builder.compile("helpers"); } diff --git a/hello-world/Kbuild b/hello-world/Kbuild index 81d6dc88..de7cf5ff 100644 --- a/hello-world/Kbuild +++ b/hello-world/Kbuild @@ -6,7 +6,7 @@ CARGO ?= cargo export c_flags $(src)/target/x86_64-linux-kernel/debug/libhello_world.a: cargo_will_determine_dependencies - cd $(src); $(CARGO) build -Z build-std=core,alloc --target=x86_64-linux-kernel + cd $(src); $(CARGO) +nightly build -Z build-std=core,alloc --target=x86_64-linux-kernel .PHONY: cargo_will_determine_dependencies diff --git a/hello-world/Makefile b/hello-world/Makefile index ecbce40d..4b12f9c5 100644 --- a/hello-world/Makefile +++ b/hello-world/Makefile @@ -1,12 +1,19 @@ export KDIR ?= /lib/modules/$(shell uname -r)/build +CONFIG_CC_IS_CLANG := y CLANG ?= clang ifeq ($(origin CC),default) CC := ${CLANG} endif +HEADER_SEMVER ?= $(shell uname -r | grep -oG "[0-9]\+\.[0-9]\+\.[0-9]\+" | head -1) +ifeq ($(shell echo $(HEADER_SEMVER) 4.4.0 | tr " " "\n" | sort -V | head -1), $(HEADER_SEMVER)) +CC := gcc +CONFIG_CC_IS_CLANG := n +endif + all: - $(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) CONFIG_CC_IS_CLANG=y + $(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) CONFIG_CC_IS_CLANG=$(CONFIG_CC_IS_CLANG) clean: $(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) clean diff --git a/src/file_operations.rs b/src/file_operations.rs index 1f7d85cc..e45544f6 100644 --- a/src/file_operations.rs +++ b/src/file_operations.rs @@ -159,7 +159,12 @@ impl FileOperationsVtable { } else { None }, - + #[cfg(not(kernel_4_1_0_or_greater))] + aio_read: None, + #[cfg(not(kernel_4_1_0_or_greater))] + aio_write: None, + #[cfg(not(kernel_3_11_0_or_greater))] + readdir: None, #[cfg(not(kernel_4_9_0_or_greater))] aio_fsync: None, check_flags: None, @@ -189,17 +194,22 @@ impl FileOperationsVtable { mmap_supported_flags: 0, owner: ptr::null_mut(), poll: None, + #[cfg(kernel_3_16_0_or_greater)] read_iter: None, #[cfg(kernel_4_20_0_or_greater)] remap_file_range: None, sendpage: None, #[cfg(kernel_aufs_setfl)] setfl: None, + #[cfg(kernel_rh_kabi)] + __bindgen_anon_1: bindings::file_operations__bindgen_ty_1 { setlease: None }, + #[cfg(not(kernel_rh_kabi))] setlease: None, show_fdinfo: None, splice_read: None, splice_write: None, unlocked_ioctl: None, + #[cfg(kernel_3_16_0_or_greater)] write_iter: None, }; }