File: relocs_read.c

package info (click to toggle)
golang-github-cilium-ebpf 0.17.3%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 4,684 kB
  • sloc: ansic: 1,259; makefile: 127; python: 113; awk: 29; sh: 24
file content (114 lines) | stat: -rw-r--r-- 2,477 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "../../testdata/common.h"
#include "bpf_core_read.h"

// Struct with the members declared in the wrong order. Accesses need
// a successful CO-RE relocation against the type in relocs_read_tgt.c
// for the test below to pass.
struct s {
	char b;
	char a;
};

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;

// Struct with bitfields.
struct bits {
	int x;
	u8 a : 4, b : 2;
	u16 c : 1;
	unsigned int d : 2;
	enum { ZERO = 0, ONE = 1 } e : 1;
	u64 f : 16, g : 30;
};

struct nonexist {
	int non_exist;
};

enum nonexist_enum { NON_EXIST = 1 };

// Perform a read from a subprog to ensure CO-RE relocations
// occurring there are tracked and executed in the final linked program.
__attribute__((noinline)) int read_subprog() {
	struct s foo = {
		.a = 0,
		.b = 1,
	};

	if (core_access(foo.a) == 0)
		return __LINE__;

	if (core_access(foo.b) == 1)
		return __LINE__;

	struct bits bar;
	char *p = (char *)&bar;
	/* Target:
	 * [4] STRUCT 'bits' size=8 vlen=7
	 * 'b' type_id=5 bits_offset=0 bitfield_size=2
	 * 'a' type_id=5 bits_offset=2 bitfield_size=4
	 * 'd' type_id=7 bits_offset=6 bitfield_size=2
	 * 'c' type_id=9 bits_offset=8 bitfield_size=1
	 * 'e' type_id=11 bits_offset=9 bitfield_size=1
	 * 'f' type_id=9 bits_offset=16
	 * 'g' type_id=12 bits_offset=32 bitfield_size=30
	 */
	*p++ = 0xff; // a, b, d
	*p++ = 0x00; // c, e
	*p++ = 0x56; // f
	*p++ = 0x56; // f
#ifdef __BIG_ENDIAN__
	*p++ = 0x55; // g
	*p++ = 0x44; // g
	*p++ = 0x33; // g
	*p++ = 0x22; // g
#else
	*p++ = 0x22; // g
	*p++ = 0x33; // g
	*p++ = 0x44; // g
	*p++ = 0x55; // g
#endif

	if (BPF_CORE_READ_BITFIELD(&bar, a) != (1 << 4) - 1)
		return __LINE__;

	if (BPF_CORE_READ_BITFIELD(&bar, b) != (1 << 2) - 1)
		return __LINE__;

	if (BPF_CORE_READ_BITFIELD(&bar, d) != (1 << 2) - 1)
		return __LINE__;

	if (BPF_CORE_READ_BITFIELD(&bar, c) != 0)
		return __LINE__;

	if (BPF_CORE_READ_BITFIELD(&bar, e) != 0)
		return __LINE__;

	if (BPF_CORE_READ_BITFIELD(&bar, f) != 0x5656)
		return __LINE__;

	if (BPF_CORE_READ_BITFIELD(&bar, g) != 0x15443322)
		return __LINE__;

	if (bpf_core_type_exists(struct nonexist) != 0)
		return __LINE__;

	if (bpf_core_field_exists(((struct nonexist *)0)->non_exist) != 0)
		return __LINE__;

	if (bpf_core_enum_value_exists(enum nonexist_enum, NON_EXIST) != 0)
		return __LINE__;

	return 0;
}

__section("socket") int reads() {
	int ret = read_subprog();
	if (ret)
		return ret;

	return 0;
}