From 23473bbf15c087fd15b854b7838b1cb4b1ccc37e Mon Sep 17 00:00:00 2001 From: adamrk Date: Wed, 20 Jan 2021 22:04:04 +0100 Subject: [PATCH 1/5] Add copy-string param --- .github/workflows/ci.yaml | 8 ++- .github/workflows/qemu-init.sh | 2 +- drivers/char/rust_example.rs | 9 +++ drivers/char/rust_example_2.rs | 9 +++ drivers/char/rust_example_3.rs | 10 +++ drivers/char/rust_example_4.rs | 9 +++ rust/module.rs | 121 +++++++++++++++++++++++++++------ 7 files changed, 146 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d9da916b6dc9da..fae3c4ffc9ca38 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,6 +9,7 @@ jobs: timeout-minutes: 20 strategy: + fail-fast: false matrix: arch: [x86_64, arm64] toolchain: [gcc, clang, llvm] @@ -156,7 +157,7 @@ jobs: # Run - run: ${{ env.BUILD_DIR }}usr/gen_init_cpio .github/workflows/qemu-initramfs.desc > qemu-initramfs.img - - run: qemu-system-${{ env.QEMU_ARCH }} -kernel ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }} -initrd qemu-initramfs.img -M ${{ env.QEMU_MACHINE }} -cpu ${{ env.QEMU_CPU }} -smp 2 -nographic -no-reboot -append '${{ env.QEMU_APPEND }} rust_example.my_i32=123321 rust_example_2.my_i32=234432' | tee qemu-stdout.log + - run: qemu-system-${{ env.QEMU_ARCH }} -kernel ${{ env.BUILD_DIR }}${{ env.IMAGE_PATH }} -initrd qemu-initramfs.img -M ${{ env.QEMU_MACHINE }} -cpu ${{ env.QEMU_CPU }} -smp 2 -nographic -no-reboot -append '${{ env.QEMU_APPEND }} rust_example.my_i32=123321 rust_example.my_str=🦀mod rust_example_2.my_i32=234432' | tee qemu-stdout.log # Check - run: grep -F '] Rust Example (init)' qemu-stdout.log @@ -169,6 +170,11 @@ jobs: - run: "grep -F '] [3] my_i32: 345543' qemu-stdout.log" - run: "grep -F '] [4] my_i32: 456654' qemu-stdout.log" + - run: "grep '\\] my_str: 🦀mod\\s*$' qemu-stdout.log" + - run: "grep '\\] \\[2\\] my_str: default str val\\s*$' qemu-stdout.log" + - run: "grep '\\] \\[3\\] my_str: 🦀mod\\s*$' qemu-stdout.log" + - run: "grep '\\] \\[4\\] my_str: default str val\\s*$' qemu-stdout.log" + - run: grep -F '] [3] Rust Example (exit)' qemu-stdout.log - run: grep -F '] [4] Rust Example (exit)' qemu-stdout.log diff --git a/.github/workflows/qemu-init.sh b/.github/workflows/qemu-init.sh index 5d623426b2a165..a0d547af61e7bd 100755 --- a/.github/workflows/qemu-init.sh +++ b/.github/workflows/qemu-init.sh @@ -1,6 +1,6 @@ #!/bin/sh -busybox insmod rust_example_3.ko my_i32=345543 +busybox insmod rust_example_3.ko my_i32=345543 my_str=🦀mod busybox insmod rust_example_4.ko my_i32=456654 busybox rmmod rust_example_3.ko busybox rmmod rust_example_4.ko diff --git a/drivers/char/rust_example.rs b/drivers/char/rust_example.rs index 47c4a7f722ef80..028f6e92eacdf5 100644 --- a/drivers/char/rust_example.rs +++ b/drivers/char/rust_example.rs @@ -25,6 +25,11 @@ module! { permissions: 0o644, description: b"Example of i32", }, + my_str: &str { + default: "default str val", + permissions: 0o644, + description: b"Example of a string param", + }, }, } @@ -51,6 +56,10 @@ impl KernelModule for RustExample { println!("Parameters:"); println!(" my_bool: {}", my_bool.read()); println!(" my_i32: {}", my_i32.read()); + println!( + " my_str: {}", + my_str.read().expect("Expected valid UTF8 parameter") + ); Ok(RustExample { message: "on the heap!".to_owned(), diff --git a/drivers/char/rust_example_2.rs b/drivers/char/rust_example_2.rs index b5ffb92870d191..9cf5b6e218f0cb 100644 --- a/drivers/char/rust_example_2.rs +++ b/drivers/char/rust_example_2.rs @@ -22,6 +22,11 @@ module! { permissions: 0o644, description: b"Example of i32", }, + my_str: &str { + default: "default str val", + permissions: 0o644, + description: b"Example of a string param", + }, }, } @@ -36,6 +41,10 @@ impl KernelModule for RustExample2 { println!("[2] Parameters:"); println!("[2] my_bool: {}", my_bool.read()); println!("[2] my_i32: {}", my_i32.read()); + println!( + "[2] my_str: {}", + my_str.read().expect("Expected valid UTF8 parameter") + ); Ok(RustExample2 { message: "on the heap!".to_owned(), }) diff --git a/drivers/char/rust_example_3.rs b/drivers/char/rust_example_3.rs index c6b867e527e9a9..00143e2ebb02fe 100644 --- a/drivers/char/rust_example_3.rs +++ b/drivers/char/rust_example_3.rs @@ -22,6 +22,11 @@ module! { permissions: 0o644, description: b"Example of i32", }, + my_str: &str { + default: "default str val", + permissions: 0o644, + description: b"Example of a string param", + }, }, } @@ -36,6 +41,11 @@ impl KernelModule for RustExample3 { println!("[3] Parameters:"); println!("[3] my_bool: {}", my_bool.read()); println!("[3] my_i32: {}", my_i32.read()); + println!( + "[3] my_str: {}", + my_str.read().expect("Expected valid UTF8 parameter") + ); + Ok(RustExample3 { message: "on the heap!".to_owned(), }) diff --git a/drivers/char/rust_example_4.rs b/drivers/char/rust_example_4.rs index b658c55b4ba80b..a0e9b530fe8333 100644 --- a/drivers/char/rust_example_4.rs +++ b/drivers/char/rust_example_4.rs @@ -22,6 +22,11 @@ module! { permissions: 0o644, description: b"Example of i32", }, + my_str: &str { + default: "default str val", + permissions: 0o644, + description: b"Example of a string param", + }, }, } @@ -36,6 +41,10 @@ impl KernelModule for RustExample4 { println!("[4] Parameters:"); println!("[4] my_bool: {}", my_bool.read()); println!("[4] my_i32: {}", my_i32.read()); + println!( + "[4] my_str: {}", + my_str.read().expect("Expected valid UTF8 parameter") + ); Ok(RustExample4 { message: "on the heap!".to_owned(), }) diff --git a/rust/module.rs b/rust/module.rs index 051a58bac8da65..14283b0a4b459c 100644 --- a/rust/module.rs +++ b/rust/module.rs @@ -5,7 +5,7 @@ use proc_macro::{token_stream, Delimiter, Group, TokenStream, TokenTree}; fn expect_ident(it: &mut token_stream::IntoIter) -> String { - if let TokenTree::Ident(ident) = it.next().unwrap() { + if let TokenTree::Ident(ident) = it.next().expect("Expected Ident") { ident.to_string() } else { panic!("Expected Ident"); @@ -13,7 +13,7 @@ fn expect_ident(it: &mut token_stream::IntoIter) -> String { } fn expect_punct(it: &mut token_stream::IntoIter) -> char { - if let TokenTree::Punct(punct) = it.next().unwrap() { + if let TokenTree::Punct(punct) = it.next().expect("Expected Punct") { punct.as_char() } else { panic!("Expected Punct"); @@ -21,7 +21,7 @@ fn expect_punct(it: &mut token_stream::IntoIter) -> char { } fn expect_literal(it: &mut token_stream::IntoIter) -> String { - if let TokenTree::Literal(literal) = it.next().unwrap() { + if let TokenTree::Literal(literal) = it.next().expect("Expected Literal") { literal.to_string() } else { panic!("Expected Literal"); @@ -29,7 +29,7 @@ fn expect_literal(it: &mut token_stream::IntoIter) -> String { } fn expect_group(it: &mut token_stream::IntoIter) -> Group { - if let TokenTree::Group(group) = it.next().unwrap() { + if let TokenTree::Group(group) = it.next().expect("Expected Group") { group } else { panic!("Expected Group"); @@ -43,6 +43,20 @@ fn expect_end(it: &mut token_stream::IntoIter) { } } +/// Only expected to parse types that are allowed for module parameters. +fn expect_type(it: &mut token_stream::IntoIter) -> String { + match it.next().expect("Expected Type") { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '&'); + let ident = expect_ident(it); + assert_eq!(ident, "str"); + "&str".to_string() + } + TokenTree::Ident(ident) => ident.to_string(), + _ => panic!("Expected type"), + } +} + fn get_ident(it: &mut token_stream::IntoIter, expected_name: &str) -> String { assert_eq!(expect_ident(it), expected_name); assert_eq!(expect_punct(it), ':'); @@ -60,6 +74,7 @@ fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String { } fn get_group(it: &mut token_stream::IntoIter, expected_name: &str) -> Group { + println!("Getting Group"); assert_eq!(expect_ident(it), expected_name); assert_eq!(expect_punct(it), ':'); let group = expect_group(it); @@ -76,6 +91,15 @@ fn get_byte_string(it: &mut token_stream::IntoIter, expected_name: &str) -> Stri byte_string[2..byte_string.len() - 1].to_string() } +fn get_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String { + let string = get_literal(it, expected_name); + + assert!(string.starts_with("\"")); + assert!(string.ends_with("\"")); + + string[1..string.len() - 1].to_string() +} + fn __build_modinfo_string_base( module: &str, field: &str, @@ -208,17 +232,18 @@ pub fn module(ts: TokenStream) -> TokenStream { }; assert_eq!(expect_punct(&mut it), ':'); - let param_type = expect_ident(&mut it); + let param_type = expect_type(&mut it); + println!("Got param type {}", param_type); let group = expect_group(&mut it); assert_eq!(expect_punct(&mut it), ','); assert_eq!(group.delimiter(), Delimiter::Brace); let mut param_it = group.stream().into_iter(); - let param_default = if param_type == "bool" { - get_ident(&mut param_it, "default") - } else { - get_literal(&mut param_it, "default") + let param_default = match param_type.as_ref() { + "bool" => get_ident(&mut param_it, "default"), + "&str" => get_string(&mut param_it, "default"), + _ => get_literal(&mut param_it, "default"), }; let param_permissions = get_literal(&mut param_it, "permissions"); let param_description = get_byte_string(&mut param_it, "description"); @@ -229,6 +254,7 @@ pub fn module(ts: TokenStream) -> TokenStream { let param_kernel_type = match param_type.as_ref() { "bool" => "bool", "i32" => "int", + "&str" => "string", t => panic!("Unrecognized type {}", t), }; @@ -244,18 +270,73 @@ pub fn module(ts: TokenStream) -> TokenStream { ¶m_name, ¶m_description, )); + let param_type_internal = match param_type.as_ref() { + "&str" => format!("[u8; {}]", param_default.len() + 1), + _ => param_type.clone(), + }; + let param_default = match param_type.as_ref() { + "&str" => format!("*b\"{}\0\"", param_default), + _ => param_default, + }; + let read_func = match param_type.as_ref() { + "&str" => format!( + " + fn read(&self) -> Result<&str, core::str::Utf8Error> {{ + unsafe {{ + let nul = __{name}_{param_name}_value + .iter() + .position(|&b| b == b'\0') + .unwrap(); + core::str::from_utf8(&__{name}_{param_name}_value[0..nul]) + }} + }} + ", + name = name, + param_name = param_name, + ), + _ => format!( + " + fn read(&self) -> {param_type} {{ + unsafe {{ __{name}_{param_name}_value }} + }} + ", + name = name, + param_name = param_name, + param_type = param_type, + ), + }; + let kparam_ptr = match param_type.as_ref() { + "&str" => format!( + " + __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{ + str_: &kernel::bindings::kparam_string {{ + maxlen: unsafe {{ __{name}_{param_name}_value.len() }} as u32 + 1, + string: unsafe {{ (&__{name}_{param_name}_value).as_ptr() }} + as *mut kernel::c_types::c_char, + }} as *const _, + }}, + ", + name = name, + param_name = param_name, + ), + _ => format!( + " + __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{ + arg: unsafe {{ &__{name}_{param_name}_value }} as *const _ as *mut kernel::c_types::c_void, + }}, + ", + name = name, + param_name = param_name, + ), + }; params_modinfo.push_str( &format!( " - static mut __{name}_{param_name}_value: {param_type} = {param_default}; + static mut __{name}_{param_name}_value: {param_type_internal} = {param_default}; struct __{name}_{param_name}; - impl __{name}_{param_name} {{ - fn read(&self) -> {param_type} {{ - unsafe {{ __{name}_{param_name}_value }} - }} - }} + impl __{name}_{param_name} {{ {read_func} }} const {param_name}: __{name}_{param_name} = __{name}_{param_name}; @@ -288,17 +369,17 @@ pub fn module(ts: TokenStream) -> TokenStream { perm: {permissions}, level: -1, flags: 0, - __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{ - arg: unsafe {{ &__{name}_{param_name}_value }} as *const _ as *mut kernel::c_types::c_void, - }}, + {kparam_ptr} }}); ", name = name, - param_type = param_type, + param_type_internal = param_type_internal, + read_func = read_func, param_kernel_type = param_kernel_type, param_default = param_default, param_name = param_name, permissions = param_permissions, + kparam_ptr = kparam_ptr, ) ); } @@ -390,5 +471,5 @@ pub fn module(ts: TokenStream) -> TokenStream { file = &build_modinfo_string_only_builtin(&name, "file", &file), params_modinfo = params_modinfo, initcall_section = ".initcall6.init" - ).parse().unwrap() + ).parse().expect("Expected parsed token stream") } From 69b0dcb911e15ad22a9dea68d2fe658d1324ef23 Mon Sep 17 00:00:00 2001 From: adamrk Date: Thu, 21 Jan 2021 23:24:07 +0100 Subject: [PATCH 2/5] cleanup --- drivers/char/rust_example.rs | 2 +- drivers/char/rust_example_2.rs | 2 +- drivers/char/rust_example_3.rs | 2 +- drivers/char/rust_example_4.rs | 2 +- rust/module.rs | 51 +++++++++++++++++----------------- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/drivers/char/rust_example.rs b/drivers/char/rust_example.rs index 028f6e92eacdf5..a9b18c48019aa9 100644 --- a/drivers/char/rust_example.rs +++ b/drivers/char/rust_example.rs @@ -25,7 +25,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: &str { + my_str: CopyString { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/drivers/char/rust_example_2.rs b/drivers/char/rust_example_2.rs index 9cf5b6e218f0cb..bfe93fb2d34035 100644 --- a/drivers/char/rust_example_2.rs +++ b/drivers/char/rust_example_2.rs @@ -22,7 +22,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: &str { + my_str: CopyString { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/drivers/char/rust_example_3.rs b/drivers/char/rust_example_3.rs index 00143e2ebb02fe..f942fa9f446910 100644 --- a/drivers/char/rust_example_3.rs +++ b/drivers/char/rust_example_3.rs @@ -22,7 +22,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: &str { + my_str: CopyString { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/drivers/char/rust_example_4.rs b/drivers/char/rust_example_4.rs index a0e9b530fe8333..76c38ce978af94 100644 --- a/drivers/char/rust_example_4.rs +++ b/drivers/char/rust_example_4.rs @@ -22,7 +22,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: &str { + my_str: CopyString { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/rust/module.rs b/rust/module.rs index 14283b0a4b459c..2dce819986cde2 100644 --- a/rust/module.rs +++ b/rust/module.rs @@ -43,20 +43,6 @@ fn expect_end(it: &mut token_stream::IntoIter) { } } -/// Only expected to parse types that are allowed for module parameters. -fn expect_type(it: &mut token_stream::IntoIter) -> String { - match it.next().expect("Expected Type") { - TokenTree::Punct(punct) => { - assert_eq!(punct.as_char(), '&'); - let ident = expect_ident(it); - assert_eq!(ident, "str"); - "&str".to_string() - } - TokenTree::Ident(ident) => ident.to_string(), - _ => panic!("Expected type"), - } -} - fn get_ident(it: &mut token_stream::IntoIter, expected_name: &str) -> String { assert_eq!(expect_ident(it), expected_name); assert_eq!(expect_punct(it), ':'); @@ -74,7 +60,6 @@ fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String { } fn get_group(it: &mut token_stream::IntoIter, expected_name: &str) -> Group { - println!("Getting Group"); assert_eq!(expect_ident(it), expected_name); assert_eq!(expect_punct(it), ':'); let group = expect_group(it); @@ -184,7 +169,7 @@ fn build_modinfo_string_param(module: &str, field: &str, param: &str, content: & /// The `type` argument should be a type which implements the [`KernelModule`] trait. /// Also accepts various forms of kernel metadata. /// -/// Example: +/// ## Example /// ```rust,no_run /// use kernel::prelude::*; /// @@ -194,16 +179,33 @@ fn build_modinfo_string_param(module: &str, field: &str, param: &str, content: & /// author: b"Rust for Linux Contributors", /// description: b"My very own kernel module!", /// license: b"GPL v2", -/// params: {}, +/// params: { +/// my_i32: i32 { +/// default: 42, +/// permissions: 0o644, +/// description: b"Example of i32", +/// }, +/// }, /// } /// /// struct MyKernelModule; /// /// impl KernelModule for MyKernelModule { /// fn init() -> KernelResult { +/// println!("bool param is: {}", my_bool.read()); /// Ok(MyKernelModule) /// } /// } +/// +/// ## Suported Parameter Types +/// | Type | `read(&self)` return type | +/// | ------------ | ------------------------------------ | +/// | `i32` | `i32` | +/// | `bool` | `bool` | +/// | `CopyString` | `Result<&str, core::str::Utf8Error>` | +/// +/// For `CopyString` the parameter is copied into the buffer of the default value and +/// cannot be longer than the default value. /// ``` #[proc_macro] pub fn module(ts: TokenStream) -> TokenStream { @@ -232,8 +234,7 @@ pub fn module(ts: TokenStream) -> TokenStream { }; assert_eq!(expect_punct(&mut it), ':'); - let param_type = expect_type(&mut it); - println!("Got param type {}", param_type); + let param_type = expect_ident(&mut it); let group = expect_group(&mut it); assert_eq!(expect_punct(&mut it), ','); @@ -242,7 +243,7 @@ pub fn module(ts: TokenStream) -> TokenStream { let mut param_it = group.stream().into_iter(); let param_default = match param_type.as_ref() { "bool" => get_ident(&mut param_it, "default"), - "&str" => get_string(&mut param_it, "default"), + "CopyString" => get_string(&mut param_it, "default"), _ => get_literal(&mut param_it, "default"), }; let param_permissions = get_literal(&mut param_it, "permissions"); @@ -254,7 +255,7 @@ pub fn module(ts: TokenStream) -> TokenStream { let param_kernel_type = match param_type.as_ref() { "bool" => "bool", "i32" => "int", - "&str" => "string", + "CopyString" => "string", t => panic!("Unrecognized type {}", t), }; @@ -271,15 +272,15 @@ pub fn module(ts: TokenStream) -> TokenStream { ¶m_description, )); let param_type_internal = match param_type.as_ref() { - "&str" => format!("[u8; {}]", param_default.len() + 1), + "CopyString" => format!("[u8; {}]", param_default.len() + 1), _ => param_type.clone(), }; let param_default = match param_type.as_ref() { - "&str" => format!("*b\"{}\0\"", param_default), + "CopyString" => format!("*b\"{}\0\"", param_default), _ => param_default, }; let read_func = match param_type.as_ref() { - "&str" => format!( + "CopyString" => format!( " fn read(&self) -> Result<&str, core::str::Utf8Error> {{ unsafe {{ @@ -306,7 +307,7 @@ pub fn module(ts: TokenStream) -> TokenStream { ), }; let kparam_ptr = match param_type.as_ref() { - "&str" => format!( + "CopyString" => format!( " __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{ str_: &kernel::bindings::kparam_string {{ From e9e539df352afb53276675a5cdea0c6bac71fcbd Mon Sep 17 00:00:00 2001 From: adamrk Date: Fri, 22 Jan 2021 23:20:11 +0100 Subject: [PATCH 3/5] add charp --- drivers/char/rust_example.rs | 287 ++++++++++++++++++++++++++++++++- drivers/char/rust_example_2.rs | 2 +- drivers/char/rust_example_3.rs | 2 +- drivers/char/rust_example_4.rs | 2 +- rust/module.rs | 21 ++- 5 files changed, 309 insertions(+), 5 deletions(-) diff --git a/drivers/char/rust_example.rs b/drivers/char/rust_example.rs index a9b18c48019aa9..4c2be2d75530ac 100644 --- a/drivers/char/rust_example.rs +++ b/drivers/char/rust_example.rs @@ -8,6 +8,291 @@ use core::pin::Pin; use kernel::prelude::*; use kernel::{cstr, file_operations::FileOperations, miscdev}; +// static mut __MOD: Option = None; +// global_asm!( r#".section ".initcall6.init", "a" +// __rust_example_initcall: +// .long __rust_example_init - . +// .previous"#); + +// #[cfg(not(MODULE))] +// #[no_mangle] +// pub extern "C" fn __rust_example_init() -> kernel::c_types::c_int { +// __init() +// } +// #[cfg(not(MODULE))] +// #[no_mangle] +// pub extern "C" fn __rust_example_exit() { __exit() } +// fn __init() -> kernel::c_types::c_int { +// match ::init() { +// Ok(m) => { unsafe { __MOD = Some(m); } return 0; } +// Err(e) => { return e.to_kernel_errno(); } +// } +// } +// fn __exit() { unsafe { __MOD = None; } } +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_author: [u8; 48] = +// *b"rust_example.author=Rust for Linux Contributors\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_description: [u8; 66] = +// *b"rust_example.description=An example kernel module written in Rust\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_license: [u8; 28] = +// *b"rust_example.license=GPL v2\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_file: [u8; 44] = +// *b"rust_example.file=drivers/char/rust_example\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parmtype_my_bool: [u8; 35] = +// *b"rust_example.parmtype=my_bool:bool\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parm_my_bool: [u8; 42] = +// *b"rust_example.parm=my_bool:Example of bool\0"; +// static mut __rust_example_my_bool_value: bool = true; +// struct __rust_example_my_bool; +// impl __rust_example_my_bool { +// fn read(&self) -> bool { unsafe { __rust_example_my_bool_value } } +// } +// const my_bool: __rust_example_my_bool = __rust_example_my_bool; +// #[repr(transparent)] +// struct __rust_example_my_bool_RacyKernelParam(kernel::bindings::kernel_param); +// unsafe impl Sync for __rust_example_my_bool_RacyKernelParam { } +// #[cfg(not(MODULE))] +// const __rust_example_my_bool_name: *const kernel::c_types::c_char = +// b"rust_example.my_bool\0" as *const _ as +// *const kernel::c_types::c_char; +// #[link_section = "__param"] +// #[used] +// static __rust_example_my_bool_struct: +// __rust_example_my_bool_RacyKernelParam = +// __rust_example_my_bool_RacyKernelParam(kernel::bindings::kernel_param{name: +// __rust_example_my_bool_name, +// mod_: +// core::ptr::null_mut(), +// ops: +// unsafe +// { +// &kernel::bindings::param_ops_bool +// } +// as +// *const kernel::bindings::kernel_param_ops, +// perm: +// 0, +// level: +// -1, +// flags: +// 0, +// __bindgen_anon_1: +// kernel::bindings::kernel_param__bindgen_ty_1{arg: +// unsafe +// { +// &__rust_example_my_bool_value +// } +// as +// *const _ +// as +// *mut kernel::c_types::c_void,},}); +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parmtype_my_i32: [u8; 33] = +// *b"rust_example.parmtype=my_i32:int\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parm_my_i32: [u8; 40] = +// *b"rust_example.parm=my_i32:Example of i32\0"; +// static mut __rust_example_my_i32_value: i32 = 42; +// struct __rust_example_my_i32; +// impl __rust_example_my_i32 { +// fn read(&self) -> i32 { unsafe { __rust_example_my_i32_value } } +// } +// const my_i32: __rust_example_my_i32 = __rust_example_my_i32; +// #[repr(transparent)] +// struct __rust_example_my_i32_RacyKernelParam(kernel::bindings::kernel_param); +// unsafe impl Sync for __rust_example_my_i32_RacyKernelParam { } +// #[cfg(not(MODULE))] +// const __rust_example_my_i32_name: *const kernel::c_types::c_char = +// b"rust_example.my_i32\0" as *const _ as +// *const kernel::c_types::c_char; +// #[link_section = "__param"] +// #[used] +// static __rust_example_my_i32_struct: __rust_example_my_i32_RacyKernelParam +// = +// __rust_example_my_i32_RacyKernelParam(kernel::bindings::kernel_param{name: +// __rust_example_my_i32_name, +// mod_: +// core::ptr::null_mut(), +// ops: +// unsafe +// { +// &kernel::bindings::param_ops_int +// } +// as +// *const kernel::bindings::kernel_param_ops, +// perm: +// 0o644, +// level: +// -1, +// flags: +// 0, +// __bindgen_anon_1: +// kernel::bindings::kernel_param__bindgen_ty_1{arg: +// unsafe +// { +// &__rust_example_my_i32_value +// } +// as +// *const _ +// as +// *mut kernel::c_types::c_void,},}); +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parmtype_my_str: [u8; 36] = +// *b"rust_example.parmtype=my_str:string\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parm_my_str: [u8; 51] = +// *b"rust_example.parm=my_str:Example of a string param\0"; +// static mut __rust_example_my_str_value: [u8; 16] = *b"default str val"; +// struct __rust_example_my_str; +// impl __rust_example_my_str { +// fn read(&self) -> Result<&str, core::str::Utf8Error> { +// unsafe { +// let nul = +// __rust_example_my_str_value.iter().position(|&b| +// b == +// b'').unwrap(); +// core::str::from_utf8(&__rust_example_my_str_value[0..nul]) +// } +// } +// } +// const my_str: __rust_example_my_str = __rust_example_my_str; +// #[repr(transparent)] +// struct __rust_example_my_str_RacyKernelParam(kernel::bindings::kernel_param); +// unsafe impl Sync for __rust_example_my_str_RacyKernelParam { } +// #[cfg(not(MODULE))] +// const __rust_example_my_str_name: *const kernel::c_types::c_char = +// b"rust_example.my_str\0" as *const _ as +// *const kernel::c_types::c_char; +// #[link_section = "__param"] +// #[used] +// static __rust_example_my_str_struct: __rust_example_my_str_RacyKernelParam +// = +// __rust_example_my_str_RacyKernelParam(kernel::bindings::kernel_param{name: +// __rust_example_my_str_name, +// mod_: +// core::ptr::null_mut(), +// ops: +// unsafe +// { +// &kernel::bindings::param_ops_string +// } +// as +// *const kernel::bindings::kernel_param_ops, +// perm: +// 0o644, +// level: +// -1, +// flags: +// 0, +// __bindgen_anon_1: +// kernel::bindings::kernel_param__bindgen_ty_1{str_: +// &kernel::bindings::kparam_string{maxlen: +// unsafe +// { +// __rust_example_my_str_value.len() +// } +// as +// u32 +// + +// 1, +// string: +// unsafe +// { +// (&__rust_example_my_str_value).as_ptr() +// } +// as +// *mut kernel::c_types::c_char,} +// as +// *const _,},}); +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parmtype_my_charp: [u8; 37] = +// *b"rust_example.parmtype=my_charp:charp\0"; +// #[cfg(not(MODULE))] +// #[link_section = ".modinfo"] +// #[used] +// pub static __rust_example_parm_my_charp: [u8; 53] = +// *b"rust_example.parm=my_charp:Example of a string param\0"; +// static mut __rust_example_my_charp_value: *mut u8 = +// unsafe { b"default charp val" as *const u8 as *mut u8 }; +// struct __rust_example_my_charp; +// impl __rust_example_my_charp { +// fn read(&self) -> Result<&str, core::str::Utf8Error> { +// unsafe { +// let mut count = 0; +// while *__rust_example_my_charp_value.add(count) != b'\0' { +// count += 1; +// } +// core::str::from_utf8(&core::slice::from_raw_parts(__rust_example_my_charp_value, count)) +// } +// } +// } +// const my_charp: __rust_example_my_charp = __rust_example_my_charp; +// #[repr(transparent)] +// struct __rust_example_my_charp_RacyKernelParam(kernel::bindings::kernel_param); +// unsafe impl Sync for __rust_example_my_charp_RacyKernelParam { } +// #[cfg(not(MODULE))] +// const __rust_example_my_charp_name: *const kernel::c_types::c_char = +// b"rust_example.my_charp\0" as *const _ as +// *const kernel::c_types::c_char; +// #[link_section = "__param"] +// #[used] +// static __rust_example_my_charp_struct: +// __rust_example_my_charp_RacyKernelParam = +// __rust_example_my_charp_RacyKernelParam(kernel::bindings::kernel_param{name: +// __rust_example_my_charp_name, +// mod_: +// core::ptr::null_mut(), +// ops: +// unsafe +// { +// &kernel::bindings::param_ops_charp +// } +// as +// *const kernel::bindings::kernel_param_ops, +// perm: +// 0o644, +// level: +// -1, +// flags: +// 0, +// __bindgen_anon_1: +// kernel::bindings::kernel_param__bindgen_ty_1{arg: +// unsafe +// { +// &__rust_example_my_charp_value +// } +// as +// *const _ +// as +// *mut kernel::c_types::c_void,},}); + module! { type: RustExample, name: b"rust_example", @@ -25,7 +310,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: CopyString { + my_str: str { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/drivers/char/rust_example_2.rs b/drivers/char/rust_example_2.rs index bfe93fb2d34035..4bb2f57cb051f2 100644 --- a/drivers/char/rust_example_2.rs +++ b/drivers/char/rust_example_2.rs @@ -22,7 +22,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: CopyString { + my_str: str { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/drivers/char/rust_example_3.rs b/drivers/char/rust_example_3.rs index f942fa9f446910..cf5e7864ea7d73 100644 --- a/drivers/char/rust_example_3.rs +++ b/drivers/char/rust_example_3.rs @@ -22,7 +22,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: CopyString { + my_str: str { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/drivers/char/rust_example_4.rs b/drivers/char/rust_example_4.rs index 76c38ce978af94..46f9a10dc6e9b4 100644 --- a/drivers/char/rust_example_4.rs +++ b/drivers/char/rust_example_4.rs @@ -22,7 +22,7 @@ module! { permissions: 0o644, description: b"Example of i32", }, - my_str: CopyString { + my_str: str { default: "default str val", permissions: 0o644, description: b"Example of a string param", diff --git a/rust/module.rs b/rust/module.rs index 2dce819986cde2..e246d1336e04de 100644 --- a/rust/module.rs +++ b/rust/module.rs @@ -244,6 +244,7 @@ pub fn module(ts: TokenStream) -> TokenStream { let param_default = match param_type.as_ref() { "bool" => get_ident(&mut param_it, "default"), "CopyString" => get_string(&mut param_it, "default"), + "str" => get_string(&mut param_it, "default"), _ => get_literal(&mut param_it, "default"), }; let param_permissions = get_literal(&mut param_it, "permissions"); @@ -256,6 +257,7 @@ pub fn module(ts: TokenStream) -> TokenStream { "bool" => "bool", "i32" => "int", "CopyString" => "string", + "str" => "charp", t => panic!("Unrecognized type {}", t), }; @@ -272,11 +274,13 @@ pub fn module(ts: TokenStream) -> TokenStream { ¶m_description, )); let param_type_internal = match param_type.as_ref() { - "CopyString" => format!("[u8; {}]", param_default.len() + 1), + "CopyString" => format!("[u8; {}]", param_default.len() + 1), + "str" => "*mut u8".to_string(), _ => param_type.clone(), }; let param_default = match param_type.as_ref() { "CopyString" => format!("*b\"{}\0\"", param_default), + "str" => format!("unsafe {{ b\"{}\0\" as *const u8 as *mut u8 }}", param_default), _ => param_default, }; let read_func = match param_type.as_ref() { @@ -295,6 +299,21 @@ pub fn module(ts: TokenStream) -> TokenStream { name = name, param_name = param_name, ), + "str" => format!( + " + fn read(&self) -> Result<&str, core::str::Utf8Error> {{ + unsafe {{ + let mut count = 0; + while *__{name}_{param_name}_value.add(count) != b'\0' {{ + count += 1; + }} + core::str::from_utf8(&core::slice::from_raw_parts(__{name}_{param_name}_value, count)) + }} + }} + ", + name = name, + param_name = param_name, + ), _ => format!( " fn read(&self) -> {param_type} {{ From 25890d725d3a8638bf1106291a8dc382a21cb27a Mon Sep 17 00:00:00 2001 From: adamrk Date: Fri, 22 Jan 2021 23:55:34 +0100 Subject: [PATCH 4/5] cleanup charp --- drivers/char/rust_example.rs | 285 ----------------------------------- rust/module.rs | 70 +++------ 2 files changed, 18 insertions(+), 337 deletions(-) diff --git a/drivers/char/rust_example.rs b/drivers/char/rust_example.rs index 4c2be2d75530ac..3efdb6d9fe3944 100644 --- a/drivers/char/rust_example.rs +++ b/drivers/char/rust_example.rs @@ -8,291 +8,6 @@ use core::pin::Pin; use kernel::prelude::*; use kernel::{cstr, file_operations::FileOperations, miscdev}; -// static mut __MOD: Option = None; -// global_asm!( r#".section ".initcall6.init", "a" -// __rust_example_initcall: -// .long __rust_example_init - . -// .previous"#); - -// #[cfg(not(MODULE))] -// #[no_mangle] -// pub extern "C" fn __rust_example_init() -> kernel::c_types::c_int { -// __init() -// } -// #[cfg(not(MODULE))] -// #[no_mangle] -// pub extern "C" fn __rust_example_exit() { __exit() } -// fn __init() -> kernel::c_types::c_int { -// match ::init() { -// Ok(m) => { unsafe { __MOD = Some(m); } return 0; } -// Err(e) => { return e.to_kernel_errno(); } -// } -// } -// fn __exit() { unsafe { __MOD = None; } } -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_author: [u8; 48] = -// *b"rust_example.author=Rust for Linux Contributors\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_description: [u8; 66] = -// *b"rust_example.description=An example kernel module written in Rust\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_license: [u8; 28] = -// *b"rust_example.license=GPL v2\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_file: [u8; 44] = -// *b"rust_example.file=drivers/char/rust_example\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parmtype_my_bool: [u8; 35] = -// *b"rust_example.parmtype=my_bool:bool\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parm_my_bool: [u8; 42] = -// *b"rust_example.parm=my_bool:Example of bool\0"; -// static mut __rust_example_my_bool_value: bool = true; -// struct __rust_example_my_bool; -// impl __rust_example_my_bool { -// fn read(&self) -> bool { unsafe { __rust_example_my_bool_value } } -// } -// const my_bool: __rust_example_my_bool = __rust_example_my_bool; -// #[repr(transparent)] -// struct __rust_example_my_bool_RacyKernelParam(kernel::bindings::kernel_param); -// unsafe impl Sync for __rust_example_my_bool_RacyKernelParam { } -// #[cfg(not(MODULE))] -// const __rust_example_my_bool_name: *const kernel::c_types::c_char = -// b"rust_example.my_bool\0" as *const _ as -// *const kernel::c_types::c_char; -// #[link_section = "__param"] -// #[used] -// static __rust_example_my_bool_struct: -// __rust_example_my_bool_RacyKernelParam = -// __rust_example_my_bool_RacyKernelParam(kernel::bindings::kernel_param{name: -// __rust_example_my_bool_name, -// mod_: -// core::ptr::null_mut(), -// ops: -// unsafe -// { -// &kernel::bindings::param_ops_bool -// } -// as -// *const kernel::bindings::kernel_param_ops, -// perm: -// 0, -// level: -// -1, -// flags: -// 0, -// __bindgen_anon_1: -// kernel::bindings::kernel_param__bindgen_ty_1{arg: -// unsafe -// { -// &__rust_example_my_bool_value -// } -// as -// *const _ -// as -// *mut kernel::c_types::c_void,},}); -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parmtype_my_i32: [u8; 33] = -// *b"rust_example.parmtype=my_i32:int\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parm_my_i32: [u8; 40] = -// *b"rust_example.parm=my_i32:Example of i32\0"; -// static mut __rust_example_my_i32_value: i32 = 42; -// struct __rust_example_my_i32; -// impl __rust_example_my_i32 { -// fn read(&self) -> i32 { unsafe { __rust_example_my_i32_value } } -// } -// const my_i32: __rust_example_my_i32 = __rust_example_my_i32; -// #[repr(transparent)] -// struct __rust_example_my_i32_RacyKernelParam(kernel::bindings::kernel_param); -// unsafe impl Sync for __rust_example_my_i32_RacyKernelParam { } -// #[cfg(not(MODULE))] -// const __rust_example_my_i32_name: *const kernel::c_types::c_char = -// b"rust_example.my_i32\0" as *const _ as -// *const kernel::c_types::c_char; -// #[link_section = "__param"] -// #[used] -// static __rust_example_my_i32_struct: __rust_example_my_i32_RacyKernelParam -// = -// __rust_example_my_i32_RacyKernelParam(kernel::bindings::kernel_param{name: -// __rust_example_my_i32_name, -// mod_: -// core::ptr::null_mut(), -// ops: -// unsafe -// { -// &kernel::bindings::param_ops_int -// } -// as -// *const kernel::bindings::kernel_param_ops, -// perm: -// 0o644, -// level: -// -1, -// flags: -// 0, -// __bindgen_anon_1: -// kernel::bindings::kernel_param__bindgen_ty_1{arg: -// unsafe -// { -// &__rust_example_my_i32_value -// } -// as -// *const _ -// as -// *mut kernel::c_types::c_void,},}); -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parmtype_my_str: [u8; 36] = -// *b"rust_example.parmtype=my_str:string\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parm_my_str: [u8; 51] = -// *b"rust_example.parm=my_str:Example of a string param\0"; -// static mut __rust_example_my_str_value: [u8; 16] = *b"default str val"; -// struct __rust_example_my_str; -// impl __rust_example_my_str { -// fn read(&self) -> Result<&str, core::str::Utf8Error> { -// unsafe { -// let nul = -// __rust_example_my_str_value.iter().position(|&b| -// b == -// b'').unwrap(); -// core::str::from_utf8(&__rust_example_my_str_value[0..nul]) -// } -// } -// } -// const my_str: __rust_example_my_str = __rust_example_my_str; -// #[repr(transparent)] -// struct __rust_example_my_str_RacyKernelParam(kernel::bindings::kernel_param); -// unsafe impl Sync for __rust_example_my_str_RacyKernelParam { } -// #[cfg(not(MODULE))] -// const __rust_example_my_str_name: *const kernel::c_types::c_char = -// b"rust_example.my_str\0" as *const _ as -// *const kernel::c_types::c_char; -// #[link_section = "__param"] -// #[used] -// static __rust_example_my_str_struct: __rust_example_my_str_RacyKernelParam -// = -// __rust_example_my_str_RacyKernelParam(kernel::bindings::kernel_param{name: -// __rust_example_my_str_name, -// mod_: -// core::ptr::null_mut(), -// ops: -// unsafe -// { -// &kernel::bindings::param_ops_string -// } -// as -// *const kernel::bindings::kernel_param_ops, -// perm: -// 0o644, -// level: -// -1, -// flags: -// 0, -// __bindgen_anon_1: -// kernel::bindings::kernel_param__bindgen_ty_1{str_: -// &kernel::bindings::kparam_string{maxlen: -// unsafe -// { -// __rust_example_my_str_value.len() -// } -// as -// u32 -// + -// 1, -// string: -// unsafe -// { -// (&__rust_example_my_str_value).as_ptr() -// } -// as -// *mut kernel::c_types::c_char,} -// as -// *const _,},}); -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parmtype_my_charp: [u8; 37] = -// *b"rust_example.parmtype=my_charp:charp\0"; -// #[cfg(not(MODULE))] -// #[link_section = ".modinfo"] -// #[used] -// pub static __rust_example_parm_my_charp: [u8; 53] = -// *b"rust_example.parm=my_charp:Example of a string param\0"; -// static mut __rust_example_my_charp_value: *mut u8 = -// unsafe { b"default charp val" as *const u8 as *mut u8 }; -// struct __rust_example_my_charp; -// impl __rust_example_my_charp { -// fn read(&self) -> Result<&str, core::str::Utf8Error> { -// unsafe { -// let mut count = 0; -// while *__rust_example_my_charp_value.add(count) != b'\0' { -// count += 1; -// } -// core::str::from_utf8(&core::slice::from_raw_parts(__rust_example_my_charp_value, count)) -// } -// } -// } -// const my_charp: __rust_example_my_charp = __rust_example_my_charp; -// #[repr(transparent)] -// struct __rust_example_my_charp_RacyKernelParam(kernel::bindings::kernel_param); -// unsafe impl Sync for __rust_example_my_charp_RacyKernelParam { } -// #[cfg(not(MODULE))] -// const __rust_example_my_charp_name: *const kernel::c_types::c_char = -// b"rust_example.my_charp\0" as *const _ as -// *const kernel::c_types::c_char; -// #[link_section = "__param"] -// #[used] -// static __rust_example_my_charp_struct: -// __rust_example_my_charp_RacyKernelParam = -// __rust_example_my_charp_RacyKernelParam(kernel::bindings::kernel_param{name: -// __rust_example_my_charp_name, -// mod_: -// core::ptr::null_mut(), -// ops: -// unsafe -// { -// &kernel::bindings::param_ops_charp -// } -// as -// *const kernel::bindings::kernel_param_ops, -// perm: -// 0o644, -// level: -// -1, -// flags: -// 0, -// __bindgen_anon_1: -// kernel::bindings::kernel_param__bindgen_ty_1{arg: -// unsafe -// { -// &__rust_example_my_charp_value -// } -// as -// *const _ -// as -// *mut kernel::c_types::c_void,},}); - module! { type: RustExample, name: b"rust_example", diff --git a/rust/module.rs b/rust/module.rs index e246d1336e04de..815fdb2e5cfbdd 100644 --- a/rust/module.rs +++ b/rust/module.rs @@ -198,11 +198,11 @@ fn build_modinfo_string_param(module: &str, field: &str, param: &str, content: & /// } /// /// ## Suported Parameter Types -/// | Type | `read(&self)` return type | -/// | ------------ | ------------------------------------ | -/// | `i32` | `i32` | -/// | `bool` | `bool` | -/// | `CopyString` | `Result<&str, core::str::Utf8Error>` | +/// | Type | `read(&self)` return type | +/// | ------ | ------------------------------------ | +/// | `i32` | `i32` | +/// | `bool` | `bool` | +/// | `str` | `Result<&str, core::str::Utf8Error>` | /// /// For `CopyString` the parameter is copied into the buffer of the default value and /// cannot be longer than the default value. @@ -243,7 +243,6 @@ pub fn module(ts: TokenStream) -> TokenStream { let mut param_it = group.stream().into_iter(); let param_default = match param_type.as_ref() { "bool" => get_ident(&mut param_it, "default"), - "CopyString" => get_string(&mut param_it, "default"), "str" => get_string(&mut param_it, "default"), _ => get_literal(&mut param_it, "default"), }; @@ -256,7 +255,6 @@ pub fn module(ts: TokenStream) -> TokenStream { let param_kernel_type = match param_type.as_ref() { "bool" => "bool", "i32" => "int", - "CopyString" => "string", "str" => "charp", t => panic!("Unrecognized type {}", t), }; @@ -274,31 +272,14 @@ pub fn module(ts: TokenStream) -> TokenStream { ¶m_description, )); let param_type_internal = match param_type.as_ref() { - "CopyString" => format!("[u8; {}]", param_default.len() + 1), - "str" => "*mut u8".to_string(), + "str" => "*mut u8".to_string(), _ => param_type.clone(), }; let param_default = match param_type.as_ref() { - "CopyString" => format!("*b\"{}\0\"", param_default), - "str" => format!("unsafe {{ b\"{}\0\" as *const u8 as *mut u8 }}", param_default), + "str" => format!("b\"{}\0\" as *const u8 as *mut u8", param_default), _ => param_default, }; let read_func = match param_type.as_ref() { - "CopyString" => format!( - " - fn read(&self) -> Result<&str, core::str::Utf8Error> {{ - unsafe {{ - let nul = __{name}_{param_name}_value - .iter() - .position(|&b| b == b'\0') - .unwrap(); - core::str::from_utf8(&__{name}_{param_name}_value[0..nul]) - }} - }} - ", - name = name, - param_name = param_name, - ), "str" => format!( " fn read(&self) -> Result<&str, core::str::Utf8Error> {{ @@ -325,30 +306,15 @@ pub fn module(ts: TokenStream) -> TokenStream { param_type = param_type, ), }; - let kparam_ptr = match param_type.as_ref() { - "CopyString" => format!( - " - __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{ - str_: &kernel::bindings::kparam_string {{ - maxlen: unsafe {{ __{name}_{param_name}_value.len() }} as u32 + 1, - string: unsafe {{ (&__{name}_{param_name}_value).as_ptr() }} - as *mut kernel::c_types::c_char, - }} as *const _, - }}, - ", - name = name, - param_name = param_name, - ), - _ => format!( - " - __bindgen_anon_1: kernel::bindings::kernel_param__bindgen_ty_1 {{ - arg: unsafe {{ &__{name}_{param_name}_value }} as *const _ as *mut kernel::c_types::c_void, - }}, - ", - name = name, - param_name = param_name, - ), - }; + let kparam = format!( + " + kernel::bindings::kernel_param__bindgen_ty_1 {{ + arg: unsafe {{ &__{name}_{param_name}_value }} as *const _ as *mut kernel::c_types::c_void, + }}, + ", + name = name, + param_name = param_name, + ); params_modinfo.push_str( &format!( " @@ -389,7 +355,7 @@ pub fn module(ts: TokenStream) -> TokenStream { perm: {permissions}, level: -1, flags: 0, - {kparam_ptr} + __bindgen_anon_1: {kparam} }}); ", name = name, @@ -399,7 +365,7 @@ pub fn module(ts: TokenStream) -> TokenStream { param_default = param_default, param_name = param_name, permissions = param_permissions, - kparam_ptr = kparam_ptr, + kparam = kparam, ) ); } From d7a39d124ceace43b5069fea7e32ea9eca297fab Mon Sep 17 00:00:00 2001 From: adamrk Date: Sat, 23 Jan 2021 00:09:19 +0100 Subject: [PATCH 5/5] cleanup --- drivers/char/rust_example.rs | 2 +- drivers/char/rust_example_2.rs | 2 +- drivers/char/rust_example_3.rs | 2 +- drivers/char/rust_example_4.rs | 2 +- rust/module.rs | 25 ++++++------------------- 5 files changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/char/rust_example.rs b/drivers/char/rust_example.rs index 3efdb6d9fe3944..0eb60f8431c3b3 100644 --- a/drivers/char/rust_example.rs +++ b/drivers/char/rust_example.rs @@ -26,7 +26,7 @@ module! { description: b"Example of i32", }, my_str: str { - default: "default str val", + default: b"default str val", permissions: 0o644, description: b"Example of a string param", }, diff --git a/drivers/char/rust_example_2.rs b/drivers/char/rust_example_2.rs index 4bb2f57cb051f2..af2805fcd7ebfa 100644 --- a/drivers/char/rust_example_2.rs +++ b/drivers/char/rust_example_2.rs @@ -23,7 +23,7 @@ module! { description: b"Example of i32", }, my_str: str { - default: "default str val", + default: b"default str val", permissions: 0o644, description: b"Example of a string param", }, diff --git a/drivers/char/rust_example_3.rs b/drivers/char/rust_example_3.rs index cf5e7864ea7d73..b91af2e7752b25 100644 --- a/drivers/char/rust_example_3.rs +++ b/drivers/char/rust_example_3.rs @@ -23,7 +23,7 @@ module! { description: b"Example of i32", }, my_str: str { - default: "default str val", + default: b"default str val", permissions: 0o644, description: b"Example of a string param", }, diff --git a/drivers/char/rust_example_4.rs b/drivers/char/rust_example_4.rs index 46f9a10dc6e9b4..b59315a9d1102d 100644 --- a/drivers/char/rust_example_4.rs +++ b/drivers/char/rust_example_4.rs @@ -23,7 +23,7 @@ module! { description: b"Example of i32", }, my_str: str { - default: "default str val", + default: b"default str val", permissions: 0o644, description: b"Example of a string param", }, diff --git a/rust/module.rs b/rust/module.rs index 815fdb2e5cfbdd..9c45ed68ed5ac8 100644 --- a/rust/module.rs +++ b/rust/module.rs @@ -76,15 +76,6 @@ fn get_byte_string(it: &mut token_stream::IntoIter, expected_name: &str) -> Stri byte_string[2..byte_string.len() - 1].to_string() } -fn get_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String { - let string = get_literal(it, expected_name); - - assert!(string.starts_with("\"")); - assert!(string.ends_with("\"")); - - string[1..string.len() - 1].to_string() -} - fn __build_modinfo_string_base( module: &str, field: &str, @@ -192,20 +183,16 @@ fn build_modinfo_string_param(module: &str, field: &str, param: &str, content: & /// /// impl KernelModule for MyKernelModule { /// fn init() -> KernelResult { -/// println!("bool param is: {}", my_bool.read()); +/// println!("i32 param is: {}", my_i32.read()); /// Ok(MyKernelModule) /// } /// } /// /// ## Suported Parameter Types -/// | Type | `read(&self)` return type | -/// | ------ | ------------------------------------ | -/// | `i32` | `i32` | -/// | `bool` | `bool` | -/// | `str` | `Result<&str, core::str::Utf8Error>` | -/// -/// For `CopyString` the parameter is copied into the buffer of the default value and -/// cannot be longer than the default value. +/// +/// - `i32` +/// - `bool` +/// - `str` - Corresponds to C `charp` param type. `read` signature is `read(&self) -> Result<&str, core::str::Utf8Error>`. /// ``` #[proc_macro] pub fn module(ts: TokenStream) -> TokenStream { @@ -243,7 +230,7 @@ pub fn module(ts: TokenStream) -> TokenStream { let mut param_it = group.stream().into_iter(); let param_default = match param_type.as_ref() { "bool" => get_ident(&mut param_it, "default"), - "str" => get_string(&mut param_it, "default"), + "str" => get_byte_string(&mut param_it, "default"), _ => get_literal(&mut param_it, "default"), }; let param_permissions = get_literal(&mut param_it, "permissions");