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

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