Commit 5705d705 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

selftests/bpf: Correct various core_reloc 64-bit assumptions



Ensure that types are memory layout- and field alignment-compatible regardless
of 32/64-bitness mix of libbpf and BPF architecture.

Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200813204945.1020225-8-andriin@fb.com
parent 4c01925f
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@
		.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),		\
		.ptr_sz = 8, /* always 8-byte pointer for BPF */	\
		.enum_sz = sizeof(((type *)0)->enum_field),		\
	}

@@ -432,20 +432,20 @@ static struct core_reloc_test_case test_cases[] = {
		.sb4 = -1,
		.sb20 = -0x17654321,
		.u32 = 0xBEEF,
		.s32 = -0x3FEDCBA987654321,
		.s32 = -0x3FEDCBA987654321LL,
	}),
	BITFIELDS_CASE(bitfields___bitfield_vs_int, {
		.ub1 = 0xFEDCBA9876543210,
		.ub1 = 0xFEDCBA9876543210LL,
		.ub2 = 0xA6,
		.ub7 = -0x7EDCBA987654321,
		.sb4 = -0x6123456789ABCDE,
		.sb20 = 0xD00D,
		.ub7 = -0x7EDCBA987654321LL,
		.sb4 = -0x6123456789ABCDELL,
		.sb20 = 0xD00DLL,
		.u32 = -0x76543,
		.s32 = 0x0ADEADBEEFBADB0B,
		.s32 = 0x0ADEADBEEFBADB0BLL,
	}),
	BITFIELDS_CASE(bitfields___just_big_enough, {
		.ub1 = 0xF,
		.ub2 = 0x0812345678FEDCBA,
		.ub1 = 0xFLL,
		.ub2 = 0x0812345678FEDCBALL,
	}),
	BITFIELDS_ERR_CASE(bitfields___err_too_big_bitfield),

+37 −32
Original line number Diff line number Diff line
#include <stdint.h>
#include <stdbool.h>

void preserce_ptr_sz_fn(long x) {}

#define __bpf_aligned __attribute__((aligned(8)))

/*
 * KERNEL
 */
@@ -444,51 +449,51 @@ struct core_reloc_primitives {
	char a;
	int b;
	enum core_reloc_primitives_enum c;
	void *d;
	int (*f)(const char *);
	void *d __bpf_aligned;
	int (*f)(const char *) __bpf_aligned;
};

struct core_reloc_primitives___diff_enum_def {
	char a;
	int b;
	void *d;
	int (*f)(const char *);
	void *d __bpf_aligned;
	int (*f)(const char *) __bpf_aligned;
	enum {
		X = 100,
		Y = 200,
	} c; /* inline enum def with differing set of values */
	} c __bpf_aligned; /* 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;
	void (*f)(int) __bpf_aligned; /* incompatible function prototype */
	void *d __bpf_aligned;
	enum core_reloc_primitives_enum c __bpf_aligned;
	int b;
	char a;
};

struct core_reloc_primitives___diff_ptr_type {
	const char * const d; /* different pointee type + modifiers */
	char a;
	const char * const d __bpf_aligned; /* different pointee type + modifiers */
	char a __bpf_aligned;
	int b;
	enum core_reloc_primitives_enum c;
	int (*f)(const char *);
	int (*f)(const char *) __bpf_aligned;
};

struct core_reloc_primitives___err_non_enum {
	char a[1];
	int b;
	int c; /* int instead of enum */
	void *d;
	int (*f)(const char *);
	void *d __bpf_aligned;
	int (*f)(const char *) __bpf_aligned;
};

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 *);
	int *b __bpf_aligned; /* ptr instead of int */
	enum core_reloc_primitives_enum c __bpf_aligned;
	void *d __bpf_aligned;
	int (*f)(const char *) __bpf_aligned;
};

struct core_reloc_primitives___err_non_ptr {
@@ -496,7 +501,7 @@ struct core_reloc_primitives___err_non_ptr {
	int b;
	enum core_reloc_primitives_enum c;
	int d; /* int instead of ptr */
	int (*f)(const char *);
	int (*f)(const char *) __bpf_aligned;
};

/*
@@ -507,7 +512,7 @@ struct core_reloc_mods_output {
};

typedef const int int_t;
typedef const char *char_ptr_t;
typedef const char *char_ptr_t __bpf_aligned;
typedef const int arr_t[7];

struct core_reloc_mods_substruct {
@@ -523,9 +528,9 @@ typedef struct {
struct core_reloc_mods {
	int a;
	int_t b;
	char *c;
	char *c __bpf_aligned;
	char_ptr_t d;
	int e[3];
	int e[3] __bpf_aligned;
	arr_t f;
	struct core_reloc_mods_substruct g;
	core_reloc_mods_substruct_t h;
@@ -535,9 +540,9 @@ struct core_reloc_mods {
struct core_reloc_mods___mod_swap {
	int b;
	int_t a;
	char *d;
	char *d __bpf_aligned;
	char_ptr_t c;
	int f[3];
	int f[3] __bpf_aligned;
	arr_t e;
	struct {
		int y;
@@ -555,7 +560,7 @@ typedef arr1_t arr2_t;
typedef arr2_t arr3_t;
typedef arr3_t arr4_t;

typedef const char * const volatile fancy_char_ptr_t;
typedef const char * const volatile fancy_char_ptr_t __bpf_aligned;

typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt;

@@ -567,7 +572,7 @@ struct core_reloc_mods___typedefs {
	arr4_t e;
	fancy_char_ptr_t d;
	fancy_char_ptr_t c;
	int3_t b;
	int3_t b __bpf_aligned;
	int3_t a;
};

@@ -740,18 +745,18 @@ struct core_reloc_bitfields___bit_sz_change {
	int32_t		sb20: 30;	/* 20 -> 30 */
	/* non-bitfields */
	uint16_t	u32;			/* 32 -> 16 */
	int64_t		s32;		/* 32 -> 64 */
	int64_t		s32 __bpf_aligned;	/* 32 -> 64 */
};

/* turn bitfield into non-bitfield and vice versa */
struct core_reloc_bitfields___bitfield_vs_int {
	uint64_t	ub1;		/*  3 -> 64 non-bitfield */
	uint8_t		ub2;		/* 20 ->  8 non-bitfield */
	int64_t		ub7;		/*  7 -> 64 non-bitfield signed */
	int64_t		sb4;		/*  4 -> 64 non-bitfield signed */
	uint64_t	sb20;		/* 20 -> 16 non-bitfield unsigned */
	int64_t		ub7 __bpf_aligned;	/*  7 -> 64 non-bitfield signed */
	int64_t		sb4 __bpf_aligned;	/*  4 -> 64 non-bitfield signed */
	uint64_t	sb20 __bpf_aligned;	/* 20 -> 16 non-bitfield unsigned */
	int32_t		u32: 20;		/* 32 non-bitfield -> 20 bitfield */
	uint64_t	s32: 60;	/* 32 non-bitfield -> 60 bitfield */
	uint64_t	s32: 60 __bpf_aligned;	/* 32 non-bitfield -> 60 bitfield */
};

struct core_reloc_bitfields___just_big_enough {