integration-test: De-duplicate BTF relocation test

pull/727/head
Tamir Duberstein 1 year ago
parent 71bc3ea0b5
commit 54c90ec72c
No known key found for this signature in database

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

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

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

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

Loading…
Cancel
Save