@ -1,3 +1,4 @@
 
		
	
		
			
				use   crate ::bindings ::bpf_raw_tracepoint_args ;  
		
	
		
			
				#[ cfg(any(
  
		
	
		
			
				     bpf_target_arch   =   "arm" ,  
		
	
		
			
				     bpf_target_arch   =   "mips" ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -13,619 +14,305 @@ use crate::bindings::pt_regs;
 
		
	
		
			
				use   crate ::bindings ::user_pt_regs   as   pt_regs ;  
		
	
		
			
				#[ cfg(bpf_target_arch =  " riscv64 " ) ]  
		
	
		
			
				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
  
		
	
		
			
				/// context.
  
		
	
		
			
				///
  
		
	
		
			
				/// Users should not implement this trait.
  
		
	
		
			
				///
  
		
	
		
			
				/// # 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   _  
		
	
		
			
				mod  sealed   {  
		
	
		
			
				     #[ expect(clippy::missing_safety_doc) ]  
		
	
		
			
				     pub   unsafe   trait   Argument   {  
		
	
		
			
				         fn  from_register ( value : u64 )   -> Self ;  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/// Helper macro to implement [`FromBtfArgument`] for a primitive type.
  
		
	
		
			
				macro_rules!   unsafe_impl_from_btf_argument   {  
		
	
		
			
				     ( $type :ident )   = >   {  
		
	
		
			
				         unsafe   impl   FromBtfArgument   for   $type   {  
		
	
		
			
				             #[ allow(trivial_numeric_casts) ]  
		
	
		
			
				             unsafe   fn  from_argument ( ctx : * const   c_void ,   n : usize )   -> Self   {  
		
	
		
			
				                 // 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   _  
		
	
		
			
				             }  
		
	
		
			
				     macro_rules!   unsafe_impl_argument   {  
		
	
		
			
				         ( $( $(   {   $( $generics :tt ) *   }   ) ?   $ty :ty   $(   {   where   $( $where :tt ) *   }   ) ? ) , +   $(, ) ? )   = >   {  
		
	
		
			
				             $(  
		
	
		
			
				                 #[ allow(clippy::cast_lossless, trivial_numeric_casts) ]  
		
	
		
			
				                 unsafe   impl $( $( $generics ) * ) ?   Argument   for   $ty   $( where   $( $where ) * ) ?   {  
		
	
		
			
				                     fn  from_register ( value : u64 )   -> Self   {  
		
	
		
			
				                         value   as   Self  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
		
			
				             ) +  
		
	
		
			
				         }  
		
	
		
			
				     } ;  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				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.
  
		
	
		
			
				     pub   fn  as_ptr ( & self )   -> * mut   pt_regs   {  
		
	
		
			
				         self . regs  
		
	
		
			
				     }  
		
	
		
			
				     unsafe_impl_argument ! (  
		
	
		
			
				         i8 ,  
		
	
		
			
				         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
  
		
	
		
			
				/// 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 > ;  
		
	
		
			
				}  
		
	
		
			
				pub   trait   Argument : sealed ::Argument   { }  
		
	
		
			
				
 
		
	
		
			
				#[ cfg(bpf_target_arch =  " x86_64 " ) ]  
		
	
		
			
				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 ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				impl < T : sealed ::Argument >   Argument   for   T   { }  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . rax ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				     }  
		
	
		
			
				/// 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.
  
		
	
		
			
				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 " ) ]  
		
	
		
			
				impl < T >   FromPtRegs   for   * const   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   * const   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				trait   PtRegsLayout   {  
		
	
		
			
				     type  Reg ;  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . uregs [ 0 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				     }  
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg > ;  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg ;  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				#[ cfg(bpf_target_arch =  " aarch64 " ) ]  
		
	
		
			
				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 [ n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     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 ( )   } ,  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::bindings ::__u64 ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // AArch64 arguments align with libbpf's __PT_PARM{1..8}_REG (regs[0..7]).
  
		
	
		
			
				         // 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 ] ) ,  
		
	
		
			
				             _   = >   None ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . ra ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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 " ) ]  
		
	
		
			
				impl < T >   FromPtRegs   for   * const   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   * const   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				#[ cfg(bpf_target_arch =  " arm " ) ]  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::cty ::c_long ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // ARM arguments follow libbpf's __PT_PARM{1..7}_REG mapping (uregs[0..6]).
  
		
	
		
			
				         // 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 >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . gpr [ 3 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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 " ) ]  
		
	
		
			
				impl < T >   FromPtRegs   for   * const   T   {  
		
	
		
			
				     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
		
	
		
			
				         if   n   < =   4   {  
		
	
		
			
				             unsafe   {   bpf_probe_read ( & ctx . gprs [ 2   +   n ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				#[ cfg(bpf_target_arch =  " loongarch64 " ) ]  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::cty ::c_ulong ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // LoongArch arguments correspond to libbpf's __PT_PARM{1..8}_REG (regs[4..11]).
  
		
	
		
			
				         // 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 >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . gprs [ 2 ] ) . map ( | v |   v   as   * const   _ ) . ok ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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 " ) ]  
		
	
		
			
				impl < T >   FromPtRegs   for   * const   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   * const   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     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 ( )   } ,  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::bindings ::__u64 ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // MIPS N64 arguments correspond to libbpf's __PT_PARM{1..8}_REG (regs[4..11]).
  
		
	
		
			
				         // https://github.com/torvalds/linux/blob/v6.17/arch/mips/include/asm/ptrace.h#L28-L52
  
		
	
		
			
				         // 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 ] ) ,  
		
	
		
			
				             _   = >   None ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . rax ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				#[ 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 ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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 =  " loongarch64 " ) ]  
		
	
		
			
				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 [ 4   +   n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				#[ cfg(bpf_target_arch =  " powerpc64 " ) ]  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::cty ::c_ulong ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // PowerPC64 arguments follow libbpf's __PT_PARM{1..8}_REG (gpr[3..10]).
  
		
	
		
			
				         // 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 >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . regs [ 4 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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 " ) ]  
		
	
		
			
				impl < T >   FromPtRegs   for   * mut   T   {  
		
	
		
			
				     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
		
	
		
			
				         match   n   {  
		
	
		
			
				             0   = >   unsafe   {   bpf_probe_read ( & ctx . a0 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             1   = >   unsafe   {   bpf_probe_read ( & ctx . a1 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             2   = >   unsafe   {   bpf_probe_read ( & ctx . a2 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             3   = >   unsafe   {   bpf_probe_read ( & ctx . a3 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             4   = >   unsafe   {   bpf_probe_read ( & ctx . a4 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             5   = >   unsafe   {   bpf_probe_read ( & ctx . a5 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             6   = >   unsafe   {   bpf_probe_read ( & ctx . a6 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				             7   = >   unsafe   {   bpf_probe_read ( & ctx . a7 ) . map ( | v |   v   as   * mut   _ ) . ok ( )   } ,  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::cty ::c_ulong ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // RISC-V arguments track libbpf's __PT_PARM{1..8}_REG (a0-a7).
  
		
	
		
			
				         // https://github.com/torvalds/linux/blob/v6.17/arch/riscv/include/asm/ptrace.h#L15-L55
  
		
	
		
			
				         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L360-L376
  
		
	
		
			
				         match   index   {  
		
	
		
			
				             0   = >   Some ( & self . a0 ) ,  
		
	
		
			
				             1   = >   Some ( & self . a1 ) ,  
		
	
		
			
				             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 ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . ra ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				#[ 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 ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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 =  " s390x " ) ]  
		
	
		
			
				impl < T >   FromPtRegs   for   * mut   T   {  
		
	
		
			
				     fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
		
	
		
			
				         if   n   < =   4   {  
		
	
		
			
				             unsafe   {   bpf_probe_read ( & ctx . gprs [ 2   +   n ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
		
	
		
			
				         }   else   {  
		
	
		
			
				             None  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         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  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::cty ::c_ulong ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // s390 arguments match libbpf's __PT_PARM{1..5}_REG (gprs[2..6]).
  
		
	
		
			
				         // 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 ] ) ,  
		
	
		
			
				             _   = >   None ,  
		
	
		
			
				         }  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     fn  from_retval ( ctx : & pt_regs )   -> Option < Self >   {  
		
	
		
			
				         unsafe   {   bpf_probe_read ( & ctx . regs [ 31 ] ) . map ( | v |   v   as   * mut   _ ) . ok ( )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // 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.
  
		
	
		
			
				macro_rules!   impl_from_pt_regs   {  
		
	
		
			
				     ( $type :ident )   = >   {  
		
	
		
			
				         #[ cfg(bpf_target_arch =  " x86_64 " ) ]  
		
	
		
			
				         impl   FromPtRegs   for   $type   {  
		
	
		
			
				             fn  from_argument ( ctx : & pt_regs ,   n : usize )   -> Option < Self >   {  
		
	
		
			
				                 match   n   {  
		
	
		
			
				                     0   = >   Some ( ctx . rdi   as   * const   $type   as   _ ) ,  
		
	
		
			
				                     1   = >   Some ( ctx . rsi   as   * const   $type   as   _ ) ,  
		
	
		
			
				                     2   = >   Some ( ctx . rdx   as   * const   $type   as   _ ) ,  
		
	
		
			
				                     3   = >   Some ( ctx . rcx   as   * const   $type   as   _ ) ,  
		
	
		
			
				                     4   = >   Some ( ctx . r8   as   * const   $type   as   _ ) ,  
		
	
		
			
				                     5   = >   Some ( ctx . r9   as   * const   $type   as   _ ) ,  
		
	
		
			
				                     _   = >   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   _ )  
		
	
		
			
				             }  
		
	
		
			
				#[ cfg(bpf_target_arch =  " x86_64 " ) ]  
		
	
		
			
				impl   PtRegsLayout   for   pt_regs   {  
		
	
		
			
				     type  Reg   =   crate ::cty ::c_ulong ;  
		
	
		
			
				
 
		
	
		
			
				     fn  arg_reg ( & self ,   index : usize )   -> Option < & Self ::Reg >   {  
		
	
		
			
				         // x86-64 arguments mirror libbpf's __PT_PARM{1..6}_REG mapping (rdi, rsi, rdx, rcx, r8, r9).
  
		
	
		
			
				         // https://github.com/torvalds/linux/blob/v6.17/arch/x86/include/asm/ptrace.h#L103-L155
  
		
	
		
			
				         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L134-L152
  
		
	
		
			
				         match   index   {  
		
	
		
			
				             0   = >   Some ( & self . rdi ) ,  
		
	
		
			
				             1   = >   Some ( & self . rsi ) ,  
		
	
		
			
				             2   = >   Some ( & self . rdx ) ,  
		
	
		
			
				             3   = >   Some ( & self . rcx ) ,  
		
	
		
			
				             4   = >   Some ( & self . r8 ) ,  
		
	
		
			
				             5   = >   Some ( & self . r9 ) ,  
		
	
		
			
				             _   = >   None ,  
		
	
		
			
				         }  
		
	
		
			
				     } ;  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				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.
  
		
	
		
			
				     ///
  
		
	
		
			
				     /// # Safety
  
		
	
		
			
				     ///
  
		
	
		
			
				     /// 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 )   }  
		
	
		
			
				     fn  rc_reg ( & self )   -> & Self ::Reg   {  
		
	
		
			
				         // Return codes use libbpf's __PT_RC_REG (rax).
  
		
	
		
			
				         // https://github.com/torvalds/linux/blob/v6.17/tools/lib/bpf/bpf_tracing.h#L148-L152
  
		
	
		
			
				         & self . rax  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				#[ expect(clippy::missing_safety_doc) ]  
		
	
		
			
				pub   unsafe   trait   FromRawTracepointArgs : Sized  {  
		
	
		
			
				     /// Returns the n-th argument of the raw tracepoint.
  
		
	
		
			
				     ///
  
		
	
		
			
				     /// # Safety
  
		
	
		
			
				     ///
  
		
	
		
			
				     /// 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.
  
		
	
		
			
				     unsafe   fn  from_argument ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> Self ;  
		
	
		
			
				/// 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.
  
		
	
		
			
				pub ( crate )   fn  arg < T : Argument > ( ctx : & pt_regs ,   n : usize )   -> Option < T >   {  
		
	
		
			
				     let   reg   =   ctx . arg_reg ( n ) ? ;  
		
	
		
			
				     #[ allow(
  
		
	
		
			
				         clippy ::cast_sign_loss ,  
		
	
		
			
				         clippy ::unnecessary_cast ,  
		
	
		
			
				         trivial_numeric_casts  
		
	
		
			
				     ) ]  
		
	
		
			
				     Some ( T ::from_register ( ( * reg )   as   u64 ) )  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				unsafe   impl < T >   FromRawTracepointArgs   for   * const   T   {  
		
	
		
			
				     unsafe   fn  from_argument ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> * const   T   {  
		
	
		
			
				         // Raw tracepoint arguments are exposed as `__u64 args[0]`.
  
		
	
		
			
				         // https://elixir.bootlin.com/linux/v6.5.5/source/include/uapi/linux/bpf.h#L6829
  
		
	
		
			
				         // They are represented as `__IncompleteArrayField<T>` in the Rust
  
		
	
		
			
				         // wraapper.
  
		
	
		
			
				         //
  
		
	
		
			
				         // 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
  
		
	
		
			
				         // assumntion and implementation is unsafe.
  
		
	
		
			
				         ( unsafe   {   ctx . args . as_slice ( n   +   1 )   } ) [ n ]   as   _  
		
	
		
			
				     }  
		
	
		
			
				/// Coerces a `T` from the return value of a pt_regs context.
  
		
	
		
			
				pub ( crate )   fn  ret < T : Argument > ( ctx : & pt_regs )   -> T   {  
		
	
		
			
				     let   reg   =   ctx . rc_reg ( ) ;  
		
	
		
			
				     #[ allow(
  
		
	
		
			
				         clippy ::cast_sign_loss ,  
		
	
		
			
				         clippy ::unnecessary_cast ,  
		
	
		
			
				         trivial_numeric_casts  
		
	
		
			
				     ) ]  
		
	
		
			
				     T ::from_register ( ( * reg )   as   u64 )  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				macro_rules!   unsafe_impl_from_raw_tracepoint_args   {  
		
	
		
			
				     ( $type :ident )   = >   {  
		
	
		
			
				         unsafe   impl   FromRawTracepointArgs   for   $type   {  
		
	
		
			
				             #[ allow(trivial_numeric_casts) ]  
		
	
		
			
				             unsafe   fn  from_argument ( ctx : & bpf_raw_tracepoint_args ,   n : usize )   -> Self   {  
		
	
		
			
				                 ( unsafe   {   ctx . args . as_slice ( n   +   1 )   } ) [ n ]   as   _  
		
	
		
			
				             }  
		
	
		
			
				         }  
		
	
		
			
				     } ;  
		
	
		
			
				/// Returns the n-th argument of the raw tracepoint.
  
		
	
		
			
				///
  
		
	
		
			
				/// # Safety
  
		
	
		
			
				///
  
		
	
		
			
				/// 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 ( 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 ) ;