selftests/bpf: add CO-RE relocs misc tests
authorAndrii Nakryiko <andriin@fb.com>
Wed, 7 Aug 2019 21:40:01 +0000 (14:40 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 7 Aug 2019 21:43:49 +0000 (14:43 -0700)
Add tests validating few edge-cases of capturing offset relocations.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/core_reloc.c
tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/core_reloc_types.h
tools/testing/selftests/bpf/progs/test_core_reloc_misc.c [new file with mode: 0644]

index 251ef8c..f3863f9 100644 (file)
@@ -260,6 +260,25 @@ static struct core_reloc_test_case test_cases[] = {
        INTS_ERR_CASE(ints___err_wrong_sz_16),
        INTS_ERR_CASE(ints___err_wrong_sz_32),
        INTS_ERR_CASE(ints___err_wrong_sz_64),
+       
+       /* validate edge cases of capturing relocations */
+       {
+               .case_name = "misc",
+               .bpf_obj_file = "test_core_reloc_misc.o",
+               .btf_src_file = "btf__core_reloc_misc.o",
+               .input = (const char *)&(struct core_reloc_misc_extensible[]){
+                       { .a = 1 },
+                       { .a = 2 }, /* not read */
+                       { .a = 3 },
+               },
+               .input_len = 4 * sizeof(int),
+               .output = STRUCT_TO_CHAR_PTR(core_reloc_misc_output) {
+                       .a = 1,
+                       .b = 1,
+                       .c = 0, /* BUG in clang, should be 3 */
+               },
+               .output_len = sizeof(struct core_reloc_misc_output),
+       },
 };
 
 struct data {
diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c
new file mode 100644 (file)
index 0000000..ed9ad8b
--- /dev/null
@@ -0,0 +1,5 @@
+#include "core_reloc_types.h"
+
+void f1(struct core_reloc_misc___a x) {}
+void f2(struct core_reloc_misc___b x) {}
+void f3(struct core_reloc_misc_extensible x) {}
index 5f3ebd4..10a252b 100644 (file)
@@ -640,3 +640,28 @@ struct core_reloc_ints___err_wrong_sz_64 {
        uint32_t        u64_field; /* not 64-bit anymore */
        int32_t         s64_field; /* not 64-bit anymore */
 };
+
+/*
+ * MISC
+ */
+struct core_reloc_misc_output {
+       int a, b, c;
+};
+
+struct core_reloc_misc___a {
+       int a1;
+       int a2;
+};
+
+struct core_reloc_misc___b {
+       int b1;
+       int b2;
+};
+
+/* this one extends core_reloc_misc_extensible struct from BPF prog */
+struct core_reloc_misc_extensible {
+       int a;
+       int b;
+       int c;
+       int d;
+};
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c
new file mode 100644 (file)
index 0000000..c59984b
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019 Facebook
+
+#include <linux/bpf.h>
+#include <stdint.h>
+#include "bpf_helpers.h"
+
+char _license[] SEC("license") = "GPL";
+
+static volatile struct data {
+       char in[256];
+       char out[256];
+} data;
+
+struct core_reloc_misc_output {
+       int a, b, c;
+};
+
+struct core_reloc_misc___a {
+       int a1;
+       int a2;
+};
+
+struct core_reloc_misc___b {
+       int b1;
+       int b2;
+};
+
+/* fixed two first members, can be extended with new fields */
+struct core_reloc_misc_extensible {
+       int a;
+       int b;
+};
+
+SEC("raw_tracepoint/sys_enter")
+int test_core_misc(void *ctx)
+{
+       struct core_reloc_misc___a *in_a = (void *)&data.in;
+       struct core_reloc_misc___b *in_b = (void *)&data.in;
+       struct core_reloc_misc_extensible *in_ext = (void *)&data.in;
+       struct core_reloc_misc_output *out = (void *)&data.out;
+
+       /* record two different relocations with the same accessor string */
+       if (BPF_CORE_READ(&out->a, &in_a->a1) ||        /* accessor: 0:0 */
+           BPF_CORE_READ(&out->b, &in_b->b1))          /* accessor: 0:0 */
+               return 1;
+
+       /* Validate relocations capture array-only accesses for structs with
+        * fixed header, but with potentially extendable tail. This will read
+        * first 4 bytes of 2nd element of in_ext array of potentially
+        * variably sized struct core_reloc_misc_extensible. */ 
+       if (BPF_CORE_READ(&out->c, &in_ext[2]))         /* accessor: 2 */
+               return 1;
+
+       return 0;
+}
+