github.com/cilium/ebpf@v0.16.0/btf/testdata/relocs_read.c (about)

     1  #include "../../testdata/common.h"
     2  #include "bpf_core_read.h"
     3  
     4  // Struct with the members declared in the wrong order. Accesses need
     5  // a successful CO-RE relocation against the type in relocs_read_tgt.c
     6  // for the test below to pass.
     7  struct s {
     8  	char b;
     9  	char a;
    10  };
    11  
    12  typedef unsigned char u8;
    13  typedef unsigned short u16;
    14  typedef unsigned int u32;
    15  typedef unsigned long u64;
    16  
    17  // Struct with bitfields.
    18  struct bits {
    19  	int x;
    20  	u8 a : 4, b : 2;
    21  	u16 c : 1;
    22  	unsigned int d : 2;
    23  	enum { ZERO = 0, ONE = 1 } e : 1;
    24  	u64 f : 16, g : 30;
    25  };
    26  
    27  struct nonexist {
    28  	int non_exist;
    29  };
    30  
    31  enum nonexist_enum { NON_EXIST = 1 };
    32  
    33  // Perform a read from a subprog to ensure CO-RE relocations
    34  // occurring there are tracked and executed in the final linked program.
    35  __attribute__((noinline)) int read_subprog() {
    36  	struct s foo = {
    37  		.a = 0,
    38  		.b = 1,
    39  	};
    40  
    41  	if (core_access(foo.a) == 0)
    42  		return __LINE__;
    43  
    44  	if (core_access(foo.b) == 1)
    45  		return __LINE__;
    46  
    47  	struct bits bar;
    48  	char *p = (char *)&bar;
    49  	/* Target:
    50  	 * [4] STRUCT 'bits' size=8 vlen=7
    51  	 * 'b' type_id=5 bits_offset=0 bitfield_size=2
    52  	 * 'a' type_id=5 bits_offset=2 bitfield_size=4
    53  	 * 'd' type_id=7 bits_offset=6 bitfield_size=2
    54  	 * 'c' type_id=9 bits_offset=8 bitfield_size=1
    55  	 * 'e' type_id=11 bits_offset=9 bitfield_size=1
    56  	 * 'f' type_id=9 bits_offset=16
    57  	 * 'g' type_id=12 bits_offset=32 bitfield_size=30
    58  	 */
    59  	*p++ = 0xff; // a, b, d
    60  	*p++ = 0x00; // c, e
    61  	*p++ = 0x56; // f
    62  	*p++ = 0x56; // f
    63  #ifdef __BIG_ENDIAN__
    64  	*p++ = 0x55; // g
    65  	*p++ = 0x44; // g
    66  	*p++ = 0x33; // g
    67  	*p++ = 0x22; // g
    68  #else
    69  	*p++ = 0x22; // g
    70  	*p++ = 0x33; // g
    71  	*p++ = 0x44; // g
    72  	*p++ = 0x55; // g
    73  #endif
    74  
    75  	if (BPF_CORE_READ_BITFIELD(&bar, a) != (1 << 4) - 1)
    76  		return __LINE__;
    77  
    78  	if (BPF_CORE_READ_BITFIELD(&bar, b) != (1 << 2) - 1)
    79  		return __LINE__;
    80  
    81  	if (BPF_CORE_READ_BITFIELD(&bar, d) != (1 << 2) - 1)
    82  		return __LINE__;
    83  
    84  	if (BPF_CORE_READ_BITFIELD(&bar, c) != 0)
    85  		return __LINE__;
    86  
    87  	if (BPF_CORE_READ_BITFIELD(&bar, e) != 0)
    88  		return __LINE__;
    89  
    90  	if (BPF_CORE_READ_BITFIELD(&bar, f) != 0x5656)
    91  		return __LINE__;
    92  
    93  	if (BPF_CORE_READ_BITFIELD(&bar, g) != 0x15443322)
    94  		return __LINE__;
    95  
    96  	if (bpf_core_type_exists(struct nonexist) != 0)
    97  		return __LINE__;
    98  
    99  	if (bpf_core_field_exists(((struct nonexist *)0)->non_exist) != 0)
   100  		return __LINE__;
   101  
   102  	if (bpf_core_enum_value_exists(enum nonexist_enum, NON_EXIST) != 0)
   103  		return __LINE__;
   104  
   105  	return 0;
   106  }
   107  
   108  __section("socket") int reads() {
   109  	int ret = read_subprog();
   110  	if (ret)
   111  		return ret;
   112  
   113  	return 0;
   114  }