Commit 2d2a3ad8 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

selftests/bpf: add btf_dump BTF-to-C conversion tests



Add new test_btf_dump set of tests, validating BTF-to-C conversion
correctness. Tests rely on clang to generate BTF from provided C test
cases.

Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 351131b5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,3 +36,4 @@ alu32
libbpf.pc
libbpf.so.*
test_hashmap
test_btf_dump
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
	test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \
	test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user \
	test_socket_cookie test_cgroup_storage test_select_reuseport test_section_names \
	test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap
	test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
	test_btf_dump

BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
TEST_GEN_FILES = $(BPF_OBJ_FILES)
+92 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

/*
 * BTF-to-C dumper tests for bitfield.
 *
 * Copyright (c) 2019 Facebook
 */
#include <stdbool.h>

/* ----- START-EXPECTED-OUTPUT ----- */
/*
 *struct bitfields_only_mixed_types {
 *	int a: 3;
 *	long int b: 2;
 *	_Bool c: 1;
 *	enum {
 *		A = 0,
 *		B = 1,
 *	} d: 1;
 *	short e: 5;
 *	int: 20;
 *	unsigned int f: 30;
 *};
 *
 */
/* ------ END-EXPECTED-OUTPUT ------ */

struct bitfields_only_mixed_types {
	int a: 3;
	long int b: 2;
	bool c: 1; /* it's really a _Bool type */
	enum {
		A, /* A = 0, dumper is very explicit */
		B, /* B = 1, same */
	} d: 1;
	short e: 5;
	/* 20-bit padding here */
	unsigned f: 30; /* this gets aligned on 4-byte boundary */
};

/* ----- START-EXPECTED-OUTPUT ----- */
/*
 *struct bitfield_mixed_with_others {
 *	char: 4;
 *	int a: 4;
 *	short b;
 *	long int c;
 *	long int d: 8;
 *	int e;
 *	int f;
 *};
 *
 */
/* ------ END-EXPECTED-OUTPUT ------ */
struct bitfield_mixed_with_others {
	long: 4; /* char is enough as a backing field */
	int a: 4;
	/* 8-bit implicit padding */
	short b; /* combined with previous bitfield */
	/* 4 more bytes of implicit padding */
	long c;
	long d: 8;
	/* 24 bits implicit padding */
	int e; /* combined with previous bitfield */
	int f;
	/* 4 bytes of padding */
};

/* ----- START-EXPECTED-OUTPUT ----- */
/*
 *struct bitfield_flushed {
 *	int a: 4;
 *	long: 60;
 *	long int b: 16;
 *};
 *
 */
/* ------ END-EXPECTED-OUTPUT ------ */
struct bitfield_flushed {
	int a: 4;
	long: 0; /* flush until next natural alignment boundary */
	long b: 16;
};

int f(struct {
	struct bitfields_only_mixed_types _1;
	struct bitfield_mixed_with_others _2;
	struct bitfield_flushed _3;
} *_)
{
	return 0;
}
+35 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

/*
 * BTF-to-C dumper test for multi-dimensional array output.
 *
 * Copyright (c) 2019 Facebook
 */
/* ----- START-EXPECTED-OUTPUT ----- */
typedef int arr_t[2];

typedef int multiarr_t[3][4][5];

typedef int *ptr_arr_t[6];

typedef int *ptr_multiarr_t[7][8][9][10];

typedef int * (*fn_ptr_arr_t[11])();

typedef int * (*fn_ptr_multiarr_t[12][13])();

struct root_struct {
	arr_t _1;
	multiarr_t _2;
	ptr_arr_t _3;
	ptr_multiarr_t _4;
	fn_ptr_arr_t _5;
	fn_ptr_multiarr_t _6;
};

/* ------ END-EXPECTED-OUTPUT ------ */

int f(struct root_struct *s)
{
	return 0;
}
+73 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

/*
 * BTF-to-C dumper test validating no name versioning happens between
 * independent C namespaces (struct/union/enum vs typedef/enum values).
 *
 * Copyright (c) 2019 Facebook
 */
/* ----- START-EXPECTED-OUTPUT ----- */
struct S {
	int S;
	int U;
};

typedef struct S S;

union U {
	int S;
	int U;
};

typedef union U U;

enum E {
	V = 0,
};

typedef enum E E;

struct A {};

union B {};

enum C {
	A = 1,
	B = 2,
	C = 3,
};

struct X {};

union Y {};

enum Z;

typedef int X;

typedef int Y;

typedef int Z;

/*------ END-EXPECTED-OUTPUT ------ */

int f(struct {
	struct S _1;
	S _2;
	union U _3;
	U _4;
	enum E _5;
	E _6;
	struct A a;
	union B b;
	enum C c;
	struct X x;
	union Y y;
	enum Z *z;
	X xx;
	Y yy;
	Z zz;
} *_)
{
	return 0;
}
Loading