diff --git a/test/integration-test/bpf/reloc.bpf.c b/test/integration-test/bpf/reloc.bpf.c index cb15dfc3..609e504b 100644 --- a/test/integration-test/bpf/reloc.bpf.c +++ b/test/integration-test/bpf/reloc.bpf.c @@ -4,7 +4,7 @@ #include // 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)); } diff --git a/test/integration-test/bpf/reloc.btf.c b/test/integration-test/bpf/reloc.btf.c deleted file mode 100644 index d50cd943..00000000 --- a/test/integration-test/bpf/reloc.btf.c +++ /dev/null @@ -1,89 +0,0 @@ -// clang-format off -#include -#include -#include -// 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(); -} diff --git a/test/integration-test/build.rs b/test/integration-test/build.rs index c1a8992f..fec40483 100644 --- a/test/integration-test/build.rs +++ b/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; diff --git a/test/integration-test/src/lib.rs b/test/integration-test/src/lib.rs index 80cd0b1d..08911a4e 100644 --- a/test/integration-test/src/lib.rs +++ b/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"));