From 3241e5a5e82fe9b86a501466a04692cb07a48d0e Mon Sep 17 00:00:00 2001
From: pdliyan <pdliyan@didiglobal.com>
Date: Wed, 30 Aug 2023 14:49:15 +0800
Subject: [PATCH] add intergration-test of stack_argument.

---
 rustfmt.toml                                  |  1 +
 test/integration-ebpf/src/map_test.rs         |  2 +
 test/integration-ebpf/src/stack_argument.rs   | 70 ++++++++++++++
 test/integration-test/src/tests/mod.rs        |  1 +
 .../src/tests/stack_argument.rs               | 95 +++++++++++++++++++
 5 files changed, 169 insertions(+)
 create mode 100644 test/integration-ebpf/src/stack_argument.rs
 create mode 100644 test/integration-test/src/tests/stack_argument.rs

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<Args> = 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<i32, i64> {
+    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::<Vec<_>>();
+
+            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);
+}