x86_64.rs 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. use proc_macro2::{Span, TokenStream};
  2. use quote::quote;
  3. use syn::{Ident, LitStr, Type};
  4. /// Generate the assembly code to load the address of a symbol and add it to a register.
  5. pub fn load_addr_of_to(symbol: &LitStr, target: &LitStr) -> TokenStream {
  6. quote! {
  7. concat!("mov %gs:0, ", #target),
  8. concat!("add $", #symbol, ", ", #target)
  9. }
  10. }
  11. /// Get the base address for percpu variables of the current thread.
  12. pub fn get_percpu_pointer(percpu: &Ident, ty: &Type) -> TokenStream {
  13. let stmt = load_addr_of_to(
  14. &LitStr::new("{ident}", Span::call_site()),
  15. &LitStr::new("{address}", Span::call_site()),
  16. );
  17. quote! {
  18. {
  19. let base: *mut #ty;
  20. ::core::arch::asm!(
  21. #stmt,
  22. ident = sym #percpu,
  23. address = out(reg) base,
  24. options(att_syntax, nostack, preserves_flags)
  25. );
  26. base
  27. }
  28. }
  29. }
  30. pub fn get_percpu_offset(percpu: &Ident) -> TokenStream {
  31. quote! {
  32. {
  33. & #percpu as *const _ as usize
  34. }
  35. }
  36. }