| 12345678910111213141516171819202122232425262728293031323334353637383940 |
- use proc_macro2::{Span, TokenStream};
- use quote::quote;
- use syn::{Ident, LitStr, Type};
- /// Generate the assembly code to load the address of a symbol and add it to a register.
- pub fn load_addr_of_to(symbol: &LitStr, target: &LitStr) -> TokenStream {
- quote! {
- concat!("mov %gs:0, ", #target),
- concat!("add $", #symbol, ", ", #target)
- }
- }
- /// Get the base address for percpu variables of the current thread.
- pub fn get_percpu_pointer(percpu: &Ident, ty: &Type) -> TokenStream {
- let stmt = load_addr_of_to(
- &LitStr::new("{ident}", Span::call_site()),
- &LitStr::new("{address}", Span::call_site()),
- );
- quote! {
- {
- let base: *mut #ty;
- ::core::arch::asm!(
- #stmt,
- ident = sym #percpu,
- address = out(reg) base,
- options(att_syntax, nostack, preserves_flags)
- );
- base
- }
- }
- }
- pub fn get_percpu_offset(percpu: &Ident) -> TokenStream {
- quote! {
- {
- & #percpu as *const _ as usize
- }
- }
- }
|