diff --git a/test/integration-test/bpf/enum_signed_32_checked_variants_reloc.bpf.c b/test/integration-test/bpf/enum_signed_32_checked_variants_reloc.bpf.c new file mode 100644 index 00000000..1b223c6e --- /dev/null +++ b/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(); +} diff --git a/test/integration-test/bpf/enum_signed_32_reloc.bpf.c b/test/integration-test/bpf/enum_signed_32_reloc.bpf.c new file mode 100644 index 00000000..5bec3a08 --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/enum_signed_64_checked_variants_reloc.bpf.c b/test/integration-test/bpf/enum_signed_64_checked_variants_reloc.bpf.c new file mode 100644 index 00000000..ef809bab --- /dev/null +++ b/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(); +} diff --git a/test/integration-test/bpf/enum_signed_64_reloc.bpf.c b/test/integration-test/bpf/enum_signed_64_reloc.bpf.c new file mode 100644 index 00000000..2cfc5668 --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/enum_unsigned_32_checked_variants_reloc.bpf.c b/test/integration-test/bpf/enum_unsigned_32_checked_variants_reloc.bpf.c new file mode 100644 index 00000000..9c1ddb93 --- /dev/null +++ b/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(); +} diff --git a/test/integration-test/bpf/enum_unsigned_32_reloc.bpf.c b/test/integration-test/bpf/enum_unsigned_32_reloc.bpf.c new file mode 100644 index 00000000..7adbef61 --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/enum_unsigned_64_checked_variants_reloc.bpf.c b/test/integration-test/bpf/enum_unsigned_64_checked_variants_reloc.bpf.c new file mode 100644 index 00000000..09c39beb --- /dev/null +++ b/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(); +} diff --git a/test/integration-test/bpf/enum_unsigned_64_reloc.bpf.c b/test/integration-test/bpf/enum_unsigned_64_reloc.bpf.c new file mode 100644 index 00000000..05d4643e --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/field_reloc.bpf.c b/test/integration-test/bpf/field_reloc.bpf.c new file mode 100644 index 00000000..7bbc9847 --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/pointer_reloc.bpf.c b/test/integration-test/bpf/pointer_reloc.bpf.c new file mode 100644 index 00000000..1193222b --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/reloc.bpf.c b/test/integration-test/bpf/reloc.bpf.c deleted file mode 100644 index f8104bbb..00000000 --- a/test/integration-test/bpf/reloc.bpf.c +++ /dev/null @@ -1,269 +0,0 @@ -// clang-format off -#include -#include -#include -// 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(); -} diff --git a/test/integration-test/bpf/reloc.h b/test/integration-test/bpf/reloc.h new file mode 100644 index 00000000..c471c6ca --- /dev/null +++ b/test/integration-test/bpf/reloc.h @@ -0,0 +1,19 @@ +// clang-format off +#include +#include +#include +// 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); +} diff --git a/test/integration-test/bpf/struct_flavors_reloc.bpf.c b/test/integration-test/bpf/struct_flavors_reloc.bpf.c new file mode 100644 index 00000000..39d0c96e --- /dev/null +++ b/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(); } diff --git a/test/integration-test/bpf/struct_with_scalars.h b/test/integration-test/bpf/struct_with_scalars.h new file mode 100644 index 00000000..185e756b --- /dev/null +++ b/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 +}; diff --git a/test/integration-test/build.rs b/test/integration-test/build.rs index a9a36219..612df7e2 100644 --- a/test/integration-test/build.rs +++ b/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(()) diff --git a/test/integration-test/src/lib.rs b/test/integration-test/src/lib.rs index ea2df7d4..f7cc30c6 100644 --- a/test/integration-test/src/lib.rs +++ b/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", diff --git a/test/integration-test/src/tests/btf_relocations.rs b/test/integration-test/src/tests/btf_relocations.rs index 4d3b6845..68dac8cb 100644 --- a/test/integration-test/src/tests/btf_relocations.rs +++ b/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(