aya-ebpf: reduce repetition and excessive traits

The traits `FromBtfArgument`, `FromRawTracepointArgs`, `FromPtRegs` are
all fancy ways of saying `Argument` - so replace these traits with it.

This also removes the use of `bpf_probe_read` which was introduced in
05c1586202 because I can't reproduce the
need for it.
reviewable/pr1376/r3
Tamir Duberstein 2 days ago
parent 4b4b9f83bd
commit 05250da20b
No known key found for this signature in database

@ -1,3 +1,4 @@
use crate::bindings::bpf_raw_tracepoint_args;
#[cfg(any(
bpf_target_arch = "arm",
bpf_target_arch = "mips",
@ -13,557 +14,268 @@ 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)
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},
);
}
/// 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 })
}
pub trait Argument: sealed::Argument {}
/// Returns a pointer to the wrapped value.
pub fn as_ptr(&self) -> *mut pt_regs {
self.regs
}
}
impl<T: sealed::Argument> Argument for T {}
/// 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
/// 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.
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> 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> {
unsafe { bpf_probe_read(&ctx.rax).map(|v| v as *const _).ok() }
}
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() }
}
}
#[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
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.gpr[3]).map(|v| v as *const _).ok() }
}
}
#[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
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.gprs[2]).map(|v| v as *const _).ok() }
}
}
#[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() },
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.rax).map(|v| v as *mut _).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 = "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
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.regs[0]).map(|v| v as *mut _).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 = "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
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.regs[4]).map(|v| v as *mut _).ok() }
}
}
#[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> {
// 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.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() }
}
}
#[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() }
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 *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> {
unsafe { bpf_probe_read(&ctx.regs[31]).map(|v| v as *mut _).ok() }
}
}
/// 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 _),
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> {
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 _)
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 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
#[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> {
Some(ctx.regs[4] as *const $type as _)
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 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 _),
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> {
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 _)
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 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
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> {
Some(ctx.gprs[2] as *const $type as _)
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]
}
}
#[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
#[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,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
Some(ctx.regs[31] as *const $type as _)
}
}
};
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
}
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 }
/// 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))
}
/// 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) }
}
/// 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)
}
#[expect(clippy::missing_safety_doc)]
pub unsafe trait FromRawTracepointArgs: Sized {
/// Returns the n-th argument of the raw tracepoint.
///
/// # Safety
@ -587,15 +299,11 @@ pub unsafe trait FromRawTracepointArgs: Sized {
///
/// 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 {
unsafe fn from_argument(ctx: &bpf_raw_tracepoint_args, n: usize) -> *const T {
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://elixir.bootlin.com/linux/v6.5.5/source/include/uapi/linux/bpf.h#L6829
// https://github.com/torvalds/linux/blob/v6.17/include/uapi/linux/bpf.h#L7231-L7233
// They are represented as `__IncompleteArrayField<T>` in the Rust
// wraapper.
// wrapper.
//
// The most convenient way of accessing such type in Rust is to use
// `__IncompleteArrayField<T>::as_slice` to represent that array as a
@ -603,29 +311,8 @@ unsafe impl<T> FromRawTracepointArgs for *const T {
//
// 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 _
}
// assumption and implementation is unsafe.
let ptr = ctx.args.as_ptr();
let ptr = unsafe { ptr.add(n) };
T::from_register(unsafe { *ptr })
}
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 _
}
}
};
}
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);

@ -26,7 +26,7 @@
pub use aya_ebpf_bindings::bindings;
mod args;
pub use args::{PtRegs, RawTracepointArgs};
pub use args::Argument;
pub mod btf_maps;
#[expect(clippy::missing_safety_doc, unsafe_op_in_unsafe_fn)]
pub mod helpers;

@ -1,6 +1,6 @@
use core::ffi::c_void;
use crate::{EbpfContext, args::FromBtfArgument};
use crate::{Argument, EbpfContext, args::btf_arg};
pub struct FEntryContext {
ctx: *mut c_void,
@ -31,9 +31,8 @@ impl FEntryContext {
/// Ok(0)
/// }
/// ```
#[expect(clippy::missing_safety_doc)]
pub unsafe fn arg<T: FromBtfArgument>(&self, n: usize) -> T {
unsafe { T::from_argument(self.ctx.cast(), n) }
pub fn arg<T: Argument>(&self, n: usize) -> T {
btf_arg(self, n)
}
}

@ -1,6 +1,6 @@
use core::ffi::c_void;
use crate::{EbpfContext, args::FromBtfArgument};
use crate::{Argument, EbpfContext, args::btf_arg};
pub struct FExitContext {
ctx: *mut c_void,
@ -31,9 +31,8 @@ impl FExitContext {
/// Ok(0)
/// }
/// ```
#[expect(clippy::missing_safety_doc)]
pub unsafe fn arg<T: FromBtfArgument>(&self, n: usize) -> T {
unsafe { T::from_argument(self.ctx.cast(), n) }
pub fn arg<T: Argument>(&self, n: usize) -> T {
btf_arg(self, n)
}
}

@ -1,6 +1,6 @@
use core::ffi::c_void;
use crate::{EbpfContext, args::FromBtfArgument};
use crate::{Argument, EbpfContext, args::btf_arg};
pub struct LsmContext {
ctx: *mut c_void,
@ -22,12 +22,6 @@ impl LsmContext {
/// this code path, or 0 if this is the first LSM program to be called. This phony
/// argument is always last in the argument list.
///
/// # 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.
/// Luckily, the BPF verifier will catch this for us.
///
/// # Examples
///
/// ```no_run
@ -52,8 +46,8 @@ impl LsmContext {
/// ```
///
/// [1]: https://elixir.bootlin.com/linux/latest/source/include/linux/lsm_hook_defs.h
pub unsafe fn arg<T: FromBtfArgument>(&self, n: usize) -> T {
unsafe { T::from_argument(self.ctx.cast(), n) }
pub fn arg<T: Argument>(&self, n: usize) -> T {
btf_arg(self, n)
}
}

@ -15,7 +15,7 @@ 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::{EbpfContext, args::FromPtRegs};
use crate::{Argument, EbpfContext, args::arg};
pub struct ProbeContext {
pub regs: *mut pt_regs,
@ -47,8 +47,8 @@ impl ProbeContext {
/// Ok(0)
/// }
/// ```
pub fn arg<T: FromPtRegs>(&self, n: usize) -> Option<T> {
T::from_argument(unsafe { &*self.regs }, n)
pub fn arg<T: Argument>(&self, n: usize) -> Option<T> {
arg(unsafe { &*self.regs }, n)
}
}

@ -1,6 +1,6 @@
use core::ffi::c_void;
use crate::{EbpfContext, args::FromRawTracepointArgs, bindings::bpf_raw_tracepoint_args};
use crate::{Argument, EbpfContext, args::raw_tracepoint_arg, bindings::bpf_raw_tracepoint_args};
pub struct RawTracePointContext {
ctx: *mut bpf_raw_tracepoint_args,
@ -11,9 +11,8 @@ impl RawTracePointContext {
Self { ctx: ctx.cast() }
}
#[expect(clippy::missing_safety_doc)]
pub unsafe fn arg<T: FromRawTracepointArgs>(&self, n: usize) -> T {
unsafe { T::from_argument(&*self.ctx, n) }
pub fn arg<T: Argument>(&self, n: usize) -> T {
raw_tracepoint_arg(unsafe { &*self.ctx }, n)
}
}

@ -15,7 +15,7 @@ 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::{EbpfContext, args::FromPtRegs};
use crate::{Argument, EbpfContext, args::ret};
pub struct RetProbeContext {
pub regs: *mut pt_regs,
@ -34,15 +34,15 @@ impl RetProbeContext {
/// # #![expect(dead_code)]
/// # use aya_ebpf::{programs::RetProbeContext, cty::c_int};
/// unsafe fn try_kretprobe_try_to_wake_up(ctx: RetProbeContext) -> Result<u32, u32> {
/// let retval: c_int = ctx.ret().ok_or(1u32)?;
/// let retval: c_int = ctx.ret();
///
/// // Do something with retval
///
/// Ok(0)
/// }
/// ```
pub fn ret<T: FromPtRegs>(&self) -> Option<T> {
T::from_retval(unsafe { &*self.regs })
pub fn ret<T: Argument>(&self) -> T {
ret(unsafe { &*self.regs })
}
}

@ -1,6 +1,6 @@
use core::ffi::c_void;
use crate::{EbpfContext, args::FromBtfArgument};
use crate::{Argument, EbpfContext, args::btf_arg};
pub struct BtfTracePointContext {
ctx: *mut c_void,
@ -16,12 +16,6 @@ impl BtfTracePointContext {
/// You can use the tplist tool provided by bcc to get a list of tracepoints and their
/// arguments. TODO: document this better, possibly add a tplist alternative to aya.
///
/// # 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.
/// Luckily, the BPF verifier will catch this for us.
///
/// # Examples
///
/// ```no_run
@ -42,8 +36,8 @@ impl BtfTracePointContext {
/// ```
///
/// [1]: https://elixir.bootlin.com/linux/latest/source/include/linux/lsm_hook_defs.h
pub unsafe fn arg<T: FromBtfArgument>(&self, n: usize) -> T {
unsafe { T::from_argument(self.ctx.cast(), n) }
pub fn arg<T: Argument>(&self, n: usize) -> T {
btf_arg(self, n)
}
}

@ -16,8 +16,8 @@ static RESULT: Array<SysEnterEvent> = Array::with_max_entries(1, 0);
#[raw_tracepoint(tracepoint = "sys_enter")]
fn sys_enter(ctx: RawTracePointContext) -> i32 {
let common_type: u16 = unsafe { ctx.arg(0) };
let common_flags: u8 = unsafe { ctx.arg(1) };
let common_type: u16 = ctx.arg(0);
let common_flags: u8 = ctx.arg(1);
if let Some(ptr) = RESULT.get_ptr_mut(0) {
unsafe {

@ -1603,7 +1603,7 @@ pub fn aya_ebpf::programs::device::DeviceContext::from(t: T) -> T
pub mod aya_ebpf::programs::fentry
pub struct aya_ebpf::programs::fentry::FEntryContext
impl aya_ebpf::programs::fentry::FEntryContext
pub unsafe fn aya_ebpf::programs::fentry::FEntryContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fentry::FEntryContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fentry::FEntryContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::fentry::FEntryContext
pub fn aya_ebpf::programs::fentry::FEntryContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -1632,7 +1632,7 @@ pub fn aya_ebpf::programs::fentry::FEntryContext::from(t: T) -> T
pub mod aya_ebpf::programs::fexit
pub struct aya_ebpf::programs::fexit::FExitContext
impl aya_ebpf::programs::fexit::FExitContext
pub unsafe fn aya_ebpf::programs::fexit::FExitContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fexit::FExitContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fexit::FExitContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::fexit::FExitContext
pub fn aya_ebpf::programs::fexit::FExitContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -1693,7 +1693,7 @@ pub fn aya_ebpf::programs::flow_dissector::FlowDissectorContext::from(t: T) -> T
pub mod aya_ebpf::programs::lsm
pub struct aya_ebpf::programs::lsm::LsmContext
impl aya_ebpf::programs::lsm::LsmContext
pub unsafe fn aya_ebpf::programs::lsm::LsmContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::lsm::LsmContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::lsm::LsmContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::lsm::LsmContext
pub fn aya_ebpf::programs::lsm::LsmContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -1751,7 +1751,7 @@ pub mod aya_ebpf::programs::probe
pub struct aya_ebpf::programs::probe::ProbeContext
pub aya_ebpf::programs::probe::ProbeContext::regs: *mut aya_ebpf_bindings::x86_64::bindings::pt_regs
impl aya_ebpf::programs::probe::ProbeContext
pub fn aya_ebpf::programs::probe::ProbeContext::arg<T: aya_ebpf::args::FromPtRegs>(&self, n: usize) -> core::option::Option<T>
pub fn aya_ebpf::programs::probe::ProbeContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> core::option::Option<T>
pub fn aya_ebpf::programs::probe::ProbeContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::probe::ProbeContext
pub fn aya_ebpf::programs::probe::ProbeContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -1780,7 +1780,7 @@ pub fn aya_ebpf::programs::probe::ProbeContext::from(t: T) -> T
pub mod aya_ebpf::programs::raw_tracepoint
pub struct aya_ebpf::programs::raw_tracepoint::RawTracePointContext
impl aya_ebpf::programs::raw_tracepoint::RawTracePointContext
pub unsafe fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::arg<T: aya_ebpf::args::FromRawTracepointArgs>(&self, n: usize) -> T
pub fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::raw_tracepoint::RawTracePointContext
pub fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -1811,7 +1811,7 @@ pub struct aya_ebpf::programs::retprobe::RetProbeContext
pub aya_ebpf::programs::retprobe::RetProbeContext::regs: *mut aya_ebpf_bindings::x86_64::bindings::pt_regs
impl aya_ebpf::programs::retprobe::RetProbeContext
pub fn aya_ebpf::programs::retprobe::RetProbeContext::new(ctx: *mut core::ffi::c_void) -> Self
pub fn aya_ebpf::programs::retprobe::RetProbeContext::ret<T: aya_ebpf::args::FromPtRegs>(&self) -> core::option::Option<T>
pub fn aya_ebpf::programs::retprobe::RetProbeContext::ret<T: aya_ebpf::Argument>(&self) -> T
impl aya_ebpf::EbpfContext for aya_ebpf::programs::retprobe::RetProbeContext
pub fn aya_ebpf::programs::retprobe::RetProbeContext::as_ptr(&self) -> *mut core::ffi::c_void
impl core::marker::Freeze for aya_ebpf::programs::retprobe::RetProbeContext
@ -2197,7 +2197,7 @@ pub fn aya_ebpf::programs::tc::TcContext::from(t: T) -> T
pub mod aya_ebpf::programs::tp_btf
pub struct aya_ebpf::programs::tp_btf::BtfTracePointContext
impl aya_ebpf::programs::tp_btf::BtfTracePointContext
pub unsafe fn aya_ebpf::programs::tp_btf::BtfTracePointContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::tp_btf::BtfTracePointContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::tp_btf::BtfTracePointContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::tp_btf::BtfTracePointContext
pub fn aya_ebpf::programs::tp_btf::BtfTracePointContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2289,7 +2289,7 @@ impl<T> core::convert::From<T> for aya_ebpf::programs::xdp::XdpContext
pub fn aya_ebpf::programs::xdp::XdpContext::from(t: T) -> T
pub struct aya_ebpf::programs::BtfTracePointContext
impl aya_ebpf::programs::tp_btf::BtfTracePointContext
pub unsafe fn aya_ebpf::programs::tp_btf::BtfTracePointContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::tp_btf::BtfTracePointContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::tp_btf::BtfTracePointContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::tp_btf::BtfTracePointContext
pub fn aya_ebpf::programs::tp_btf::BtfTracePointContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2345,7 +2345,7 @@ impl<T> core::convert::From<T> for aya_ebpf::programs::device::DeviceContext
pub fn aya_ebpf::programs::device::DeviceContext::from(t: T) -> T
pub struct aya_ebpf::programs::FEntryContext
impl aya_ebpf::programs::fentry::FEntryContext
pub unsafe fn aya_ebpf::programs::fentry::FEntryContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fentry::FEntryContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fentry::FEntryContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::fentry::FEntryContext
pub fn aya_ebpf::programs::fentry::FEntryContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2373,7 +2373,7 @@ impl<T> core::convert::From<T> for aya_ebpf::programs::fentry::FEntryContext
pub fn aya_ebpf::programs::fentry::FEntryContext::from(t: T) -> T
pub struct aya_ebpf::programs::FExitContext
impl aya_ebpf::programs::fexit::FExitContext
pub unsafe fn aya_ebpf::programs::fexit::FExitContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fexit::FExitContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::fexit::FExitContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::fexit::FExitContext
pub fn aya_ebpf::programs::fexit::FExitContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2432,7 +2432,7 @@ impl<T> core::convert::From<T> for aya_ebpf::programs::flow_dissector::FlowDisse
pub fn aya_ebpf::programs::flow_dissector::FlowDissectorContext::from(t: T) -> T
pub struct aya_ebpf::programs::LsmContext
impl aya_ebpf::programs::lsm::LsmContext
pub unsafe fn aya_ebpf::programs::lsm::LsmContext::arg<T: aya_ebpf::args::FromBtfArgument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::lsm::LsmContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::lsm::LsmContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::lsm::LsmContext
pub fn aya_ebpf::programs::lsm::LsmContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2488,7 +2488,7 @@ pub fn aya_ebpf::programs::perf_event::PerfEventContext::from(t: T) -> T
pub struct aya_ebpf::programs::ProbeContext
pub aya_ebpf::programs::ProbeContext::regs: *mut aya_ebpf_bindings::x86_64::bindings::pt_regs
impl aya_ebpf::programs::probe::ProbeContext
pub fn aya_ebpf::programs::probe::ProbeContext::arg<T: aya_ebpf::args::FromPtRegs>(&self, n: usize) -> core::option::Option<T>
pub fn aya_ebpf::programs::probe::ProbeContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> core::option::Option<T>
pub fn aya_ebpf::programs::probe::ProbeContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::probe::ProbeContext
pub fn aya_ebpf::programs::probe::ProbeContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2516,7 +2516,7 @@ impl<T> core::convert::From<T> for aya_ebpf::programs::probe::ProbeContext
pub fn aya_ebpf::programs::probe::ProbeContext::from(t: T) -> T
pub struct aya_ebpf::programs::RawTracePointContext
impl aya_ebpf::programs::raw_tracepoint::RawTracePointContext
pub unsafe fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::arg<T: aya_ebpf::args::FromRawTracepointArgs>(&self, n: usize) -> T
pub fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::arg<T: aya_ebpf::Argument>(&self, n: usize) -> T
pub fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::new(ctx: *mut core::ffi::c_void) -> Self
impl aya_ebpf::EbpfContext for aya_ebpf::programs::raw_tracepoint::RawTracePointContext
pub fn aya_ebpf::programs::raw_tracepoint::RawTracePointContext::as_ptr(&self) -> *mut core::ffi::c_void
@ -2546,7 +2546,7 @@ pub struct aya_ebpf::programs::RetProbeContext
pub aya_ebpf::programs::RetProbeContext::regs: *mut aya_ebpf_bindings::x86_64::bindings::pt_regs
impl aya_ebpf::programs::retprobe::RetProbeContext
pub fn aya_ebpf::programs::retprobe::RetProbeContext::new(ctx: *mut core::ffi::c_void) -> Self
pub fn aya_ebpf::programs::retprobe::RetProbeContext::ret<T: aya_ebpf::args::FromPtRegs>(&self) -> core::option::Option<T>
pub fn aya_ebpf::programs::retprobe::RetProbeContext::ret<T: aya_ebpf::Argument>(&self) -> T
impl aya_ebpf::EbpfContext for aya_ebpf::programs::retprobe::RetProbeContext
pub fn aya_ebpf::programs::retprobe::RetProbeContext::as_ptr(&self) -> *mut core::ffi::c_void
impl core::marker::Freeze for aya_ebpf::programs::retprobe::RetProbeContext
@ -2935,61 +2935,9 @@ impl<T> core::convert::From<T> for aya_ebpf::programs::xdp::XdpContext
pub fn aya_ebpf::programs::xdp::XdpContext::from(t: T) -> T
pub macro aya_ebpf::bpf_printk!
pub macro aya_ebpf::btf_map_def!
pub struct aya_ebpf::PtRegs
impl aya_ebpf::PtRegs
pub fn aya_ebpf::PtRegs::arg<T: aya_ebpf::args::FromPtRegs>(&self, n: usize) -> core::option::Option<T>
pub fn aya_ebpf::PtRegs::as_ptr(&self) -> *mut aya_ebpf_bindings::x86_64::bindings::pt_regs
pub fn aya_ebpf::PtRegs::new(regs: *mut aya_ebpf_bindings::x86_64::bindings::pt_regs) -> Self
pub fn aya_ebpf::PtRegs::ret<T: aya_ebpf::args::FromPtRegs>(&self) -> core::option::Option<T>
impl core::marker::Freeze for aya_ebpf::PtRegs
impl !core::marker::Send for aya_ebpf::PtRegs
impl !core::marker::Sync for aya_ebpf::PtRegs
impl core::marker::Unpin for aya_ebpf::PtRegs
impl core::panic::unwind_safe::RefUnwindSafe for aya_ebpf::PtRegs
impl core::panic::unwind_safe::UnwindSafe for aya_ebpf::PtRegs
impl<T, U> core::convert::Into<U> for aya_ebpf::PtRegs where U: core::convert::From<T>
pub fn aya_ebpf::PtRegs::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_ebpf::PtRegs where U: core::convert::Into<T>
pub type aya_ebpf::PtRegs::Error = core::convert::Infallible
pub fn aya_ebpf::PtRegs::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_ebpf::PtRegs where U: core::convert::TryFrom<T>
pub type aya_ebpf::PtRegs::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_ebpf::PtRegs::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_ebpf::PtRegs where T: 'static + ?core::marker::Sized
pub fn aya_ebpf::PtRegs::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_ebpf::PtRegs where T: ?core::marker::Sized
pub fn aya_ebpf::PtRegs::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_ebpf::PtRegs where T: ?core::marker::Sized
pub fn aya_ebpf::PtRegs::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_ebpf::PtRegs
pub fn aya_ebpf::PtRegs::from(t: T) -> T
pub struct aya_ebpf::RawTracepointArgs
impl aya_ebpf::RawTracepointArgs
pub unsafe fn aya_ebpf::RawTracepointArgs::arg<T: aya_ebpf::args::FromRawTracepointArgs>(&self, n: usize) -> T
pub fn aya_ebpf::RawTracepointArgs::new(args: *mut aya_ebpf_bindings::x86_64::bindings::bpf_raw_tracepoint_args) -> Self
impl core::marker::Freeze for aya_ebpf::RawTracepointArgs
impl !core::marker::Send for aya_ebpf::RawTracepointArgs
impl !core::marker::Sync for aya_ebpf::RawTracepointArgs
impl core::marker::Unpin for aya_ebpf::RawTracepointArgs
impl core::panic::unwind_safe::RefUnwindSafe for aya_ebpf::RawTracepointArgs
impl core::panic::unwind_safe::UnwindSafe for aya_ebpf::RawTracepointArgs
impl<T, U> core::convert::Into<U> for aya_ebpf::RawTracepointArgs where U: core::convert::From<T>
pub fn aya_ebpf::RawTracepointArgs::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_ebpf::RawTracepointArgs where U: core::convert::Into<T>
pub type aya_ebpf::RawTracepointArgs::Error = core::convert::Infallible
pub fn aya_ebpf::RawTracepointArgs::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_ebpf::RawTracepointArgs where U: core::convert::TryFrom<T>
pub type aya_ebpf::RawTracepointArgs::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_ebpf::RawTracepointArgs::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_ebpf::RawTracepointArgs where T: 'static + ?core::marker::Sized
pub fn aya_ebpf::RawTracepointArgs::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_ebpf::RawTracepointArgs where T: ?core::marker::Sized
pub fn aya_ebpf::RawTracepointArgs::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_ebpf::RawTracepointArgs where T: ?core::marker::Sized
pub fn aya_ebpf::RawTracepointArgs::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_ebpf::RawTracepointArgs
pub fn aya_ebpf::RawTracepointArgs::from(t: T) -> T
pub const aya_ebpf::TASK_COMM_LEN: usize
pub trait aya_ebpf::Argument: aya_ebpf::args::sealed::Argument
impl<T: aya_ebpf::args::sealed::Argument> aya_ebpf::Argument for T
pub trait aya_ebpf::EbpfContext
pub fn aya_ebpf::EbpfContext::as_ptr(&self) -> *mut aya_ebpf_cty::c_void
pub fn aya_ebpf::EbpfContext::command(&self) -> core::result::Result<[u8; 16], aya_ebpf_cty::od::c_long>

Loading…
Cancel
Save