Commit 0b163565 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann
Browse files

selftests/bpf: Add field size relocation tests



Add test verifying correctness and logic of field size relocation support in
libbpf.

Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20191101222810.1246166-6-andriin@fb.com
parent 8b1cb1c9
Loading
Loading
Loading
Loading
+34 −5
Original line number Diff line number Diff line
@@ -174,15 +174,11 @@
	.fails = true,							\
}

#define EXISTENCE_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {	\
	.a = 42,							\
}

#define EXISTENCE_CASE_COMMON(name)					\
	.case_name = #name,						\
	.bpf_obj_file = "test_core_reloc_existence.o",			\
	.btf_src_file = "btf__core_reloc_" #name ".o",			\
	.relaxed_core_relocs = true					\
	.relaxed_core_relocs = true

#define EXISTENCE_ERR_CASE(name) {					\
	EXISTENCE_CASE_COMMON(name),					\
@@ -225,6 +221,35 @@
	.fails = true,							\
}

#define SIZE_CASE_COMMON(name)						\
	.case_name = #name,						\
	.bpf_obj_file = "test_core_reloc_size.o",			\
	.btf_src_file = "btf__core_reloc_" #name ".o",			\
	.relaxed_core_relocs = true

#define SIZE_OUTPUT_DATA(type)						\
	STRUCT_TO_CHAR_PTR(core_reloc_size_output) {			\
		.int_sz = sizeof(((type *)0)->int_field),		\
		.struct_sz = sizeof(((type *)0)->struct_field),		\
		.union_sz = sizeof(((type *)0)->union_field),		\
		.arr_sz = sizeof(((type *)0)->arr_field),		\
		.arr_elem_sz = sizeof(((type *)0)->arr_field[0]),	\
		.ptr_sz = sizeof(((type *)0)->ptr_field),		\
		.enum_sz = sizeof(((type *)0)->enum_field),	\
	}

#define SIZE_CASE(name) {						\
	SIZE_CASE_COMMON(name),						\
	.input_len = 0,							\
	.output = SIZE_OUTPUT_DATA(struct core_reloc_##name),		\
	.output_len = sizeof(struct core_reloc_size_output),		\
}

#define SIZE_ERR_CASE(name) {						\
	SIZE_CASE_COMMON(name),						\
	.fails = true,							\
}

struct core_reloc_test_case {
	const char *case_name;
	const char *bpf_obj_file;
@@ -423,6 +448,10 @@ static struct core_reloc_test_case test_cases[] = {
		.ub2 = 0x0812345678FEDCBA,
	}),
	BITFIELDS_ERR_CASE(bitfields___err_too_big_bitfield),

	/* size relocation checks */
	SIZE_CASE(size),
	SIZE_CASE(size___diff_sz),
};

struct data {
+3 −0
Original line number Diff line number Diff line
#include "core_reloc_types.h"

void f(struct core_reloc_size x) {}
+3 −0
Original line number Diff line number Diff line
#include "core_reloc_types.h"

void f(struct core_reloc_size___diff_sz x) {}
+31 −0
Original line number Diff line number Diff line
@@ -734,3 +734,34 @@ struct core_reloc_bitfields___err_too_big_bitfield {
	uint32_t	u32;
	uint32_t	s32;
} __attribute__((packed)) ;

/*
 * SIZE
 */
struct core_reloc_size_output {
	int int_sz;
	int struct_sz;
	int union_sz;
	int arr_sz;
	int arr_elem_sz;
	int ptr_sz;
	int enum_sz;
};

struct core_reloc_size {
	int int_field;
	struct { int x; } struct_field;
	union { int x; } union_field;
	int arr_field[4];
	void *ptr_field;
	enum { VALUE = 123 } enum_field;
};

struct core_reloc_size___diff_sz {
	uint64_t int_field;
	struct { int x; int y; int z; } struct_field;
	union { int x; char bla[123]; } union_field;
	char arr_field[10];
	void *ptr_field;
	enum { OTHER_VALUE = 0xFFFFFFFFFFFFFFFF } enum_field;
};
+51 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Facebook

#include <linux/bpf.h>
#include <stdint.h>
#include "bpf_helpers.h"
#include "bpf_core_read.h"

char _license[] SEC("license") = "GPL";

static volatile struct data {
	char in[256];
	char out[256];
} data;

struct core_reloc_size_output {
	int int_sz;
	int struct_sz;
	int union_sz;
	int arr_sz;
	int arr_elem_sz;
	int ptr_sz;
	int enum_sz;
};

struct core_reloc_size {
	int int_field;
	struct { int x; } struct_field;
	union { int x; } union_field;
	int arr_field[4];
	void *ptr_field;
	enum { VALUE = 123 } enum_field;
};

SEC("raw_tracepoint/sys_enter")
int test_core_size(void *ctx)
{
	struct core_reloc_size *in = (void *)&data.in;
	struct core_reloc_size_output *out = (void *)&data.out;

	out->int_sz = bpf_core_field_size(in->int_field);
	out->struct_sz = bpf_core_field_size(in->struct_field);
	out->union_sz = bpf_core_field_size(in->union_field);
	out->arr_sz = bpf_core_field_size(in->arr_field);
	out->arr_elem_sz = bpf_core_field_size(in->arr_field[0]);
	out->ptr_sz = bpf_core_field_size(in->ptr_field);
	out->enum_sz = bpf_core_field_size(in->enum_field);

	return 0;
}