ebpf_kern/
ctx.rs

1use core::ffi::c_void;
2
3use super::helpers;
4
5// TODO: cross-platform
6pub struct Context {
7    inner: *const c_void,
8}
9
10impl Context {
11    #[inline(always)]
12    pub unsafe fn cast(ctx: *const c_void) -> Self {
13        Context { inner: ctx }
14    }
15
16    #[inline(always)]
17    pub fn read_here<T>(&self, offset: usize) -> T {
18        unsafe { (self.inner.add(offset) as *const T).read() }
19    }
20
21    #[inline(always)]
22    pub fn read_into(&self, offset: usize, slice: &mut [u8]) {
23        unsafe {
24            helpers::probe_read_kernel(
25                slice.as_mut_ptr() as _,
26                slice.len() as u32,
27                self.inner.add(offset) as *const _,
28            );
29        }
30    }
31
32    #[inline(always)]
33    pub fn read<T>(&self, offset: usize) -> T {
34        use core::mem;
35
36        let mut value = mem::MaybeUninit::uninit();
37        unsafe {
38            helpers::probe_read_kernel(
39                value.as_mut_ptr() as _,
40                mem::size_of::<T>() as u32,
41                self.inner.add(offset) as *const _,
42            );
43            value.assume_init()
44        }
45    }
46
47    #[inline(always)]
48    pub fn get_user_stack(&self, buf: &mut [u8]) -> Result<usize, i32> {
49        let c = unsafe {
50            helpers::get_stack(self.inner as _, buf.as_mut_ptr() as _, buf.len() as _, 256)
51        };
52        if c < 0 {
53            Err(c as _)
54        } else {
55            Ok(c as _)
56        }
57    }
58}