From 86144a7676d6557fe1ef797b51f6c4c802a5fda5 Mon Sep 17 00:00:00 2001 From: Anton Bulakh Date: Wed, 21 Jul 2021 15:41:19 +0300 Subject: [PATCH 1/2] Fix procedural macros --- src/lib.rs | 4 ++++ uefi-macros/src/lib.rs | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2f6d20dd1..dbefd722c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,10 @@ #[cfg(feature = "exts")] extern crate alloc as alloc_api; +// allow referring to self as ::uefi for macros to work universally (from this crate and from others) +// see https://github.com/rust-lang/rust/issues/54647 +extern crate self as uefi; + #[macro_use] pub mod data_types; pub use self::data_types::{unsafe_guid, Identify}; diff --git a/uefi-macros/src/lib.rs b/uefi-macros/src/lib.rs index d3d8d910e..7661e7d9d 100644 --- a/uefi-macros/src/lib.rs +++ b/uefi-macros/src/lib.rs @@ -6,6 +6,7 @@ use proc_macro::TokenStream; use quote::{quote, TokenStreamExt}; use syn::parse::{Parse, ParseStream}; use syn::{parse_macro_input, DeriveInput, Generics, Ident, ItemFn, ItemType, LitStr}; +use proc_macro2::Span; /// Parses a type definition, extracts its identifier and generic parameters struct TypeDefinition { @@ -87,10 +88,10 @@ pub fn unsafe_guid(args: TokenStream, input: TokenStream) -> TokenStream { let ident = type_definition.ident.clone(); let (impl_generics, ty_generics, where_clause) = type_definition.generics.split_for_impl(); result.append_all(quote! { - unsafe impl #impl_generics crate::Identify for #ident #ty_generics #where_clause { + unsafe impl #impl_generics ::uefi::Identify for #ident #ty_generics #where_clause { #[doc(hidden)] #[allow(clippy::unreadable_literal)] - const GUID : crate::Guid = crate::Guid::from_values( + const GUID: ::uefi::Guid = ::uefi::Guid::from_values( #time_low, #time_mid, #time_high_and_version, @@ -113,7 +114,7 @@ pub fn derive_protocol(item: TokenStream) -> TokenStream { let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl(); let result = quote! { // Mark this as a `Protocol` implementation - impl #impl_generics crate::proto::Protocol for #ident #ty_generics #where_clause {} + impl #impl_generics ::uefi::proto::Protocol for #ident #ty_generics #where_clause {} // Most UEFI functions expect to be called on the bootstrap processor. impl #impl_generics !Send for #ident #ty_generics #where_clause {} @@ -134,14 +135,15 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { panic!("This attribute accepts no arguments"); } - let f = parse_macro_input!(input as ItemFn); + let mut f = parse_macro_input!(input as ItemFn); - let entry_fn_ident = &f.sig.ident; + // force the exported symbol to be 'efi_main' + f.sig.ident = Ident::new("efi_main", Span::call_site()); - let result = quote!( - static _UEFI_ENTRY_POINT_TYPE_CHECK: extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable) -> uefi::Status = #entry_fn_ident; + let result = quote! { + static _UEFI_ENTRY_POINT_TYPE_CHECK: extern "efiapi" fn(uefi::Handle, uefi::table::SystemTable) -> uefi::Status = efi_main; #[no_mangle] pub extern "efiapi" #f - ); + }; result.into() } From e5cc7da793a68e49904a90a69fb59753b55ed044 Mon Sep 17 00:00:00 2001 From: Anton Bulakh Date: Thu, 22 Jul 2021 18:07:39 +0300 Subject: [PATCH 2/2] Improve docs and fix formatting --- BUILDING.md | 11 ++++++++--- uefi-macros/src/lib.rs | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 1072d3227..9e7482764 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -15,11 +15,16 @@ The following steps allow you to build a simple UEFI app. #![feature(abi_efiapi)] use uefi::prelude::*; + extern crate rlibc; + #[entry] - fn efi_main(handle: Handle, mut system_table: SystemTable) -> Status; + fn main(handle: Handle, mut system_table: SystemTable) -> Status; ``` - You will also want to add a dependency to the [`rlibc`](https://docs.rs/rlibc/) crate, - to avoid linking errors. + Note that Rust EFI target requires the entry function to be exported with an `efi_main` symbol, + the `#[entry]` macro takes care of that, so the function name is irrelevant. + + You will also want to add a dependency to the [`rlibc`](https://docs.rs/rlibc/) crate and + explicitly link it with `extern crate rlibc;` line to avoid linking errors. - Build using a `nightly` version of the compiler and activate the [`build-std`](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std) diff --git a/uefi-macros/src/lib.rs b/uefi-macros/src/lib.rs index 7661e7d9d..92cc2dcfd 100644 --- a/uefi-macros/src/lib.rs +++ b/uefi-macros/src/lib.rs @@ -3,10 +3,11 @@ extern crate proc_macro; use proc_macro::TokenStream; + +use proc_macro2::Span; use quote::{quote, TokenStreamExt}; use syn::parse::{Parse, ParseStream}; use syn::{parse_macro_input, DeriveInput, Generics, Ident, ItemFn, ItemType, LitStr}; -use proc_macro2::Span; /// Parses a type definition, extracts its identifier and generic parameters struct TypeDefinition {