Explorar o código

Split relocation tests into multiple files

This avoids requiring kernel support for all types of relocations when
testing a specific type.
Tamir Duberstein hai 2 semanas
pai
achega
630a767117

+ 33 - 0
test/integration-test/bpf/enum_signed_32_checked_variants_reloc.bpf.c

@@ -0,0 +1,33 @@
+#include "reloc.h"
+
+enum relocated_enum_signed_32_checked_variants {
+#ifndef TARGET
+  S32_VAL_A = -0x7AAAAAAA,
+#endif
+  S32_VAL_B = -0x7BBBBBBB,
+#ifdef TARGET
+  S32_VAL_C = -0x7CCCCCCC
+#endif
+};
+
+__noinline int enum_signed_32_checked_variants_global() {
+#ifndef TARGET
+  if (bpf_core_enum_value_exists(enum relocated_enum_signed_32_checked_variants,
+                                 S32_VAL_A)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_signed_32_checked_variants, S32_VAL_A));
+#else
+  if (bpf_core_enum_value_exists(enum relocated_enum_signed_32_checked_variants,
+                                 S32_VAL_C)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_signed_32_checked_variants, S32_VAL_C));
+#endif
+  } else {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_signed_32_checked_variants, S32_VAL_B));
+  }
+}
+
+SEC("uprobe") int program(void *ctx) {
+  return enum_signed_32_checked_variants_global();
+}

+ 17 - 0
test/integration-test/bpf/enum_signed_32_reloc.bpf.c

@@ -0,0 +1,17 @@
+#include "reloc.h"
+
+enum relocated_enum_signed_32 {
+  S32_VAL =
+#ifndef TARGET
+      -0x7AAAAAAA
+#else
+      -0x7BBBBBBB
+#endif
+};
+
+__noinline int enum_signed_32_global() {
+  return set_output(
+      bpf_core_enum_value(enum relocated_enum_signed_32, S32_VAL));
+}
+
+SEC("uprobe") int program(void *ctx) { return enum_signed_32_global(); }

+ 33 - 0
test/integration-test/bpf/enum_signed_64_checked_variants_reloc.bpf.c

@@ -0,0 +1,33 @@
+#include "reloc.h"
+
+enum relocated_enum_signed_64_checked_variants {
+#ifndef TARGET
+  S64_VAL_A = -0xAAAAAAABBBBBBB,
+#endif
+  S64_VAL_B = -0xCCCCCCCDDDDDDD,
+#ifdef TARGET
+  S64_VAL_C = -0xEEEEEEEFFFFFFF
+#endif
+};
+
+__noinline int enum_signed_64_checked_variants_global() {
+#ifndef TARGET
+  if (bpf_core_enum_value_exists(enum relocated_enum_signed_64_checked_variants,
+                                 S64_VAL_A)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_signed_64_checked_variants, S64_VAL_A));
+#else
+  if (bpf_core_enum_value_exists(enum relocated_enum_signed_64_checked_variants,
+                                 S64_VAL_C)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_signed_64_checked_variants, S64_VAL_C));
+#endif
+  } else {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_signed_64_checked_variants, S64_VAL_B));
+  }
+}
+
+SEC("uprobe") int program(void *ctx) {
+  return enum_signed_64_checked_variants_global();
+}

+ 17 - 0
test/integration-test/bpf/enum_signed_64_reloc.bpf.c

@@ -0,0 +1,17 @@
+#include "reloc.h"
+
+enum relocated_enum_signed_64 {
+  S64_VAL =
+#ifndef TARGET
+      -0xAAAAAAABBBBBBBB
+#else
+      -0xCCCCCCCDDDDDDDD
+#endif
+};
+
+__noinline int enum_signed_64_global() {
+  return set_output(
+      bpf_core_enum_value(enum relocated_enum_signed_64, S64_VAL));
+}
+
+SEC("uprobe") int program(void *ctx) { return enum_signed_64_global(); }

+ 33 - 0
test/integration-test/bpf/enum_unsigned_32_checked_variants_reloc.bpf.c

@@ -0,0 +1,33 @@
+#include "reloc.h"
+
+enum relocated_enum_unsigned_32_checked_variants {
+#ifndef TARGET
+  U32_VAL_A = 0xAAAAAAAA,
+#endif
+  U32_VAL_B = 0xBBBBBBBB,
+#ifdef TARGET
+  U32_VAL_C = 0xCCCCCCCC
+#endif
+};
+
+__noinline int enum_unsigned_32_checked_variants_global() {
+#ifndef TARGET
+  if (bpf_core_enum_value_exists(
+          enum relocated_enum_unsigned_32_checked_variants, U32_VAL_A)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_unsigned_32_checked_variants, U32_VAL_A));
+#else
+  if (bpf_core_enum_value_exists(
+          enum relocated_enum_unsigned_32_checked_variants, U32_VAL_C)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_unsigned_32_checked_variants, U32_VAL_C));
+#endif
+  } else {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_unsigned_32_checked_variants, U32_VAL_B));
+  }
+}
+
+SEC("uprobe") int program(void *ctx) {
+  return enum_unsigned_32_checked_variants_global();
+}

+ 17 - 0
test/integration-test/bpf/enum_unsigned_32_reloc.bpf.c

@@ -0,0 +1,17 @@
+#include "reloc.h"
+
+enum relocated_enum_unsigned_32 {
+  U32_VAL =
+#ifndef TARGET
+      0xAAAAAAAA
+#else
+      0xBBBBBBBB
+#endif
+};
+
+__noinline int enum_unsigned_32_global() {
+  return set_output(
+      bpf_core_enum_value(enum relocated_enum_unsigned_32, U32_VAL));
+}
+
+SEC("uprobe") int program(void *ctx) { return enum_unsigned_32_global(); }

+ 33 - 0
test/integration-test/bpf/enum_unsigned_64_checked_variants_reloc.bpf.c

@@ -0,0 +1,33 @@
+#include "reloc.h"
+
+enum relocated_enum_unsigned_64_checked_variants {
+#ifndef TARGET
+  U64_VAL_A = 0xAAAAAAAABBBBBBBB,
+#endif
+  U64_VAL_B = 0xCCCCCCCCDDDDDDDD,
+#ifdef TARGET
+  U64_VAL_C = 0xEEEEEEEEFFFFFFFF
+#endif
+};
+
+__noinline int enum_unsigned_64_checked_variants_global() {
+#ifndef TARGET
+  if (bpf_core_enum_value_exists(
+          enum relocated_enum_unsigned_64_checked_variants, U64_VAL_A)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_unsigned_64_checked_variants, U64_VAL_A));
+#else
+  if (bpf_core_enum_value_exists(
+          enum relocated_enum_unsigned_64_checked_variants, U64_VAL_C)) {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_unsigned_64_checked_variants, U64_VAL_C));
+#endif
+  } else {
+    return set_output(bpf_core_enum_value(
+        enum relocated_enum_unsigned_64_checked_variants, U64_VAL_B));
+  }
+}
+
+SEC("uprobe") int program(void *ctx) {
+  return enum_unsigned_64_checked_variants_global();
+}

+ 17 - 0
test/integration-test/bpf/enum_unsigned_64_reloc.bpf.c

@@ -0,0 +1,17 @@
+#include "reloc.h"
+
+enum relocated_enum_unsigned_64 {
+  U64_VAL =
+#ifndef TARGET
+      0xAAAAAAAABBBBBBBB
+#else
+      0xCCCCCCCCDDDDDDDD
+#endif
+};
+
+__noinline int enum_unsigned_64_global() {
+  return set_output(
+      bpf_core_enum_value(enum relocated_enum_unsigned_64, U64_VAL));
+}
+
+SEC("uprobe") int program(void *ctx) { return enum_unsigned_64_global(); }

+ 9 - 0
test/integration-test/bpf/field_reloc.bpf.c

@@ -0,0 +1,9 @@
+#include "reloc.h"
+#include "struct_with_scalars.h"
+
+__noinline int field_global() {
+  struct relocated_struct_with_scalars s = {1, 2, 3};
+  return set_output(__builtin_preserve_access_index(s.b));
+}
+
+SEC("uprobe") int program(void *ctx) { return field_global(); }

+ 21 - 0
test/integration-test/bpf/pointer_reloc.bpf.c

@@ -0,0 +1,21 @@
+#include "reloc.h"
+
+struct relocated_struct_with_pointer {
+#ifndef TARGET
+  struct relocated_struct_with_pointer *first;
+#endif
+  struct relocated_struct_with_pointer *second;
+#ifdef TARGET
+  struct relocated_struct_with_pointer *first;
+#endif
+};
+
+__noinline int pointer_global() {
+  struct relocated_struct_with_pointer s = {
+      (struct relocated_struct_with_pointer *)42,
+      (struct relocated_struct_with_pointer *)21,
+  };
+  return set_output((__u64)__builtin_preserve_access_index(s.first));
+}
+
+SEC("uprobe") int program(void *ctx) { return pointer_global(); }

+ 0 - 269
test/integration-test/bpf/reloc.bpf.c

@@ -1,269 +0,0 @@
-// clang-format off
-#include <vmlinux.h>
-#include <bpf/bpf_helpers.h>
-#include <bpf/bpf_core_read.h>
-// clang-format on
-
-char _license[] SEC("license") = "GPL";
-
-struct {
-  __uint(type, BPF_MAP_TYPE_ARRAY);
-  __type(key, __u32);
-  __type(value, __u64);
-  __uint(max_entries, 1);
-} output_map SEC(".maps");
-
-long set_output(__u64 value) {
-  __u32 key = 0;
-  return bpf_map_update_elem(&output_map, &key, &value, BPF_ANY);
-}
-
-struct relocated_struct_with_scalars {
-#ifndef TARGET
-  __u8 a;
-#endif
-  __u8 b;
-  __u8 c;
-#ifdef TARGET
-  __u8 d;
-#endif
-};
-
-__noinline int field_global() {
-  struct relocated_struct_with_scalars s = {1, 2, 3};
-  return set_output(__builtin_preserve_access_index(s.b));
-}
-
-SEC("uprobe") int field(void *ctx) { return field_global(); }
-
-struct relocated_struct_with_pointer {
-#ifndef TARGET
-  struct relocated_struct_with_pointer *first;
-#endif
-  struct relocated_struct_with_pointer *second;
-#ifdef TARGET
-  struct relocated_struct_with_pointer *first;
-#endif
-};
-
-__noinline int pointer_global() {
-  struct relocated_struct_with_pointer s = {
-      (struct relocated_struct_with_pointer *)42,
-      (struct relocated_struct_with_pointer *)21,
-  };
-  return set_output((__u64)__builtin_preserve_access_index(s.first));
-}
-
-SEC("uprobe") int pointer(void *ctx) { return pointer_global(); }
-
-__noinline int struct_flavors_global() {
-  struct relocated_struct_with_scalars s = {1, 2, 3};
-#ifndef TARGET
-  if (bpf_core_field_exists(s.a)) {
-    return set_output(__builtin_preserve_access_index(s.a));
-#else
-  if (bpf_core_field_exists(s.d)) {
-    return set_output(__builtin_preserve_access_index(s.d));
-#endif
-  } else {
-    return set_output(__builtin_preserve_access_index(s.c));
-  }
-}
-
-SEC("uprobe") int struct_flavors(void *ctx) { return struct_flavors_global(); }
-
-enum relocated_enum_unsigned_32 {
-  U32_VAL =
-#ifndef TARGET
-      0xAAAAAAAA
-#else
-      0xBBBBBBBB
-#endif
-};
-
-__noinline int enum_unsigned_32_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_unsigned_32, U32_VAL));
-}
-
-SEC("uprobe") int enum_unsigned_32(void *ctx) {
-  return enum_unsigned_32_global();
-}
-
-enum relocated_enum_unsigned_32_checked_variants {
-#ifndef TARGET
-  U32_VAL_A = 0xAAAAAAAA,
-#endif
-  U32_VAL_B = 0xBBBBBBBB,
-#ifdef TARGET
-  U32_VAL_C = 0xCCCCCCCC
-#endif
-};
-
-__noinline int enum_unsigned_32_checked_variants_global() {
-#ifndef TARGET
-  if (bpf_core_enum_value_exists(
-          enum relocated_enum_unsigned_32_checked_variants, U32_VAL_A)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_unsigned_32_checked_variants, U32_VAL_A));
-#else
-  if (bpf_core_enum_value_exists(
-          enum relocated_enum_unsigned_32_checked_variants, U32_VAL_C)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_unsigned_32_checked_variants, U32_VAL_C));
-#endif
-  } else {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_unsigned_32_checked_variants, U32_VAL_B));
-  }
-}
-
-SEC("uprobe") int enum_unsigned_32_checked_variants(void *ctx) {
-  return enum_unsigned_32_checked_variants_global();
-}
-
-enum relocated_enum_signed_32 {
-  S32_VAL =
-#ifndef TARGET
-      -0x7AAAAAAA
-#else
-      -0x7BBBBBBB
-#endif
-};
-
-__noinline int enum_signed_32_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_signed_32, S32_VAL));
-}
-
-SEC("uprobe") int enum_signed_32(void *ctx) { return enum_signed_32_global(); }
-
-enum relocated_enum_signed_32_checked_variants {
-#ifndef TARGET
-  S32_VAL_A = -0x7AAAAAAA,
-#endif
-  S32_VAL_B = -0x7BBBBBBB,
-#ifdef TARGET
-  S32_VAL_C = -0x7CCCCCCC
-#endif
-};
-
-__noinline int enum_signed_32_checked_variants_global() {
-#ifndef TARGET
-  if (bpf_core_enum_value_exists(enum relocated_enum_signed_32_checked_variants,
-                                 S32_VAL_A)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_signed_32_checked_variants, S32_VAL_A));
-#else
-  if (bpf_core_enum_value_exists(enum relocated_enum_signed_32_checked_variants,
-                                 S32_VAL_C)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_signed_32_checked_variants, S32_VAL_C));
-#endif
-  } else {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_signed_32_checked_variants, S32_VAL_B));
-  }
-}
-
-SEC("uprobe") int enum_signed_32_checked_variants(void *ctx) {
-  return enum_signed_32_checked_variants_global();
-}
-
-enum relocated_enum_unsigned_64 {
-  U64_VAL =
-#ifndef TARGET
-      0xAAAAAAAABBBBBBBB
-#else
-      0xCCCCCCCCDDDDDDDD
-#endif
-};
-
-__noinline int enum_unsigned_64_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_unsigned_64, U64_VAL));
-}
-
-SEC("uprobe") int enum_unsigned_64(void *ctx) {
-  return enum_unsigned_64_global();
-}
-
-enum relocated_enum_unsigned_64_checked_variants {
-#ifndef TARGET
-  U64_VAL_A = 0xAAAAAAAABBBBBBBB,
-#endif
-  U64_VAL_B = 0xCCCCCCCCDDDDDDDD,
-#ifdef TARGET
-  U64_VAL_C = 0xEEEEEEEEFFFFFFFF
-#endif
-};
-
-__noinline int enum_unsigned_64_checked_variants_global() {
-#ifndef TARGET
-  if (bpf_core_enum_value_exists(
-          enum relocated_enum_unsigned_64_checked_variants, U64_VAL_A)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_unsigned_64_checked_variants, U64_VAL_A));
-#else
-  if (bpf_core_enum_value_exists(
-          enum relocated_enum_unsigned_64_checked_variants, U64_VAL_C)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_unsigned_64_checked_variants, U64_VAL_C));
-#endif
-  } else {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_unsigned_64_checked_variants, U64_VAL_B));
-  }
-}
-
-SEC("uprobe") int enum_unsigned_64_checked_variants(void *ctx) {
-  return enum_unsigned_64_checked_variants_global();
-}
-
-enum relocated_enum_signed_64 {
-  S64_VAL =
-#ifndef TARGET
-      -0xAAAAAAABBBBBBBB
-#else
-      -0xCCCCCCCDDDDDDDD
-#endif
-};
-
-__noinline int enum_signed_64_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_signed_64, S64_VAL));
-}
-
-SEC("uprobe") int enum_signed_64(void *ctx) { return enum_signed_64_global(); }
-
-enum relocated_enum_signed_64_checked_variants {
-#ifndef TARGET
-  S64_VAL_A = -0xAAAAAAABBBBBBB,
-#endif
-  S64_VAL_B = -0xCCCCCCCDDDDDDD,
-#ifdef TARGET
-  S64_VAL_C = -0xEEEEEEEFFFFFFF
-#endif
-};
-
-__noinline int enum_signed_64_checked_variants_global() {
-#ifndef TARGET
-  if (bpf_core_enum_value_exists(enum relocated_enum_signed_64_checked_variants,
-                                 S64_VAL_A)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_signed_64_checked_variants, S64_VAL_A));
-#else
-  if (bpf_core_enum_value_exists(enum relocated_enum_signed_64_checked_variants,
-                                 S64_VAL_C)) {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_signed_64_checked_variants, S64_VAL_C));
-#endif
-  } else {
-    return set_output(bpf_core_enum_value(
-        enum relocated_enum_signed_64_checked_variants, S64_VAL_B));
-  }
-}
-
-SEC("uprobe") int enum_signed_64_checked_variants(void *ctx) {
-  return enum_signed_64_checked_variants_global();
-}

+ 19 - 0
test/integration-test/bpf/reloc.h

@@ -0,0 +1,19 @@
+// clang-format off
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_core_read.h>
+// clang-format on
+
+char _license[] SEC("license") = "GPL";
+
+struct {
+  __uint(type, BPF_MAP_TYPE_ARRAY);
+  __type(key, __u32);
+  __type(value, __u64);
+  __uint(max_entries, 1);
+} output_map SEC(".maps");
+
+long set_output(__u64 value) {
+  __u32 key = 0;
+  return bpf_map_update_elem(&output_map, &key, &value, BPF_ANY);
+}

+ 18 - 0
test/integration-test/bpf/struct_flavors_reloc.bpf.c

@@ -0,0 +1,18 @@
+#include "reloc.h"
+#include "struct_with_scalars.h"
+
+__noinline int struct_flavors_global() {
+  struct relocated_struct_with_scalars s = {1, 2, 3};
+#ifndef TARGET
+  if (bpf_core_field_exists(s.a)) {
+    return set_output(__builtin_preserve_access_index(s.a));
+#else
+  if (bpf_core_field_exists(s.d)) {
+    return set_output(__builtin_preserve_access_index(s.d));
+#endif
+  } else {
+    return set_output(__builtin_preserve_access_index(s.c));
+  }
+}
+
+SEC("uprobe") int program(void *ctx) { return struct_flavors_global(); }

+ 10 - 0
test/integration-test/bpf/struct_with_scalars.h

@@ -0,0 +1,10 @@
+struct relocated_struct_with_scalars {
+#ifndef TARGET
+  __u8 a;
+#endif
+  __u8 b;
+  __u8 c;
+#ifdef TARGET
+  __u8 d;
+#endif
+};

+ 39 - 9
test/integration-test/build.rs

@@ -2,7 +2,7 @@ use std::{
     env,
     ffi::OsString,
     fs,
-    path::PathBuf,
+    path::{Path, PathBuf},
     process::{Child, Command, Output, Stdio},
 };
 
@@ -66,10 +66,21 @@ fn main() -> Result<()> {
         ("iter.bpf.c", true),
         ("main.bpf.c", false),
         ("multimap-btf.bpf.c", false),
-        ("reloc.bpf.c", true),
+        ("enum_signed_32_checked_variants_reloc.bpf.c", true),
+        ("enum_signed_32_reloc.bpf.c", true),
+        ("enum_signed_64_checked_variants_reloc.bpf.c", true),
+        ("enum_signed_64_reloc.bpf.c", true),
+        ("enum_unsigned_32_checked_variants_reloc.bpf.c", true),
+        ("enum_unsigned_32_reloc.bpf.c", true),
+        ("enum_unsigned_64_checked_variants_reloc.bpf.c", true),
+        ("enum_unsigned_64_reloc.bpf.c", true),
+        ("field_reloc.bpf.c", true),
+        ("pointer_reloc.bpf.c", true),
+        ("struct_flavors_reloc.bpf.c", true),
         ("text_64_64_reloc.c", false),
         ("variables_reloc.bpf.c", false),
     ];
+    const C_BPF_HEADERS: &[&str] = &["reloc.h", "struct_with_scalars.h"];
 
     if build_integration_bpf {
         let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN")
@@ -126,13 +137,31 @@ fn main() -> Result<()> {
             cmd
         };
 
+        let rerun_if_changed = |path: &Path| {
+            use std::{io::Write as _, os::unix::ffi::OsStrExt as _};
+
+            let mut stdout = std::io::stdout().lock();
+            stdout.write_all("cargo:rerun-if-changed=".as_bytes())?;
+            stdout.write_all(path.as_os_str().as_bytes())?;
+            stdout.write_all("\n".as_bytes())?;
+
+            Ok(())
+        };
+
+        for hdr in C_BPF_HEADERS {
+            let hdr = bpf_dir.join(hdr);
+            let exists = hdr
+                .try_exists()
+                .with_context(|| format!("{}", hdr.display()))?;
+            anyhow::ensure!(exists, "{}", hdr.display());
+            rerun_if_changed(&hdr).with_context(|| format!("{}", hdr.display()))?;
+        }
+
         for (src, build_btf) in C_BPF {
             let dst = out_dir.join(src).with_extension("o");
             let src = bpf_dir.join(src);
-            {
-                let src = src.to_str().with_context(|| format!("{src:?}"))?;
-                println!("cargo:rerun-if-changed={src}");
-            }
+
+            rerun_if_changed(&src).with_context(|| format!("{}", src.display()))?;
 
             exec(clang().arg(&src).arg("-o").arg(&dst))?;
 
@@ -178,10 +207,11 @@ fn main() -> Result<()> {
     } else {
         for (src, build_btf) in C_BPF {
             let dst = out_dir.join(src).with_extension("o");
-            fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?;
+            fs::write(&dst, []).with_context(|| format!("failed to create {}", dst.display()))?;
             if *build_btf {
                 let dst = dst.with_extension("target.o");
-                fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?;
+                fs::write(&dst, [])
+                    .with_context(|| format!("failed to create {}", dst.display()))?;
             }
         }
 
@@ -191,7 +221,7 @@ fn main() -> Result<()> {
                 continue;
             }
             let dst = out_dir.join(name);
-            fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?;
+            fs::write(&dst, []).with_context(|| format!("failed to create {}", dst.display()))?;
         }
     }
     Ok(())

+ 24 - 2
test/integration-test/src/lib.rs

@@ -11,8 +11,30 @@ bpf_file!(
     ITER_TASK => "iter.bpf.o",
     MAIN => "main.bpf.o",
     MULTIMAP_BTF => "multimap-btf.bpf.o",
-    RELOC_BPF => "reloc.bpf.o",
-    RELOC_BTF => "reloc.bpf.target.o",
+
+    ENUM_SIGNED_32_RELOC_BPF => "enum_signed_32_reloc.bpf.o",
+    ENUM_SIGNED_32_RELOC_BTF => "enum_signed_32_reloc.bpf.target.o",
+    ENUM_SIGNED_32_CHECKED_VARIANTS_RELOC_BPF => "enum_signed_32_checked_variants_reloc.bpf.o",
+    ENUM_SIGNED_32_CHECKED_VARIANTS_RELOC_BTF => "enum_signed_32_checked_variants_reloc.bpf.target.o",
+    ENUM_SIGNED_64_RELOC_BPF => "enum_signed_64_reloc.bpf.o",
+    ENUM_SIGNED_64_RELOC_BTF => "enum_signed_64_reloc.bpf.target.o",
+    ENUM_SIGNED_64_CHECKED_VARIANTS_RELOC_BPF => "enum_signed_64_checked_variants_reloc.bpf.o",
+    ENUM_SIGNED_64_CHECKED_VARIANTS_RELOC_BTF => "enum_signed_64_checked_variants_reloc.bpf.target.o",
+    ENUM_UNSIGNED_32_RELOC_BPF => "enum_unsigned_32_reloc.bpf.o",
+    ENUM_UNSIGNED_32_RELOC_BTF => "enum_unsigned_32_reloc.bpf.target.o",
+    ENUM_UNSIGNED_32_CHECKED_VARIANTS_RELOC_BPF => "enum_unsigned_32_checked_variants_reloc.bpf.o",
+    ENUM_UNSIGNED_32_CHECKED_VARIANTS_RELOC_BTF => "enum_unsigned_32_checked_variants_reloc.bpf.target.o",
+    ENUM_UNSIGNED_64_RELOC_BPF => "enum_unsigned_64_reloc.bpf.o",
+    ENUM_UNSIGNED_64_RELOC_BTF => "enum_unsigned_64_reloc.bpf.target.o",
+    ENUM_UNSIGNED_64_CHECKED_VARIANTS_RELOC_BPF => "enum_unsigned_64_checked_variants_reloc.bpf.o",
+    ENUM_UNSIGNED_64_CHECKED_VARIANTS_RELOC_BTF => "enum_unsigned_64_checked_variants_reloc.bpf.target.o",
+    FIELD_RELOC_BPF => "field_reloc.bpf.o",
+    FIELD_RELOC_BTF => "field_reloc.bpf.target.o",
+    POINTER_RELOC_BPF => "pointer_reloc.bpf.o",
+    POINTER_RELOC_BTF => "pointer_reloc.bpf.target.o",
+    STRUCT_FLAVORS_RELOC_BPF => "struct_flavors_reloc.bpf.o",
+    STRUCT_FLAVORS_RELOC_BTF => "struct_flavors_reloc.bpf.target.o",
+
     TEXT_64_64_RELOC => "text_64_64_reloc.o",
     VARIABLES_RELOC => "variables_reloc.bpf.o",
 

+ 48 - 29
test/integration-test/src/tests/btf_relocations.rs

@@ -1,31 +1,51 @@
 use aya::{Btf, EbpfLoader, Endianness, maps::Array, programs::UProbe, util::KernelVersion};
 use test_case::test_case;
 
-#[test_case("enum_signed_32", false, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7AAAAAAAi32 as u64)]
-#[test_case("enum_signed_32", true, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7BBBBBBBi32 as u64)]
-#[test_case("enum_signed_32_checked_variants", false, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7AAAAAAAi32 as u64)]
-#[test_case("enum_signed_32_checked_variants", true, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7BBBBBBBi32 as u64)]
-#[test_case("enum_signed_64", false, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xAAAAAAABBBBBBBBi64 as u64)]
-#[test_case("enum_signed_64", true, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xCCCCCCCDDDDDDDDi64 as u64)]
-#[test_case("enum_signed_64_checked_variants", false, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xAAAAAAABBBBBBBi64 as u64)]
-#[test_case("enum_signed_64_checked_variants", true, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xCCCCCCCDDDDDDDi64 as u64)]
-#[test_case("enum_unsigned_32", false, None, 0xAAAAAAAA)]
-#[test_case("enum_unsigned_32", true, None, 0xBBBBBBBB)]
-#[test_case("enum_unsigned_32_checked_variants", false, None, 0xAAAAAAAA)]
-#[test_case("enum_unsigned_32_checked_variants", true, None, 0xBBBBBBBB)]
-#[test_case("enum_unsigned_64", false, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xAAAAAAAABBBBBBBB)]
-#[test_case("enum_unsigned_64", true, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xCCCCCCCCDDDDDDDD)]
-#[test_case("enum_unsigned_64_checked_variants", false, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xAAAAAAAABBBBBBBB)]
-#[test_case("enum_unsigned_64_checked_variants", true, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xCCCCCCCCDDDDDDDD)]
-#[test_case("field", false, None, 2)]
-#[test_case("field", true, None, 1)]
-#[test_case("pointer", false, None, 42)]
-#[test_case("pointer", true, None, 21)]
-#[test_case("struct_flavors", false, None, 1)]
-#[test_case("struct_flavors", true, None, 2)]
+#[test_case(crate::ENUM_SIGNED_32_RELOC_BPF, None, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7AAAAAAAi32 as u64)]
+#[test_case(crate::ENUM_SIGNED_32_RELOC_BPF, Some(crate::ENUM_SIGNED_32_RELOC_BTF), Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7BBBBBBBi32 as u64)]
+#[test_case(crate::ENUM_SIGNED_32_CHECKED_VARIANTS_RELOC_BPF, None, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7AAAAAAAi32 as u64)]
+#[test_case(crate::ENUM_SIGNED_32_CHECKED_VARIANTS_RELOC_BPF, Some(crate::ENUM_SIGNED_32_CHECKED_VARIANTS_RELOC_BTF), Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0x7BBBBBBBi32 as u64)]
+#[test_case(crate::ENUM_SIGNED_64_RELOC_BPF, None, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xAAAAAAABBBBBBBBi64 as u64)]
+#[test_case(crate::ENUM_SIGNED_64_RELOC_BPF, Some(crate::ENUM_SIGNED_64_RELOC_BTF), Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xCCCCCCCDDDDDDDDi64 as u64)]
+#[test_case(crate::ENUM_SIGNED_64_CHECKED_VARIANTS_RELOC_BPF, None, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xAAAAAAABBBBBBBi64 as u64)]
+#[test_case(crate::ENUM_SIGNED_64_CHECKED_VARIANTS_RELOC_BPF, Some(crate::ENUM_SIGNED_64_CHECKED_VARIANTS_RELOC_BTF), Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), -0xCCCCCCCDDDDDDDi64 as u64)]
+#[test_case(crate::ENUM_UNSIGNED_32_RELOC_BPF, None, None, 0xAAAAAAAA)]
+#[test_case(
+    crate::ENUM_UNSIGNED_32_RELOC_BPF,
+    Some(crate::ENUM_UNSIGNED_32_RELOC_BTF),
+    None,
+    0xBBBBBBBB
+)]
+#[test_case(
+    crate::ENUM_UNSIGNED_32_CHECKED_VARIANTS_RELOC_BPF,
+    None,
+    None,
+    0xAAAAAAAA
+)]
+#[test_case(
+    crate::ENUM_UNSIGNED_32_CHECKED_VARIANTS_RELOC_BPF,
+    Some(crate::ENUM_UNSIGNED_32_CHECKED_VARIANTS_RELOC_BTF),
+    None,
+    0xBBBBBBBB
+)]
+#[test_case(crate::ENUM_UNSIGNED_64_RELOC_BPF, None, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xAAAAAAAABBBBBBBB)]
+#[test_case(crate::ENUM_UNSIGNED_64_RELOC_BPF, Some(crate::ENUM_UNSIGNED_64_RELOC_BTF), Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xCCCCCCCCDDDDDDDD)]
+#[test_case(crate::ENUM_UNSIGNED_64_CHECKED_VARIANTS_RELOC_BPF, None, Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xAAAAAAAABBBBBBBB)]
+#[test_case(crate::ENUM_UNSIGNED_64_CHECKED_VARIANTS_RELOC_BPF, Some(crate::ENUM_UNSIGNED_64_CHECKED_VARIANTS_RELOC_BTF), Some((KernelVersion::new(6, 0, 0), "https://github.com/torvalds/linux/commit/6089fb3")), 0xCCCCCCCCDDDDDDDD)]
+#[test_case(crate::FIELD_RELOC_BPF, None, None, 2)]
+#[test_case(crate::FIELD_RELOC_BPF, Some(crate::FIELD_RELOC_BTF), None, 1)]
+#[test_case(crate::POINTER_RELOC_BPF, None, None, 42)]
+#[test_case(crate::POINTER_RELOC_BPF, Some(crate::POINTER_RELOC_BTF), None, 21)]
+#[test_case(crate::STRUCT_FLAVORS_RELOC_BPF, None, None, 1)]
+#[test_case(
+    crate::STRUCT_FLAVORS_RELOC_BPF,
+    Some(crate::STRUCT_FLAVORS_RELOC_BTF),
+    None,
+    2
+)]
 fn relocation_tests(
-    program: &str,
-    with_relocations: bool,
+    bpf: &[u8],
+    btf: Option<&[u8]>,
     required_kernel_version: Option<(KernelVersion, &str)>,
     expected: u64,
 ) {
@@ -33,20 +53,19 @@ fn relocation_tests(
         let current_kernel_version = KernelVersion::current().unwrap();
         if current_kernel_version < required_kernel_version {
             eprintln!(
-                "skipping test on kernel {current_kernel_version:?}, support for {program} was added in {required_kernel_version:?}; see {commit}"
+                "skipping test on kernel {current_kernel_version:?}, support was added in {required_kernel_version:?}; see {commit}"
             );
             return;
         }
     }
     let mut bpf = EbpfLoader::new()
         .btf(
-            with_relocations
-                .then(|| Btf::parse(crate::RELOC_BTF, Endianness::default()).unwrap())
+            btf.map(|btf| Btf::parse(btf, Endianness::default()).unwrap())
                 .as_ref(),
         )
-        .load(crate::RELOC_BPF)
+        .load(bpf)
         .unwrap();
-    let program: &mut UProbe = bpf.program_mut(program).unwrap().try_into().unwrap();
+    let program: &mut UProbe = bpf.program_mut("program").unwrap().try_into().unwrap();
     program.load().unwrap();
     program
         .attach(