GNU Linux-libre 4.19.286-gnu1
[releases.git] / tools / lib / bpf / btf.c
1 // SPDX-License-Identifier: LGPL-2.1
2 /* Copyright (c) 2018 Facebook */
3
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <errno.h>
8 #include <linux/err.h>
9 #include <linux/btf.h>
10 #include "btf.h"
11 #include "bpf.h"
12
13 #define elog(fmt, ...) { if (err_log) err_log(fmt, ##__VA_ARGS__); }
14 #define max(a, b) ((a) > (b) ? (a) : (b))
15 #define min(a, b) ((a) < (b) ? (a) : (b))
16
17 #define BTF_MAX_NR_TYPES 65535
18
19 #define IS_MODIFIER(k) (((k) == BTF_KIND_TYPEDEF) || \
20                 ((k) == BTF_KIND_VOLATILE) || \
21                 ((k) == BTF_KIND_CONST) || \
22                 ((k) == BTF_KIND_RESTRICT))
23
24 static struct btf_type btf_void;
25
26 struct btf {
27         union {
28                 struct btf_header *hdr;
29                 void *data;
30         };
31         struct btf_type **types;
32         const char *strings;
33         void *nohdr_data;
34         __u32 nr_types;
35         __u32 types_size;
36         __u32 data_size;
37         int fd;
38 };
39
40 static int btf_add_type(struct btf *btf, struct btf_type *t)
41 {
42         if (btf->types_size - btf->nr_types < 2) {
43                 struct btf_type **new_types;
44                 __u32 expand_by, new_size;
45
46                 if (btf->types_size == BTF_MAX_NR_TYPES)
47                         return -E2BIG;
48
49                 expand_by = max(btf->types_size >> 2, 16);
50                 new_size = min(BTF_MAX_NR_TYPES, btf->types_size + expand_by);
51
52                 new_types = realloc(btf->types, sizeof(*new_types) * new_size);
53                 if (!new_types)
54                         return -ENOMEM;
55
56                 if (btf->nr_types == 0)
57                         new_types[0] = &btf_void;
58
59                 btf->types = new_types;
60                 btf->types_size = new_size;
61         }
62
63         btf->types[++(btf->nr_types)] = t;
64
65         return 0;
66 }
67
68 static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log)
69 {
70         const struct btf_header *hdr = btf->hdr;
71         __u32 meta_left;
72
73         if (btf->data_size < sizeof(struct btf_header)) {
74                 elog("BTF header not found\n");
75                 return -EINVAL;
76         }
77
78         if (hdr->magic != BTF_MAGIC) {
79                 elog("Invalid BTF magic:%x\n", hdr->magic);
80                 return -EINVAL;
81         }
82
83         if (hdr->version != BTF_VERSION) {
84                 elog("Unsupported BTF version:%u\n", hdr->version);
85                 return -ENOTSUP;
86         }
87
88         if (hdr->flags) {
89                 elog("Unsupported BTF flags:%x\n", hdr->flags);
90                 return -ENOTSUP;
91         }
92
93         meta_left = btf->data_size - sizeof(*hdr);
94         if (!meta_left) {
95                 elog("BTF has no data\n");
96                 return -EINVAL;
97         }
98
99         if (meta_left < hdr->type_off) {
100                 elog("Invalid BTF type section offset:%u\n", hdr->type_off);
101                 return -EINVAL;
102         }
103
104         if (meta_left < hdr->str_off) {
105                 elog("Invalid BTF string section offset:%u\n", hdr->str_off);
106                 return -EINVAL;
107         }
108
109         if (hdr->type_off >= hdr->str_off) {
110                 elog("BTF type section offset >= string section offset. No type?\n");
111                 return -EINVAL;
112         }
113
114         if (hdr->type_off & 0x02) {
115                 elog("BTF type section is not aligned to 4 bytes\n");
116                 return -EINVAL;
117         }
118
119         btf->nohdr_data = btf->hdr + 1;
120
121         return 0;
122 }
123
124 static int btf_parse_str_sec(struct btf *btf, btf_print_fn_t err_log)
125 {
126         const struct btf_header *hdr = btf->hdr;
127         const char *start = btf->nohdr_data + hdr->str_off;
128         const char *end = start + btf->hdr->str_len;
129
130         if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_NAME_OFFSET ||
131             start[0] || end[-1]) {
132                 elog("Invalid BTF string section\n");
133                 return -EINVAL;
134         }
135
136         btf->strings = start;
137
138         return 0;
139 }
140
141 static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
142 {
143         struct btf_header *hdr = btf->hdr;
144         void *nohdr_data = btf->nohdr_data;
145         void *next_type = nohdr_data + hdr->type_off;
146         void *end_type = nohdr_data + hdr->str_off;
147
148         while (next_type < end_type) {
149                 struct btf_type *t = next_type;
150                 __u16 vlen = BTF_INFO_VLEN(t->info);
151                 int err;
152
153                 next_type += sizeof(*t);
154                 switch (BTF_INFO_KIND(t->info)) {
155                 case BTF_KIND_INT:
156                         next_type += sizeof(int);
157                         break;
158                 case BTF_KIND_ARRAY:
159                         next_type += sizeof(struct btf_array);
160                         break;
161                 case BTF_KIND_STRUCT:
162                 case BTF_KIND_UNION:
163                         next_type += vlen * sizeof(struct btf_member);
164                         break;
165                 case BTF_KIND_ENUM:
166                         next_type += vlen * sizeof(struct btf_enum);
167                         break;
168                 case BTF_KIND_TYPEDEF:
169                 case BTF_KIND_PTR:
170                 case BTF_KIND_FWD:
171                 case BTF_KIND_VOLATILE:
172                 case BTF_KIND_CONST:
173                 case BTF_KIND_RESTRICT:
174                         break;
175                 default:
176                         elog("Unsupported BTF_KIND:%u\n",
177                              BTF_INFO_KIND(t->info));
178                         return -EINVAL;
179                 }
180
181                 err = btf_add_type(btf, t);
182                 if (err)
183                         return err;
184         }
185
186         return 0;
187 }
188
189 const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
190 {
191         if (type_id > btf->nr_types)
192                 return NULL;
193
194         return btf->types[type_id];
195 }
196
197 static bool btf_type_is_void(const struct btf_type *t)
198 {
199         return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD;
200 }
201
202 static bool btf_type_is_void_or_null(const struct btf_type *t)
203 {
204         return !t || btf_type_is_void(t);
205 }
206
207 static __s64 btf_type_size(const struct btf_type *t)
208 {
209         switch (BTF_INFO_KIND(t->info)) {
210         case BTF_KIND_INT:
211         case BTF_KIND_STRUCT:
212         case BTF_KIND_UNION:
213         case BTF_KIND_ENUM:
214                 return t->size;
215         case BTF_KIND_PTR:
216                 return sizeof(void *);
217         default:
218                 return -EINVAL;
219         }
220 }
221
222 #define MAX_RESOLVE_DEPTH 32
223
224 __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
225 {
226         const struct btf_array *array;
227         const struct btf_type *t;
228         __u32 nelems = 1;
229         __s64 size = -1;
230         int i;
231
232         t = btf__type_by_id(btf, type_id);
233         for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
234              i++) {
235                 size = btf_type_size(t);
236                 if (size >= 0)
237                         break;
238
239                 switch (BTF_INFO_KIND(t->info)) {
240                 case BTF_KIND_TYPEDEF:
241                 case BTF_KIND_VOLATILE:
242                 case BTF_KIND_CONST:
243                 case BTF_KIND_RESTRICT:
244                         type_id = t->type;
245                         break;
246                 case BTF_KIND_ARRAY:
247                         array = (const struct btf_array *)(t + 1);
248                         if (nelems && array->nelems > UINT32_MAX / nelems)
249                                 return -E2BIG;
250                         nelems *= array->nelems;
251                         type_id = array->type;
252                         break;
253                 default:
254                         return -EINVAL;
255                 }
256
257                 t = btf__type_by_id(btf, type_id);
258         }
259
260         if (size < 0)
261                 return -EINVAL;
262
263         if (nelems && size > UINT32_MAX / nelems)
264                 return -E2BIG;
265
266         return nelems * size;
267 }
268
269 int btf__resolve_type(const struct btf *btf, __u32 type_id)
270 {
271         const struct btf_type *t;
272         int depth = 0;
273
274         t = btf__type_by_id(btf, type_id);
275         while (depth < MAX_RESOLVE_DEPTH &&
276                !btf_type_is_void_or_null(t) &&
277                IS_MODIFIER(BTF_INFO_KIND(t->info))) {
278                 type_id = t->type;
279                 t = btf__type_by_id(btf, type_id);
280                 depth++;
281         }
282
283         if (depth == MAX_RESOLVE_DEPTH || btf_type_is_void_or_null(t))
284                 return -EINVAL;
285
286         return type_id;
287 }
288
289 __s32 btf__find_by_name(const struct btf *btf, const char *type_name)
290 {
291         __u32 i;
292
293         if (!strcmp(type_name, "void"))
294                 return 0;
295
296         for (i = 1; i <= btf->nr_types; i++) {
297                 const struct btf_type *t = btf->types[i];
298                 const char *name = btf__name_by_offset(btf, t->name_off);
299
300                 if (name && !strcmp(type_name, name))
301                         return i;
302         }
303
304         return -ENOENT;
305 }
306
307 void btf__free(struct btf *btf)
308 {
309         if (!btf)
310                 return;
311
312         if (btf->fd != -1)
313                 close(btf->fd);
314
315         free(btf->data);
316         free(btf->types);
317         free(btf);
318 }
319
320 struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)
321 {
322         __u32 log_buf_size = 0;
323         char *log_buf = NULL;
324         struct btf *btf;
325         int err;
326
327         btf = calloc(1, sizeof(struct btf));
328         if (!btf)
329                 return ERR_PTR(-ENOMEM);
330
331         btf->fd = -1;
332
333         if (err_log) {
334                 log_buf = malloc(BPF_LOG_BUF_SIZE);
335                 if (!log_buf) {
336                         err = -ENOMEM;
337                         goto done;
338                 }
339                 *log_buf = 0;
340                 log_buf_size = BPF_LOG_BUF_SIZE;
341         }
342
343         btf->data = malloc(size);
344         if (!btf->data) {
345                 err = -ENOMEM;
346                 goto done;
347         }
348
349         memcpy(btf->data, data, size);
350         btf->data_size = size;
351
352         btf->fd = bpf_load_btf(btf->data, btf->data_size,
353                                log_buf, log_buf_size, false);
354
355         if (btf->fd == -1) {
356                 err = -errno;
357                 elog("Error loading BTF: %s(%d)\n", strerror(errno), errno);
358                 if (log_buf && *log_buf)
359                         elog("%s\n", log_buf);
360                 goto done;
361         }
362
363         err = btf_parse_hdr(btf, err_log);
364         if (err)
365                 goto done;
366
367         err = btf_parse_str_sec(btf, err_log);
368         if (err)
369                 goto done;
370
371         err = btf_parse_type_sec(btf, err_log);
372
373 done:
374         free(log_buf);
375
376         if (err) {
377                 btf__free(btf);
378                 return ERR_PTR(err);
379         }
380
381         return btf;
382 }
383
384 int btf__fd(const struct btf *btf)
385 {
386         return btf->fd;
387 }
388
389 const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
390 {
391         if (offset < btf->hdr->str_len)
392                 return &btf->strings[offset];
393         else
394                 return NULL;
395 }