瀏覽代碼

integration tests: add relocation tests

Alessandro Decina 2 年之前
父節點
當前提交
b2b9bd2edf

+ 4 - 0
test/integration-ebpf/Cargo.toml

@@ -22,3 +22,7 @@ path = "src/pass.rs"
 [[bin]]
 name = "test"
 path = "src/test.rs"
+
+[[bin]]
+name = "relocations"
+path = "src/relocations.rs"

+ 28 - 0
test/integration-ebpf/src/bpf/text_64_64_reloc.c

@@ -0,0 +1,28 @@
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+char _license[] SEC("license") = "GPL";
+
+struct {
+        __uint(type, BPF_MAP_TYPE_ARRAY);
+        __type(key, __u32);
+        __type(value, __u64);
+        __uint(max_entries, 2);
+} RESULTS SEC(".maps");
+
+static __u64
+inc_cb(void *map, __u32 *key, void *val,
+	       void *data)
+{
+	__u64 *value = val;
+	*value += 1;
+	return 0;
+}
+
+SEC("uprobe/test_text_64_64_reloc")
+int test_text_64_64_reloc(struct pt_regs *ctx)
+{
+	bpf_for_each_map_elem(&RESULTS, inc_cb, NULL, 0);
+    return 0;
+}
+

+ 45 - 0
test/integration-ebpf/src/relocations.rs

@@ -0,0 +1,45 @@
+#![no_std]
+#![no_main]
+
+use core::hint;
+
+use aya_bpf::{
+    macros::{map, uprobe},
+    maps::Array,
+    programs::ProbeContext,
+};
+
+#[map]
+static mut RESULTS: Array<u64> = Array::with_max_entries(3, 0);
+
+#[uprobe]
+pub fn test_64_32_call_relocs(_ctx: ProbeContext) {
+    // this will link set_result and do a forward call
+    set_result(0, hint::black_box(1));
+
+    // set_result is already linked, this will just do the forward call
+    set_result(1, hint::black_box(2));
+
+    // this will link set_result_backward after set_result. Then will do a
+    // backward call to set_result.
+    set_result_backward(2, hint::black_box(3));
+}
+
+#[inline(never)]
+fn set_result(index: u32, value: u64) {
+    unsafe {
+        if let Some(v) = RESULTS.get_ptr_mut(index) {
+            *v = value;
+        }
+    }
+}
+
+#[inline(never)]
+fn set_result_backward(index: u32, value: u64) {
+    set_result(index, value);
+}
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+    unsafe { core::hint::unreachable_unchecked() }
+}

+ 1 - 0
test/integration-test/src/tests/mod.rs

@@ -8,6 +8,7 @@ pub mod btf_relocations;
 pub mod elf;
 pub mod load;
 pub mod rbpf;
+pub mod relocations;
 pub mod smoke;
 
 pub use integration_test_macros::integration_test;

+ 70 - 0
test/integration-test/src/tests/relocations.rs

@@ -0,0 +1,70 @@
+use std::{process::exit, time::Duration};
+
+use aya::{
+    include_bytes_aligned,
+    programs::{ProgramError, UProbe},
+    Bpf,
+};
+use integration_test_macros::integration_test;
+
+#[integration_test]
+fn relocations() {
+    let bpf = load_and_attach(
+        "test_64_32_call_relocs",
+        include_bytes_aligned!("../../../../target/bpfel-unknown-none/release/relocations"),
+    );
+
+    trigger_relocations_program();
+    std::thread::sleep(Duration::from_millis(100));
+
+    let m = aya::maps::Array::<_, u64>::try_from(bpf.map("RESULTS").unwrap()).unwrap();
+    assert_eq!(m.get(&0, 0).unwrap(), 1);
+    assert_eq!(m.get(&1, 0).unwrap(), 2);
+    assert_eq!(m.get(&2, 0).unwrap(), 3);
+}
+
+#[integration_test]
+fn text_64_64_reloc() {
+    let mut bpf = load_and_attach(
+        "test_text_64_64_reloc",
+        include_bytes_aligned!("../../../../target/bpfel-unknown-none/release/text_64_64_reloc.o"),
+    );
+
+    let mut m = aya::maps::Array::<_, u64>::try_from(bpf.map_mut("RESULTS").unwrap()).unwrap();
+    m.set(0, 1, 0).unwrap();
+    m.set(1, 2, 0).unwrap();
+
+    trigger_relocations_program();
+    std::thread::sleep(Duration::from_millis(100));
+
+    assert_eq!(m.get(&0, 0).unwrap(), 2);
+    assert_eq!(m.get(&1, 0).unwrap(), 3);
+}
+
+fn load_and_attach(name: &str, bytes: &[u8]) -> Bpf {
+    let mut bpf = Bpf::load(bytes).unwrap();
+
+    let prog: &mut UProbe = bpf.program_mut(name).unwrap().try_into().unwrap();
+    if let Err(ProgramError::LoadError {
+        io_error,
+        verifier_log,
+    }) = prog.load()
+    {
+        println!("Failed to load program `{name}`: {io_error}. Verifier log:\n{verifier_log:#}");
+        exit(1);
+    };
+
+    prog.attach(
+        Some("trigger_relocations_program"),
+        0,
+        "/proc/self/exe",
+        None,
+    )
+    .unwrap();
+
+    bpf
+}
+
+#[no_mangle]
+#[inline(never)]
+pub extern "C" fn trigger_relocations_program() {}