link_boot/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::parse_quote;
4
5#[proc_macro_attribute]
6pub fn link_boot(_args: TokenStream, input: TokenStream) -> TokenStream {
7    let mut input = syn::parse_macro_input!(input as syn::ItemMod);
8
9    if let Some((_brace, items)) = input.content.as_mut() {
10        for item in items {
11            match item {
12                syn::Item::Fn(v) => {
13                    v.attrs.push(parse_quote! {
14                        #[unsafe(link_section = ".text.boot")]
15                    });
16                }
17                syn::Item::Static(v) => {
18                    v.attrs.push(parse_quote! {
19                        #[unsafe(link_section = ".data.boot")]
20                    });
21                }
22                syn::Item::Impl(v) => {
23                    v.attrs.push(parse_quote! {
24                        #[unsafe(link_section = ".text.boot")]
25                    });
26
27                    for item in v.items.iter_mut() {
28                        if let syn::ImplItem::Fn(v) = item {
29                            v.attrs.push(parse_quote! {
30                                #[unsafe(link_section = ".text.boot")]
31                            });
32                        }
33                    }
34                }
35                _ => {}
36            }
37        }
38    }
39
40    let items = input.content.unwrap().1;
41
42    quote! {
43      #(#items)*
44    }
45    .into()
46}