...

Text file src/github.com/cilium/ebpf/btf/testdata/relocs.c

Documentation: github.com/cilium/ebpf/btf/testdata

     1#include "../../testdata/common.h"
     2#include "bpf_core_read.h"
     3
     4enum e {
     5	// clang-12 doesn't allow enum relocations with zero value.
     6	// See https://reviews.llvm.org/D97659
     7	ONE = 1,
     8	TWO,
     9};
    10
    11typedef enum e e_t;
    12
    13struct s {
    14	int _1;
    15	char _2;
    16};
    17
    18typedef struct s s_t;
    19
    20union u {
    21	int *_1;
    22	char *_2;
    23};
    24
    25typedef union u u_t;
    26
    27#define local_id_zero(expr) \
    28	({ \
    29		if (bpf_core_type_id_local(expr) != 0) { \
    30			return __LINE__; \
    31		} \
    32	})
    33
    34#define local_id_not_zero(expr) \
    35	({ \
    36		if (bpf_core_type_id_local(expr) == 0) { \
    37			return __LINE__; \
    38		} \
    39	})
    40
    41#define target_and_local_id_match(expr) \
    42	({ \
    43		if (bpf_core_type_id_kernel(expr) != bpf_core_type_id_local(expr)) { \
    44			return __LINE__; \
    45		} \
    46	})
    47
    48__section("socket_filter/type_ids") int type_ids() {
    49	local_id_not_zero(int);
    50	local_id_not_zero(struct { int frob; });
    51	local_id_not_zero(enum {FRAP});
    52	local_id_not_zero(union { char bar; });
    53
    54	local_id_not_zero(struct s);
    55	local_id_not_zero(s_t);
    56	local_id_not_zero(const s_t);
    57	local_id_not_zero(volatile s_t);
    58	local_id_not_zero(enum e);
    59	local_id_not_zero(e_t);
    60	local_id_not_zero(const e_t);
    61	local_id_not_zero(volatile e_t);
    62	local_id_not_zero(union u);
    63	local_id_not_zero(u_t);
    64	local_id_not_zero(const u_t);
    65	local_id_not_zero(volatile u_t);
    66
    67	// Qualifiers on types crash clang.
    68	target_and_local_id_match(struct s);
    69	target_and_local_id_match(s_t);
    70	// target_and_local_id_match(const s_t);
    71	// target_and_local_id_match(volatile s_t);
    72	target_and_local_id_match(enum e);
    73	target_and_local_id_match(e_t);
    74	// target_and_local_id_match(const e_t);
    75	// target_and_local_id_match(volatile e_t);
    76	target_and_local_id_match(union u);
    77	target_and_local_id_match(u_t);
    78	// target_and_local_id_match(const u_t);
    79	// target_and_local_id_match(volatile u_t);
    80
    81	return 0;
    82}
    83
    84#define type_exists(expr) \
    85	({ \
    86		if (!bpf_core_type_exists(expr)) { \
    87			return __LINE__; \
    88		} \
    89	})
    90
    91#define type_size_matches(expr) \
    92	({ \
    93		if (bpf_core_type_size(expr) != sizeof(expr)) { \
    94			return __LINE__; \
    95		} \
    96	})
    97
    98__section("socket_filter/types") int types() {
    99	type_exists(struct s);
   100	type_exists(s_t);
   101	type_exists(const s_t);
   102	type_exists(volatile s_t);
   103	type_exists(enum e);
   104	type_exists(e_t);
   105	type_exists(const e_t);
   106	type_exists(volatile e_t);
   107	type_exists(union u);
   108	type_exists(u_t);
   109	type_exists(const u_t);
   110	type_exists(volatile u_t);
   111	// TODO: Check non-existence.
   112
   113	type_size_matches(struct s);
   114	type_size_matches(s_t);
   115	type_size_matches(const s_t);
   116	type_size_matches(volatile s_t);
   117	type_size_matches(enum e);
   118	type_size_matches(e_t);
   119	type_size_matches(const e_t);
   120	type_size_matches(volatile e_t);
   121	type_size_matches(union u);
   122	type_size_matches(u_t);
   123	type_size_matches(const u_t);
   124	type_size_matches(volatile u_t);
   125
   126	return 0;
   127}
   128
   129#define enum_value_exists(t, v) \
   130	({ \
   131		if (!bpf_core_enum_value_exists(t, v)) { \
   132			return __LINE__; \
   133		} \
   134	})
   135
   136#define enum_value_matches(t, v) \
   137	({ \
   138		if (v != bpf_core_enum_value(t, v)) { \
   139			return __LINE__; \
   140		} \
   141	})
   142
   143__section("socket_filter/enums") int enums() {
   144	enum_value_exists(enum e, ONE);
   145	enum_value_exists(volatile enum e, ONE);
   146	enum_value_exists(const enum e, ONE);
   147	enum_value_exists(e_t, TWO);
   148	// TODO: Check non-existence.
   149
   150	enum_value_matches(enum e, TWO);
   151	enum_value_matches(e_t, ONE);
   152	enum_value_matches(volatile e_t, ONE);
   153	enum_value_matches(const e_t, ONE);
   154
   155	return 0;
   156}
   157
   158#define field_exists(f) \
   159	({ \
   160		if (!bpf_core_field_exists(f)) { \
   161			return __LINE__; \
   162		} \
   163	})
   164
   165#define field_size_matches(f) \
   166	({ \
   167		if (sizeof(f) != bpf_core_field_size(f)) { \
   168			return __LINE__; \
   169		} \
   170	})
   171
   172#define field_offset_matches(t, f) \
   173	({ \
   174		if (__builtin_offsetof(t, f) != __builtin_preserve_field_info(((typeof(t) *)0)->f, BPF_FIELD_BYTE_OFFSET)) { \
   175			return __LINE__; \
   176		} \
   177	})
   178
   179__section("socket_filter/fields") int fields() {
   180	field_exists((struct s){}._1);
   181	field_exists((s_t){}._2);
   182	field_exists((union u){}._1);
   183	field_exists((u_t){}._2);
   184
   185	field_size_matches((struct s){}._1);
   186	field_size_matches((s_t){}._2);
   187	field_size_matches((union u){}._1);
   188	field_size_matches((u_t){}._2);
   189
   190	field_offset_matches(struct s, _1);
   191	field_offset_matches(s_t, _2);
   192	field_offset_matches(union u, _1);
   193	field_offset_matches(u_t, _2);
   194
   195	struct t {
   196		union {
   197			s_t s[10];
   198		};
   199		struct {
   200			union u u;
   201		};
   202	} bar, *barp = &bar;
   203
   204	field_exists(bar.s[2]._1);
   205	field_exists(bar.s[1]._2);
   206	field_exists(bar.u._1);
   207	field_exists(bar.u._2);
   208	field_exists(barp[1].u._2);
   209
   210	field_size_matches(bar.s[2]._1);
   211	field_size_matches(bar.s[1]._2);
   212	field_size_matches(bar.u._1);
   213	field_size_matches(bar.u._2);
   214	field_size_matches(barp[1].u._2);
   215
   216	field_offset_matches(struct t, s[2]._1);
   217	field_offset_matches(struct t, s[1]._2);
   218	field_offset_matches(struct t, u._1);
   219	field_offset_matches(struct t, u._2);
   220
   221	return 0;
   222}
   223
   224struct ambiguous {
   225	int _1;
   226	char _2;
   227};
   228
   229struct ambiguous___flavour {
   230	char _1;
   231	int _2;
   232};
   233
   234__section("socket_filter/err_ambiguous") int err_ambiguous() {
   235	return bpf_core_type_id_kernel(struct ambiguous);
   236}
   237
   238__section("socket_filter/err_ambiguous_flavour") int err_ambiguous_flavour() {
   239	return bpf_core_type_id_kernel(struct ambiguous___flavour);
   240}

View as plain text