tracepoint.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. use std::borrow::Cow;
  2. use proc_macro2::TokenStream;
  3. use proc_macro_error::abort;
  4. use quote::quote;
  5. use syn::{ItemFn, Result};
  6. use crate::args::{err_on_unknown_args, pop_arg};
  7. pub(crate) struct TracePoint {
  8. item: ItemFn,
  9. category: Option<String>,
  10. name: Option<String>,
  11. }
  12. impl TracePoint {
  13. pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<TracePoint> {
  14. let mut args = syn::parse2(attrs)?;
  15. let item = syn::parse2(item)?;
  16. let name = pop_arg(&mut args, "name");
  17. let category = pop_arg(&mut args, "category");
  18. err_on_unknown_args(&args)?;
  19. Ok(TracePoint {
  20. item,
  21. category,
  22. name,
  23. })
  24. }
  25. pub(crate) fn expand(&self) -> Result<TokenStream> {
  26. let section_name: Cow<'_, _> = match (&self.category, &self.name) {
  27. (Some(category), Some(name)) => format!("tracepoint/{}/{}", category, name).into(),
  28. (Some(_), None) => abort!(self.item, "expected `name` and `category` arguments"),
  29. (None, Some(_)) => abort!(self.item, "expected `name` and `category` arguments"),
  30. _ => "tracepoint".into(),
  31. };
  32. let fn_vis = &self.item.vis;
  33. let fn_name = self.item.sig.ident.clone();
  34. let item = &self.item;
  35. Ok(quote! {
  36. #[no_mangle]
  37. #[link_section = #section_name]
  38. #fn_vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> u32 {
  39. let _ = #fn_name(::aya_bpf::programs::TracePointContext::new(ctx));
  40. return 0;
  41. #item
  42. }
  43. })
  44. }
  45. }
  46. #[cfg(test)]
  47. mod tests {
  48. use super::*;
  49. use syn::parse_quote;
  50. #[test]
  51. fn test_tracepoint() {
  52. let prog = TracePoint::parse(
  53. parse_quote! { name = "sys_enter_bind", category = "syscalls" },
  54. parse_quote! {
  55. fn prog(ctx: &mut ::aya_bpf::programs::TracePointContext) -> i32 {
  56. 0
  57. }
  58. },
  59. )
  60. .unwrap();
  61. let expanded = prog.expand().unwrap();
  62. let expected = quote! {
  63. #[no_mangle]
  64. #[link_section = "tracepoint/syscalls/sys_enter_bind"]
  65. fn prog(ctx: *mut ::core::ffi::c_void) -> u32 {
  66. let _ = prog(::aya_bpf::programs::TracePointContext::new(ctx));
  67. return 0;
  68. fn prog(ctx: &mut ::aya_bpf::programs::TracePointContext) -> i32 {
  69. 0
  70. }
  71. }
  72. };
  73. assert_eq!(expected.to_string(), expanded.to_string());
  74. }
  75. }