Commit d9db3550 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

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: default avatarAndrii Nakryiko <andriin@fb.com>
Acked-by: default avatarSong Liu <songliubraving@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 20a9ad2e
......@@ -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 {
......
#include "core_reloc_types.h"
void f(struct core_reloc_primitives x) {}
#include "core_reloc_types.h"
void f(struct core_reloc_primitives___diff_enum_def x) {}
#include "core_reloc_types.h"
void f(struct core_reloc_primitives___diff_func_proto x) {}
#include "core_reloc_types.h"
void f(struct core_reloc_primitives___diff_ptr_type x) {}
#include "core_reloc_types.h"
void f(struct core_reloc_primitives___err_non_enum x) {}
#include "core_reloc_types.h"
void f(struct core_reloc_primitives___err_non_int x) {}
#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 *);
};
// 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment