raw_tracepoint.rs 2.3 KB

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