1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 #![recursion_limit = "128"]
19 
20 extern crate proc_macro;
21 
22 use proc_macro::TokenStream;
23 use quote::quote;
24 use syn::parse_macro_input;
25 use syn::spanned::Spanned;
26 
27 /// Attribute to declare the init function of a plugin
28 /// ``` no_run
29 /// #[plugin_init]
30 /// fn plugin_init() -> Result<()> {}
31 /// ```
32 #[proc_macro_attribute]
plugin_init(_args: TokenStream, input: TokenStream) -> TokenStream33 pub fn plugin_init(_args: TokenStream, input: TokenStream) -> TokenStream {
34     let f = parse_macro_input!(input as syn::ItemFn);
35     let f_vis = &f.vis;
36     let f_block = &f.block;
37     let f_decl = &f.decl;
38     let f_inputs = &f_decl.inputs;
39 
40     // check the function signature
41     let valid_signature = f.constness.is_none()
42         && match f_vis {
43             syn::Visibility::Inherited => true,
44             _ => false,
45         }
46         && f.abi.is_none()
47         && f_inputs.len() == 0
48         && f.decl.generics.where_clause.is_none()
49         && f.decl.variadic.is_none();
50 
51     if !valid_signature {
52         return syn::parse::Error::new(
53             f.span(),
54             "`#[plugin_init]` function must have signature `fn()`",
55         )
56         .to_compile_error()
57         .into();
58     }
59 
60     quote!(
61         #[no_mangle]
62         pub fn _plugin_init() -> optee_teec::Result<()> {
63             #f_block
64             Ok(())
65         }
66     )
67     .into()
68 
69 }
70 
71 /// Attribute to declare the invoke function of a plugin
72 /// ``` no_run
73 /// #[plugin_invoke]
74 /// fn plugin_invoke(params: &mut PluginParameters) {}
75 /// ```
76 #[proc_macro_attribute]
plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream77 pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
78     let f = parse_macro_input!(input as syn::ItemFn);
79     let f_vis = &f.vis;
80     let f_block = &f.block;
81     let f_decl = &f.decl;
82     let f_inputs = &f_decl.inputs;
83 
84     // check the function signature
85     let valid_signature = f.constness.is_none()
86         && match f_vis {
87             syn::Visibility::Inherited => true,
88             _ => false,
89         }
90         && f.abi.is_none()
91         && f_inputs.len() == 1
92         && f.decl.generics.where_clause.is_none()
93         && f.decl.variadic.is_none();
94 
95     if !valid_signature {
96         return syn::parse::Error::new(
97             f.span(),
98             "`#[plugin_invoke]` function must have signature `fn(params: &mut PluginParamters)`",
99         )
100         .to_compile_error()
101         .into();
102     }
103 
104     quote!(
105         #[no_mangle]
106         pub fn _plugin_invoke(
107             cmd: u32,
108             sub_cmd: u32,
109             data: *mut c_char,
110             in_len: u32,
111             out_len: *mut u32
112         ) -> optee_teec::Result<()> {
113             let mut inbuf = unsafe { std::slice::from_raw_parts_mut(data, in_len as usize) };
114             let mut params = PluginParameters::new(cmd, sub_cmd, inbuf);
115             #f_block
116             let outslice = params.get_out_slice();
117             unsafe {
118                 *out_len = outslice.len() as u32;
119                 std::ptr::copy(outslice.as_ptr(), data, outslice.len());
120             }
121 
122             Ok(())
123         }
124     )
125     .into()
126 
127 }
128