Skip to content

Instantly share code, notes, and snippets.

@adamrk
Last active March 16, 2021 20:19

Revisions

  1. adamrk revised this gist Mar 16, 2021. 1 changed file with 153 additions and 12 deletions.
    165 changes: 153 additions & 12 deletions expanded.rs
    Original file line number Diff line number Diff line change
    @@ -55,7 +55,13 @@ global_asm! .section ".initcall6.init", "a"
    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 } }
    fn read(&self)
    -> &<bool as kernel::module_param::ModuleParam>::Value {
    unsafe {
    <bool as
    kernel::module_param::ModuleParam>::value(&__rust_example_my_bool_value)
    }
    }
    }
    const my_bool: __rust_example_my_bool = __rust_example_my_bool;
    #[repr(transparent)]
    @@ -111,8 +117,12 @@ global_asm! .section ".initcall6.init", "a"
    static mut __rust_example_my_i32_value: i32 = 42;
    struct __rust_example_my_i32;
    impl __rust_example_my_i32 {
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck i32 {
    unsafe { &__rust_example_my_i32_value }
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard)
    -> &'lck <i32 as kernel::module_param::ModuleParam>::Value {
    unsafe {
    <i32 as
    kernel::module_param::ModuleParam>::value(&__rust_example_my_i32_value)
    }
    }
    }
    const my_i32: __rust_example_my_i32 = __rust_example_my_i32;
    @@ -159,20 +169,25 @@ global_asm! .section ".initcall6.init", "a"
    #[cfg(not(MODULE))]
    #[link_section = ".modinfo"]
    #[used]
    pub static __rust_example_parmtype_my_str: [u8; 35] =
    *b"rust_example.parmtype=my_str:charp\0";
    pub static __rust_example_parmtype_my_str: [u8; 33] =
    *b"rust_example.parmtype=my_str:str\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: *mut kernel::c_types::c_char =
    b"default str val" as *const _ as *mut kernel::c_types::c_char;
    static mut __rust_example_my_str_value: kernel::module_param::StringParam
    =
    kernel::module_param::StringParam::Ref(b"default str val");
    struct __rust_example_my_str;
    impl __rust_example_my_str {
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck [u8] {
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard)
    ->
    &'lck <kernel::module_param::StringParam as
    kernel::module_param::ModuleParam>::Value {
    unsafe {
    kernel::c_types::c_string_bytes(__rust_example_my_str_value)
    <kernel::module_param::StringParam as
    kernel::module_param::ModuleParam>::value(&__rust_example_my_str_value)
    }
    }
    }
    @@ -197,7 +212,7 @@ global_asm! .section ".initcall6.init", "a"
    ops:
    unsafe
    {
    &kernel::bindings::param_ops_charp
    &kernel::module_param::PARAM_OPS_STR
    }
    as
    *const kernel::bindings::kernel_param_ops,
    @@ -230,8 +245,12 @@ global_asm! .section ".initcall6.init", "a"
    static mut __rust_example_my_usize_value: usize = 42;
    struct __rust_example_my_usize;
    impl __rust_example_my_usize {
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck usize {
    unsafe { &__rust_example_my_usize_value }
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard)
    -> &'lck <usize as kernel::module_param::ModuleParam>::Value {
    unsafe {
    <usize as
    kernel::module_param::ModuleParam>::value(&__rust_example_my_usize_value)
    }
    }
    }
    const my_usize: __rust_example_my_usize = __rust_example_my_usize;
    @@ -275,3 +294,125 @@ global_asm! .section ".initcall6.init", "a"
    *const _
    as
    *mut kernel::c_types::c_void,},});
    #[cfg(not(MODULE))]
    #[link_section = ".modinfo"]
    #[used]
    pub static __rust_example_parmtype_my_array: [u8; 56] =
    *b"rust_example.parmtype=my_array:__rust_array_param_i32_3\0";
    #[cfg(not(MODULE))]
    #[link_section = ".modinfo"]
    #[used]
    pub static __rust_example_parm_my_array: [u8; 44] =
    *b"rust_example.parm=my_array:Example of array\0";
    static mut __rust_example_my_array_value:
    kernel::module_param::ArrayParam<i32, 3> =
    kernel::module_param::ArrayParam::create(&[0, 1]);
    struct __rust_example_my_array;
    impl __rust_example_my_array {
    fn read(&self)
    ->
    &<kernel::module_param::ArrayParam<i32, 3> as
    kernel::module_param::ModuleParam>::Value {
    unsafe {
    <kernel::module_param::ArrayParam<i32, 3> as
    kernel::module_param::ModuleParam>::value(&__rust_example_my_array_value)
    }
    }
    }
    const my_array: __rust_example_my_array = __rust_example_my_array;
    #[repr(transparent)]
    struct __rust_example_my_array_RacyKernelParam(kernel::bindings::kernel_param);
    unsafe impl Sync for __rust_example_my_array_RacyKernelParam { }
    #[cfg(not(MODULE))]
    const __rust_example_my_array_name: *const kernel::c_types::c_char =
    b"rust_example.my_array\0" as *const _ as
    *const kernel::c_types::c_char;
    #[link_section = "__param"]
    #[used]
    static __rust_example_my_array_struct:
    __rust_example_my_array_RacyKernelParam =
    __rust_example_my_array_RacyKernelParam(kernel::bindings::kernel_param{name:
    __rust_example_my_array_name,

    #[cfg(not(MODULE))]
    mod_:
    core::ptr::null_mut(),
    ops:
    unsafe
    {
    &__generated_array_ops_i32_3
    }
    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_array_value
    }
    as
    *const _
    as
    *mut kernel::c_types::c_void,},});






    // Test mutexes.
    // SAFETY: `init` is called below.

    // Test spinlocks.
    // SAFETY: `init` is called below.

    // Including this large variable on the stack will trigger
    // stack probing on the supported archs.
    // This will verify that stack probing does not lead to
    // any errors if we need to link `__rust_probestack`.



    #[doc = ""]
    ///
    /// Static [`kernel_param_ops`](../../../include/linux/moduleparam.h)
    /// struct generated by [`make_param_ops`].
    pub static __generated_array_ops_i32_3:
    ::kernel::bindings::kernel_param_ops =
    ::kernel::bindings::kernel_param_ops{flags:
    if <kernel::module_param::ArrayParam<i32,
    {
    3
    }>
    as
    ::kernel::module_param::ModuleParam>::NOARG_ALLOWED
    {
    ::kernel::bindings::KERNEL_PARAM_OPS_FL_NOARG
    } else { 0 },
    set:
    Some(<kernel::module_param::ArrayParam<i32,
    {
    3
    }>
    as
    ::kernel::module_param::ModuleParam>::set_param),
    get:
    Some(<kernel::module_param::ArrayParam<i32,
    {
    3
    }>
    as
    ::kernel::module_param::ModuleParam>::get_param),
    free:
    Some(<kernel::module_param::ArrayParam<i32,
    {
    3
    }>
    as
    ::kernel::module_param::ModuleParam>::free),};
  2. adamrk created this gist Mar 16, 2021.
    277 changes: 277 additions & 0 deletions expanded.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,277 @@
    static mut __MOD: Option<RustExample> = None;
    #[cfg(not(MODULE))]
    static THIS_MODULE: kernel::ThisModule =
    unsafe { kernel::ThisModule::from_ptr(core::ptr::null_mut()) };
    global_asm! .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 <RustExample as KernelModule>::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,

    #[cfg(not(MODULE))]
    mod_:
    core::ptr::null_mut(),
    ops:
    unsafe
    {
    &kernel::module_param::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:i32\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<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck 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,

    #[cfg(not(MODULE))]
    mod_:
    core::ptr::null_mut(),
    ops:
    unsafe
    {
    &kernel::module_param::PARAM_OPS_I32
    }
    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; 35] =
    *b"rust_example.parmtype=my_str:charp\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: *mut kernel::c_types::c_char =
    b"default str val" as *const _ as *mut kernel::c_types::c_char;
    struct __rust_example_my_str;
    impl __rust_example_my_str {
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck [u8] {
    unsafe {
    kernel::c_types::c_string_bytes(__rust_example_my_str_value)
    }
    }
    }
    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,

    #[cfg(not(MODULE))]
    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_str_value
    }
    as
    *const _
    as
    *mut kernel::c_types::c_void,},});
    #[cfg(not(MODULE))]
    #[link_section = ".modinfo"]
    #[used]
    pub static __rust_example_parmtype_my_usize: [u8; 37] =
    *b"rust_example.parmtype=my_usize:usize\0";
    #[cfg(not(MODULE))]
    #[link_section = ".modinfo"]
    #[used]
    pub static __rust_example_parm_my_usize: [u8; 44] =
    *b"rust_example.parm=my_usize:Example of usize\0";
    static mut __rust_example_my_usize_value: usize = 42;
    struct __rust_example_my_usize;
    impl __rust_example_my_usize {
    fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck usize {
    unsafe { &__rust_example_my_usize_value }
    }
    }
    const my_usize: __rust_example_my_usize = __rust_example_my_usize;
    #[repr(transparent)]
    struct __rust_example_my_usize_RacyKernelParam(kernel::bindings::kernel_param);
    unsafe impl Sync for __rust_example_my_usize_RacyKernelParam { }
    #[cfg(not(MODULE))]
    const __rust_example_my_usize_name: *const kernel::c_types::c_char =
    b"rust_example.my_usize\0" as *const _ as
    *const kernel::c_types::c_char;
    #[link_section = "__param"]
    #[used]
    static __rust_example_my_usize_struct:
    __rust_example_my_usize_RacyKernelParam =
    __rust_example_my_usize_RacyKernelParam(kernel::bindings::kernel_param{name:
    __rust_example_my_usize_name,

    #[cfg(not(MODULE))]
    mod_:
    core::ptr::null_mut(),
    ops:
    unsafe
    {
    &kernel::module_param::PARAM_OPS_USIZE
    }
    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_usize_value
    }
    as
    *const _
    as
    *mut kernel::c_types::c_void,},});