mod.rs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. mod bpf;
  2. mod netlink;
  3. mod perf_event;
  4. #[cfg(test)]
  5. mod fake;
  6. use std::{io, mem};
  7. use libc::{c_int, c_long, pid_t, SYS_bpf, SYS_perf_event_open};
  8. pub(crate) use bpf::*;
  9. #[cfg(test)]
  10. pub(crate) use fake::*;
  11. pub(crate) use netlink::*;
  12. pub(crate) use perf_event::*;
  13. use crate::generated::{bpf_attr, bpf_cmd, perf_event_attr};
  14. pub(crate) type SysResult = Result<c_long, (c_long, io::Error)>;
  15. pub(crate) enum Syscall<'a> {
  16. Bpf {
  17. cmd: bpf_cmd,
  18. attr: &'a bpf_attr,
  19. },
  20. PerfEventOpen {
  21. attr: perf_event_attr,
  22. pid: pid_t,
  23. cpu: i32,
  24. group: i32,
  25. flags: u32,
  26. },
  27. PerfEventIoctl {
  28. fd: c_int,
  29. request: c_int,
  30. arg: c_int,
  31. },
  32. }
  33. fn syscall(call: Syscall) -> SysResult {
  34. #[cfg(test)]
  35. return TEST_SYSCALL.with(|test_impl| unsafe { test_impl.borrow()(call) });
  36. #[cfg_attr(test, allow(unreachable_code))]
  37. match unsafe {
  38. match call {
  39. Syscall::Bpf { cmd, attr } => {
  40. libc::syscall(SYS_bpf, cmd, attr, mem::size_of::<bpf_attr>())
  41. }
  42. Syscall::PerfEventOpen {
  43. attr,
  44. pid,
  45. cpu,
  46. group,
  47. flags,
  48. } => libc::syscall(SYS_perf_event_open, &attr, pid, cpu, group, flags),
  49. Syscall::PerfEventIoctl { fd, request, arg } => {
  50. libc::ioctl(fd, request.try_into().unwrap(), arg) as libc::c_long
  51. }
  52. }
  53. } {
  54. ret @ 0.. => Ok(ret),
  55. ret => Err((ret, io::Error::last_os_error())),
  56. }
  57. }