|  |  | @ -13,7 +13,7 @@ pub use aya_bpf_bindings::helpers as gen; | 
			
		
	
		
		
			
				
					
					|  |  |  | #[doc(hidden)] |  |  |  | #[doc(hidden)] | 
			
		
	
		
		
			
				
					
					|  |  |  | pub use gen::*; |  |  |  | pub use gen::*; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::cty::{c_long, c_void}; |  |  |  | use crate::cty::{c_char, c_long, c_void}; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Read bytes stored at `src` and store them as a `T`.
 |  |  |  | /// Read bytes stored at `src` and store them as a `T`.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | ///
 |  |  |  | ///
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -701,3 +701,163 @@ pub fn bpf_get_current_pid_tgid() -> u64 { | 
			
		
	
		
		
			
				
					
					|  |  |  | pub fn bpf_get_current_uid_gid() -> u64 { |  |  |  | pub fn bpf_get_current_uid_gid() -> u64 { | 
			
		
	
		
		
			
				
					
					|  |  |  |     unsafe { gen::bpf_get_current_uid_gid() } |  |  |  |     unsafe { gen::bpf_get_current_uid_gid() } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Prints a debug message to the BPF debugging pipe.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// The [format string syntax][fmt] is the same as that of the `printk` kernel
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// function. It is passed in as a fixed-size byte array (`&[u8; N]`), so you
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// will have to prefix your string literal with a `b`. A terminating zero byte
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// is appended automatically.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// The macro can read from arbitrary pointers, so it must be used in an `unsafe`
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// scope in order to compile.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Invocations with less than 4 arguments call the `bpf_trace_printk` helper,
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// otherwise the `bpf_trace_vprintk` function is called. The latter function
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// requires a kernel version >= 5.16 whereas the former has been around since
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// the dawn of eBPF. The return value of the BPF helper is also returned from
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// this macro.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Messages can be read by executing the following command in a second terminal:
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// ```bash
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// sudo cat /sys/kernel/debug/tracing/trace_pipe
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// ```
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// If no messages are printed when calling [`bpf_printk!`] after executing the
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// above command, it is possible that tracing must first be enabled by running:
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// ```bash
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// ```
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// # Example
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// ```no_run
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// # use aya_bpf::helpers::bpf_printk;
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// unsafe {
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///   bpf_printk!(b"hi there! dec: %d, hex: 0x%08X", 42, 0x1234);
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// }
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// ```
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// [fmt]: https://www.kernel.org/doc/html/latest/core-api/printk-formats.html#printk-specifiers
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[macro_export] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | macro_rules! bpf_printk { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ($fmt:literal $(,)? $($arg:expr),* $(,)?) => {{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         use $crate::helpers::PrintkArg; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         const FMT: [u8; { $fmt.len() + 1 }] = $crate::helpers::zero_pad_array::< | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             { $fmt.len() }, { $fmt.len() + 1 }>(*$fmt); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         let data = [$(PrintkArg::from($arg)),*]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         $crate::helpers::bpf_printk_impl(&FMT, &data) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     }}; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Macros are always exported from the crate root. Also export it from `helpers`.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[doc(inline)] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | pub use bpf_printk; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Argument ready to be passed to `printk` BPF helper.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[repr(transparent)] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[derive(Copy, Clone)] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | pub struct PrintkArg(u64); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | impl PrintkArg { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     /// Manually construct a `printk` BPF helper argument.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     #[inline] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pub fn from_raw(x: u64) -> Self { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         Self(x) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | macro_rules! impl_integer_promotion { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ($($ty:ty : via $via:ty),* $(,)?) => {$( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         /// Create `printk` arguments from integer types.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         impl From<$ty> for PrintkArg { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             #[inline] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             fn from(x: $ty) -> PrintkArg { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 PrintkArg(x as $via as u64) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     )*} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | impl_integer_promotion!( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   char:  via u64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   u8:    via u64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   u16:   via u64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   u32:   via u64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   u64:   via u64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   usize: via u64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   i8:    via i64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   i16:   via i64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   i32:   via i64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   i64:   via i64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   isize: via i64, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Construct `printk` BPF helper arguments from constant pointers.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | impl<T> From<*const T> for PrintkArg { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     #[inline] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     fn from(x: *const T) -> Self { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         PrintkArg(x as usize as u64) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Construct `printk` BPF helper arguments from mutable pointers.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | impl<T> From<*mut T> for PrintkArg { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     #[inline] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     fn from(x: *mut T) -> Self { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         PrintkArg(x as usize as u64) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Expands the given byte array to `DST_LEN`, right-padding it with zeros. If
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// `DST_LEN` is smaller than `SRC_LEN`, the array is instead truncated.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// This function serves as a helper for the [`bpf_printk!`] macro.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[doc(hidden)] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | pub const fn zero_pad_array<const SRC_LEN: usize, const DST_LEN: usize>( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     src: [u8; SRC_LEN], | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ) -> [u8; DST_LEN] { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let mut out: [u8; DST_LEN] = [0u8; DST_LEN]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // The `min` function is not `const`. Hand-roll it.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let mut i = if DST_LEN > SRC_LEN { SRC_LEN } else { DST_LEN }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     while i > 0 { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         i -= 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         out[i] = src[i]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     out | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// Internal helper function for the [`bpf_printk!`] macro.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ///
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// The BPF helpers require the length for both the format string as well as
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// the argument array to be of constant size to pass the verifier. Const
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// generics are used to represent this requirement in Rust.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[inline] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #[doc(hidden)] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | pub unsafe fn bpf_printk_impl<const FMT_LEN: usize, const NUM_ARGS: usize>( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     fmt: &[u8; FMT_LEN], | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     args: &[PrintkArg; NUM_ARGS], | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ) -> i64 { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // This function can't be wrapped in `helpers.rs` because it has variadic
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // arguments. We also can't turn the definitions in `helpers.rs` into
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // `const`s because MIRI believes casting arbitrary integers to function
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // pointers to be an error.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let printk: unsafe extern "C" fn(fmt: *const c_char, fmt_size: u32, ...) -> c_long = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         mem::transmute(6usize); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let fmt_ptr = fmt.as_ptr() as *const c_char; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let fmt_size = fmt.len() as u32; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     match NUM_ARGS { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         0 => printk(fmt_ptr, fmt_size), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         1 => printk(fmt_ptr, fmt_size, args[0]), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         2 => printk(fmt_ptr, fmt_size, args[0], args[1]), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         3 => printk(fmt_ptr, fmt_size, args[0], args[1], args[2]), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         _ => gen::bpf_trace_vprintk(fmt_ptr, fmt_size, args.as_ptr() as _, (NUM_ARGS * 8) as _), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |