Skip to content

Commit

Permalink
selftests/bpf: add btf_dump BTF-to-C conversion tests
Browse files Browse the repository at this point in the history
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: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Andrii Nakryiko authored and Alexei Starovoitov committed May 24, 2019
1 parent 351131b commit 2d2a3ad
Show file tree
Hide file tree
Showing 10 changed files with 824 additions and 1 deletion.
1 change: 1 addition & 0 deletions tools/testing/selftests/bpf/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ alu32
libbpf.pc
libbpf.so.*
test_hashmap
test_btf_dump
3 changes: 2 additions & 1 deletion tools/testing/selftests/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
92 changes: 92 additions & 0 deletions tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// 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 changes: 35 additions & 0 deletions tools/testing/selftests/bpf/progs/btf_dump_test_case_multidim.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 changes: 73 additions & 0 deletions tools/testing/selftests/bpf/progs/btf_dump_test_case_namespacing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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;
}
63 changes: 63 additions & 0 deletions tools/testing/selftests/bpf/progs/btf_dump_test_case_ordering.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

/*
* BTF-to-C dumper test for topological sorting of dependent structs.
*
* Copyright (c) 2019 Facebook
*/
/* ----- START-EXPECTED-OUTPUT ----- */
struct s1 {};

struct s3;

struct s4;

struct s2 {
struct s2 *s2;
struct s3 *s3;
struct s4 *s4;
};

struct s3 {
struct s1 s1;
struct s2 s2;
};

struct s4 {
struct s1 s1;
struct s3 s3;
};

struct list_head {
struct list_head *next;
struct list_head *prev;
};

struct hlist_node {
struct hlist_node *next;
struct hlist_node **pprev;
};

struct hlist_head {
struct hlist_node *first;
};

struct callback_head {
struct callback_head *next;
void (*func)(struct callback_head *);
};

struct root_struct {
struct s4 s4;
struct list_head l;
struct hlist_node n;
struct hlist_head h;
struct callback_head cb;
};

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

int f(struct root_struct *root)
{
return 0;
}
75 changes: 75 additions & 0 deletions tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

/*
* BTF-to-C dumper tests for struct packing determination.
*
* Copyright (c) 2019 Facebook
*/
/* ----- START-EXPECTED-OUTPUT ----- */
struct packed_trailing_space {
int a;
short b;
} __attribute__((packed));

struct non_packed_trailing_space {
int a;
short b;
};

struct packed_fields {
short a;
int b;
} __attribute__((packed));

struct non_packed_fields {
short a;
int b;
};

struct nested_packed {
char: 4;
int a: 4;
long int b;
struct {
char c;
int d;
} __attribute__((packed)) e;
} __attribute__((packed));

union union_is_never_packed {
int a: 4;
char b;
char c: 1;
};

union union_does_not_need_packing {
struct {
long int a;
int b;
} __attribute__((packed));
int c;
};

union jump_code_union {
char code[5];
struct {
char jump;
int offset;
} __attribute__((packed));
};

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

int f(struct {
struct packed_trailing_space _1;
struct non_packed_trailing_space _2;
struct packed_fields _3;
struct non_packed_fields _4;
struct nested_packed _5;
union union_is_never_packed _6;
union union_does_not_need_packing _7;
union jump_code_union _8;
} *_)
{
return 0;
}
Loading

0 comments on commit 2d2a3ad

Please sign in to comment.