1
2#ifndef __BPF_CORE_READ_H__
3#define __BPF_CORE_READ_H__
4
5
6
7
8
9
10
11
12
13enum bpf_field_info_kind {
14 BPF_FIELD_BYTE_OFFSET = 0,
15 BPF_FIELD_BYTE_SIZE = 1,
16 BPF_FIELD_EXISTS = 2,
17 BPF_FIELD_SIGNED = 3,
18 BPF_FIELD_LSHIFT_U64 = 4,
19 BPF_FIELD_RSHIFT_U64 = 5,
20};
21
22#define __CORE_RELO(src, field, info) \
23 __builtin_preserve_field_info((src)->field, BPF_FIELD_##info)
24
25#if __BYTE_ORDER == __LITTLE_ENDIAN
26#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
27 bpf_probe_read((void *)dst, \
28 __CORE_RELO(src, fld, BYTE_SIZE), \
29 (const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
30#else
31
32
33
34
35#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
36 bpf_probe_read((void *)dst + (8 - __CORE_RELO(src, fld, BYTE_SIZE)), \
37 __CORE_RELO(src, fld, BYTE_SIZE), \
38 (const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
39#endif
40
41
42
43
44
45
46
47
48
49#define BPF_CORE_READ_BITFIELD_PROBED(s, field) ({ \
50 unsigned long long val = 0; \
51 \
52 __CORE_BITFIELD_PROBE_READ(&val, s, field); \
53 val <<= __CORE_RELO(s, field, LSHIFT_U64); \
54 if (__CORE_RELO(s, field, SIGNED)) \
55 val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \
56 else \
57 val = val >> __CORE_RELO(s, field, RSHIFT_U64); \
58 val; \
59})
60
61
62
63
64
65
66
67#define BPF_CORE_READ_BITFIELD(s, field) ({ \
68 const void *p = (const void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \
69 unsigned long long val; \
70 \
71 switch (__CORE_RELO(s, field, BYTE_SIZE)) { \
72 case 1: val = *(const unsigned char *)p; \
73 case 2: val = *(const unsigned short *)p; \
74 case 4: val = *(const unsigned int *)p; \
75 case 8: val = *(const unsigned long long *)p; \
76 } \
77 val <<= __CORE_RELO(s, field, LSHIFT_U64); \
78 if (__CORE_RELO(s, field, SIGNED)) \
79 val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \
80 else \
81 val = val >> __CORE_RELO(s, field, RSHIFT_U64); \
82 val; \
83})
84
85
86
87
88
89
90
91#define bpf_core_field_exists(field) \
92 __builtin_preserve_field_info(field, BPF_FIELD_EXISTS)
93
94
95
96
97
98#define bpf_core_field_size(field) \
99 __builtin_preserve_field_info(field, BPF_FIELD_BYTE_SIZE)
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117#define bpf_core_read(dst, sz, src) \
118 bpf_probe_read(dst, sz, \
119 (const void *)__builtin_preserve_access_index(src))
120
121
122
123
124
125
126#define bpf_core_read_str(dst, sz, src) \
127 bpf_probe_read_str(dst, sz, \
128 (const void *)__builtin_preserve_access_index(src))
129
130#define ___concat(a, b) a ## b
131#define ___apply(fn, n) ___concat(fn, n)
132#define ___nth(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, __11, N, ...) N
133
134
135
136
137
138#define ___narg(...) ___nth(_, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
139
140
141
142
143
144#define ___empty(...) ___nth(_, ##__VA_ARGS__, N, N, N, N, N, N, N, N, N, N, 0)
145
146#define ___last1(x) x
147#define ___last2(a, x) x
148#define ___last3(a, b, x) x
149#define ___last4(a, b, c, x) x
150#define ___last5(a, b, c, d, x) x
151#define ___last6(a, b, c, d, e, x) x
152#define ___last7(a, b, c, d, e, f, x) x
153#define ___last8(a, b, c, d, e, f, g, x) x
154#define ___last9(a, b, c, d, e, f, g, h, x) x
155#define ___last10(a, b, c, d, e, f, g, h, i, x) x
156#define ___last(...) ___apply(___last, ___narg(__VA_ARGS__))(__VA_ARGS__)
157
158#define ___nolast2(a, _) a
159#define ___nolast3(a, b, _) a, b
160#define ___nolast4(a, b, c, _) a, b, c
161#define ___nolast5(a, b, c, d, _) a, b, c, d
162#define ___nolast6(a, b, c, d, e, _) a, b, c, d, e
163#define ___nolast7(a, b, c, d, e, f, _) a, b, c, d, e, f
164#define ___nolast8(a, b, c, d, e, f, g, _) a, b, c, d, e, f, g
165#define ___nolast9(a, b, c, d, e, f, g, h, _) a, b, c, d, e, f, g, h
166#define ___nolast10(a, b, c, d, e, f, g, h, i, _) a, b, c, d, e, f, g, h, i
167#define ___nolast(...) ___apply(___nolast, ___narg(__VA_ARGS__))(__VA_ARGS__)
168
169#define ___arrow1(a) a
170#define ___arrow2(a, b) a->b
171#define ___arrow3(a, b, c) a->b->c
172#define ___arrow4(a, b, c, d) a->b->c->d
173#define ___arrow5(a, b, c, d, e) a->b->c->d->e
174#define ___arrow6(a, b, c, d, e, f) a->b->c->d->e->f
175#define ___arrow7(a, b, c, d, e, f, g) a->b->c->d->e->f->g
176#define ___arrow8(a, b, c, d, e, f, g, h) a->b->c->d->e->f->g->h
177#define ___arrow9(a, b, c, d, e, f, g, h, i) a->b->c->d->e->f->g->h->i
178#define ___arrow10(a, b, c, d, e, f, g, h, i, j) a->b->c->d->e->f->g->h->i->j
179#define ___arrow(...) ___apply(___arrow, ___narg(__VA_ARGS__))(__VA_ARGS__)
180
181#define ___type(...) typeof(___arrow(__VA_ARGS__))
182
183#define ___read(read_fn, dst, src_type, src, accessor) \
184 read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor)
185
186
187#define ___rd_first(src, a) ___read(bpf_core_read, &__t, ___type(src), src, a);
188#define ___rd_last(...) \
189 ___read(bpf_core_read, &__t, \
190 ___type(___nolast(__VA_ARGS__)), __t, ___last(__VA_ARGS__));
191#define ___rd_p1(...) const void *__t; ___rd_first(__VA_ARGS__)
192#define ___rd_p2(...) ___rd_p1(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
193#define ___rd_p3(...) ___rd_p2(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
194#define ___rd_p4(...) ___rd_p3(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
195#define ___rd_p5(...) ___rd_p4(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
196#define ___rd_p6(...) ___rd_p5(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
197#define ___rd_p7(...) ___rd_p6(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
198#define ___rd_p8(...) ___rd_p7(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
199#define ___rd_p9(...) ___rd_p8(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
200#define ___read_ptrs(src, ...) \
201 ___apply(___rd_p, ___narg(__VA_ARGS__))(src, __VA_ARGS__)
202
203#define ___core_read0(fn, dst, src, a) \
204 ___read(fn, dst, ___type(src), src, a);
205#define ___core_readN(fn, dst, src, ...) \
206 ___read_ptrs(src, ___nolast(__VA_ARGS__)) \
207 ___read(fn, dst, ___type(src, ___nolast(__VA_ARGS__)), __t, \
208 ___last(__VA_ARGS__));
209#define ___core_read(fn, dst, src, a, ...) \
210 ___apply(___core_read, ___empty(__VA_ARGS__))(fn, dst, \
211 src, a, ##__VA_ARGS__)
212
213
214
215
216
217
218#define BPF_CORE_READ_INTO(dst, src, a, ...) \
219 ({ \
220 ___core_read(bpf_core_read, dst, src, a, ##__VA_ARGS__) \
221 })
222
223
224
225
226
227
228#define BPF_CORE_READ_STR_INTO(dst, src, a, ...) \
229 ({ \
230 ___core_read(bpf_core_read_str, dst, src, a, ##__VA_ARGS__) \
231 })
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255#define BPF_CORE_READ(src, a, ...) \
256 ({ \
257 ___type(src, a, ##__VA_ARGS__) __r; \
258 BPF_CORE_READ_INTO(&__r, src, a, ##__VA_ARGS__); \
259 __r; \
260 })
261
262#endif
263
264