diff --git a/rustfmt.toml b/rustfmt.toml index 0c3bc0ee..b47fe15f 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,3 +1,4 @@ +edition = "2021" unstable_features = true reorder_imports = true imports_granularity = "Crate" diff --git a/test/integration-ebpf/src/map_test.rs b/test/integration-ebpf/src/map_test.rs index 87c07557..33fa3194 100644 --- a/test/integration-ebpf/src/map_test.rs +++ b/test/integration-ebpf/src/map_test.rs @@ -1,6 +1,8 @@ #![no_std] #![no_main] +pub mod stack_argument; + use aya_bpf::{ bindings::xdp_action, macros::{map, xdp}, diff --git a/test/integration-ebpf/src/stack_argument.rs b/test/integration-ebpf/src/stack_argument.rs new file mode 100644 index 00000000..723847fc --- /dev/null +++ b/test/integration-ebpf/src/stack_argument.rs @@ -0,0 +1,70 @@ +#![no_std] +#![no_main] + +use aya_bpf::{ + macros::{uprobe, map}, + programs::{perf_event, ProbeContext}, maps::PerfEventArray, +}; +use aya_log_ebpf::{debug, info}; + +pub struct Args { + a_0: u64, + a_1: u64, + a_2: u64, + a_3: u64, + a_4: u64, + a_5: u64, + + a_6: u64, + a_7: i64, +} + +impl Args{ + fn new()->Self{ + Self{ + a_0: 0, + a_1: 0, + a_2: 0, + a_3: 0, + a_4: 0, + a_5: 0, + a_6: 0, + a_7: 0, + } + } +} + +#[map] +static EVENTS: PerfEventArray = PerfEventArray::with_max_entries(1024, 0); + +#[uprobe] +pub fn test_stack_argument(ctx: ProbeContext) -> i32 { + debug!(&ctx, "Hello from eBPF!"); + match try_stack_argument(ctx) { + Ok(ret) => ret, + Err(_) => 0, + } +} + +//read argument, and send event +fn try_stack_argument(ctx: ProbeContext) -> Result { + let args = Args::new(); + args.a_0 = ctx.arg(0).ok_or(255)?; + args.a_1 = ctx.arg(1).ok_or(255)?; + args.a_2 = ctx.arg(2).ok_or(255)?; + args.a_3 = ctx.arg(3).ok_or(255)?; + args.a_4 = ctx.arg(4).ok_or(255)?; + args.a_5 = ctx.arg(5).ok_or(255)?; + args.a_6 = ctx.stack_arg(0).ok_or(255)?; + args.a_7 = ctx.stack_arg(1).ok_or(255)?; + + + EVENTS.output(&ctx, &args, 0); + + Ok(0) +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { core::hint::unreachable_unchecked() } +} diff --git a/test/integration-test/src/tests/mod.rs b/test/integration-test/src/tests/mod.rs index 93e6aaa3..312c1a84 100644 --- a/test/integration-test/src/tests/mod.rs +++ b/test/integration-test/src/tests/mod.rs @@ -12,6 +12,7 @@ pub mod log; pub mod rbpf; pub mod relocations; pub mod smoke; +pub mod stack_argument; pub use integration_test_macros::{integration_test, tokio_integration_test}; diff --git a/test/integration-test/src/tests/stack_argument.rs b/test/integration-test/src/tests/stack_argument.rs new file mode 100644 index 00000000..2d721b60 --- /dev/null +++ b/test/integration-test/src/tests/stack_argument.rs @@ -0,0 +1,95 @@ +use aya::{ + include_bytes_aligned, maps::AsyncPerfEventArray, programs::UProbe, util::online_cpus, Bpf, +}; +use integration_test_macros::tokio_integration_test; +use log::warn; +use tokio::{signal, task}; + +pub struct Args { + a_0: u64, + a_1: u64, + a_2: u64, + a_3: u64, + a_4: u64, + a_5: u64, + + a_6: u64, + a_7: i64, +} + +impl Args{ + fn new()->Self{ + Self{ + a_0: 0, + a_1: 0, + a_2: 0, + a_3: 0, + a_4: 0, + a_5: 0, + a_6: 0, + a_7: 0, + } + } +} +#[no_mangle] +#[inline(never)] +pub extern "C" fn trigger_stack_argument( + a_0: u64, + a_1: u64, + a_2: u64, + a_3: u64, + a_4: u64, + a_5: u64, + //from arg6, stack_argument would be used + a_6: u64, + a_7: i64, +) { +} + +#[tokio_integration_test] +async fn stack_argument() { + let bytes = + include_bytes_aligned!("../../../../target/bpfel-unknown-none/release/stack_argument"); + let mut bpf = Bpf::load(bytes).unwrap(); + + if let Err(e) = BpfLogger::init(&mut bpf) { + warn!("failed to initialize eBPF logger: {}", e); + } + let prog: &mut UProbe = bpf + .program_mut("test_stack_argument") + .unwrap() + .try_into() + .unwrap(); + prog.load().unwrap(); + prog.attach(Some("trigger_stack_argument"), 0, "/proc/self/exe", None) + .unwrap(); + let mut perf_array = AsyncPerfEventArray::try_from(bpf.take_map("EVENTS").unwrap())?; + for cpu_id in online_cpus()? { + let mut buf = perf_array.open(cpu_id, None)?; + + task::spawn(async move { + let mut buffers = (0..10) + .map(|_| BytesMut::with_capacity(1024)) + .collect::>(); + + loop { + let events = buf.read_events(&mut buffer).await.unwrap(); + for buf in buffers.iter_mut().task(events.read){ + let ptr = buf.as_ptr() as *const Args; + let data = unsafe{ptr.read_unaligned()}; + assert_eq!(data.a_0, 0); + assert_eq!(data.a_1, 1); + assert_eq!(data.a_2, 2); + assert_eq!(data.a_3, 3); + assert_eq!(data.a_4, 4); + assert_eq!(data.a_5, 5); + assert_eq!(data.a_6, 6); + assert_eq!(data.a_7, 7); + break; + } + } + }); + } + + trigger_stack_argument(0, 1, 2, 3, 4, 5, 6, 7); +}