Split relocation tests into multiple files

This avoids requiring kernel support for all types of relocations when
testing a specific type.
reviewable/pr1251/r21
Tamir Duberstein 2 weeks ago
parent c8e9037ca6
commit 630a767117

@ -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();
}

@ -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(); }

@ -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();
}

@ -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(); }

@ -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();
}

@ -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(); }

@ -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();
}

@ -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(); }

@ -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(); }

@ -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(); }

@ -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();
}

@ -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);
}

@ -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(); }

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

@ -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(())

@ -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",

@ -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(

Loading…
Cancel
Save