@ -1,3 +1,4 @@
 
			
		
	
		
		
			
				
					
					use   crate ::bindings ::bpf_raw_tracepoint_args ;  
			
		
	
		
		
			
				
					
					#[ cfg(any(
 #[ cfg(any(
  
			
		
	
		
		
			
				
					
					     bpf_target_arch   =   "arm" ,      bpf_target_arch   =   "arm" ,  
			
		
	
		
		
			
				
					
					     bpf_target_arch   =   "mips" ,      bpf_target_arch   =   "mips" ,  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -13,619 +14,305 @@ use crate::bindings::pt_regs;
 
			
		
	
		
		
			
				
					
					use   crate ::bindings ::user_pt_regs   as   pt_regs ; use   crate ::bindings ::user_pt_regs   as   pt_regs ;  
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " riscv64 " ) ] #[ cfg(bpf_target_arch =  " riscv64 " ) ]  
			
		
	
		
		
			
				
					
					use   crate ::bindings ::user_regs_struct   as   pt_regs ; use   crate ::bindings ::user_regs_struct   as   pt_regs ;  
			
		
	
		
		
			
				
					
					use   crate ::{ bindings ::bpf_raw_tracepoint_args ,   cty ::c_void ,   helpers ::bpf_probe_read } ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// A trait that indicates a valid type for an argument which can be coerced from a BTF
 mod  sealed   {  
			
				
				
			
		
	
		
		
			
				
					
					/// context.
      #[ expect(clippy::missing_safety_doc) ]  
			
				
				
			
		
	
		
		
			
				
					
					///
      pub   unsafe   trait   Argument   {  
			
				
				
			
		
	
		
		
			
				
					
					/// Users should not implement this trait.
          fn  from_register ( value : u64 )   -> Self ;  
			
				
				
			
		
	
		
		
			
				
					
					///
  
			
		
	
		
		
			
				
					
					/// # Safety
  
			
		
	
		
		
			
				
					
					///
  
			
		
	
		
		
			
				
					
					/// This trait is _only_ safe to implement on primitive types that can fit into
  
			
		
	
		
		
			
				
					
					/// a `u64`. For example, integers and raw pointers may be coerced from a BTF context.
  
			
		
	
		
		
			
				
					
					pub   unsafe   trait   FromBtfArgument : Sized  {  
			
		
	
		
		
			
				
					
					     /// Coerces a `T` from the `n`th argument from a BTF context where `n` starts
  
			
		
	
		
		
			
				
					
					     /// at 0 and increases by 1 for each successive argument.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// # Safety
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// This function is deeply unsafe, as we are reading raw pointers into kernel
  
			
		
	
		
		
			
				
					
					     /// memory. In particular, the value of `n` must not exceed the number of function
  
			
		
	
		
		
			
				
					
					     /// arguments. Moreover, `ctx` must be a valid pointer to a BTF context, and `T` must
  
			
		
	
		
		
			
				
					
					     /// be the right type for the given argument.
  
			
		
	
		
		
			
				
					
					     unsafe   fn  from_argument ( ctx : * const   c_void ,   n : usize )   -> Self ;  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					unsafe   impl < T >   FromBtfArgument   for   * const   T   {  
			
		
	
		
		
			
				
					
					     unsafe   fn  from_argument ( ctx : * const   c_void ,   n : usize )   -> * const   T   {  
			
		
	
		
		
			
				
					
					         // BTF arguments are exposed as an array of `usize` where `usize` can
  
			
		
	
		
		
			
				
					
					         // either be treated as a pointer or a primitive type
  
			
		
	
		
		
			
				
					
					         let   ctx : * const   usize   =   ctx . cast ( ) ;  
			
		
	
		
		
			
				
					
					         ( unsafe   {   * ctx . add ( n )   } )   as   _  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// Helper macro to implement [`FromBtfArgument`] for a primitive type.
      macro_rules!   unsafe_impl_argument   {  
			
				
				
			
		
	
		
		
			
				
					
					macro_rules!   unsafe_impl_from_btf_argument   {          ( $( $(   {   $( $generics :tt ) *   }   ) ?   $ty :ty   $(   {   where   $( $where :tt ) *   }   ) ? ) , +   $(, ) ? )   = >   {  
			
				
				
			
		
	
		
		
			
				
					
					     ( $type :ident )   = >   {              $(  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   impl   FromBtfArgument   for   $type   {                  #[ allow(clippy::cast_lossless, trivial_numeric_casts) ]  
			
				
				
			
		
	
		
		
			
				
					
					             #[ allow(trivial_numeric_casts) ]                  unsafe   impl $( $( $generics ) * ) ?   Argument   for   $ty   $( where   $( $where ) * ) ?   {  
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   fn  from_argument ( ctx : * const   c_void ,   n : usize )   -> Self   {                      fn  from_register ( value : u64 )   -> Self   {  
			
				
				
			
		
	
		
		
			
				
					
					                 // BTF arguments are exposed as an array of `usize` where `usize` can
                          value   as   Self  
			
				
				
			
		
	
		
		
			
				
					
					                 // either be treated as a pointer or a primitive type
                      }  
			
				
				
			
		
	
		
		
			
				
					
					                 let   ctx : * const   usize   =   ctx . cast ( ) ;                  }  
			
				
				
			
		
	
		
		
			
				
					
					                 ( unsafe   {   * ctx . add ( n )   } )   as   _              ) +  
			
				
				
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     } ;  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( u8 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( u16 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( u32 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( u64 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( i8 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( i16 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( i32 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( i64 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( usize ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_btf_argument ! ( isize ) ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					pub   struct  PtRegs   {  
			
		
	
		
		
			
				
					
					     regs : * mut   pt_regs ,  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// A portable wrapper around pt_regs, user_pt_regs and user_regs_struct.
  
			
		
	
		
		
			
				
					
					impl   PtRegs   {  
			
		
	
		
		
			
				
					
					     pub   fn  new ( regs : * mut   pt_regs )   -> Self   {  
			
		
	
		
		
			
				
					
					         Self   {   regs   }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Returns the value of the register used to pass arg `n`.
  
			
		
	
		
		
			
				
					
					     pub   fn  arg < T : FromPtRegs > ( & self ,   n : usize )   -> Option < T >   {  
			
		
	
		
		
			
				
					
					         T ::from_argument ( unsafe   {   & * self . regs   } ,   n )  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Returns the value of the register used to pass the return value.
  
			
		
	
		
		
			
				
					
					     pub   fn  ret < T : FromPtRegs > ( & self )   -> Option < T >   {  
			
		
	
		
		
			
				
					
					         T ::from_retval ( unsafe   {   & * self . regs   } )  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Returns a pointer to the wrapped value.
      unsafe_impl_argument ! (  
			
				
				
			
		
	
		
		
			
				
					
					     pub   fn  as_ptr ( & self )   -> * mut   pt_regs   {          i8 ,  
			
				
				
			
		
	
		
		
			
				
					
					         self . regs          u8 ,  
			
				
				
			
		
	
		
		
			
				
					
					     }          i16 ,  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         u16 ,  
			
		
	
		
		
			
				
					
					         i32 ,  
			
		
	
		
		
			
				
					
					         u32 ,  
			
		
	
		
		
			
				
					
					         i64 ,  
			
		
	
		
		
			
				
					
					         u64 ,  
			
		
	
		
		
			
				
					
					         i128 ,  
			
		
	
		
		
			
				
					
					         u128 ,  
			
		
	
		
		
			
				
					
					         isize ,  
			
		
	
		
		
			
				
					
					         usize ,  
			
		
	
		
		
			
				
					
					         { < T > }   * const   T   { where   T : ' static } ,  
			
		
	
		
		
			
				
					
					         { < T > }   * mut   T   { where   T : ' static } ,  
			
		
	
		
		
			
				
					
					     ) ;  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// A trait that indicates a valid type for an argument which can be coerced from
 pub   trait   Argument : sealed ::Argument   { }  
			
				
				
			
		
	
		
		
			
				
					
					/// a pt_regs context.
  
			
		
	
		
		
			
				
					
					///
  
			
		
	
		
		
			
				
					
					/// Any implementation of this trait is strictly architecture-specific and depends on the
  
			
		
	
		
		
			
				
					
					/// layout of the underlying pt_regs struct and the target processor's calling
  
			
		
	
		
		
			
				
					
					/// conventions. Users should not implement this trait.
  
			
		
	
		
		
			
				
					
					pub   trait   FromPtRegs : Sized  {  
			
		
	
		
		
			
				
					
					     /// Coerces a `T` from the `n`th argument of a pt_regs context where `n` starts
  
			
		
	
		
		
			
				
					
					     /// at 0 and increases by 1 for each successive argument.
  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self > ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Coerces a `T` from the return value of a pt_regs context.
  
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self > ;  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " x86_64 " ) ] impl < T : sealed ::Argument >   Argument   for   T   { }  
			
				
				
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         match   n   {  
			
		
	
		
		
			
				
					
					             0   = >   unsafe   {   bpf_probe_read ( & ctx . rdi ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             1   = >   unsafe   {   bpf_probe_read ( & ctx . rsi ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             2   = >   unsafe   {   bpf_probe_read ( & ctx . rdx ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             3   = >   unsafe   {   bpf_probe_read ( & ctx . rcx ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             4   = >   unsafe   {   bpf_probe_read ( & ctx . r8 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             5   = >   unsafe   {   bpf_probe_read ( & ctx . r9 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             _   = >   None ,  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   { /// Coerces a `T` from the `n`th argument from a BTF context where `n` starts
  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . rax ) . map ( | v |   v   as   * const   _ ) . ok ( )   } /// at 0 and increases by 1 for each successive argument.
  
			
				
				
			
		
	
		
		
			
				
					
					     } pub ( crate )   fn  btf_arg < T : Argument > ( ctx : & impl   crate ::EbpfContext ,   n : usize )   -> T   {  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					     // BTF arguments are exposed as an array of `usize` where `usize` can
  
			
		
	
		
		
			
				
					
					     // either be treated as a pointer or a primitive type
  
			
		
	
		
		
			
				
					
					     let   ptr : * const   usize   =   ctx . as_ptr ( ) . cast ( ) ;  
			
		
	
		
		
			
				
					
					     let   ptr   =   unsafe   {   ptr . add ( n )   } ;  
			
		
	
		
		
			
				
					
					     T ::from_register ( unsafe   {   * ptr   as   u64   } )  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " arm " ) ] trait   PtRegsLayout   {  
			
				
				
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   {      type  Reg ;  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         if   n   < =   6   {  
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . uregs [ n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg > ;  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . uregs [ 0 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }      fn  rc_reg ( & self )   -> & Self ::Reg ;  
			
				
				
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " aarch64 " ) ] #[ cfg(bpf_target_arch =  " aarch64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::bindings ::__u64 ;  
			
				
				
			
		
	
		
		
			
				
					
					         if   n   < =   7   { 
 
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . regs [ n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					         }   else   {          // AArch64 arguments align with libbpf's __PT_PARM{1..8}_REG (regs[0..7]).
  
			
				
				
			
		
	
		
		
			
				
					
					             None          // https://github.com/torvalds/linux/blob/v6.17/arch/arm64/include/uapi/asm/ptrace.h#L88-L93
  
			
				
				
			
		
	
		
		
			
				
					
					         }          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L229-L244
  
			
				
				
			
		
	
		
		
			
				
					
					     }          match   index   {  
			
				
				
			
		
	
		
		
			
				
					
					
             0 ..= 7   = >   Some ( & self . regs [ index ] ) ,  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . regs [ 0 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " loongarch64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         if   n   < =   7   {  
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . regs [ 4   +   n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . regs [ 4 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " riscv64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         match   n   {  
			
		
	
		
		
			
				
					
					             0   = >   unsafe   {   bpf_probe_read ( & ctx . a0 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             1   = >   unsafe   {   bpf_probe_read ( & ctx . a1 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             2   = >   unsafe   {   bpf_probe_read ( & ctx . a2 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             3   = >   unsafe   {   bpf_probe_read ( & ctx . a3 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             4   = >   unsafe   {   bpf_probe_read ( & ctx . a4 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             5   = >   unsafe   {   bpf_probe_read ( & ctx . a5 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             6   = >   unsafe   {   bpf_probe_read ( & ctx . a6 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             7   = >   unsafe   {   bpf_probe_read ( & ctx . a7 ) . map ( | v |   v   as   * const   _ ) . ok ( )   } ,  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					             _   = >   None ,              _   = >   None ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . ra ) . map ( | v |   v   as   * const   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (regs[0]/x0).
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L248-L251
  
			
		
	
		
		
			
				
					
					         & self . regs [ 0 ]  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " powerpc64 " ) ] #[ cfg(bpf_target_arch =  " arm " ) ]  
			
				
				
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::cty ::c_long ;  
			
				
				
			
		
	
		
		
			
				
					
					         if   n   < =   7   { 
 
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . gpr [ 3   +   n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					         }   else   {          // ARM arguments follow libbpf's __PT_PARM{1..7}_REG mapping (uregs[0..6]).
  
			
				
				
			
		
	
		
		
			
				
					
					             None          // https://github.com/torvalds/linux/blob/v6.17/arch/arm/include/uapi/asm/ptrace.h#L124-L152
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L198-L210
  
			
		
	
		
		
			
				
					
					         match   index   {  
			
		
	
		
		
			
				
					
					             0 ..= 6   = >   Some ( & self . uregs [ index ] ) ,  
			
		
	
		
		
			
				
					
					             _   = >   None ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . gpr [ 3 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (uregs[0]).
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L211-L214
  
			
		
	
		
		
			
				
					
					         & self . uregs [ 0 ]  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " s390x " ) ] #[ cfg(bpf_target_arch =  " loongarch64 " ) ]  
			
				
				
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::cty ::c_ulong ;  
			
				
				
			
		
	
		
		
			
				
					
					         if   n   < =   4   { 
 
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . gprs [ 2   +   n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					         }   else   {          // LoongArch arguments correspond to libbpf's __PT_PARM{1..8}_REG (regs[4..11]).
  
			
				
				
			
		
	
		
		
			
				
					
					             None          // https://github.com/torvalds/linux/blob/v6.17/arch/loongarch/include/asm/ptrace.h#L20-L33
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L427-L444
  
			
		
	
		
		
			
				
					
					         match   index   {  
			
		
	
		
		
			
				
					
					             0 ..= 7   = >   Some ( & self . regs [ 4   +   index ] ) ,  
			
		
	
		
		
			
				
					
					             _   = >   None ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . gprs [ 2 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (regs[4], a0).
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L445-L447
  
			
		
	
		
		
			
				
					
					         & self . regs [ 4 ]  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " mips " ) ] #[ cfg(bpf_target_arch =  " mips " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * const   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::bindings ::__u64 ;  
			
				
				
			
		
	
		
		
			
				
					
					         // Assume N64 ABI like libbpf does.
 
 
			
				
				
			
		
	
		
		
			
				
					
					         if   n   < =   7   {      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . regs [ n   +   4 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }          // MIPS N64 arguments correspond to libbpf's __PT_PARM{1..8}_REG (regs[4..11]).
  
			
				
				
			
		
	
		
		
			
				
					
					         }   else   {          // https://github.com/torvalds/linux/blob/v6.17/arch/mips/include/asm/ptrace.h#L28-L52
  
			
				
				
			
		
	
		
		
			
				
					
					             None          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L261-L275
  
			
				
				
			
		
	
		
		
			
				
					
					         }          match   index   {  
			
				
				
			
		
	
		
		
			
				
					
					     }              0 ..= 7   = >   Some ( & self . regs [ 4   +   index ] ) ,  
			
				
				
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . regs [ 31 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " x86_64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         match   n   {  
			
		
	
		
		
			
				
					
					             0   = >   unsafe   {   bpf_probe_read ( & ctx . rdi ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             1   = >   unsafe   {   bpf_probe_read ( & ctx . rsi ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             2   = >   unsafe   {   bpf_probe_read ( & ctx . rdx ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             3   = >   unsafe   {   bpf_probe_read ( & ctx . rcx ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             4   = >   unsafe   {   bpf_probe_read ( & ctx . r8 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
			
		
	
		
		
			
				
					
					             5   = >   unsafe   {   bpf_probe_read ( & ctx . r9 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					             _   = >   None ,              _   = >   None ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . rax ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (regs[2], which aliases MIPS $v0).
  
			
				
				
			
		
	
		
		
			
				
					
					     }          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L277-L279
  
			
				
				
			
		
	
		
		
			
				
					
					}          & self . regs [ 2 ]  
			
				
				
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " arm " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         if   n   < =   6   {  
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . uregs [ n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . uregs [ 0 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " aarch64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         if   n   < =   7   {  
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . regs [ n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . regs [ 0 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " loongarch64 " ) ] #[ cfg(bpf_target_arch =  " powerpc64 " ) ]  
			
				
				
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::cty ::c_ulong ;  
			
				
				
			
		
	
		
		
			
				
					
					         if   n   < =   7   { 
 
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . regs [ 4   +   n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					         }   else   {          // PowerPC64 arguments follow libbpf's __PT_PARM{1..8}_REG (gpr[3..10]).
  
			
				
				
			
		
	
		
		
			
				
					
					             None          // https://github.com/torvalds/linux/blob/v6.17/arch/powerpc/include/asm/ptrace.h#L28-L56
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L290-L308
  
			
		
	
		
		
			
				
					
					         match   index   {  
			
		
	
		
		
			
				
					
					             0 ..= 7   = >   Some ( & self . gpr [ 3   +   index ] ) ,  
			
		
	
		
		
			
				
					
					             _   = >   None ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . regs [ 4 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (gpr[3]).
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L311-L314
  
			
		
	
		
		
			
				
					
					         & self . gpr [ 3 ]  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " riscv64 " ) ] #[ cfg(bpf_target_arch =  " riscv64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::cty ::c_ulong ;  
			
				
				
			
		
	
		
		
			
				
					
					         match   n   { 
 
			
				
				
			
		
	
		
		
			
				
					
					             0   = >   unsafe   {   bpf_probe_read ( & ctx . a0 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					             1   = >   unsafe   {   bpf_probe_read ( & ctx . a1 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,          // RISC-V arguments track libbpf's __PT_PARM{1..8}_REG (a0-a7).
  
			
				
				
			
		
	
		
		
			
				
					
					             2   = >   unsafe   {   bpf_probe_read ( & ctx . a2 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,          // https://github.com/torvalds/linux/blob/v6.17/arch/riscv/include/asm/ptrace.h#L15-L55
  
			
				
				
			
		
	
		
		
			
				
					
					             3   = >   unsafe   {   bpf_probe_read ( & ctx . a3 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L360-L376
  
			
				
				
			
		
	
		
		
			
				
					
					             4   = >   unsafe   {   bpf_probe_read ( & ctx . a4 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,          match   index   {  
			
				
				
			
		
	
		
		
			
				
					
					             5   = >   unsafe   {   bpf_probe_read ( & ctx . a5 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,              0   = >   Some ( & self . a0 ) ,  
			
				
				
			
		
	
		
		
			
				
					
					             6   = >   unsafe   {   bpf_probe_read ( & ctx . a6 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,              1   = >   Some ( & self . a1 ) ,  
			
				
				
			
		
	
		
		
			
				
					
					             7   = >   unsafe   {   bpf_probe_read ( & ctx . a7 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,              2   = >   Some ( & self . a2 ) ,  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					             3   = >   Some ( & self . a3 ) ,  
			
		
	
		
		
			
				
					
					             4   = >   Some ( & self . a4 ) ,  
			
		
	
		
		
			
				
					
					             5   = >   Some ( & self . a5 ) ,  
			
		
	
		
		
			
				
					
					             6   = >   Some ( & self . a6 ) ,  
			
		
	
		
		
			
				
					
					             7   = >   Some ( & self . a7 ) ,  
			
		
	
		
		
			
				
					
					             _   = >   None ,              _   = >   None ,  
			
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . ra ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (a0).
  
			
				
				
			
		
	
		
		
			
				
					
					     }          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L379-L382
  
			
				
				
			
		
	
		
		
			
				
					
					}          & self . a0  
			
				
				
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " powerpc64 " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         if   n   < =   7   {  
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . gpr [ 3   +   n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . gpr [ 3 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " s390x " ) ] #[ cfg(bpf_target_arch =  " s390x " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {      type  Reg   =   crate ::cty ::c_ulong ;  
			
				
				
			
		
	
		
		
			
				
					
					         if   n   < =   4   { 
 
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . gprs [ 2   +   n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					         }   else   {          // s390 arguments match libbpf's __PT_PARM{1..5}_REG (gprs[2..6]).
  
			
				
				
			
		
	
		
		
			
				
					
					             None          // https://github.com/torvalds/linux/blob/v6.17/arch/s390/include/asm/ptrace.h#L111-L131
  
			
				
				
			
		
	
		
		
			
				
					
					         }          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L170-L181
  
			
				
				
			
		
	
		
		
			
				
					
					     }          match   index   {  
			
				
				
			
		
	
		
		
			
				
					
					
             0 ..= 4   = >   Some ( & self . gprs [ 2   +   index ] ) ,  
			
				
				
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {              _   = >   None ,  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . gprs [ 2 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ cfg(bpf_target_arch =  " mips " ) ]  
			
		
	
		
		
			
				
					
					impl < T >   FromPtRegs   for   * mut   T   {  
			
		
	
		
		
			
				
					
					     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					         // Assume N64 ABI like libbpf does.
  
			
		
	
		
		
			
				
					
					         if   n   < =   7   {  
			
		
	
		
		
			
				
					
					             unsafe   {   bpf_probe_read ( & ctx . regs [ n   +   4 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
			
		
	
		
		
			
				
					
					         }   else   {  
			
		
	
		
		
			
				
					
					             None  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   {   bpf_probe_read ( & ctx . regs [ 31 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }          // Return codes use libbpf's __PT_RC_REG (gprs[2]).
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L186-L188
  
			
		
	
		
		
			
				
					
					         & self . gprs [ 2 ]  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// Helper macro to implement [`FromPtRegs`] for a primitive type.
 #[ cfg(bpf_target_arch =  " x86_64 " ) ]  
			
				
				
			
		
	
		
		
			
				
					
					macro_rules!   impl_from_pt_regs   { impl   PtRegsLayout   for   pt_regs   {  
			
				
				
			
		
	
		
		
			
				
					
					     ( $type :ident )   = >   {      type  Reg   =   crate ::cty ::c_ulong ;  
			
				
				
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " x86_64 " ) ] 
 
			
				
				
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {      fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
			
				
				
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {          // x86-64 arguments mirror libbpf's __PT_PARM{1..6}_REG mapping (rdi, rsi, rdx, rcx, r8, r9).
  
			
				
				
			
		
	
		
		
			
				
					
					                 match   n   {          // https://github.com/torvalds/linux/blob/v6.17/arch/x86/include/asm/ptrace.h#L103-L155
  
			
				
				
			
		
	
		
		
			
				
					
					                     0   = >   Some ( ctx . rdi   as   * const   $type   as   _ ) ,          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L134-L152
  
			
				
				
			
		
	
		
		
			
				
					
					                     1   = >   Some ( ctx . rsi   as   * const   $type   as   _ ) ,          match   index   {  
			
				
				
			
		
	
		
		
			
				
					
					                     2   = >   Some ( ctx . rdx   as   * const   $type   as   _ ) ,              0   = >   Some ( & self . rdi ) ,  
			
				
				
			
		
	
		
		
			
				
					
					                     3   = >   Some ( ctx . rcx   as   * const   $type   as   _ ) ,              1   = >   Some ( & self . rsi ) ,  
			
				
				
			
		
	
		
		
			
				
					
					                     4   = >   Some ( ctx . r8   as   * const   $type   as   _ ) ,              2   = >   Some ( & self . rdx ) ,  
			
				
				
			
		
	
		
		
			
				
					
					                     5   = >   Some ( ctx . r9   as   * const   $type   as   _ ) ,              3   = >   Some ( & self . rcx ) ,  
			
				
				
			
		
	
		
		
			
				
					
					                     _   = >   None ,              4   = >   Some ( & self . r8 ) ,  
			
				
				
			
		
	
		
		
			
				
					
					                 }              5   = >   Some ( & self . r9 ) ,  
			
				
				
			
		
	
		
		
			
				
					
					             }              _   = >   None ,  
			
				
				
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . rax   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " arm " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 if   n   < =   6   {  
			
		
	
		
		
			
				
					
					                     Some ( ctx . uregs [ n ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					                 }   else   {  
			
		
	
		
		
			
				
					
					                     None  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . uregs [ 0 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " aarch64 " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 if   n   < =   7   {  
			
		
	
		
		
			
				
					
					                     Some ( ctx . regs [ n ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					                 }   else   {  
			
		
	
		
		
			
				
					
					                     None  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . regs [ 0 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " loongarch64 " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 if   n   < =   7   {  
			
		
	
		
		
			
				
					
					                     Some ( ctx . regs [ 4   +   n ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					                 }   else   {  
			
		
	
		
		
			
				
					
					                     None  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . regs [ 4 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " riscv64 " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 match   n   {  
			
		
	
		
		
			
				
					
					                     0   = >   Some ( ctx . a0   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     1   = >   Some ( ctx . a1   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     2   = >   Some ( ctx . a2   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     3   = >   Some ( ctx . a3   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     4   = >   Some ( ctx . a4   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     5   = >   Some ( ctx . a5   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     6   = >   Some ( ctx . a6   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     7   = >   Some ( ctx . a7   as   * const   $type   as   _ ) ,  
			
		
	
		
		
			
				
					
					                     _   = >   None ,  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . ra   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " powerpc64 " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 if   n   < =   7   {  
			
		
	
		
		
			
				
					
					                     Some ( ctx . gpr [ 3   +   n ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					                 }   else   {  
			
		
	
		
		
			
				
					
					                     None  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . gpr [ 3 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " s390x " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 if   n   < =   4   {  
			
		
	
		
		
			
				
					
					                     Some ( ctx . gprs [ 2   +   n ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					                 }   else   {  
			
		
	
		
		
			
				
					
					                     None  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . gprs [ 2 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					         }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					         #[ cfg(bpf_target_arch =  " mips " ) ]  
			
		
	
		
		
			
				
					
					         impl   FromPtRegs   for   $type   {  
			
		
	
		
		
			
				
					
					             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 if   n   < =   7   {  
			
		
	
		
		
			
				
					
					                     Some ( ctx . regs [ n   +   4 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					                 }   else   {  
			
		
	
		
		
			
				
					
					                     None  
			
		
	
		
		
			
				
					
					                 }  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					             fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
			
		
	
		
		
			
				
					
					                 Some ( ctx . regs [ 31 ]   as   * const   $type   as   _ )  
			
		
	
		
		
			
				
					
					             }  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					         }          }  
			
		
	
		
		
			
				
					
					     } ;  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( u8 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( u16 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( u32 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( u64 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( i8 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( i16 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( i32 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( i64 ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( usize ) ;  
			
		
	
		
		
			
				
					
					impl_from_pt_regs ! ( isize ) ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/// A Rust wrapper on `bpf_raw_tracepoint_args`.
  
			
		
	
		
		
			
				
					
					pub   struct  RawTracepointArgs   {  
			
		
	
		
		
			
				
					
					     args : * mut   bpf_raw_tracepoint_args ,  
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					impl   RawTracepointArgs   {  
			
		
	
		
		
			
				
					
					     /// Creates a new instance of `RawTracepointArgs` from the given
  
			
		
	
		
		
			
				
					
					     /// `bpf_raw_tracepoint_args` raw pointer to allow easier access
  
			
		
	
		
		
			
				
					
					     /// to raw tracepoint argumetns.
  
			
		
	
		
		
			
				
					
					     pub   fn  new ( args : * mut   bpf_raw_tracepoint_args )   -> Self   {  
			
		
	
		
		
			
				
					
					         Self   {   args   }  
			
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					     /// Returns the n-th argument of the raw tracepoint.
      fn  rc_reg ( & self )   -> & Self ::Reg   {  
			
				
				
			
		
	
		
		
			
				
					
					     ///
          // Return codes use libbpf's __PT_RC_REG (rax).
  
			
				
				
			
		
	
		
		
			
				
					
					     /// # Safety
          // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L148-L152
  
			
				
				
			
		
	
		
		
			
				
					
					     ///
          & self . rax  
			
				
				
			
		
	
		
		
			
				
					
					     /// This method is unsafe because it performs raw pointer conversion and makes assumptions
  
			
		
	
		
		
			
				
					
					     /// about the structure of the `bpf_raw_tracepoint_args` type. The tracepoint arguments are
  
			
		
	
		
		
			
				
					
					     /// represented as an array of `__u64` values. To be precise, the wrapped
  
			
		
	
		
		
			
				
					
					     /// `bpf_raw_tracepoint_args` binding defines it as `__IncompleteArrayField<__u64>` and the
  
			
		
	
		
		
			
				
					
					     /// original C type as `__u64 args[0]`. This method provides a way to access these arguments
  
			
		
	
		
		
			
				
					
					     /// conveniently in Rust using `__IncompleteArrayField<T>::as_slice` to represent that array
  
			
		
	
		
		
			
				
					
					     /// as a slice of length n and then retrieve the n-th element of it.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// However, the method does not check the total number of available arguments for a given
  
			
		
	
		
		
			
				
					
					     /// tracepoint and assumes that the slice has at least `n` elements, leading to undefined
  
			
		
	
		
		
			
				
					
					     /// behavior if this condition is not met. Such check is impossible to do, because the
  
			
		
	
		
		
			
				
					
					     /// tracepoint context doesn't contain any information about number of arguments.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// This method also cannot guarantee that the requested type matches the actual value type.
  
			
		
	
		
		
			
				
					
					     /// Wrong assumptions about types can lead to undefined behavior. The tracepoint context
  
			
		
	
		
		
			
				
					
					     /// doesn't provide any type information.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// The caller is responsible for ensuring they have accurate knowledge of the arguments
  
			
		
	
		
		
			
				
					
					     /// and their respective types for the accessed tracepoint context.
  
			
		
	
		
		
			
				
					
					     pub   unsafe   fn  arg < T : FromRawTracepointArgs > ( & self ,   n : usize )   -> T   {  
			
		
	
		
		
			
				
					
					         unsafe   {   T ::from_argument ( & * self . args ,   n )   }  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					     }      }  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					#[ expect(clippy::missing_safety_doc) ] /// Coerces a `T` from the `n`th argument of a pt_regs context where `n` starts
  
			
				
				
			
		
	
		
		
			
				
					
					pub   unsafe   trait   FromRawTracepointArgs : Sized  { /// at 0 and increases by 1 for each successive argument.
  
			
				
				
			
		
	
		
		
			
				
					
					     /// Returns the n-th argument of the raw tracepoint.
 pub ( crate )   fn  arg < T : Argument > ( ctx : & pt_regs ,   n : usize )   -> Option < T >   {  
			
				
				
			
		
	
		
		
			
				
					
					     ///
      let   reg   =   ctx . arg_reg ( n ) ? ;  
			
				
				
			
		
	
		
		
			
				
					
					     /// # Safety
      #[ allow(
  
			
				
				
			
		
	
		
		
			
				
					
					     ///
          clippy ::cast_sign_loss ,  
			
				
				
			
		
	
		
		
			
				
					
					     /// This method is unsafe because it performs raw pointer conversion and makes assumptions
          clippy ::unnecessary_cast ,  
			
				
				
			
		
	
		
		
			
				
					
					     /// about the structure of the `bpf_raw_tracepoint_args` type. The tracepoint arguments are
          trivial_numeric_casts  
			
				
				
			
		
	
		
		
			
				
					
					     /// represented as an array of `__u64` values. To be precise, the wrapped
      ) ]  
			
				
				
			
		
	
		
		
			
				
					
					     /// `bpf_raw_tracepoint_args` binding defines it as `__IncompleteArrayField<__u64>` and the
      Some ( T ::from_register ( ( * reg )   as   u64 ) )  
			
				
				
			
		
	
		
		
			
				
					
					     /// original C type as `__u64 args[0]`. This method provides a way to access these arguments
  
			
		
	
		
		
			
				
					
					     /// conveniently in Rust using `__IncompleteArrayField<T>::as_slice` to represent that array
  
			
		
	
		
		
			
				
					
					     /// as a slice of length n and then retrieve the n-th element of it.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// However, the method does not check the total number of available arguments for a given
  
			
		
	
		
		
			
				
					
					     /// tracepoint and assumes that the slice has at least `n` elements, leading to undefined
  
			
		
	
		
		
			
				
					
					     /// behavior if this condition is not met. Such check is impossible to do, because the
  
			
		
	
		
		
			
				
					
					     /// tracepoint context doesn't contain any information about number of arguments.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// This method also cannot guarantee that the requested type matches the actual value type.
  
			
		
	
		
		
			
				
					
					     /// Wrong assumptions about types can lead to undefined behavior. The tracepoint context
  
			
		
	
		
		
			
				
					
					     /// doesn't provide any type information.
  
			
		
	
		
		
			
				
					
					     ///
  
			
		
	
		
		
			
				
					
					     /// The caller is responsible for ensuring they have accurate knowledge of the arguments
  
			
		
	
		
		
			
				
					
					     /// and their respective types for the accessed tracepoint context.
  
			
		
	
		
		
			
				
					
					     unsafe   fn  from_argument ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> Self ;  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					unsafe   impl < T >   FromRawTracepointArgs   for   * const   T   { /// Coerces a `T` from the return value of a pt_regs context.
  
			
				
				
			
		
	
		
		
			
				
					
					     unsafe   fn  from_argument ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> * const   T   { pub ( crate )   fn  ret < T : Argument > ( ctx : & pt_regs )   -> T   {  
			
				
				
			
		
	
		
		
			
				
					
					         // Raw tracepoint arguments are exposed as `__u64 args[0]`.
      let   reg   =   ctx . rc_reg ( ) ;  
			
				
				
			
		
	
		
		
			
				
					
					         // https://elixir.bootlin.com/linux/v6.5.5/source/include/uapi/linux/bpf.h#L6829
      #[ allow(
  
			
				
				
			
		
	
		
		
			
				
					
					         // They are represented as `__IncompleteArrayField<T>` in the Rust
          clippy ::cast_sign_loss ,  
			
				
				
			
		
	
		
		
			
				
					
					         // wraapper.
          clippy ::unnecessary_cast ,  
			
				
				
			
		
	
		
		
			
				
					
					         //
          trivial_numeric_casts  
			
				
				
			
		
	
		
		
			
				
					
					         // The most convenient way of accessing such type in Rust is to use
      ) ]  
			
				
				
			
		
	
		
		
			
				
					
					         // `__IncompleteArrayField<T>::as_slice` to represent that array as a
      T ::from_register ( ( * reg )   as   u64 )  
			
				
				
			
		
	
		
		
			
				
					
					         // slice of length n and then retrieve the n-th element of it.
  
			
		
	
		
		
			
				
					
					         //
  
			
		
	
		
		
			
				
					
					         // We don't know how many arguments are there for the given tracepoint,
  
			
		
	
		
		
			
				
					
					         // so we just assume that the slice has at least n elements. The whole
  
			
		
	
		
		
			
				
					
					         // assumntion and implementation is unsafe.
  
			
		
	
		
		
			
				
					
					         ( unsafe   {   ctx . args . as_slice ( n   +   1 )   } ) [ n ]   as   _  
			
		
	
		
		
			
				
					
					     }  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					macro_rules!   unsafe_impl_from_raw_tracepoint_args   { /// Returns the n-th argument of the raw tracepoint.
  
			
				
				
			
		
	
		
		
			
				
					
					     ( $type :ident )   = >   { ///
  
			
				
				
			
		
	
		
		
			
				
					
					         unsafe   impl   FromRawTracepointArgs   for   $type   { /// # Safety
  
			
				
				
			
		
	
		
		
			
				
					
					             #[ allow(trivial_numeric_casts) ] ///
  
			
				
				
			
		
	
		
		
			
				
					
					             unsafe   fn  from_argument ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> Self   { /// This method is unsafe because it performs raw pointer conversion and makes assumptions
  
			
				
				
			
		
	
		
		
			
				
					
					                 ( unsafe   {   ctx . args . as_slice ( n   +   1 )   } ) [ n ]   as   _ /// about the structure of the `bpf_raw_tracepoint_args` type. The tracepoint arguments are
  
			
				
				
			
		
	
		
		
			
				
					
					             } /// represented as an array of `__u64` values. To be precise, the wrapped
  
			
				
				
			
		
	
		
		
			
				
					
					         } /// `bpf_raw_tracepoint_args` binding defines it as `__IncompleteArrayField<__u64>` and the
  
			
				
				
			
		
	
		
		
			
				
					
					     } ; /// original C type as `__u64 args[0]`. This method provides a way to access these arguments
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					/// conveniently in Rust using `__IncompleteArrayField<T>::as_slice` to represent that array
  
			
		
	
		
		
			
				
					
					/// as a slice of length n and then retrieve the n-th element of it.
  
			
		
	
		
		
			
				
					
					///
  
			
		
	
		
		
			
				
					
					/// However, the method does not check the total number of available arguments for a given
  
			
		
	
		
		
			
				
					
					/// tracepoint and assumes that the slice has at least `n` elements, leading to undefined
  
			
		
	
		
		
			
				
					
					/// behavior if this condition is not met. Such check is impossible to do, because the
  
			
		
	
		
		
			
				
					
					/// tracepoint context doesn't contain any information about number of arguments.
  
			
		
	
		
		
			
				
					
					///
  
			
		
	
		
		
			
				
					
					/// This method also cannot guarantee that the requested type matches the actual value type.
  
			
		
	
		
		
			
				
					
					/// Wrong assumptions about types can lead to undefined behavior. The tracepoint context
  
			
		
	
		
		
			
				
					
					/// doesn't provide any type information.
  
			
		
	
		
		
			
				
					
					///
  
			
		
	
		
		
			
				
					
					/// The caller is responsible for ensuring they have accurate knowledge of the arguments
  
			
		
	
		
		
			
				
					
					/// and their respective types for the accessed tracepoint context.
  
			
		
	
		
		
			
				
					
					pub ( crate )   fn  raw_tracepoint_arg < T : Argument > ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> T   {  
			
		
	
		
		
			
				
					
					     // Raw tracepoint arguments are exposed as `__u64 args[0]`.
  
			
		
	
		
		
			
				
					
					     // https://github.com/torvalds/linux/blob/v6.17/include/uapi/linux/bpf.h#L7231-L7233
  
			
		
	
		
		
			
				
					
					     // They are represented as `__IncompleteArrayField<T>` in the Rust
  
			
		
	
		
		
			
				
					
					     // wrapper.
  
			
		
	
		
		
			
				
					
					     //
  
			
		
	
		
		
			
				
					
					     // The most convenient way of accessing such type in Rust is to use
  
			
		
	
		
		
			
				
					
					     // `__IncompleteArrayField<T>::as_slice` to represent that array as a
  
			
		
	
		
		
			
				
					
					     // slice of length n and then retrieve the n-th element of it.
  
			
		
	
		
		
			
				
					
					     //
  
			
		
	
		
		
			
				
					
					     // We don't know how many arguments are there for the given tracepoint,
  
			
		
	
		
		
			
				
					
					     // so we just assume that the slice has at least n elements. The whole
  
			
		
	
		
		
			
				
					
					     // assumption and implementation is unsafe.
  
			
		
	
		
		
			
				
					
					     let   ptr   =   ctx . args . as_ptr ( ) ;  
			
		
	
		
		
			
				
					
					     let   ptr   =   unsafe   {   ptr . add ( n )   } ;  
			
		
	
		
		
			
				
					
					     T ::from_register ( unsafe   {   * ptr   } )  
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( u8 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( u16 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( u32 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( u64 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( i8 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( i16 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( i32 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( i64 ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( usize ) ;  
			
		
	
		
		
			
				
					
					unsafe_impl_from_raw_tracepoint_args ! ( isize ) ;