github.com/kubeshark/ebpf@v0.9.2/btf/testdata/relocs.c (about)

     1  #include "../../testdata/common.h"
     2  #include "bpf_core_read.h"
     3  
     4  enum 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  
    11  typedef enum e e_t;
    12  
    13  struct s {
    14  	int _1;
    15  	char _2;
    16  };
    17  
    18  typedef struct s s_t;
    19  
    20  union u {
    21  	int *_1;
    22  	char *_2;
    23  };
    24  
    25  typedef 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  
   224  struct ambiguous {
   225  	int _1;
   226  	char _2;
   227  };
   228  
   229  struct 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  }