Sfoglia il codice sorgente

integration-test: De-duplicate BTF relocation test

Tamir Duberstein 1 anno fa
parent
commit
54c90ec72c

+ 55 - 12
test/integration-test/bpf/reloc.bpf.c

@@ -4,7 +4,7 @@
 #include <bpf/bpf_core_read.h>
 // clang-format on
 
-char _license[] __attribute__((section("license"), used)) = "GPL";
+char _license[] SEC("license") = "GPL";
 
 struct {
   __uint(type, BPF_MAP_TYPE_ARRAY);
@@ -19,12 +19,17 @@ long set_output(__u64 value) {
 }
 
 struct relocated_struct_with_scalars {
+#ifndef TARGET
   __u8 a;
+#endif
   __u8 b;
   __u8 c;
+#ifdef TARGET
+  __u8 d;
+#endif
 };
 
-__attribute__((noinline)) int field_global() {
+__noinline int field_global() {
   struct relocated_struct_with_scalars s = {1, 2, 3};
   return set_output(__builtin_preserve_access_index(s.b));
 }
@@ -32,11 +37,16 @@ __attribute__((noinline)) int field_global() {
 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
 };
 
-__attribute__((noinline)) int pointer_global() {
+__noinline int pointer_global() {
   struct relocated_struct_with_pointer s = {
       (struct relocated_struct_with_pointer *)42,
       (struct relocated_struct_with_pointer *)21,
@@ -46,10 +56,15 @@ __attribute__((noinline)) int pointer_global() {
 
 SEC("uprobe") int pointer(void *ctx) { return pointer_global(); }
 
-__attribute__((noinline)) int struct_flavors_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));
   }
@@ -57,9 +72,16 @@ __attribute__((noinline)) int struct_flavors_global() {
 
 SEC("uprobe") int struct_flavors(void *ctx) { return struct_flavors_global(); }
 
-enum relocated_enum_unsigned_32 { U32_VAL = 0xAAAAAAAA };
+enum relocated_enum_unsigned_32 {
+  U32_VAL =
+#ifndef TARGET
+      0xAAAAAAAA
+#else
+      0xBBBBBBBB
+#endif
+};
 
-__attribute__((noinline)) int enum_unsigned_32_global() {
+__noinline int enum_unsigned_32_global() {
   return set_output(
       bpf_core_enum_value(enum relocated_enum_unsigned_32, U32_VAL));
 }
@@ -68,18 +90,32 @@ SEC("uprobe") int enum_unsigned_32(void *ctx) {
   return enum_unsigned_32_global();
 }
 
-enum relocated_enum_signed_32 { S32_VAL = -0x7AAAAAAA };
+enum relocated_enum_signed_32 {
+  S32_VAL =
+#ifndef TARGET
+      -0x7AAAAAAA
+#else
+      -0x7BBBBBBB
+#endif
+};
 
-__attribute__((noinline)) int enum_signed_32_global() {
+__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_unsigned_64 { U64_VAL = 0xAAAAAAAABBBBBBBB };
+enum relocated_enum_unsigned_64 {
+  U64_VAL =
+#ifndef TARGET
+      0xAAAAAAAABBBBBBBB
+#else
+      0xCCCCCCCCDDDDDDDD
+#endif
+};
 
-__attribute__((noinline)) int enum_unsigned_64_global() {
+__noinline int enum_unsigned_64_global() {
   return set_output(
       bpf_core_enum_value(enum relocated_enum_unsigned_64, U64_VAL));
 }
@@ -88,9 +124,16 @@ SEC("uprobe") int enum_unsigned_64(void *ctx) {
   return enum_unsigned_64_global();
 }
 
-enum relocated_enum_signed_64 { S64_VAL = -0xAAAAAAABBBBBBBB };
+enum relocated_enum_signed_64 {
+  S64_VAL =
+#ifndef TARGET
+      -0xAAAAAAABBBBBBBB
+#else
+      -0xCCCCCCCDDDDDDDD
+#endif
+};
 
-__attribute__((noinline)) int enum_signed_64_global() {
+__noinline int enum_signed_64_global() {
   return set_output(
       bpf_core_enum_value(enum relocated_enum_signed_64, S64_VAL));
 }

+ 0 - 89
test/integration-test/bpf/reloc.btf.c

@@ -1,89 +0,0 @@
-// clang-format off
-#include <vmlinux.h>
-#include <bpf/bpf_helpers.h>
-#include <bpf/bpf_core_read.h>
-// clang-format on
-
-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 {
-  __u8 b;
-  __u8 c;
-  __u8 d;
-};
-
-__attribute__((noinline)) int field_global() {
-  struct relocated_struct_with_scalars s = {1, 2, 3};
-  return set_output(__builtin_preserve_access_index(s.b));
-}
-
-struct relocated_struct_with_pointer {
-  struct relocated_struct_with_pointer *second;
-  struct relocated_struct_with_pointer *first;
-};
-
-__attribute__((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));
-}
-
-__attribute__((noinline)) int struct_flavors_global() {
-  struct relocated_struct_with_scalars s = {1, 2, 3};
-  if (bpf_core_field_exists(s.b)) {
-    return set_output(__builtin_preserve_access_index(s.b));
-  } else {
-    return set_output(__builtin_preserve_access_index(s.c));
-  }
-}
-
-enum relocated_enum_unsigned_32 { U32_VAL = 0xBBBBBBBB };
-
-__attribute__((noinline)) int enum_unsigned_32_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_unsigned_32, U32_VAL));
-}
-
-enum relocated_enum_signed_32 { S32_VAL = -0x7BBBBBBB };
-
-__attribute__((noinline)) int enum_signed_32_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_signed_32, S32_VAL));
-}
-
-enum relocated_enum_unsigned_64 { U64_VAL = 0xCCCCCCCCDDDDDDDD };
-
-__attribute__((noinline)) int enum_unsigned_64_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_unsigned_64, U64_VAL));
-}
-
-enum relocated_enum_signed_64 { S64_VAL = -0xCCCCCCCDDDDDDDD };
-
-__attribute__((noinline)) int enum_signed_64_global() {
-  return set_output(
-      bpf_core_enum_value(enum relocated_enum_signed_64, S64_VAL));
-}
-
-// Avoids dead code elimination by the compiler.
-int main() {
-  field_global();
-  pointer_global();
-  struct_flavors_global();
-  enum_unsigned_32_global();
-  enum_signed_32_global();
-  enum_unsigned_64_global();
-  enum_signed_64_global();
-}

+ 50 - 50
test/integration-test/build.rs

@@ -64,20 +64,14 @@ fn main() {
         panic!("unsupported endian={:?}", endian)
     };
 
-    const C_BPF: &[(&str, &str)] = &[
-        ("ext.bpf.c", "ext.bpf.o"),
-        ("main.bpf.c", "main.bpf.o"),
-        ("multimap-btf.bpf.c", "multimap-btf.bpf.o"),
-        ("reloc.bpf.c", "reloc.bpf.o"),
-        ("text_64_64_reloc.c", "text_64_64_reloc.o"),
+    const C_BPF: &[(&str, bool)] = &[
+        ("ext.bpf.c", false),
+        ("main.bpf.c", false),
+        ("multimap-btf.bpf.c", false),
+        ("reloc.bpf.c", true),
+        ("text_64_64_reloc.c", false),
     ];
 
-    let c_bpf = C_BPF.iter().map(|(src, dst)| (src, out_dir.join(dst)));
-
-    const C_BTF: &[(&str, &str)] = &[("reloc.btf.c", "reloc.btf.o")];
-
-    let c_btf = C_BTF.iter().map(|(src, dst)| (src, out_dir.join(dst)));
-
     if build_integration_bpf {
         let libbpf_dir = manifest_dir
             .parent()
@@ -137,46 +131,47 @@ fn main() {
             cmd
         };
 
-        for (src, dst) in c_bpf {
-            let src = bpf_dir.join(src);
-            println!("cargo:rerun-if-changed={}", src.to_str().unwrap());
-
-            exec(clang().arg(src).arg("-o").arg(dst)).unwrap();
-        }
-
-        for (src, dst) in c_btf {
+        for (src, build_btf) in C_BPF {
+            let dst = out_dir.join(src).with_extension("o");
             let src = bpf_dir.join(src);
             println!("cargo:rerun-if-changed={}", src.to_str().unwrap());
 
-            let mut cmd = clang();
-            let mut child = cmd
-                .arg(src)
-                .args(["-o", "-"])
-                .stdout(Stdio::piped())
-                .spawn()
-                .unwrap_or_else(|err| panic!("failed to spawn {cmd:?}: {err}"));
-
-            let Child { stdout, .. } = &mut child;
-            let stdout = stdout.take().unwrap();
-
-            let mut output = OsString::new();
-            output.push(".BTF=");
-            output.push(dst);
-            exec(
-                // NB: objcopy doesn't support reading from stdin, so we have to use llvm-objcopy.
-                Command::new("llvm-objcopy")
-                    .arg("--dump-section")
-                    .arg(output)
-                    .arg("-")
-                    .stdin(stdout),
-            )
-            .unwrap();
-
-            let output = child
-                .wait_with_output()
-                .unwrap_or_else(|err| panic!("failed to wait for {cmd:?}: {err}"));
-            let Output { status, .. } = &output;
-            assert_eq!(status.code(), Some(0), "{cmd:?} failed: {output:?}");
+            exec(clang().arg(&src).arg("-o").arg(&dst)).unwrap();
+
+            if *build_btf {
+                let mut cmd = clang();
+                let mut child = cmd
+                    .arg("-DTARGET")
+                    .arg(&src)
+                    .args(["-o", "-"])
+                    .stdout(Stdio::piped())
+                    .spawn()
+                    .unwrap_or_else(|err| panic!("failed to spawn {cmd:?}: {err}"));
+
+                let Child { stdout, .. } = &mut child;
+                let stdout = stdout.take().unwrap();
+
+                let dst = dst.with_extension("target.o");
+
+                let mut output = OsString::new();
+                output.push(".BTF=");
+                output.push(dst);
+                exec(
+                    // NB: objcopy doesn't support reading from stdin, so we have to use llvm-objcopy.
+                    Command::new("llvm-objcopy")
+                        .arg("--dump-section")
+                        .arg(output)
+                        .arg("-")
+                        .stdin(stdout),
+                )
+                .unwrap();
+
+                let output = child
+                    .wait_with_output()
+                    .unwrap_or_else(|err| panic!("failed to wait for {cmd:?}: {err}"));
+                let Output { status, .. } = &output;
+                assert_eq!(status.code(), Some(0), "{cmd:?} failed: {output:?}");
+            }
         }
 
         let target = format!("{target}-unknown-none");
@@ -268,8 +263,13 @@ fn main() {
                 .unwrap_or_else(|err| panic!("failed to copy {binary:?} to {dst:?}: {err}"));
         }
     } else {
-        for (_src, dst) in c_bpf.chain(c_btf) {
+        for (src, build_btf) in C_BPF {
+            let dst = out_dir.join(src).with_extension("o");
             fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}"));
+            if *build_btf {
+                let dst = dst.with_extension("target.o");
+                fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}"));
+            }
         }
 
         let Package { targets, .. } = integration_ebpf_package;

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

@@ -5,7 +5,8 @@ pub const MAIN: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/main.b
 pub const MULTIMAP_BTF: &[u8] =
     include_bytes_aligned!(concat!(env!("OUT_DIR"), "/multimap-btf.bpf.o"));
 pub const RELOC_BPF: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/reloc.bpf.o"));
-pub const RELOC_BTF: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/reloc.btf.o"));
+pub const RELOC_BTF: &[u8] =
+    include_bytes_aligned!(concat!(env!("OUT_DIR"), "/reloc.bpf.target.o"));
 pub const TEXT_64_64_RELOC: &[u8] =
     include_bytes_aligned!(concat!(env!("OUT_DIR"), "/text_64_64_reloc.o"));