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