selftests/bpf: add CO-RE relocs enum/ptr/func_proto tests
Test CO-RE relocation handling of ints, enums, pointers, func protos, etc. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
20a9ad2e71
commit
d9db355030
|
@ -81,6 +81,32 @@
|
|||
.fails = true, \
|
||||
}
|
||||
|
||||
#define PRIMITIVES_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \
|
||||
.a = 1, \
|
||||
.b = 2, \
|
||||
.c = 3, \
|
||||
.d = (void *)4, \
|
||||
.f = (void *)5, \
|
||||
}
|
||||
|
||||
#define PRIMITIVES_CASE_COMMON(name) \
|
||||
.case_name = #name, \
|
||||
.bpf_obj_file = "test_core_reloc_primitives.o", \
|
||||
.btf_src_file = "btf__core_reloc_" #name ".o"
|
||||
|
||||
#define PRIMITIVES_CASE(name) { \
|
||||
PRIMITIVES_CASE_COMMON(name), \
|
||||
.input = PRIMITIVES_DATA(core_reloc_##name), \
|
||||
.input_len = sizeof(struct core_reloc_##name), \
|
||||
.output = PRIMITIVES_DATA(core_reloc_primitives), \
|
||||
.output_len = sizeof(struct core_reloc_primitives), \
|
||||
}
|
||||
|
||||
#define PRIMITIVES_ERR_CASE(name) { \
|
||||
PRIMITIVES_CASE_COMMON(name), \
|
||||
.fails = true, \
|
||||
}
|
||||
|
||||
struct core_reloc_test_case {
|
||||
const char *case_name;
|
||||
const char *bpf_obj_file;
|
||||
|
@ -137,6 +163,16 @@ static struct core_reloc_test_case test_cases[] = {
|
|||
ARRAYS_ERR_CASE(arrays___err_non_array),
|
||||
ARRAYS_ERR_CASE(arrays___err_wrong_val_type1),
|
||||
ARRAYS_ERR_CASE(arrays___err_wrong_val_type2),
|
||||
|
||||
/* enum/ptr/int handling scenarios */
|
||||
PRIMITIVES_CASE(primitives),
|
||||
PRIMITIVES_CASE(primitives___diff_enum_def),
|
||||
PRIMITIVES_CASE(primitives___diff_func_proto),
|
||||
PRIMITIVES_CASE(primitives___diff_ptr_type),
|
||||
|
||||
PRIMITIVES_ERR_CASE(primitives___err_non_enum),
|
||||
PRIMITIVES_ERR_CASE(primitives___err_non_int),
|
||||
PRIMITIVES_ERR_CASE(primitives___err_non_ptr),
|
||||
};
|
||||
|
||||
struct data {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives x) {}
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives___diff_enum_def x) {}
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives___diff_func_proto x) {}
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives___diff_ptr_type x) {}
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives___err_non_enum x) {}
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives___err_non_int x) {}
|
|
@ -0,0 +1,3 @@
|
|||
#include "core_reloc_types.h"
|
||||
|
||||
void f(struct core_reloc_primitives___err_non_ptr x) {}
|
|
@ -387,3 +387,70 @@ struct core_reloc_arrays___err_wrong_val_type2 {
|
|||
int c[3]; /* value is not a struct */
|
||||
struct core_reloc_arrays_substruct d[1][2];
|
||||
};
|
||||
|
||||
/*
|
||||
* PRIMITIVES
|
||||
*/
|
||||
enum core_reloc_primitives_enum {
|
||||
A = 0,
|
||||
B = 1,
|
||||
};
|
||||
|
||||
struct core_reloc_primitives {
|
||||
char a;
|
||||
int b;
|
||||
enum core_reloc_primitives_enum c;
|
||||
void *d;
|
||||
int (*f)(const char *);
|
||||
};
|
||||
|
||||
struct core_reloc_primitives___diff_enum_def {
|
||||
char a;
|
||||
int b;
|
||||
void *d;
|
||||
int (*f)(const char *);
|
||||
enum {
|
||||
X = 100,
|
||||
Y = 200,
|
||||
} c; /* inline enum def with differing set of values */
|
||||
};
|
||||
|
||||
struct core_reloc_primitives___diff_func_proto {
|
||||
void (*f)(int); /* incompatible function prototype */
|
||||
void *d;
|
||||
enum core_reloc_primitives_enum c;
|
||||
int b;
|
||||
char a;
|
||||
};
|
||||
|
||||
struct core_reloc_primitives___diff_ptr_type {
|
||||
const char * const d; /* different pointee type + modifiers */
|
||||
char a;
|
||||
int b;
|
||||
enum core_reloc_primitives_enum c;
|
||||
int (*f)(const char *);
|
||||
};
|
||||
|
||||
struct core_reloc_primitives___err_non_enum {
|
||||
char a[1];
|
||||
int b;
|
||||
int c; /* int instead of enum */
|
||||
void *d;
|
||||
int (*f)(const char *);
|
||||
};
|
||||
|
||||
struct core_reloc_primitives___err_non_int {
|
||||
char a[1];
|
||||
int *b; /* ptr instead of int */
|
||||
enum core_reloc_primitives_enum c;
|
||||
void *d;
|
||||
int (*f)(const char *);
|
||||
};
|
||||
|
||||
struct core_reloc_primitives___err_non_ptr {
|
||||
char a[1];
|
||||
int b;
|
||||
enum core_reloc_primitives_enum c;
|
||||
int d; /* int instead of ptr */
|
||||
int (*f)(const char *);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// 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;
|
||||
|
||||
enum core_reloc_primitives_enum {
|
||||
A = 0,
|
||||
B = 1,
|
||||
};
|
||||
|
||||
struct core_reloc_primitives {
|
||||
char a;
|
||||
int b;
|
||||
enum core_reloc_primitives_enum c;
|
||||
void *d;
|
||||
int (*f)(const char *);
|
||||
};
|
||||
|
||||
SEC("raw_tracepoint/sys_enter")
|
||||
int test_core_primitives(void *ctx)
|
||||
{
|
||||
struct core_reloc_primitives *in = (void *)&data.in;
|
||||
struct core_reloc_primitives *out = (void *)&data.out;
|
||||
|
||||
if (BPF_CORE_READ(&out->a, &in->a) ||
|
||||
BPF_CORE_READ(&out->b, &in->b) ||
|
||||
BPF_CORE_READ(&out->c, &in->c) ||
|
||||
BPF_CORE_READ(&out->d, &in->d) ||
|
||||
BPF_CORE_READ(&out->f, &in->f))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue