aya-ebpf: reduce repetition

reviewable/pr1376/r1
Tamir Duberstein 2 weeks ago
parent 4b4b9f83bd
commit 85636f6164
No known key found for this signature in database

@ -113,413 +113,202 @@ pub trait FromPtRegs: Sized {
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() }
}
}
#[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
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.uregs[0]).map(|v| v as *const _).ok() }
}
}
#[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() },
_ => 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
}
}
trait PtRegsLayout {
type Reg: Copy;
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() }
}
fn arg_reg(&self, index: usize) -> Option<&Self::Reg>;
fn ret_reg(&self) -> &Self::Reg;
}
#[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::cty::c_ulong;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
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> {
unsafe { bpf_probe_read(&ctx.rax).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.rax
}
}
#[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
impl PtRegsLayout for pt_regs {
type Reg = crate::cty::c_long;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
match index {
0..=6 => Some(&self.uregs[index]),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.uregs[0]).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.uregs[0]
}
}
#[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::bindings::__u64;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
match index {
0..=7 => Some(&self.regs[index]),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.regs[0]).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.regs[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
impl PtRegsLayout for pt_regs {
type Reg = crate::cty::c_ulong;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
match index {
0..=7 => Some(&self.regs[4 + index]),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.regs[4]).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.regs[4]
}
}
#[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> {
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() }
fn ret_reg(&self) -> &Self::Reg {
&self.ra
}
}
#[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
impl PtRegsLayout for pt_regs {
type Reg = crate::cty::c_ulong;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
match index {
0..=7 => Some(&self.gpr[3 + index]),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.gpr[3]).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.gpr[3]
}
}
#[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
impl PtRegsLayout for pt_regs {
type Reg = crate::cty::c_ulong;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
match index {
0..=4 => Some(&self.gprs[2 + index]),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.gprs[2]).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.gprs[2]
}
}
#[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::bindings::__u64;
fn arg_reg(&self, index: usize) -> Option<&Self::Reg> {
match index {
0..=7 => Some(&self.regs[4 + index]),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
unsafe { bpf_probe_read(&ctx.regs[31]).map(|v| v as *mut _).ok() }
fn ret_reg(&self) -> &Self::Reg {
&self.regs[31]
}
}
/// 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 {
macro_rules! impl_pointer_from_pt_regs {
($( { $($generics:tt)* } )? $type:ty) => {
impl$($($generics)*)? 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
}
let reg = ctx.arg_reg(n)?;
let ptr = core::ptr::from_ref(reg).cast();
unsafe { bpf_probe_read(ptr) }.ok()
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
Some(ctx.gpr[3] as *const $type as _)
let reg = ctx.ret_reg();
let ptr = core::ptr::from_ref(reg).cast();
unsafe { bpf_probe_read(ptr) }.ok()
}
}
};
}
#[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 _)
}
}
impl_pointer_from_pt_regs!({<T>} *const T);
impl_pointer_from_pt_regs!({<T>} *mut T);
#[cfg(bpf_target_arch = "mips")]
macro_rules! impl_scalar_from_pt_regs {
($type:ty) => {
impl FromPtRegs for $type {
#[allow(trivial_numeric_casts)]
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
if n <= 7 {
Some(ctx.regs[n + 4] as *const $type as _)
} else {
None
}
let reg = ctx.arg_reg(n)?;
Some(*reg as Self)
}
#[allow(trivial_numeric_casts)]
fn from_retval(ctx: &pt_regs) -> Option<Self> {
Some(ctx.regs[31] as *const $type as _)
let reg = ctx.ret_reg();
Some(*reg as Self)
}
}
};
}
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);
impl_scalar_from_pt_regs!(u8);
impl_scalar_from_pt_regs!(u16);
impl_scalar_from_pt_regs!(u32);
impl_scalar_from_pt_regs!(u64);
impl_scalar_from_pt_regs!(i8);
impl_scalar_from_pt_regs!(i16);
impl_scalar_from_pt_regs!(i32);
impl_scalar_from_pt_regs!(i64);
impl_scalar_from_pt_regs!(usize);
impl_scalar_from_pt_regs!(isize);
/// A Rust wrapper on `bpf_raw_tracepoint_args`.
pub struct RawTracepointArgs {

Loading…
Cancel
Save