1
2
3
4#include <byteswap.h>
5#include <endian.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <fcntl.h>
10#include <unistd.h>
11#include <errno.h>
12#include <sys/utsname.h>
13#include <sys/param.h>
14#include <sys/stat.h>
15#include <linux/kernel.h>
16#include <linux/err.h>
17#include <linux/btf.h>
18#include <gelf.h>
19#include "btf.h"
20#include "bpf.h"
21#include "libbpf.h"
22#include "libbpf_internal.h"
23#include "hashmap.h"
24#include "strset.h"
25
26#define BTF_MAX_NR_TYPES 0x7fffffffU
27#define BTF_MAX_STR_OFFSET 0x7fffffffU
28
29static struct btf_type btf_void;
30
31struct btf {
32
33 void *raw_data;
34
35 void *raw_data_swapped;
36 __u32 raw_size;
37
38 bool swapped_endian;
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 struct btf_header *hdr;
78
79 void *types_data;
80 size_t types_data_cap;
81
82
83
84
85
86
87 __u32 *type_offs;
88 size_t type_offs_cap;
89
90
91
92
93 __u32 nr_types;
94
95
96
97 struct btf *base_btf;
98
99
100
101
102 int start_id;
103
104
105
106
107 int start_str_off;
108
109
110
111
112
113 void *strs_data;
114
115 struct strset *strs_set;
116
117 bool strs_deduped;
118
119
120 int fd;
121
122
123 int ptr_sz;
124};
125
126static inline __u64 ptr_to_u64(const void *ptr)
127{
128 return (__u64) (unsigned long) ptr;
129}
130
131
132
133
134
135
136
137
138
139
140
141void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
142 size_t cur_cnt, size_t max_cnt, size_t add_cnt)
143{
144 size_t new_cnt;
145 void *new_data;
146
147 if (cur_cnt + add_cnt <= *cap_cnt)
148 return *data + cur_cnt * elem_sz;
149
150
151 if (cur_cnt + add_cnt > max_cnt)
152 return NULL;
153
154 new_cnt = *cap_cnt;
155 new_cnt += new_cnt / 4;
156 if (new_cnt < 16)
157 new_cnt = 16;
158 if (new_cnt > max_cnt)
159 new_cnt = max_cnt;
160 if (new_cnt < cur_cnt + add_cnt)
161 new_cnt = cur_cnt + add_cnt;
162
163 new_data = libbpf_reallocarray(*data, new_cnt, elem_sz);
164 if (!new_data)
165 return NULL;
166
167
168 memset(new_data + (*cap_cnt) * elem_sz, 0, (new_cnt - *cap_cnt) * elem_sz);
169
170 *data = new_data;
171 *cap_cnt = new_cnt;
172 return new_data + cur_cnt * elem_sz;
173}
174
175
176
177
178int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt)
179{
180 void *p;
181
182 if (need_cnt <= *cap_cnt)
183 return 0;
184
185 p = libbpf_add_mem(data, cap_cnt, elem_sz, *cap_cnt, SIZE_MAX, need_cnt - *cap_cnt);
186 if (!p)
187 return -ENOMEM;
188
189 return 0;
190}
191
192static int btf_add_type_idx_entry(struct btf *btf, __u32 type_off)
193{
194 __u32 *p;
195
196 p = libbpf_add_mem((void **)&btf->type_offs, &btf->type_offs_cap, sizeof(__u32),
197 btf->nr_types, BTF_MAX_NR_TYPES, 1);
198 if (!p)
199 return -ENOMEM;
200
201 *p = type_off;
202 return 0;
203}
204
205static void btf_bswap_hdr(struct btf_header *h)
206{
207 h->magic = bswap_16(h->magic);
208 h->hdr_len = bswap_32(h->hdr_len);
209 h->type_off = bswap_32(h->type_off);
210 h->type_len = bswap_32(h->type_len);
211 h->str_off = bswap_32(h->str_off);
212 h->str_len = bswap_32(h->str_len);
213}
214
215static int btf_parse_hdr(struct btf *btf)
216{
217 struct btf_header *hdr = btf->hdr;
218 __u32 meta_left;
219
220 if (btf->raw_size < sizeof(struct btf_header)) {
221 pr_debug("BTF header not found\n");
222 return -EINVAL;
223 }
224
225 if (hdr->magic == bswap_16(BTF_MAGIC)) {
226 btf->swapped_endian = true;
227 if (bswap_32(hdr->hdr_len) != sizeof(struct btf_header)) {
228 pr_warn("Can't load BTF with non-native endianness due to unsupported header length %u\n",
229 bswap_32(hdr->hdr_len));
230 return -ENOTSUP;
231 }
232 btf_bswap_hdr(hdr);
233 } else if (hdr->magic != BTF_MAGIC) {
234 pr_debug("Invalid BTF magic:%x\n", hdr->magic);
235 return -EINVAL;
236 }
237
238 meta_left = btf->raw_size - sizeof(*hdr);
239 if (meta_left < hdr->str_off + hdr->str_len) {
240 pr_debug("Invalid BTF total size:%u\n", btf->raw_size);
241 return -EINVAL;
242 }
243
244 if (hdr->type_off + hdr->type_len > hdr->str_off) {
245 pr_debug("Invalid BTF data sections layout: type data at %u + %u, strings data at %u + %u\n",
246 hdr->type_off, hdr->type_len, hdr->str_off, hdr->str_len);
247 return -EINVAL;
248 }
249
250 if (hdr->type_off % 4) {
251 pr_debug("BTF type section is not aligned to 4 bytes\n");
252 return -EINVAL;
253 }
254
255 return 0;
256}
257
258static int btf_parse_str_sec(struct btf *btf)
259{
260 const struct btf_header *hdr = btf->hdr;
261 const char *start = btf->strs_data;
262 const char *end = start + btf->hdr->str_len;
263
264 if (btf->base_btf && hdr->str_len == 0)
265 return 0;
266 if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_STR_OFFSET || end[-1]) {
267 pr_debug("Invalid BTF string section\n");
268 return -EINVAL;
269 }
270 if (!btf->base_btf && start[0]) {
271 pr_debug("Invalid BTF string section\n");
272 return -EINVAL;
273 }
274 return 0;
275}
276
277static int btf_type_size(const struct btf_type *t)
278{
279 const int base_size = sizeof(struct btf_type);
280 __u16 vlen = btf_vlen(t);
281
282 switch (btf_kind(t)) {
283 case BTF_KIND_FWD:
284 case BTF_KIND_CONST:
285 case BTF_KIND_VOLATILE:
286 case BTF_KIND_RESTRICT:
287 case BTF_KIND_PTR:
288 case BTF_KIND_TYPEDEF:
289 case BTF_KIND_FUNC:
290 case BTF_KIND_FLOAT:
291 return base_size;
292 case BTF_KIND_INT:
293 return base_size + sizeof(__u32);
294 case BTF_KIND_ENUM:
295 return base_size + vlen * sizeof(struct btf_enum);
296 case BTF_KIND_ARRAY:
297 return base_size + sizeof(struct btf_array);
298 case BTF_KIND_STRUCT:
299 case BTF_KIND_UNION:
300 return base_size + vlen * sizeof(struct btf_member);
301 case BTF_KIND_FUNC_PROTO:
302 return base_size + vlen * sizeof(struct btf_param);
303 case BTF_KIND_VAR:
304 return base_size + sizeof(struct btf_var);
305 case BTF_KIND_DATASEC:
306 return base_size + vlen * sizeof(struct btf_var_secinfo);
307 default:
308 pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
309 return -EINVAL;
310 }
311}
312
313static void btf_bswap_type_base(struct btf_type *t)
314{
315 t->name_off = bswap_32(t->name_off);
316 t->info = bswap_32(t->info);
317 t->type = bswap_32(t->type);
318}
319
320static int btf_bswap_type_rest(struct btf_type *t)
321{
322 struct btf_var_secinfo *v;
323 struct btf_member *m;
324 struct btf_array *a;
325 struct btf_param *p;
326 struct btf_enum *e;
327 __u16 vlen = btf_vlen(t);
328 int i;
329
330 switch (btf_kind(t)) {
331 case BTF_KIND_FWD:
332 case BTF_KIND_CONST:
333 case BTF_KIND_VOLATILE:
334 case BTF_KIND_RESTRICT:
335 case BTF_KIND_PTR:
336 case BTF_KIND_TYPEDEF:
337 case BTF_KIND_FUNC:
338 case BTF_KIND_FLOAT:
339 return 0;
340 case BTF_KIND_INT:
341 *(__u32 *)(t + 1) = bswap_32(*(__u32 *)(t + 1));
342 return 0;
343 case BTF_KIND_ENUM:
344 for (i = 0, e = btf_enum(t); i < vlen; i++, e++) {
345 e->name_off = bswap_32(e->name_off);
346 e->val = bswap_32(e->val);
347 }
348 return 0;
349 case BTF_KIND_ARRAY:
350 a = btf_array(t);
351 a->type = bswap_32(a->type);
352 a->index_type = bswap_32(a->index_type);
353 a->nelems = bswap_32(a->nelems);
354 return 0;
355 case BTF_KIND_STRUCT:
356 case BTF_KIND_UNION:
357 for (i = 0, m = btf_members(t); i < vlen; i++, m++) {
358 m->name_off = bswap_32(m->name_off);
359 m->type = bswap_32(m->type);
360 m->offset = bswap_32(m->offset);
361 }
362 return 0;
363 case BTF_KIND_FUNC_PROTO:
364 for (i = 0, p = btf_params(t); i < vlen; i++, p++) {
365 p->name_off = bswap_32(p->name_off);
366 p->type = bswap_32(p->type);
367 }
368 return 0;
369 case BTF_KIND_VAR:
370 btf_var(t)->linkage = bswap_32(btf_var(t)->linkage);
371 return 0;
372 case BTF_KIND_DATASEC:
373 for (i = 0, v = btf_var_secinfos(t); i < vlen; i++, v++) {
374 v->type = bswap_32(v->type);
375 v->offset = bswap_32(v->offset);
376 v->size = bswap_32(v->size);
377 }
378 return 0;
379 default:
380 pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
381 return -EINVAL;
382 }
383}
384
385static int btf_parse_type_sec(struct btf *btf)
386{
387 struct btf_header *hdr = btf->hdr;
388 void *next_type = btf->types_data;
389 void *end_type = next_type + hdr->type_len;
390 int err, type_size;
391
392 while (next_type + sizeof(struct btf_type) <= end_type) {
393 if (btf->swapped_endian)
394 btf_bswap_type_base(next_type);
395
396 type_size = btf_type_size(next_type);
397 if (type_size < 0)
398 return type_size;
399 if (next_type + type_size > end_type) {
400 pr_warn("BTF type [%d] is malformed\n", btf->start_id + btf->nr_types);
401 return -EINVAL;
402 }
403
404 if (btf->swapped_endian && btf_bswap_type_rest(next_type))
405 return -EINVAL;
406
407 err = btf_add_type_idx_entry(btf, next_type - btf->types_data);
408 if (err)
409 return err;
410
411 next_type += type_size;
412 btf->nr_types++;
413 }
414
415 if (next_type != end_type) {
416 pr_warn("BTF types data is malformed\n");
417 return -EINVAL;
418 }
419
420 return 0;
421}
422
423__u32 btf__get_nr_types(const struct btf *btf)
424{
425 return btf->start_id + btf->nr_types - 1;
426}
427
428const struct btf *btf__base_btf(const struct btf *btf)
429{
430 return btf->base_btf;
431}
432
433
434struct btf_type *btf_type_by_id(struct btf *btf, __u32 type_id)
435{
436 if (type_id == 0)
437 return &btf_void;
438 if (type_id < btf->start_id)
439 return btf_type_by_id(btf->base_btf, type_id);
440 return btf->types_data + btf->type_offs[type_id - btf->start_id];
441}
442
443const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
444{
445 if (type_id >= btf->start_id + btf->nr_types)
446 return NULL;
447 return btf_type_by_id((struct btf *)btf, type_id);
448}
449
450static int determine_ptr_size(const struct btf *btf)
451{
452 const struct btf_type *t;
453 const char *name;
454 int i, n;
455
456 if (btf->base_btf && btf->base_btf->ptr_sz > 0)
457 return btf->base_btf->ptr_sz;
458
459 n = btf__get_nr_types(btf);
460 for (i = 1; i <= n; i++) {
461 t = btf__type_by_id(btf, i);
462 if (!btf_is_int(t))
463 continue;
464
465 name = btf__name_by_offset(btf, t->name_off);
466 if (!name)
467 continue;
468
469 if (strcmp(name, "long int") == 0 ||
470 strcmp(name, "long unsigned int") == 0) {
471 if (t->size != 4 && t->size != 8)
472 continue;
473 return t->size;
474 }
475 }
476
477 return -1;
478}
479
480static size_t btf_ptr_sz(const struct btf *btf)
481{
482 if (!btf->ptr_sz)
483 ((struct btf *)btf)->ptr_sz = determine_ptr_size(btf);
484 return btf->ptr_sz < 0 ? sizeof(void *) : btf->ptr_sz;
485}
486
487
488
489
490
491
492
493
494
495size_t btf__pointer_size(const struct btf *btf)
496{
497 if (!btf->ptr_sz)
498 ((struct btf *)btf)->ptr_sz = determine_ptr_size(btf);
499
500 if (btf->ptr_sz < 0)
501
502 return 0;
503
504 return btf->ptr_sz;
505}
506
507
508
509
510int btf__set_pointer_size(struct btf *btf, size_t ptr_sz)
511{
512 if (ptr_sz != 4 && ptr_sz != 8)
513 return -EINVAL;
514 btf->ptr_sz = ptr_sz;
515 return 0;
516}
517
518static bool is_host_big_endian(void)
519{
520#if __BYTE_ORDER == __LITTLE_ENDIAN
521 return false;
522#elif __BYTE_ORDER == __BIG_ENDIAN
523 return true;
524#else
525# error "Unrecognized __BYTE_ORDER__"
526#endif
527}
528
529enum btf_endianness btf__endianness(const struct btf *btf)
530{
531 if (is_host_big_endian())
532 return btf->swapped_endian ? BTF_LITTLE_ENDIAN : BTF_BIG_ENDIAN;
533 else
534 return btf->swapped_endian ? BTF_BIG_ENDIAN : BTF_LITTLE_ENDIAN;
535}
536
537int btf__set_endianness(struct btf *btf, enum btf_endianness endian)
538{
539 if (endian != BTF_LITTLE_ENDIAN && endian != BTF_BIG_ENDIAN)
540 return -EINVAL;
541
542 btf->swapped_endian = is_host_big_endian() != (endian == BTF_BIG_ENDIAN);
543 if (!btf->swapped_endian) {
544 free(btf->raw_data_swapped);
545 btf->raw_data_swapped = NULL;
546 }
547 return 0;
548}
549
550static bool btf_type_is_void(const struct btf_type *t)
551{
552 return t == &btf_void || btf_is_fwd(t);
553}
554
555static bool btf_type_is_void_or_null(const struct btf_type *t)
556{
557 return !t || btf_type_is_void(t);
558}
559
560#define MAX_RESOLVE_DEPTH 32
561
562__s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
563{
564 const struct btf_array *array;
565 const struct btf_type *t;
566 __u32 nelems = 1;
567 __s64 size = -1;
568 int i;
569
570 t = btf__type_by_id(btf, type_id);
571 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
572 i++) {
573 switch (btf_kind(t)) {
574 case BTF_KIND_INT:
575 case BTF_KIND_STRUCT:
576 case BTF_KIND_UNION:
577 case BTF_KIND_ENUM:
578 case BTF_KIND_DATASEC:
579 case BTF_KIND_FLOAT:
580 size = t->size;
581 goto done;
582 case BTF_KIND_PTR:
583 size = btf_ptr_sz(btf);
584 goto done;
585 case BTF_KIND_TYPEDEF:
586 case BTF_KIND_VOLATILE:
587 case BTF_KIND_CONST:
588 case BTF_KIND_RESTRICT:
589 case BTF_KIND_VAR:
590 type_id = t->type;
591 break;
592 case BTF_KIND_ARRAY:
593 array = btf_array(t);
594 if (nelems && array->nelems > UINT32_MAX / nelems)
595 return -E2BIG;
596 nelems *= array->nelems;
597 type_id = array->type;
598 break;
599 default:
600 return -EINVAL;
601 }
602
603 t = btf__type_by_id(btf, type_id);
604 }
605
606done:
607 if (size < 0)
608 return -EINVAL;
609 if (nelems && size > UINT32_MAX / nelems)
610 return -E2BIG;
611
612 return nelems * size;
613}
614
615int btf__align_of(const struct btf *btf, __u32 id)
616{
617 const struct btf_type *t = btf__type_by_id(btf, id);
618 __u16 kind = btf_kind(t);
619
620 switch (kind) {
621 case BTF_KIND_INT:
622 case BTF_KIND_ENUM:
623 case BTF_KIND_FLOAT:
624 return min(btf_ptr_sz(btf), (size_t)t->size);
625 case BTF_KIND_PTR:
626 return btf_ptr_sz(btf);
627 case BTF_KIND_TYPEDEF:
628 case BTF_KIND_VOLATILE:
629 case BTF_KIND_CONST:
630 case BTF_KIND_RESTRICT:
631 return btf__align_of(btf, t->type);
632 case BTF_KIND_ARRAY:
633 return btf__align_of(btf, btf_array(t)->type);
634 case BTF_KIND_STRUCT:
635 case BTF_KIND_UNION: {
636 const struct btf_member *m = btf_members(t);
637 __u16 vlen = btf_vlen(t);
638 int i, max_align = 1, align;
639
640 for (i = 0; i < vlen; i++, m++) {
641 align = btf__align_of(btf, m->type);
642 if (align <= 0)
643 return align;
644 max_align = max(max_align, align);
645 }
646
647 return max_align;
648 }
649 default:
650 pr_warn("unsupported BTF_KIND:%u\n", btf_kind(t));
651 return 0;
652 }
653}
654
655int btf__resolve_type(const struct btf *btf, __u32 type_id)
656{
657 const struct btf_type *t;
658 int depth = 0;
659
660 t = btf__type_by_id(btf, type_id);
661 while (depth < MAX_RESOLVE_DEPTH &&
662 !btf_type_is_void_or_null(t) &&
663 (btf_is_mod(t) || btf_is_typedef(t) || btf_is_var(t))) {
664 type_id = t->type;
665 t = btf__type_by_id(btf, type_id);
666 depth++;
667 }
668
669 if (depth == MAX_RESOLVE_DEPTH || btf_type_is_void_or_null(t))
670 return -EINVAL;
671
672 return type_id;
673}
674
675__s32 btf__find_by_name(const struct btf *btf, const char *type_name)
676{
677 __u32 i, nr_types = btf__get_nr_types(btf);
678
679 if (!strcmp(type_name, "void"))
680 return 0;
681
682 for (i = 1; i <= nr_types; i++) {
683 const struct btf_type *t = btf__type_by_id(btf, i);
684 const char *name = btf__name_by_offset(btf, t->name_off);
685
686 if (name && !strcmp(type_name, name))
687 return i;
688 }
689
690 return -ENOENT;
691}
692
693__s32 btf__find_by_name_kind(const struct btf *btf, const char *type_name,
694 __u32 kind)
695{
696 __u32 i, nr_types = btf__get_nr_types(btf);
697
698 if (kind == BTF_KIND_UNKN || !strcmp(type_name, "void"))
699 return 0;
700
701 for (i = 1; i <= nr_types; i++) {
702 const struct btf_type *t = btf__type_by_id(btf, i);
703 const char *name;
704
705 if (btf_kind(t) != kind)
706 continue;
707 name = btf__name_by_offset(btf, t->name_off);
708 if (name && !strcmp(type_name, name))
709 return i;
710 }
711
712 return -ENOENT;
713}
714
715static bool btf_is_modifiable(const struct btf *btf)
716{
717 return (void *)btf->hdr != btf->raw_data;
718}
719
720void btf__free(struct btf *btf)
721{
722 if (IS_ERR_OR_NULL(btf))
723 return;
724
725 if (btf->fd >= 0)
726 close(btf->fd);
727
728 if (btf_is_modifiable(btf)) {
729
730
731
732
733
734
735 free(btf->hdr);
736 free(btf->types_data);
737 strset__free(btf->strs_set);
738 }
739 free(btf->raw_data);
740 free(btf->raw_data_swapped);
741 free(btf->type_offs);
742 free(btf);
743}
744
745static struct btf *btf_new_empty(struct btf *base_btf)
746{
747 struct btf *btf;
748
749 btf = calloc(1, sizeof(*btf));
750 if (!btf)
751 return ERR_PTR(-ENOMEM);
752
753 btf->nr_types = 0;
754 btf->start_id = 1;
755 btf->start_str_off = 0;
756 btf->fd = -1;
757 btf->ptr_sz = sizeof(void *);
758 btf->swapped_endian = false;
759
760 if (base_btf) {
761 btf->base_btf = base_btf;
762 btf->start_id = btf__get_nr_types(base_btf) + 1;
763 btf->start_str_off = base_btf->hdr->str_len;
764 }
765
766
767 btf->raw_size = sizeof(struct btf_header) + (base_btf ? 0 : 1);
768 btf->raw_data = calloc(1, btf->raw_size);
769 if (!btf->raw_data) {
770 free(btf);
771 return ERR_PTR(-ENOMEM);
772 }
773
774 btf->hdr = btf->raw_data;
775 btf->hdr->hdr_len = sizeof(struct btf_header);
776 btf->hdr->magic = BTF_MAGIC;
777 btf->hdr->version = BTF_VERSION;
778
779 btf->types_data = btf->raw_data + btf->hdr->hdr_len;
780 btf->strs_data = btf->raw_data + btf->hdr->hdr_len;
781 btf->hdr->str_len = base_btf ? 0 : 1;
782
783 return btf;
784}
785
786struct btf *btf__new_empty(void)
787{
788 return btf_new_empty(NULL);
789}
790
791struct btf *btf__new_empty_split(struct btf *base_btf)
792{
793 return btf_new_empty(base_btf);
794}
795
796static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf)
797{
798 struct btf *btf;
799 int err;
800
801 btf = calloc(1, sizeof(struct btf));
802 if (!btf)
803 return ERR_PTR(-ENOMEM);
804
805 btf->nr_types = 0;
806 btf->start_id = 1;
807 btf->start_str_off = 0;
808
809 if (base_btf) {
810 btf->base_btf = base_btf;
811 btf->start_id = btf__get_nr_types(base_btf) + 1;
812 btf->start_str_off = base_btf->hdr->str_len;
813 }
814
815 btf->raw_data = malloc(size);
816 if (!btf->raw_data) {
817 err = -ENOMEM;
818 goto done;
819 }
820 memcpy(btf->raw_data, data, size);
821 btf->raw_size = size;
822
823 btf->hdr = btf->raw_data;
824 err = btf_parse_hdr(btf);
825 if (err)
826 goto done;
827
828 btf->strs_data = btf->raw_data + btf->hdr->hdr_len + btf->hdr->str_off;
829 btf->types_data = btf->raw_data + btf->hdr->hdr_len + btf->hdr->type_off;
830
831 err = btf_parse_str_sec(btf);
832 err = err ?: btf_parse_type_sec(btf);
833 if (err)
834 goto done;
835
836 btf->fd = -1;
837
838done:
839 if (err) {
840 btf__free(btf);
841 return ERR_PTR(err);
842 }
843
844 return btf;
845}
846
847struct btf *btf__new(const void *data, __u32 size)
848{
849 return btf_new(data, size, NULL);
850}
851
852static struct btf *btf_parse_elf(const char *path, struct btf *base_btf,
853 struct btf_ext **btf_ext)
854{
855 Elf_Data *btf_data = NULL, *btf_ext_data = NULL;
856 int err = 0, fd = -1, idx = 0;
857 struct btf *btf = NULL;
858 Elf_Scn *scn = NULL;
859 Elf *elf = NULL;
860 GElf_Ehdr ehdr;
861 size_t shstrndx;
862
863 if (elf_version(EV_CURRENT) == EV_NONE) {
864 pr_warn("failed to init libelf for %s\n", path);
865 return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
866 }
867
868 fd = open(path, O_RDONLY);
869 if (fd < 0) {
870 err = -errno;
871 pr_warn("failed to open %s: %s\n", path, strerror(errno));
872 return ERR_PTR(err);
873 }
874
875 err = -LIBBPF_ERRNO__FORMAT;
876
877 elf = elf_begin(fd, ELF_C_READ, NULL);
878 if (!elf) {
879 pr_warn("failed to open %s as ELF file\n", path);
880 goto done;
881 }
882 if (!gelf_getehdr(elf, &ehdr)) {
883 pr_warn("failed to get EHDR from %s\n", path);
884 goto done;
885 }
886
887 if (elf_getshdrstrndx(elf, &shstrndx)) {
888 pr_warn("failed to get section names section index for %s\n",
889 path);
890 goto done;
891 }
892
893 if (!elf_rawdata(elf_getscn(elf, shstrndx), NULL)) {
894 pr_warn("failed to get e_shstrndx from %s\n", path);
895 goto done;
896 }
897
898 while ((scn = elf_nextscn(elf, scn)) != NULL) {
899 GElf_Shdr sh;
900 char *name;
901
902 idx++;
903 if (gelf_getshdr(scn, &sh) != &sh) {
904 pr_warn("failed to get section(%d) header from %s\n",
905 idx, path);
906 goto done;
907 }
908 name = elf_strptr(elf, shstrndx, sh.sh_name);
909 if (!name) {
910 pr_warn("failed to get section(%d) name from %s\n",
911 idx, path);
912 goto done;
913 }
914 if (strcmp(name, BTF_ELF_SEC) == 0) {
915 btf_data = elf_getdata(scn, 0);
916 if (!btf_data) {
917 pr_warn("failed to get section(%d, %s) data from %s\n",
918 idx, name, path);
919 goto done;
920 }
921 continue;
922 } else if (btf_ext && strcmp(name, BTF_EXT_ELF_SEC) == 0) {
923 btf_ext_data = elf_getdata(scn, 0);
924 if (!btf_ext_data) {
925 pr_warn("failed to get section(%d, %s) data from %s\n",
926 idx, name, path);
927 goto done;
928 }
929 continue;
930 }
931 }
932
933 err = 0;
934
935 if (!btf_data) {
936 err = -ENOENT;
937 goto done;
938 }
939 btf = btf_new(btf_data->d_buf, btf_data->d_size, base_btf);
940 if (IS_ERR(btf))
941 goto done;
942
943 switch (gelf_getclass(elf)) {
944 case ELFCLASS32:
945 btf__set_pointer_size(btf, 4);
946 break;
947 case ELFCLASS64:
948 btf__set_pointer_size(btf, 8);
949 break;
950 default:
951 pr_warn("failed to get ELF class (bitness) for %s\n", path);
952 break;
953 }
954
955 if (btf_ext && btf_ext_data) {
956 *btf_ext = btf_ext__new(btf_ext_data->d_buf,
957 btf_ext_data->d_size);
958 if (IS_ERR(*btf_ext))
959 goto done;
960 } else if (btf_ext) {
961 *btf_ext = NULL;
962 }
963done:
964 if (elf)
965 elf_end(elf);
966 close(fd);
967
968 if (err)
969 return ERR_PTR(err);
970
971
972
973
974 if (IS_ERR(btf))
975 return btf;
976 if (btf_ext && IS_ERR(*btf_ext)) {
977 btf__free(btf);
978 err = PTR_ERR(*btf_ext);
979 return ERR_PTR(err);
980 }
981 return btf;
982}
983
984struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext)
985{
986 return btf_parse_elf(path, NULL, btf_ext);
987}
988
989struct btf *btf__parse_elf_split(const char *path, struct btf *base_btf)
990{
991 return btf_parse_elf(path, base_btf, NULL);
992}
993
994static struct btf *btf_parse_raw(const char *path, struct btf *base_btf)
995{
996 struct btf *btf = NULL;
997 void *data = NULL;
998 FILE *f = NULL;
999 __u16 magic;
1000 int err = 0;
1001 long sz;
1002
1003 f = fopen(path, "rb");
1004 if (!f) {
1005 err = -errno;
1006 goto err_out;
1007 }
1008
1009
1010 if (fread(&magic, 1, sizeof(magic), f) < sizeof(magic)) {
1011 err = -EIO;
1012 goto err_out;
1013 }
1014 if (magic != BTF_MAGIC && magic != bswap_16(BTF_MAGIC)) {
1015
1016 err = -EPROTO;
1017 goto err_out;
1018 }
1019
1020
1021 if (fseek(f, 0, SEEK_END)) {
1022 err = -errno;
1023 goto err_out;
1024 }
1025 sz = ftell(f);
1026 if (sz < 0) {
1027 err = -errno;
1028 goto err_out;
1029 }
1030
1031 if (fseek(f, 0, SEEK_SET)) {
1032 err = -errno;
1033 goto err_out;
1034 }
1035
1036
1037 data = malloc(sz);
1038 if (!data) {
1039 err = -ENOMEM;
1040 goto err_out;
1041 }
1042 if (fread(data, 1, sz, f) < sz) {
1043 err = -EIO;
1044 goto err_out;
1045 }
1046
1047
1048 btf = btf_new(data, sz, base_btf);
1049
1050err_out:
1051 free(data);
1052 if (f)
1053 fclose(f);
1054 return err ? ERR_PTR(err) : btf;
1055}
1056
1057struct btf *btf__parse_raw(const char *path)
1058{
1059 return btf_parse_raw(path, NULL);
1060}
1061
1062struct btf *btf__parse_raw_split(const char *path, struct btf *base_btf)
1063{
1064 return btf_parse_raw(path, base_btf);
1065}
1066
1067static struct btf *btf_parse(const char *path, struct btf *base_btf, struct btf_ext **btf_ext)
1068{
1069 struct btf *btf;
1070
1071 if (btf_ext)
1072 *btf_ext = NULL;
1073
1074 btf = btf_parse_raw(path, base_btf);
1075 if (!IS_ERR(btf) || PTR_ERR(btf) != -EPROTO)
1076 return btf;
1077
1078 return btf_parse_elf(path, base_btf, btf_ext);
1079}
1080
1081struct btf *btf__parse(const char *path, struct btf_ext **btf_ext)
1082{
1083 return btf_parse(path, NULL, btf_ext);
1084}
1085
1086struct btf *btf__parse_split(const char *path, struct btf *base_btf)
1087{
1088 return btf_parse(path, base_btf, NULL);
1089}
1090
1091static int compare_vsi_off(const void *_a, const void *_b)
1092{
1093 const struct btf_var_secinfo *a = _a;
1094 const struct btf_var_secinfo *b = _b;
1095
1096 return a->offset - b->offset;
1097}
1098
1099static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,
1100 struct btf_type *t)
1101{
1102 __u32 size = 0, off = 0, i, vars = btf_vlen(t);
1103 const char *name = btf__name_by_offset(btf, t->name_off);
1104 const struct btf_type *t_var;
1105 struct btf_var_secinfo *vsi;
1106 const struct btf_var *var;
1107 int ret;
1108
1109 if (!name) {
1110 pr_debug("No name found in string section for DATASEC kind.\n");
1111 return -ENOENT;
1112 }
1113
1114
1115
1116
1117 if (t->size)
1118 goto sort_vars;
1119
1120 ret = bpf_object__section_size(obj, name, &size);
1121 if (ret || !size || (t->size && t->size != size)) {
1122 pr_debug("Invalid size for section %s: %u bytes\n", name, size);
1123 return -ENOENT;
1124 }
1125
1126 t->size = size;
1127
1128 for (i = 0, vsi = btf_var_secinfos(t); i < vars; i++, vsi++) {
1129 t_var = btf__type_by_id(btf, vsi->type);
1130 var = btf_var(t_var);
1131
1132 if (!btf_is_var(t_var)) {
1133 pr_debug("Non-VAR type seen in section %s\n", name);
1134 return -EINVAL;
1135 }
1136
1137 if (var->linkage == BTF_VAR_STATIC)
1138 continue;
1139
1140 name = btf__name_by_offset(btf, t_var->name_off);
1141 if (!name) {
1142 pr_debug("No name found in string section for VAR kind\n");
1143 return -ENOENT;
1144 }
1145
1146 ret = bpf_object__variable_offset(obj, name, &off);
1147 if (ret) {
1148 pr_debug("No offset found in symbol table for VAR %s\n",
1149 name);
1150 return -ENOENT;
1151 }
1152
1153 vsi->offset = off;
1154 }
1155
1156sort_vars:
1157 qsort(btf_var_secinfos(t), vars, sizeof(*vsi), compare_vsi_off);
1158 return 0;
1159}
1160
1161int btf__finalize_data(struct bpf_object *obj, struct btf *btf)
1162{
1163 int err = 0;
1164 __u32 i;
1165
1166 for (i = 1; i <= btf->nr_types; i++) {
1167 struct btf_type *t = btf_type_by_id(btf, i);
1168
1169
1170
1171
1172
1173
1174 if (btf_is_datasec(t)) {
1175 err = btf_fixup_datasec(obj, btf, t);
1176 if (err)
1177 break;
1178 }
1179 }
1180
1181 return err;
1182}
1183
1184static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);
1185
1186int btf__load(struct btf *btf)
1187{
1188 __u32 log_buf_size = 0, raw_size;
1189 char *log_buf = NULL;
1190 void *raw_data;
1191 int err = 0;
1192
1193 if (btf->fd >= 0)
1194 return -EEXIST;
1195
1196retry_load:
1197 if (log_buf_size) {
1198 log_buf = malloc(log_buf_size);
1199 if (!log_buf)
1200 return -ENOMEM;
1201
1202 *log_buf = 0;
1203 }
1204
1205 raw_data = btf_get_raw_data(btf, &raw_size, false);
1206 if (!raw_data) {
1207 err = -ENOMEM;
1208 goto done;
1209 }
1210
1211 btf->raw_size = raw_size;
1212 btf->raw_data = raw_data;
1213
1214 btf->fd = bpf_load_btf(raw_data, raw_size, log_buf, log_buf_size, false);
1215 if (btf->fd < 0) {
1216 if (!log_buf || errno == ENOSPC) {
1217 log_buf_size = max((__u32)BPF_LOG_BUF_SIZE,
1218 log_buf_size << 1);
1219 free(log_buf);
1220 goto retry_load;
1221 }
1222
1223 err = -errno;
1224 pr_warn("Error loading BTF: %s(%d)\n", strerror(errno), errno);
1225 if (*log_buf)
1226 pr_warn("%s\n", log_buf);
1227 goto done;
1228 }
1229
1230done:
1231 free(log_buf);
1232 return err;
1233}
1234
1235int btf__fd(const struct btf *btf)
1236{
1237 return btf->fd;
1238}
1239
1240void btf__set_fd(struct btf *btf, int fd)
1241{
1242 btf->fd = fd;
1243}
1244
1245static const void *btf_strs_data(const struct btf *btf)
1246{
1247 return btf->strs_data ? btf->strs_data : strset__data(btf->strs_set);
1248}
1249
1250static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian)
1251{
1252 struct btf_header *hdr = btf->hdr;
1253 struct btf_type *t;
1254 void *data, *p;
1255 __u32 data_sz;
1256 int i;
1257
1258 data = swap_endian ? btf->raw_data_swapped : btf->raw_data;
1259 if (data) {
1260 *size = btf->raw_size;
1261 return data;
1262 }
1263
1264 data_sz = hdr->hdr_len + hdr->type_len + hdr->str_len;
1265 data = calloc(1, data_sz);
1266 if (!data)
1267 return NULL;
1268 p = data;
1269
1270 memcpy(p, hdr, hdr->hdr_len);
1271 if (swap_endian)
1272 btf_bswap_hdr(p);
1273 p += hdr->hdr_len;
1274
1275 memcpy(p, btf->types_data, hdr->type_len);
1276 if (swap_endian) {
1277 for (i = 0; i < btf->nr_types; i++) {
1278 t = p + btf->type_offs[i];
1279
1280
1281
1282
1283 if (btf_bswap_type_rest(t))
1284 goto err_out;
1285 btf_bswap_type_base(t);
1286 }
1287 }
1288 p += hdr->type_len;
1289
1290 memcpy(p, btf_strs_data(btf), hdr->str_len);
1291 p += hdr->str_len;
1292
1293 *size = data_sz;
1294 return data;
1295err_out:
1296 free(data);
1297 return NULL;
1298}
1299
1300const void *btf__get_raw_data(const struct btf *btf_ro, __u32 *size)
1301{
1302 struct btf *btf = (struct btf *)btf_ro;
1303 __u32 data_sz;
1304 void *data;
1305
1306 data = btf_get_raw_data(btf, &data_sz, btf->swapped_endian);
1307 if (!data)
1308 return NULL;
1309
1310 btf->raw_size = data_sz;
1311 if (btf->swapped_endian)
1312 btf->raw_data_swapped = data;
1313 else
1314 btf->raw_data = data;
1315 *size = data_sz;
1316 return data;
1317}
1318
1319const char *btf__str_by_offset(const struct btf *btf, __u32 offset)
1320{
1321 if (offset < btf->start_str_off)
1322 return btf__str_by_offset(btf->base_btf, offset);
1323 else if (offset - btf->start_str_off < btf->hdr->str_len)
1324 return btf_strs_data(btf) + (offset - btf->start_str_off);
1325 else
1326 return NULL;
1327}
1328
1329const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
1330{
1331 return btf__str_by_offset(btf, offset);
1332}
1333
1334struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf)
1335{
1336 struct bpf_btf_info btf_info;
1337 __u32 len = sizeof(btf_info);
1338 __u32 last_size;
1339 struct btf *btf;
1340 void *ptr;
1341 int err;
1342
1343
1344
1345
1346
1347 last_size = 4096;
1348 ptr = malloc(last_size);
1349 if (!ptr)
1350 return ERR_PTR(-ENOMEM);
1351
1352 memset(&btf_info, 0, sizeof(btf_info));
1353 btf_info.btf = ptr_to_u64(ptr);
1354 btf_info.btf_size = last_size;
1355 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
1356
1357 if (!err && btf_info.btf_size > last_size) {
1358 void *temp_ptr;
1359
1360 last_size = btf_info.btf_size;
1361 temp_ptr = realloc(ptr, last_size);
1362 if (!temp_ptr) {
1363 btf = ERR_PTR(-ENOMEM);
1364 goto exit_free;
1365 }
1366 ptr = temp_ptr;
1367
1368 len = sizeof(btf_info);
1369 memset(&btf_info, 0, sizeof(btf_info));
1370 btf_info.btf = ptr_to_u64(ptr);
1371 btf_info.btf_size = last_size;
1372
1373 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
1374 }
1375
1376 if (err || btf_info.btf_size > last_size) {
1377 btf = err ? ERR_PTR(-errno) : ERR_PTR(-E2BIG);
1378 goto exit_free;
1379 }
1380
1381 btf = btf_new(ptr, btf_info.btf_size, base_btf);
1382
1383exit_free:
1384 free(ptr);
1385 return btf;
1386}
1387
1388int btf__get_from_id(__u32 id, struct btf **btf)
1389{
1390 struct btf *res;
1391 int btf_fd;
1392
1393 *btf = NULL;
1394 btf_fd = bpf_btf_get_fd_by_id(id);
1395 if (btf_fd < 0)
1396 return -errno;
1397
1398 res = btf_get_from_fd(btf_fd, NULL);
1399 close(btf_fd);
1400 if (IS_ERR(res))
1401 return PTR_ERR(res);
1402
1403 *btf = res;
1404 return 0;
1405}
1406
1407int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
1408 __u32 expected_key_size, __u32 expected_value_size,
1409 __u32 *key_type_id, __u32 *value_type_id)
1410{
1411 const struct btf_type *container_type;
1412 const struct btf_member *key, *value;
1413 const size_t max_name = 256;
1414 char container_name[max_name];
1415 __s64 key_size, value_size;
1416 __s32 container_id;
1417
1418 if (snprintf(container_name, max_name, "____btf_map_%s", map_name) ==
1419 max_name) {
1420 pr_warn("map:%s length of '____btf_map_%s' is too long\n",
1421 map_name, map_name);
1422 return -EINVAL;
1423 }
1424
1425 container_id = btf__find_by_name(btf, container_name);
1426 if (container_id < 0) {
1427 pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
1428 map_name, container_name);
1429 return container_id;
1430 }
1431
1432 container_type = btf__type_by_id(btf, container_id);
1433 if (!container_type) {
1434 pr_warn("map:%s cannot find BTF type for container_id:%u\n",
1435 map_name, container_id);
1436 return -EINVAL;
1437 }
1438
1439 if (!btf_is_struct(container_type) || btf_vlen(container_type) < 2) {
1440 pr_warn("map:%s container_name:%s is an invalid container struct\n",
1441 map_name, container_name);
1442 return -EINVAL;
1443 }
1444
1445 key = btf_members(container_type);
1446 value = key + 1;
1447
1448 key_size = btf__resolve_size(btf, key->type);
1449 if (key_size < 0) {
1450 pr_warn("map:%s invalid BTF key_type_size\n", map_name);
1451 return key_size;
1452 }
1453
1454 if (expected_key_size != key_size) {
1455 pr_warn("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
1456 map_name, (__u32)key_size, expected_key_size);
1457 return -EINVAL;
1458 }
1459
1460 value_size = btf__resolve_size(btf, value->type);
1461 if (value_size < 0) {
1462 pr_warn("map:%s invalid BTF value_type_size\n", map_name);
1463 return value_size;
1464 }
1465
1466 if (expected_value_size != value_size) {
1467 pr_warn("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
1468 map_name, (__u32)value_size, expected_value_size);
1469 return -EINVAL;
1470 }
1471
1472 *key_type_id = key->type;
1473 *value_type_id = value->type;
1474
1475 return 0;
1476}
1477
1478static void btf_invalidate_raw_data(struct btf *btf)
1479{
1480 if (btf->raw_data) {
1481 free(btf->raw_data);
1482 btf->raw_data = NULL;
1483 }
1484 if (btf->raw_data_swapped) {
1485 free(btf->raw_data_swapped);
1486 btf->raw_data_swapped = NULL;
1487 }
1488}
1489
1490
1491
1492
1493
1494static int btf_ensure_modifiable(struct btf *btf)
1495{
1496 void *hdr, *types;
1497 struct strset *set = NULL;
1498 int err = -ENOMEM;
1499
1500 if (btf_is_modifiable(btf)) {
1501
1502 btf_invalidate_raw_data(btf);
1503 return 0;
1504 }
1505
1506
1507 hdr = malloc(btf->hdr->hdr_len);
1508 types = malloc(btf->hdr->type_len);
1509 if (!hdr || !types)
1510 goto err_out;
1511
1512 memcpy(hdr, btf->hdr, btf->hdr->hdr_len);
1513 memcpy(types, btf->types_data, btf->hdr->type_len);
1514
1515
1516 set = strset__new(BTF_MAX_STR_OFFSET, btf->strs_data, btf->hdr->str_len);
1517 if (IS_ERR(set)) {
1518 err = PTR_ERR(set);
1519 goto err_out;
1520 }
1521
1522
1523 btf->hdr = hdr;
1524 btf->types_data = types;
1525 btf->types_data_cap = btf->hdr->type_len;
1526 btf->strs_data = NULL;
1527 btf->strs_set = set;
1528
1529
1530
1531 if (btf->hdr->str_len == 0)
1532 btf->strs_deduped = true;
1533 if (!btf->base_btf && btf->hdr->str_len == 1)
1534 btf->strs_deduped = true;
1535
1536
1537 btf_invalidate_raw_data(btf);
1538
1539 return 0;
1540
1541err_out:
1542 strset__free(set);
1543 free(hdr);
1544 free(types);
1545 return err;
1546}
1547
1548
1549
1550
1551
1552
1553
1554int btf__find_str(struct btf *btf, const char *s)
1555{
1556 int off;
1557
1558 if (btf->base_btf) {
1559 off = btf__find_str(btf->base_btf, s);
1560 if (off != -ENOENT)
1561 return off;
1562 }
1563
1564
1565 if (btf_ensure_modifiable(btf))
1566 return -ENOMEM;
1567
1568 off = strset__find_str(btf->strs_set, s);
1569 if (off < 0)
1570 return off;
1571
1572 return btf->start_str_off + off;
1573}
1574
1575
1576
1577
1578
1579
1580int btf__add_str(struct btf *btf, const char *s)
1581{
1582 int off;
1583
1584 if (btf->base_btf) {
1585 off = btf__find_str(btf->base_btf, s);
1586 if (off != -ENOENT)
1587 return off;
1588 }
1589
1590 if (btf_ensure_modifiable(btf))
1591 return -ENOMEM;
1592
1593 off = strset__add_str(btf->strs_set, s);
1594 if (off < 0)
1595 return off;
1596
1597 btf->hdr->str_len = strset__data_size(btf->strs_set);
1598
1599 return btf->start_str_off + off;
1600}
1601
1602static void *btf_add_type_mem(struct btf *btf, size_t add_sz)
1603{
1604 return libbpf_add_mem(&btf->types_data, &btf->types_data_cap, 1,
1605 btf->hdr->type_len, UINT_MAX, add_sz);
1606}
1607
1608static void btf_type_inc_vlen(struct btf_type *t)
1609{
1610 t->info = btf_type_info(btf_kind(t), btf_vlen(t) + 1, btf_kflag(t));
1611}
1612
1613static int btf_commit_type(struct btf *btf, int data_sz)
1614{
1615 int err;
1616
1617 err = btf_add_type_idx_entry(btf, btf->hdr->type_len);
1618 if (err)
1619 return err;
1620
1621 btf->hdr->type_len += data_sz;
1622 btf->hdr->str_off += data_sz;
1623 btf->nr_types++;
1624 return btf->start_id + btf->nr_types - 1;
1625}
1626
1627struct btf_pipe {
1628 const struct btf *src;
1629 struct btf *dst;
1630};
1631
1632static int btf_rewrite_str(__u32 *str_off, void *ctx)
1633{
1634 struct btf_pipe *p = ctx;
1635 int off;
1636
1637 if (!*str_off)
1638 return 0;
1639
1640 off = btf__add_str(p->dst, btf__str_by_offset(p->src, *str_off));
1641 if (off < 0)
1642 return off;
1643
1644 *str_off = off;
1645 return 0;
1646}
1647
1648int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_type *src_type)
1649{
1650 struct btf_pipe p = { .src = src_btf, .dst = btf };
1651 struct btf_type *t;
1652 int sz, err;
1653
1654 sz = btf_type_size(src_type);
1655 if (sz < 0)
1656 return sz;
1657
1658
1659 if (btf_ensure_modifiable(btf))
1660 return -ENOMEM;
1661
1662 t = btf_add_type_mem(btf, sz);
1663 if (!t)
1664 return -ENOMEM;
1665
1666 memcpy(t, src_type, sz);
1667
1668 err = btf_type_visit_str_offs(t, btf_rewrite_str, &p);
1669 if (err)
1670 return err;
1671
1672 return btf_commit_type(btf, sz);
1673}
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding)
1685{
1686 struct btf_type *t;
1687 int sz, name_off;
1688
1689
1690 if (!name || !name[0])
1691 return -EINVAL;
1692
1693 if (!byte_sz || (byte_sz & (byte_sz - 1)) || byte_sz > 16)
1694 return -EINVAL;
1695 if (encoding & ~(BTF_INT_SIGNED | BTF_INT_CHAR | BTF_INT_BOOL))
1696 return -EINVAL;
1697
1698
1699 if (btf_ensure_modifiable(btf))
1700 return -ENOMEM;
1701
1702 sz = sizeof(struct btf_type) + sizeof(int);
1703 t = btf_add_type_mem(btf, sz);
1704 if (!t)
1705 return -ENOMEM;
1706
1707
1708
1709
1710
1711 name_off = btf__add_str(btf, name);
1712 if (name_off < 0)
1713 return name_off;
1714
1715 t->name_off = name_off;
1716 t->info = btf_type_info(BTF_KIND_INT, 0, 0);
1717 t->size = byte_sz;
1718
1719 *(__u32 *)(t + 1) = (encoding << 24) | (byte_sz * 8);
1720
1721 return btf_commit_type(btf, sz);
1722}
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732int btf__add_float(struct btf *btf, const char *name, size_t byte_sz)
1733{
1734 struct btf_type *t;
1735 int sz, name_off;
1736
1737
1738 if (!name || !name[0])
1739 return -EINVAL;
1740
1741
1742 if (byte_sz != 2 && byte_sz != 4 && byte_sz != 8 && byte_sz != 12 &&
1743 byte_sz != 16)
1744 return -EINVAL;
1745
1746 if (btf_ensure_modifiable(btf))
1747 return -ENOMEM;
1748
1749 sz = sizeof(struct btf_type);
1750 t = btf_add_type_mem(btf, sz);
1751 if (!t)
1752 return -ENOMEM;
1753
1754 name_off = btf__add_str(btf, name);
1755 if (name_off < 0)
1756 return name_off;
1757
1758 t->name_off = name_off;
1759 t->info = btf_type_info(BTF_KIND_FLOAT, 0, 0);
1760 t->size = byte_sz;
1761
1762 return btf_commit_type(btf, sz);
1763}
1764
1765
1766
1767
1768
1769static int validate_type_id(int id)
1770{
1771 if (id < 0 || id > BTF_MAX_NR_TYPES)
1772 return -EINVAL;
1773 return 0;
1774}
1775
1776
1777static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id)
1778{
1779 struct btf_type *t;
1780 int sz, name_off = 0;
1781
1782 if (validate_type_id(ref_type_id))
1783 return -EINVAL;
1784
1785 if (btf_ensure_modifiable(btf))
1786 return -ENOMEM;
1787
1788 sz = sizeof(struct btf_type);
1789 t = btf_add_type_mem(btf, sz);
1790 if (!t)
1791 return -ENOMEM;
1792
1793 if (name && name[0]) {
1794 name_off = btf__add_str(btf, name);
1795 if (name_off < 0)
1796 return name_off;
1797 }
1798
1799 t->name_off = name_off;
1800 t->info = btf_type_info(kind, 0, 0);
1801 t->type = ref_type_id;
1802
1803 return btf_commit_type(btf, sz);
1804}
1805
1806
1807
1808
1809
1810
1811
1812
1813int btf__add_ptr(struct btf *btf, int ref_type_id)
1814{
1815 return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id);
1816}
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827int btf__add_array(struct btf *btf, int index_type_id, int elem_type_id, __u32 nr_elems)
1828{
1829 struct btf_type *t;
1830 struct btf_array *a;
1831 int sz;
1832
1833 if (validate_type_id(index_type_id) || validate_type_id(elem_type_id))
1834 return -EINVAL;
1835
1836 if (btf_ensure_modifiable(btf))
1837 return -ENOMEM;
1838
1839 sz = sizeof(struct btf_type) + sizeof(struct btf_array);
1840 t = btf_add_type_mem(btf, sz);
1841 if (!t)
1842 return -ENOMEM;
1843
1844 t->name_off = 0;
1845 t->info = btf_type_info(BTF_KIND_ARRAY, 0, 0);
1846 t->size = 0;
1847
1848 a = btf_array(t);
1849 a->type = elem_type_id;
1850 a->index_type = index_type_id;
1851 a->nelems = nr_elems;
1852
1853 return btf_commit_type(btf, sz);
1854}
1855
1856
1857static int btf_add_composite(struct btf *btf, int kind, const char *name, __u32 bytes_sz)
1858{
1859 struct btf_type *t;
1860 int sz, name_off = 0;
1861
1862 if (btf_ensure_modifiable(btf))
1863 return -ENOMEM;
1864
1865 sz = sizeof(struct btf_type);
1866 t = btf_add_type_mem(btf, sz);
1867 if (!t)
1868 return -ENOMEM;
1869
1870 if (name && name[0]) {
1871 name_off = btf__add_str(btf, name);
1872 if (name_off < 0)
1873 return name_off;
1874 }
1875
1876
1877
1878
1879 t->name_off = name_off;
1880 t->info = btf_type_info(kind, 0, 0);
1881 t->size = bytes_sz;
1882
1883 return btf_commit_type(btf, sz);
1884}
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898int btf__add_struct(struct btf *btf, const char *name, __u32 byte_sz)
1899{
1900 return btf_add_composite(btf, BTF_KIND_STRUCT, name, byte_sz);
1901}
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916int btf__add_union(struct btf *btf, const char *name, __u32 byte_sz)
1917{
1918 return btf_add_composite(btf, BTF_KIND_UNION, name, byte_sz);
1919}
1920
1921static struct btf_type *btf_last_type(struct btf *btf)
1922{
1923 return btf_type_by_id(btf, btf__get_nr_types(btf));
1924}
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936int btf__add_field(struct btf *btf, const char *name, int type_id,
1937 __u32 bit_offset, __u32 bit_size)
1938{
1939 struct btf_type *t;
1940 struct btf_member *m;
1941 bool is_bitfield;
1942 int sz, name_off = 0;
1943
1944
1945 if (btf->nr_types == 0)
1946 return -EINVAL;
1947 t = btf_last_type(btf);
1948 if (!btf_is_composite(t))
1949 return -EINVAL;
1950
1951 if (validate_type_id(type_id))
1952 return -EINVAL;
1953
1954 is_bitfield = bit_size || (bit_offset % 8 != 0);
1955 if (is_bitfield && (bit_size == 0 || bit_size > 255 || bit_offset > 0xffffff))
1956 return -EINVAL;
1957
1958
1959 if (btf_is_union(t) && bit_offset)
1960 return -EINVAL;
1961
1962
1963 if (btf_ensure_modifiable(btf))
1964 return -ENOMEM;
1965
1966 sz = sizeof(struct btf_member);
1967 m = btf_add_type_mem(btf, sz);
1968 if (!m)
1969 return -ENOMEM;
1970
1971 if (name && name[0]) {
1972 name_off = btf__add_str(btf, name);
1973 if (name_off < 0)
1974 return name_off;
1975 }
1976
1977 m->name_off = name_off;
1978 m->type = type_id;
1979 m->offset = bit_offset | (bit_size << 24);
1980
1981
1982 t = btf_last_type(btf);
1983
1984 t->info = btf_type_info(btf_kind(t), btf_vlen(t) + 1, is_bitfield || btf_kflag(t));
1985
1986 btf->hdr->type_len += sz;
1987 btf->hdr->str_off += sz;
1988 return 0;
1989}
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004int btf__add_enum(struct btf *btf, const char *name, __u32 byte_sz)
2005{
2006 struct btf_type *t;
2007 int sz, name_off = 0;
2008
2009
2010 if (!byte_sz || (byte_sz & (byte_sz - 1)) || byte_sz > 8)
2011 return -EINVAL;
2012
2013 if (btf_ensure_modifiable(btf))
2014 return -ENOMEM;
2015
2016 sz = sizeof(struct btf_type);
2017 t = btf_add_type_mem(btf, sz);
2018 if (!t)
2019 return -ENOMEM;
2020
2021 if (name && name[0]) {
2022 name_off = btf__add_str(btf, name);
2023 if (name_off < 0)
2024 return name_off;
2025 }
2026
2027
2028 t->name_off = name_off;
2029 t->info = btf_type_info(BTF_KIND_ENUM, 0, 0);
2030 t->size = byte_sz;
2031
2032 return btf_commit_type(btf, sz);
2033}
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043int btf__add_enum_value(struct btf *btf, const char *name, __s64 value)
2044{
2045 struct btf_type *t;
2046 struct btf_enum *v;
2047 int sz, name_off;
2048
2049
2050 if (btf->nr_types == 0)
2051 return -EINVAL;
2052 t = btf_last_type(btf);
2053 if (!btf_is_enum(t))
2054 return -EINVAL;
2055
2056
2057 if (!name || !name[0])
2058 return -EINVAL;
2059 if (value < INT_MIN || value > UINT_MAX)
2060 return -E2BIG;
2061
2062
2063 if (btf_ensure_modifiable(btf))
2064 return -ENOMEM;
2065
2066 sz = sizeof(struct btf_enum);
2067 v = btf_add_type_mem(btf, sz);
2068 if (!v)
2069 return -ENOMEM;
2070
2071 name_off = btf__add_str(btf, name);
2072 if (name_off < 0)
2073 return name_off;
2074
2075 v->name_off = name_off;
2076 v->val = value;
2077
2078
2079 t = btf_last_type(btf);
2080 btf_type_inc_vlen(t);
2081
2082 btf->hdr->type_len += sz;
2083 btf->hdr->str_off += sz;
2084 return 0;
2085}
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind)
2097{
2098 if (!name || !name[0])
2099 return -EINVAL;
2100
2101 switch (fwd_kind) {
2102 case BTF_FWD_STRUCT:
2103 case BTF_FWD_UNION: {
2104 struct btf_type *t;
2105 int id;
2106
2107 id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0);
2108 if (id <= 0)
2109 return id;
2110 t = btf_type_by_id(btf, id);
2111 t->info = btf_type_info(BTF_KIND_FWD, 0, fwd_kind == BTF_FWD_UNION);
2112 return id;
2113 }
2114 case BTF_FWD_ENUM:
2115
2116
2117
2118 return btf__add_enum(btf, name, sizeof(int));
2119 default:
2120 return -EINVAL;
2121 }
2122}
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id)
2133{
2134 if (!name || !name[0])
2135 return -EINVAL;
2136
2137 return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id);
2138}
2139
2140
2141
2142
2143
2144
2145
2146
2147int btf__add_volatile(struct btf *btf, int ref_type_id)
2148{
2149 return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id);
2150}
2151
2152
2153
2154
2155
2156
2157
2158
2159int btf__add_const(struct btf *btf, int ref_type_id)
2160{
2161 return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id);
2162}
2163
2164
2165
2166
2167
2168
2169
2170
2171int btf__add_restrict(struct btf *btf, int ref_type_id)
2172{
2173 return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id);
2174}
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184int btf__add_func(struct btf *btf, const char *name,
2185 enum btf_func_linkage linkage, int proto_type_id)
2186{
2187 int id;
2188
2189 if (!name || !name[0])
2190 return -EINVAL;
2191 if (linkage != BTF_FUNC_STATIC && linkage != BTF_FUNC_GLOBAL &&
2192 linkage != BTF_FUNC_EXTERN)
2193 return -EINVAL;
2194
2195 id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id);
2196 if (id > 0) {
2197 struct btf_type *t = btf_type_by_id(btf, id);
2198
2199 t->info = btf_type_info(BTF_KIND_FUNC, linkage, 0);
2200 }
2201 return id;
2202}
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216int btf__add_func_proto(struct btf *btf, int ret_type_id)
2217{
2218 struct btf_type *t;
2219 int sz;
2220
2221 if (validate_type_id(ret_type_id))
2222 return -EINVAL;
2223
2224 if (btf_ensure_modifiable(btf))
2225 return -ENOMEM;
2226
2227 sz = sizeof(struct btf_type);
2228 t = btf_add_type_mem(btf, sz);
2229 if (!t)
2230 return -ENOMEM;
2231
2232
2233
2234
2235 t->name_off = 0;
2236 t->info = btf_type_info(BTF_KIND_FUNC_PROTO, 0, 0);
2237 t->type = ret_type_id;
2238
2239 return btf_commit_type(btf, sz);
2240}
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250int btf__add_func_param(struct btf *btf, const char *name, int type_id)
2251{
2252 struct btf_type *t;
2253 struct btf_param *p;
2254 int sz, name_off = 0;
2255
2256 if (validate_type_id(type_id))
2257 return -EINVAL;
2258
2259
2260 if (btf->nr_types == 0)
2261 return -EINVAL;
2262 t = btf_last_type(btf);
2263 if (!btf_is_func_proto(t))
2264 return -EINVAL;
2265
2266
2267 if (btf_ensure_modifiable(btf))
2268 return -ENOMEM;
2269
2270 sz = sizeof(struct btf_param);
2271 p = btf_add_type_mem(btf, sz);
2272 if (!p)
2273 return -ENOMEM;
2274
2275 if (name && name[0]) {
2276 name_off = btf__add_str(btf, name);
2277 if (name_off < 0)
2278 return name_off;
2279 }
2280
2281 p->name_off = name_off;
2282 p->type = type_id;
2283
2284
2285 t = btf_last_type(btf);
2286 btf_type_inc_vlen(t);
2287
2288 btf->hdr->type_len += sz;
2289 btf->hdr->str_off += sz;
2290 return 0;
2291}
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303int btf__add_var(struct btf *btf, const char *name, int linkage, int type_id)
2304{
2305 struct btf_type *t;
2306 struct btf_var *v;
2307 int sz, name_off;
2308
2309
2310 if (!name || !name[0])
2311 return -EINVAL;
2312 if (linkage != BTF_VAR_STATIC && linkage != BTF_VAR_GLOBAL_ALLOCATED &&
2313 linkage != BTF_VAR_GLOBAL_EXTERN)
2314 return -EINVAL;
2315 if (validate_type_id(type_id))
2316 return -EINVAL;
2317
2318
2319 if (btf_ensure_modifiable(btf))
2320 return -ENOMEM;
2321
2322 sz = sizeof(struct btf_type) + sizeof(struct btf_var);
2323 t = btf_add_type_mem(btf, sz);
2324 if (!t)
2325 return -ENOMEM;
2326
2327 name_off = btf__add_str(btf, name);
2328 if (name_off < 0)
2329 return name_off;
2330
2331 t->name_off = name_off;
2332 t->info = btf_type_info(BTF_KIND_VAR, 0, 0);
2333 t->type = type_id;
2334
2335 v = btf_var(t);
2336 v->linkage = linkage;
2337
2338 return btf_commit_type(btf, sz);
2339}
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353int btf__add_datasec(struct btf *btf, const char *name, __u32 byte_sz)
2354{
2355 struct btf_type *t;
2356 int sz, name_off;
2357
2358
2359 if (!name || !name[0])
2360 return -EINVAL;
2361
2362 if (btf_ensure_modifiable(btf))
2363 return -ENOMEM;
2364
2365 sz = sizeof(struct btf_type);
2366 t = btf_add_type_mem(btf, sz);
2367 if (!t)
2368 return -ENOMEM;
2369
2370 name_off = btf__add_str(btf, name);
2371 if (name_off < 0)
2372 return name_off;
2373
2374
2375 t->name_off = name_off;
2376 t->info = btf_type_info(BTF_KIND_DATASEC, 0, 0);
2377 t->size = byte_sz;
2378
2379 return btf_commit_type(btf, sz);
2380}
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __u32 byte_sz)
2393{
2394 struct btf_type *t;
2395 struct btf_var_secinfo *v;
2396 int sz;
2397
2398
2399 if (btf->nr_types == 0)
2400 return -EINVAL;
2401 t = btf_last_type(btf);
2402 if (!btf_is_datasec(t))
2403 return -EINVAL;
2404
2405 if (validate_type_id(var_type_id))
2406 return -EINVAL;
2407
2408
2409 if (btf_ensure_modifiable(btf))
2410 return -ENOMEM;
2411
2412 sz = sizeof(struct btf_var_secinfo);
2413 v = btf_add_type_mem(btf, sz);
2414 if (!v)
2415 return -ENOMEM;
2416
2417 v->type = var_type_id;
2418 v->offset = offset;
2419 v->size = byte_sz;
2420
2421
2422 t = btf_last_type(btf);
2423 btf_type_inc_vlen(t);
2424
2425 btf->hdr->type_len += sz;
2426 btf->hdr->str_off += sz;
2427 return 0;
2428}
2429
2430struct btf_ext_sec_setup_param {
2431 __u32 off;
2432 __u32 len;
2433 __u32 min_rec_size;
2434 struct btf_ext_info *ext_info;
2435 const char *desc;
2436};
2437
2438static int btf_ext_setup_info(struct btf_ext *btf_ext,
2439 struct btf_ext_sec_setup_param *ext_sec)
2440{
2441 const struct btf_ext_info_sec *sinfo;
2442 struct btf_ext_info *ext_info;
2443 __u32 info_left, record_size;
2444
2445 void *info;
2446
2447 if (ext_sec->len == 0)
2448 return 0;
2449
2450 if (ext_sec->off & 0x03) {
2451 pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
2452 ext_sec->desc);
2453 return -EINVAL;
2454 }
2455
2456 info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
2457 info_left = ext_sec->len;
2458
2459 if (btf_ext->data + btf_ext->data_size < info + ext_sec->len) {
2460 pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
2461 ext_sec->desc, ext_sec->off, ext_sec->len);
2462 return -EINVAL;
2463 }
2464
2465
2466 if (info_left < sizeof(__u32)) {
2467 pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc);
2468 return -EINVAL;
2469 }
2470
2471
2472 record_size = *(__u32 *)info;
2473 if (record_size < ext_sec->min_rec_size ||
2474 record_size & 0x03) {
2475 pr_debug("%s section in .BTF.ext has invalid record size %u\n",
2476 ext_sec->desc, record_size);
2477 return -EINVAL;
2478 }
2479
2480 sinfo = info + sizeof(__u32);
2481 info_left -= sizeof(__u32);
2482
2483
2484 if (!info_left) {
2485 pr_debug("%s section in .BTF.ext has no records", ext_sec->desc);
2486 return -EINVAL;
2487 }
2488
2489 while (info_left) {
2490 unsigned int sec_hdrlen = sizeof(struct btf_ext_info_sec);
2491 __u64 total_record_size;
2492 __u32 num_records;
2493
2494 if (info_left < sec_hdrlen) {
2495 pr_debug("%s section header is not found in .BTF.ext\n",
2496 ext_sec->desc);
2497 return -EINVAL;
2498 }
2499
2500 num_records = sinfo->num_info;
2501 if (num_records == 0) {
2502 pr_debug("%s section has incorrect num_records in .BTF.ext\n",
2503 ext_sec->desc);
2504 return -EINVAL;
2505 }
2506
2507 total_record_size = sec_hdrlen +
2508 (__u64)num_records * record_size;
2509 if (info_left < total_record_size) {
2510 pr_debug("%s section has incorrect num_records in .BTF.ext\n",
2511 ext_sec->desc);
2512 return -EINVAL;
2513 }
2514
2515 info_left -= total_record_size;
2516 sinfo = (void *)sinfo + total_record_size;
2517 }
2518
2519 ext_info = ext_sec->ext_info;
2520 ext_info->len = ext_sec->len - sizeof(__u32);
2521 ext_info->rec_size = record_size;
2522 ext_info->info = info + sizeof(__u32);
2523
2524 return 0;
2525}
2526
2527static int btf_ext_setup_func_info(struct btf_ext *btf_ext)
2528{
2529 struct btf_ext_sec_setup_param param = {
2530 .off = btf_ext->hdr->func_info_off,
2531 .len = btf_ext->hdr->func_info_len,
2532 .min_rec_size = sizeof(struct bpf_func_info_min),
2533 .ext_info = &btf_ext->func_info,
2534 .desc = "func_info"
2535 };
2536
2537 return btf_ext_setup_info(btf_ext, ¶m);
2538}
2539
2540static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
2541{
2542 struct btf_ext_sec_setup_param param = {
2543 .off = btf_ext->hdr->line_info_off,
2544 .len = btf_ext->hdr->line_info_len,
2545 .min_rec_size = sizeof(struct bpf_line_info_min),
2546 .ext_info = &btf_ext->line_info,
2547 .desc = "line_info",
2548 };
2549
2550 return btf_ext_setup_info(btf_ext, ¶m);
2551}
2552
2553static int btf_ext_setup_core_relos(struct btf_ext *btf_ext)
2554{
2555 struct btf_ext_sec_setup_param param = {
2556 .off = btf_ext->hdr->core_relo_off,
2557 .len = btf_ext->hdr->core_relo_len,
2558 .min_rec_size = sizeof(struct bpf_core_relo),
2559 .ext_info = &btf_ext->core_relo_info,
2560 .desc = "core_relo",
2561 };
2562
2563 return btf_ext_setup_info(btf_ext, ¶m);
2564}
2565
2566static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
2567{
2568 const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
2569
2570 if (data_size < offsetofend(struct btf_ext_header, hdr_len) ||
2571 data_size < hdr->hdr_len) {
2572 pr_debug("BTF.ext header not found");
2573 return -EINVAL;
2574 }
2575
2576 if (hdr->magic == bswap_16(BTF_MAGIC)) {
2577 pr_warn("BTF.ext in non-native endianness is not supported\n");
2578 return -ENOTSUP;
2579 } else if (hdr->magic != BTF_MAGIC) {
2580 pr_debug("Invalid BTF.ext magic:%x\n", hdr->magic);
2581 return -EINVAL;
2582 }
2583
2584 if (hdr->version != BTF_VERSION) {
2585 pr_debug("Unsupported BTF.ext version:%u\n", hdr->version);
2586 return -ENOTSUP;
2587 }
2588
2589 if (hdr->flags) {
2590 pr_debug("Unsupported BTF.ext flags:%x\n", hdr->flags);
2591 return -ENOTSUP;
2592 }
2593
2594 if (data_size == hdr->hdr_len) {
2595 pr_debug("BTF.ext has no data\n");
2596 return -EINVAL;
2597 }
2598
2599 return 0;
2600}
2601
2602void btf_ext__free(struct btf_ext *btf_ext)
2603{
2604 if (IS_ERR_OR_NULL(btf_ext))
2605 return;
2606 free(btf_ext->data);
2607 free(btf_ext);
2608}
2609
2610struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
2611{
2612 struct btf_ext *btf_ext;
2613 int err;
2614
2615 err = btf_ext_parse_hdr(data, size);
2616 if (err)
2617 return ERR_PTR(err);
2618
2619 btf_ext = calloc(1, sizeof(struct btf_ext));
2620 if (!btf_ext)
2621 return ERR_PTR(-ENOMEM);
2622
2623 btf_ext->data_size = size;
2624 btf_ext->data = malloc(size);
2625 if (!btf_ext->data) {
2626 err = -ENOMEM;
2627 goto done;
2628 }
2629 memcpy(btf_ext->data, data, size);
2630
2631 if (btf_ext->hdr->hdr_len <
2632 offsetofend(struct btf_ext_header, line_info_len))
2633 goto done;
2634 err = btf_ext_setup_func_info(btf_ext);
2635 if (err)
2636 goto done;
2637
2638 err = btf_ext_setup_line_info(btf_ext);
2639 if (err)
2640 goto done;
2641
2642 if (btf_ext->hdr->hdr_len < offsetofend(struct btf_ext_header, core_relo_len))
2643 goto done;
2644 err = btf_ext_setup_core_relos(btf_ext);
2645 if (err)
2646 goto done;
2647
2648done:
2649 if (err) {
2650 btf_ext__free(btf_ext);
2651 return ERR_PTR(err);
2652 }
2653
2654 return btf_ext;
2655}
2656
2657const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size)
2658{
2659 *size = btf_ext->data_size;
2660 return btf_ext->data;
2661}
2662
2663static int btf_ext_reloc_info(const struct btf *btf,
2664 const struct btf_ext_info *ext_info,
2665 const char *sec_name, __u32 insns_cnt,
2666 void **info, __u32 *cnt)
2667{
2668 __u32 sec_hdrlen = sizeof(struct btf_ext_info_sec);
2669 __u32 i, record_size, existing_len, records_len;
2670 struct btf_ext_info_sec *sinfo;
2671 const char *info_sec_name;
2672 __u64 remain_len;
2673 void *data;
2674
2675 record_size = ext_info->rec_size;
2676 sinfo = ext_info->info;
2677 remain_len = ext_info->len;
2678 while (remain_len > 0) {
2679 records_len = sinfo->num_info * record_size;
2680 info_sec_name = btf__name_by_offset(btf, sinfo->sec_name_off);
2681 if (strcmp(info_sec_name, sec_name)) {
2682 remain_len -= sec_hdrlen + records_len;
2683 sinfo = (void *)sinfo + sec_hdrlen + records_len;
2684 continue;
2685 }
2686
2687 existing_len = (*cnt) * record_size;
2688 data = realloc(*info, existing_len + records_len);
2689 if (!data)
2690 return -ENOMEM;
2691
2692 memcpy(data + existing_len, sinfo->data, records_len);
2693
2694
2695
2696 for (i = 0; i < sinfo->num_info; i++) {
2697 __u32 *insn_off;
2698
2699 insn_off = data + existing_len + (i * record_size);
2700 *insn_off = *insn_off / sizeof(struct bpf_insn) +
2701 insns_cnt;
2702 }
2703 *info = data;
2704 *cnt += sinfo->num_info;
2705 return 0;
2706 }
2707
2708 return -ENOENT;
2709}
2710
2711int btf_ext__reloc_func_info(const struct btf *btf,
2712 const struct btf_ext *btf_ext,
2713 const char *sec_name, __u32 insns_cnt,
2714 void **func_info, __u32 *cnt)
2715{
2716 return btf_ext_reloc_info(btf, &btf_ext->func_info, sec_name,
2717 insns_cnt, func_info, cnt);
2718}
2719
2720int btf_ext__reloc_line_info(const struct btf *btf,
2721 const struct btf_ext *btf_ext,
2722 const char *sec_name, __u32 insns_cnt,
2723 void **line_info, __u32 *cnt)
2724{
2725 return btf_ext_reloc_info(btf, &btf_ext->line_info, sec_name,
2726 insns_cnt, line_info, cnt);
2727}
2728
2729__u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext)
2730{
2731 return btf_ext->func_info.rec_size;
2732}
2733
2734__u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext)
2735{
2736 return btf_ext->line_info.rec_size;
2737}
2738
2739struct btf_dedup;
2740
2741static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext,
2742 const struct btf_dedup_opts *opts);
2743static void btf_dedup_free(struct btf_dedup *d);
2744static int btf_dedup_prep(struct btf_dedup *d);
2745static int btf_dedup_strings(struct btf_dedup *d);
2746static int btf_dedup_prim_types(struct btf_dedup *d);
2747static int btf_dedup_struct_types(struct btf_dedup *d);
2748static int btf_dedup_ref_types(struct btf_dedup *d);
2749static int btf_dedup_compact_types(struct btf_dedup *d);
2750static int btf_dedup_remap_types(struct btf_dedup *d);
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889int btf__dedup(struct btf *btf, struct btf_ext *btf_ext,
2890 const struct btf_dedup_opts *opts)
2891{
2892 struct btf_dedup *d = btf_dedup_new(btf, btf_ext, opts);
2893 int err;
2894
2895 if (IS_ERR(d)) {
2896 pr_debug("btf_dedup_new failed: %ld", PTR_ERR(d));
2897 return -EINVAL;
2898 }
2899
2900 if (btf_ensure_modifiable(btf))
2901 return -ENOMEM;
2902
2903 err = btf_dedup_prep(d);
2904 if (err) {
2905 pr_debug("btf_dedup_prep failed:%d\n", err);
2906 goto done;
2907 }
2908 err = btf_dedup_strings(d);
2909 if (err < 0) {
2910 pr_debug("btf_dedup_strings failed:%d\n", err);
2911 goto done;
2912 }
2913 err = btf_dedup_prim_types(d);
2914 if (err < 0) {
2915 pr_debug("btf_dedup_prim_types failed:%d\n", err);
2916 goto done;
2917 }
2918 err = btf_dedup_struct_types(d);
2919 if (err < 0) {
2920 pr_debug("btf_dedup_struct_types failed:%d\n", err);
2921 goto done;
2922 }
2923 err = btf_dedup_ref_types(d);
2924 if (err < 0) {
2925 pr_debug("btf_dedup_ref_types failed:%d\n", err);
2926 goto done;
2927 }
2928 err = btf_dedup_compact_types(d);
2929 if (err < 0) {
2930 pr_debug("btf_dedup_compact_types failed:%d\n", err);
2931 goto done;
2932 }
2933 err = btf_dedup_remap_types(d);
2934 if (err < 0) {
2935 pr_debug("btf_dedup_remap_types failed:%d\n", err);
2936 goto done;
2937 }
2938
2939done:
2940 btf_dedup_free(d);
2941 return err;
2942}
2943
2944#define BTF_UNPROCESSED_ID ((__u32)-1)
2945#define BTF_IN_PROGRESS_ID ((__u32)-2)
2946
2947struct btf_dedup {
2948
2949 struct btf *btf;
2950
2951
2952
2953
2954 struct btf_ext *btf_ext;
2955
2956
2957
2958
2959
2960
2961
2962 struct hashmap *dedup_table;
2963
2964 __u32 *map;
2965
2966 __u32 *hypot_map;
2967 __u32 *hypot_list;
2968 size_t hypot_cnt;
2969 size_t hypot_cap;
2970
2971
2972
2973
2974
2975
2976 bool hypot_adjust_canon;
2977
2978 struct btf_dedup_opts opts;
2979
2980 struct strset *strs_set;
2981};
2982
2983static long hash_combine(long h, long value)
2984{
2985 return h * 31 + value;
2986}
2987
2988#define for_each_dedup_cand(d, node, hash) \
2989 hashmap__for_each_key_entry(d->dedup_table, node, (void *)hash)
2990
2991static int btf_dedup_table_add(struct btf_dedup *d, long hash, __u32 type_id)
2992{
2993 return hashmap__append(d->dedup_table,
2994 (void *)hash, (void *)(long)type_id);
2995}
2996
2997static int btf_dedup_hypot_map_add(struct btf_dedup *d,
2998 __u32 from_id, __u32 to_id)
2999{
3000 if (d->hypot_cnt == d->hypot_cap) {
3001 __u32 *new_list;
3002
3003 d->hypot_cap += max((size_t)16, d->hypot_cap / 2);
3004 new_list = libbpf_reallocarray(d->hypot_list, d->hypot_cap, sizeof(__u32));
3005 if (!new_list)
3006 return -ENOMEM;
3007 d->hypot_list = new_list;
3008 }
3009 d->hypot_list[d->hypot_cnt++] = from_id;
3010 d->hypot_map[from_id] = to_id;
3011 return 0;
3012}
3013
3014static void btf_dedup_clear_hypot_map(struct btf_dedup *d)
3015{
3016 int i;
3017
3018 for (i = 0; i < d->hypot_cnt; i++)
3019 d->hypot_map[d->hypot_list[i]] = BTF_UNPROCESSED_ID;
3020 d->hypot_cnt = 0;
3021 d->hypot_adjust_canon = false;
3022}
3023
3024static void btf_dedup_free(struct btf_dedup *d)
3025{
3026 hashmap__free(d->dedup_table);
3027 d->dedup_table = NULL;
3028
3029 free(d->map);
3030 d->map = NULL;
3031
3032 free(d->hypot_map);
3033 d->hypot_map = NULL;
3034
3035 free(d->hypot_list);
3036 d->hypot_list = NULL;
3037
3038 free(d);
3039}
3040
3041static size_t btf_dedup_identity_hash_fn(const void *key, void *ctx)
3042{
3043 return (size_t)key;
3044}
3045
3046static size_t btf_dedup_collision_hash_fn(const void *key, void *ctx)
3047{
3048 return 0;
3049}
3050
3051static bool btf_dedup_equal_fn(const void *k1, const void *k2, void *ctx)
3052{
3053 return k1 == k2;
3054}
3055
3056static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext,
3057 const struct btf_dedup_opts *opts)
3058{
3059 struct btf_dedup *d = calloc(1, sizeof(struct btf_dedup));
3060 hashmap_hash_fn hash_fn = btf_dedup_identity_hash_fn;
3061 int i, err = 0, type_cnt;
3062
3063 if (!d)
3064 return ERR_PTR(-ENOMEM);
3065
3066 d->opts.dont_resolve_fwds = opts && opts->dont_resolve_fwds;
3067
3068 if (opts && opts->dedup_table_size == 1)
3069 hash_fn = btf_dedup_collision_hash_fn;
3070
3071 d->btf = btf;
3072 d->btf_ext = btf_ext;
3073
3074 d->dedup_table = hashmap__new(hash_fn, btf_dedup_equal_fn, NULL);
3075 if (IS_ERR(d->dedup_table)) {
3076 err = PTR_ERR(d->dedup_table);
3077 d->dedup_table = NULL;
3078 goto done;
3079 }
3080
3081 type_cnt = btf__get_nr_types(btf) + 1;
3082 d->map = malloc(sizeof(__u32) * type_cnt);
3083 if (!d->map) {
3084 err = -ENOMEM;
3085 goto done;
3086 }
3087
3088 d->map[0] = 0;
3089 for (i = 1; i < type_cnt; i++) {
3090 struct btf_type *t = btf_type_by_id(d->btf, i);
3091
3092
3093 if (btf_is_var(t) || btf_is_datasec(t))
3094 d->map[i] = i;
3095 else
3096 d->map[i] = BTF_UNPROCESSED_ID;
3097 }
3098
3099 d->hypot_map = malloc(sizeof(__u32) * type_cnt);
3100 if (!d->hypot_map) {
3101 err = -ENOMEM;
3102 goto done;
3103 }
3104 for (i = 0; i < type_cnt; i++)
3105 d->hypot_map[i] = BTF_UNPROCESSED_ID;
3106
3107done:
3108 if (err) {
3109 btf_dedup_free(d);
3110 return ERR_PTR(err);
3111 }
3112
3113 return d;
3114}
3115
3116
3117
3118
3119
3120static int btf_for_each_str_off(struct btf_dedup *d, str_off_visit_fn fn, void *ctx)
3121{
3122 int i, r;
3123
3124 for (i = 0; i < d->btf->nr_types; i++) {
3125 struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i);
3126
3127 r = btf_type_visit_str_offs(t, fn, ctx);
3128 if (r)
3129 return r;
3130 }
3131
3132 if (!d->btf_ext)
3133 return 0;
3134
3135 r = btf_ext_visit_str_offs(d->btf_ext, fn, ctx);
3136 if (r)
3137 return r;
3138
3139 return 0;
3140}
3141
3142static int strs_dedup_remap_str_off(__u32 *str_off_ptr, void *ctx)
3143{
3144 struct btf_dedup *d = ctx;
3145 __u32 str_off = *str_off_ptr;
3146 const char *s;
3147 int off, err;
3148
3149
3150 if (str_off == 0 || str_off < d->btf->start_str_off)
3151 return 0;
3152
3153 s = btf__str_by_offset(d->btf, str_off);
3154 if (d->btf->base_btf) {
3155 err = btf__find_str(d->btf->base_btf, s);
3156 if (err >= 0) {
3157 *str_off_ptr = err;
3158 return 0;
3159 }
3160 if (err != -ENOENT)
3161 return err;
3162 }
3163
3164 off = strset__add_str(d->strs_set, s);
3165 if (off < 0)
3166 return off;
3167
3168 *str_off_ptr = d->btf->start_str_off + off;
3169 return 0;
3170}
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183static int btf_dedup_strings(struct btf_dedup *d)
3184{
3185 int err;
3186
3187 if (d->btf->strs_deduped)
3188 return 0;
3189
3190 d->strs_set = strset__new(BTF_MAX_STR_OFFSET, NULL, 0);
3191 if (IS_ERR(d->strs_set)) {
3192 err = PTR_ERR(d->strs_set);
3193 goto err_out;
3194 }
3195
3196 if (!d->btf->base_btf) {
3197
3198
3199
3200 err = strset__add_str(d->strs_set, "");
3201 if (err < 0)
3202 goto err_out;
3203 }
3204
3205
3206 err = btf_for_each_str_off(d, strs_dedup_remap_str_off, d);
3207 if (err)
3208 goto err_out;
3209
3210
3211 strset__free(d->btf->strs_set);
3212 d->btf->hdr->str_len = strset__data_size(d->strs_set);
3213 d->btf->strs_set = d->strs_set;
3214 d->strs_set = NULL;
3215 d->btf->strs_deduped = true;
3216 return 0;
3217
3218err_out:
3219 strset__free(d->strs_set);
3220 d->strs_set = NULL;
3221
3222 return err;
3223}
3224
3225static long btf_hash_common(struct btf_type *t)
3226{
3227 long h;
3228
3229 h = hash_combine(0, t->name_off);
3230 h = hash_combine(h, t->info);
3231 h = hash_combine(h, t->size);
3232 return h;
3233}
3234
3235static bool btf_equal_common(struct btf_type *t1, struct btf_type *t2)
3236{
3237 return t1->name_off == t2->name_off &&
3238 t1->info == t2->info &&
3239 t1->size == t2->size;
3240}
3241
3242
3243static long btf_hash_int(struct btf_type *t)
3244{
3245 __u32 info = *(__u32 *)(t + 1);
3246 long h;
3247
3248 h = btf_hash_common(t);
3249 h = hash_combine(h, info);
3250 return h;
3251}
3252
3253
3254static bool btf_equal_int(struct btf_type *t1, struct btf_type *t2)
3255{
3256 __u32 info1, info2;
3257
3258 if (!btf_equal_common(t1, t2))
3259 return false;
3260 info1 = *(__u32 *)(t1 + 1);
3261 info2 = *(__u32 *)(t2 + 1);
3262 return info1 == info2;
3263}
3264
3265
3266static long btf_hash_enum(struct btf_type *t)
3267{
3268 long h;
3269
3270
3271 h = hash_combine(0, t->name_off);
3272 h = hash_combine(h, t->info & ~0xffff);
3273 h = hash_combine(h, t->size);
3274 return h;
3275}
3276
3277
3278static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2)
3279{
3280 const struct btf_enum *m1, *m2;
3281 __u16 vlen;
3282 int i;
3283
3284 if (!btf_equal_common(t1, t2))
3285 return false;
3286
3287 vlen = btf_vlen(t1);
3288 m1 = btf_enum(t1);
3289 m2 = btf_enum(t2);
3290 for (i = 0; i < vlen; i++) {
3291 if (m1->name_off != m2->name_off || m1->val != m2->val)
3292 return false;
3293 m1++;
3294 m2++;
3295 }
3296 return true;
3297}
3298
3299static inline bool btf_is_enum_fwd(struct btf_type *t)
3300{
3301 return btf_is_enum(t) && btf_vlen(t) == 0;
3302}
3303
3304static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
3305{
3306 if (!btf_is_enum_fwd(t1) && !btf_is_enum_fwd(t2))
3307 return btf_equal_enum(t1, t2);
3308
3309 return t1->name_off == t2->name_off &&
3310 (t1->info & ~0xffff) == (t2->info & ~0xffff) &&
3311 t1->size == t2->size;
3312}
3313
3314
3315
3316
3317
3318
3319static long btf_hash_struct(struct btf_type *t)
3320{
3321 const struct btf_member *member = btf_members(t);
3322 __u32 vlen = btf_vlen(t);
3323 long h = btf_hash_common(t);
3324 int i;
3325
3326 for (i = 0; i < vlen; i++) {
3327 h = hash_combine(h, member->name_off);
3328 h = hash_combine(h, member->offset);
3329
3330 member++;
3331 }
3332 return h;
3333}
3334
3335
3336
3337
3338
3339
3340static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2)
3341{
3342 const struct btf_member *m1, *m2;
3343 __u16 vlen;
3344 int i;
3345
3346 if (!btf_equal_common(t1, t2))
3347 return false;
3348
3349 vlen = btf_vlen(t1);
3350 m1 = btf_members(t1);
3351 m2 = btf_members(t2);
3352 for (i = 0; i < vlen; i++) {
3353 if (m1->name_off != m2->name_off || m1->offset != m2->offset)
3354 return false;
3355 m1++;
3356 m2++;
3357 }
3358 return true;
3359}
3360
3361
3362
3363
3364
3365
3366static long btf_hash_array(struct btf_type *t)
3367{
3368 const struct btf_array *info = btf_array(t);
3369 long h = btf_hash_common(t);
3370
3371 h = hash_combine(h, info->type);
3372 h = hash_combine(h, info->index_type);
3373 h = hash_combine(h, info->nelems);
3374 return h;
3375}
3376
3377
3378
3379
3380
3381
3382
3383
3384static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2)
3385{
3386 const struct btf_array *info1, *info2;
3387
3388 if (!btf_equal_common(t1, t2))
3389 return false;
3390
3391 info1 = btf_array(t1);
3392 info2 = btf_array(t2);
3393 return info1->type == info2->type &&
3394 info1->index_type == info2->index_type &&
3395 info1->nelems == info2->nelems;
3396}
3397
3398
3399
3400
3401
3402
3403static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2)
3404{
3405 if (!btf_equal_common(t1, t2))
3406 return false;
3407
3408 return btf_array(t1)->nelems == btf_array(t2)->nelems;
3409}
3410
3411
3412
3413
3414
3415
3416static long btf_hash_fnproto(struct btf_type *t)
3417{
3418 const struct btf_param *member = btf_params(t);
3419 __u16 vlen = btf_vlen(t);
3420 long h = btf_hash_common(t);
3421 int i;
3422
3423 for (i = 0; i < vlen; i++) {
3424 h = hash_combine(h, member->name_off);
3425 h = hash_combine(h, member->type);
3426 member++;
3427 }
3428 return h;
3429}
3430
3431
3432
3433
3434
3435
3436
3437
3438static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
3439{
3440 const struct btf_param *m1, *m2;
3441 __u16 vlen;
3442 int i;
3443
3444 if (!btf_equal_common(t1, t2))
3445 return false;
3446
3447 vlen = btf_vlen(t1);
3448 m1 = btf_params(t1);
3449 m2 = btf_params(t2);
3450 for (i = 0; i < vlen; i++) {
3451 if (m1->name_off != m2->name_off || m1->type != m2->type)
3452 return false;
3453 m1++;
3454 m2++;
3455 }
3456 return true;
3457}
3458
3459
3460
3461
3462
3463
3464static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2)
3465{
3466 const struct btf_param *m1, *m2;
3467 __u16 vlen;
3468 int i;
3469
3470
3471 if (t1->name_off != t2->name_off || t1->info != t2->info)
3472 return false;
3473
3474 vlen = btf_vlen(t1);
3475 m1 = btf_params(t1);
3476 m2 = btf_params(t2);
3477 for (i = 0; i < vlen; i++) {
3478 if (m1->name_off != m2->name_off)
3479 return false;
3480 m1++;
3481 m2++;
3482 }
3483 return true;
3484}
3485
3486
3487
3488
3489
3490static int btf_dedup_prep(struct btf_dedup *d)
3491{
3492 struct btf_type *t;
3493 int type_id;
3494 long h;
3495
3496 if (!d->btf->base_btf)
3497 return 0;
3498
3499 for (type_id = 1; type_id < d->btf->start_id; type_id++) {
3500 t = btf_type_by_id(d->btf, type_id);
3501
3502
3503 d->map[type_id] = type_id;
3504
3505 switch (btf_kind(t)) {
3506 case BTF_KIND_VAR:
3507 case BTF_KIND_DATASEC:
3508
3509 continue;
3510 case BTF_KIND_CONST:
3511 case BTF_KIND_VOLATILE:
3512 case BTF_KIND_RESTRICT:
3513 case BTF_KIND_PTR:
3514 case BTF_KIND_FWD:
3515 case BTF_KIND_TYPEDEF:
3516 case BTF_KIND_FUNC:
3517 case BTF_KIND_FLOAT:
3518 h = btf_hash_common(t);
3519 break;
3520 case BTF_KIND_INT:
3521 h = btf_hash_int(t);
3522 break;
3523 case BTF_KIND_ENUM:
3524 h = btf_hash_enum(t);
3525 break;
3526 case BTF_KIND_STRUCT:
3527 case BTF_KIND_UNION:
3528 h = btf_hash_struct(t);
3529 break;
3530 case BTF_KIND_ARRAY:
3531 h = btf_hash_array(t);
3532 break;
3533 case BTF_KIND_FUNC_PROTO:
3534 h = btf_hash_fnproto(t);
3535 break;
3536 default:
3537 pr_debug("unknown kind %d for type [%d]\n", btf_kind(t), type_id);
3538 return -EINVAL;
3539 }
3540 if (btf_dedup_table_add(d, h, type_id))
3541 return -ENOMEM;
3542 }
3543
3544 return 0;
3545}
3546
3547
3548
3549
3550
3551
3552
3553static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
3554{
3555 struct btf_type *t = btf_type_by_id(d->btf, type_id);
3556 struct hashmap_entry *hash_entry;
3557 struct btf_type *cand;
3558
3559 __u32 new_id = type_id;
3560 __u32 cand_id;
3561 long h;
3562
3563 switch (btf_kind(t)) {
3564 case BTF_KIND_CONST:
3565 case BTF_KIND_VOLATILE:
3566 case BTF_KIND_RESTRICT:
3567 case BTF_KIND_PTR:
3568 case BTF_KIND_TYPEDEF:
3569 case BTF_KIND_ARRAY:
3570 case BTF_KIND_STRUCT:
3571 case BTF_KIND_UNION:
3572 case BTF_KIND_FUNC:
3573 case BTF_KIND_FUNC_PROTO:
3574 case BTF_KIND_VAR:
3575 case BTF_KIND_DATASEC:
3576 return 0;
3577
3578 case BTF_KIND_INT:
3579 h = btf_hash_int(t);
3580 for_each_dedup_cand(d, hash_entry, h) {
3581 cand_id = (__u32)(long)hash_entry->value;
3582 cand = btf_type_by_id(d->btf, cand_id);
3583 if (btf_equal_int(t, cand)) {
3584 new_id = cand_id;
3585 break;
3586 }
3587 }
3588 break;
3589
3590 case BTF_KIND_ENUM:
3591 h = btf_hash_enum(t);
3592 for_each_dedup_cand(d, hash_entry, h) {
3593 cand_id = (__u32)(long)hash_entry->value;
3594 cand = btf_type_by_id(d->btf, cand_id);
3595 if (btf_equal_enum(t, cand)) {
3596 new_id = cand_id;
3597 break;
3598 }
3599 if (d->opts.dont_resolve_fwds)
3600 continue;
3601 if (btf_compat_enum(t, cand)) {
3602 if (btf_is_enum_fwd(t)) {
3603
3604 new_id = cand_id;
3605 break;
3606 }
3607
3608 d->map[cand_id] = type_id;
3609 }
3610 }
3611 break;
3612
3613 case BTF_KIND_FWD:
3614 case BTF_KIND_FLOAT:
3615 h = btf_hash_common(t);
3616 for_each_dedup_cand(d, hash_entry, h) {
3617 cand_id = (__u32)(long)hash_entry->value;
3618 cand = btf_type_by_id(d->btf, cand_id);
3619 if (btf_equal_common(t, cand)) {
3620 new_id = cand_id;
3621 break;
3622 }
3623 }
3624 break;
3625
3626 default:
3627 return -EINVAL;
3628 }
3629
3630 d->map[type_id] = new_id;
3631 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
3632 return -ENOMEM;
3633
3634 return 0;
3635}
3636
3637static int btf_dedup_prim_types(struct btf_dedup *d)
3638{
3639 int i, err;
3640
3641 for (i = 0; i < d->btf->nr_types; i++) {
3642 err = btf_dedup_prim_type(d, d->btf->start_id + i);
3643 if (err)
3644 return err;
3645 }
3646 return 0;
3647}
3648
3649
3650
3651
3652static inline bool is_type_mapped(struct btf_dedup *d, uint32_t type_id)
3653{
3654 return d->map[type_id] <= BTF_MAX_NR_TYPES;
3655}
3656
3657
3658
3659
3660
3661
3662static inline __u32 resolve_type_id(struct btf_dedup *d, __u32 type_id)
3663{
3664 while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
3665 type_id = d->map[type_id];
3666 return type_id;
3667}
3668
3669
3670
3671
3672
3673static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id)
3674{
3675 __u32 orig_type_id = type_id;
3676
3677 if (!btf_is_fwd(btf__type_by_id(d->btf, type_id)))
3678 return type_id;
3679
3680 while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
3681 type_id = d->map[type_id];
3682
3683 if (!btf_is_fwd(btf__type_by_id(d->btf, type_id)))
3684 return type_id;
3685
3686 return orig_type_id;
3687}
3688
3689
3690static inline __u16 btf_fwd_kind(struct btf_type *t)
3691{
3692 return btf_kflag(t) ? BTF_KIND_UNION : BTF_KIND_STRUCT;
3693}
3694
3695
3696static int btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
3697{
3698 struct btf_type *t1, *t2;
3699
3700 t1 = btf_type_by_id(d->btf, id1);
3701 t2 = btf_type_by_id(d->btf, id2);
3702 if (!btf_is_array(t1) || !btf_is_array(t2))
3703 return 0;
3704
3705 return btf_equal_array(t1, t2);
3706}
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
3802 __u32 canon_id)
3803{
3804 struct btf_type *cand_type;
3805 struct btf_type *canon_type;
3806 __u32 hypot_type_id;
3807 __u16 cand_kind;
3808 __u16 canon_kind;
3809 int i, eq;
3810
3811
3812 if (resolve_type_id(d, cand_id) == resolve_type_id(d, canon_id))
3813 return 1;
3814
3815 canon_id = resolve_fwd_id(d, canon_id);
3816
3817 hypot_type_id = d->hypot_map[canon_id];
3818 if (hypot_type_id <= BTF_MAX_NR_TYPES) {
3819
3820
3821
3822
3823
3824
3825
3826
3827 return hypot_type_id == cand_id ||
3828 btf_dedup_identical_arrays(d, hypot_type_id, cand_id);
3829 }
3830
3831 if (btf_dedup_hypot_map_add(d, canon_id, cand_id))
3832 return -ENOMEM;
3833
3834 cand_type = btf_type_by_id(d->btf, cand_id);
3835 canon_type = btf_type_by_id(d->btf, canon_id);
3836 cand_kind = btf_kind(cand_type);
3837 canon_kind = btf_kind(canon_type);
3838
3839 if (cand_type->name_off != canon_type->name_off)
3840 return 0;
3841
3842
3843 if (!d->opts.dont_resolve_fwds
3844 && (cand_kind == BTF_KIND_FWD || canon_kind == BTF_KIND_FWD)
3845 && cand_kind != canon_kind) {
3846 __u16 real_kind;
3847 __u16 fwd_kind;
3848
3849 if (cand_kind == BTF_KIND_FWD) {
3850 real_kind = canon_kind;
3851 fwd_kind = btf_fwd_kind(cand_type);
3852 } else {
3853 real_kind = cand_kind;
3854 fwd_kind = btf_fwd_kind(canon_type);
3855
3856 if (fwd_kind == real_kind && canon_id < d->btf->start_id)
3857 d->hypot_adjust_canon = true;
3858 }
3859 return fwd_kind == real_kind;
3860 }
3861
3862 if (cand_kind != canon_kind)
3863 return 0;
3864
3865 switch (cand_kind) {
3866 case BTF_KIND_INT:
3867 return btf_equal_int(cand_type, canon_type);
3868
3869 case BTF_KIND_ENUM:
3870 if (d->opts.dont_resolve_fwds)
3871 return btf_equal_enum(cand_type, canon_type);
3872 else
3873 return btf_compat_enum(cand_type, canon_type);
3874
3875 case BTF_KIND_FWD:
3876 case BTF_KIND_FLOAT:
3877 return btf_equal_common(cand_type, canon_type);
3878
3879 case BTF_KIND_CONST:
3880 case BTF_KIND_VOLATILE:
3881 case BTF_KIND_RESTRICT:
3882 case BTF_KIND_PTR:
3883 case BTF_KIND_TYPEDEF:
3884 case BTF_KIND_FUNC:
3885 if (cand_type->info != canon_type->info)
3886 return 0;
3887 return btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
3888
3889 case BTF_KIND_ARRAY: {
3890 const struct btf_array *cand_arr, *canon_arr;
3891
3892 if (!btf_compat_array(cand_type, canon_type))
3893 return 0;
3894 cand_arr = btf_array(cand_type);
3895 canon_arr = btf_array(canon_type);
3896 eq = btf_dedup_is_equiv(d, cand_arr->index_type, canon_arr->index_type);
3897 if (eq <= 0)
3898 return eq;
3899 return btf_dedup_is_equiv(d, cand_arr->type, canon_arr->type);
3900 }
3901
3902 case BTF_KIND_STRUCT:
3903 case BTF_KIND_UNION: {
3904 const struct btf_member *cand_m, *canon_m;
3905 __u16 vlen;
3906
3907 if (!btf_shallow_equal_struct(cand_type, canon_type))
3908 return 0;
3909 vlen = btf_vlen(cand_type);
3910 cand_m = btf_members(cand_type);
3911 canon_m = btf_members(canon_type);
3912 for (i = 0; i < vlen; i++) {
3913 eq = btf_dedup_is_equiv(d, cand_m->type, canon_m->type);
3914 if (eq <= 0)
3915 return eq;
3916 cand_m++;
3917 canon_m++;
3918 }
3919
3920 return 1;
3921 }
3922
3923 case BTF_KIND_FUNC_PROTO: {
3924 const struct btf_param *cand_p, *canon_p;
3925 __u16 vlen;
3926
3927 if (!btf_compat_fnproto(cand_type, canon_type))
3928 return 0;
3929 eq = btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
3930 if (eq <= 0)
3931 return eq;
3932 vlen = btf_vlen(cand_type);
3933 cand_p = btf_params(cand_type);
3934 canon_p = btf_params(canon_type);
3935 for (i = 0; i < vlen; i++) {
3936 eq = btf_dedup_is_equiv(d, cand_p->type, canon_p->type);
3937 if (eq <= 0)
3938 return eq;
3939 cand_p++;
3940 canon_p++;
3941 }
3942 return 1;
3943 }
3944
3945 default:
3946 return -EINVAL;
3947 }
3948 return 0;
3949}
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977static void btf_dedup_merge_hypot_map(struct btf_dedup *d)
3978{
3979 __u32 canon_type_id, targ_type_id;
3980 __u16 t_kind, c_kind;
3981 __u32 t_id, c_id;
3982 int i;
3983
3984 for (i = 0; i < d->hypot_cnt; i++) {
3985 canon_type_id = d->hypot_list[i];
3986 targ_type_id = d->hypot_map[canon_type_id];
3987 t_id = resolve_type_id(d, targ_type_id);
3988 c_id = resolve_type_id(d, canon_type_id);
3989 t_kind = btf_kind(btf__type_by_id(d->btf, t_id));
3990 c_kind = btf_kind(btf__type_by_id(d->btf, c_id));
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011 if (t_kind != BTF_KIND_FWD && c_kind == BTF_KIND_FWD)
4012 d->map[c_id] = t_id;
4013
4014
4015
4016
4017
4018
4019 if (d->hypot_adjust_canon)
4020 continue;
4021
4022 if (t_kind == BTF_KIND_FWD && c_kind != BTF_KIND_FWD)
4023 d->map[t_id] = c_id;
4024
4025 if ((t_kind == BTF_KIND_STRUCT || t_kind == BTF_KIND_UNION) &&
4026 c_kind != BTF_KIND_FWD &&
4027 is_type_mapped(d, c_id) &&
4028 !is_type_mapped(d, t_id)) {
4029
4030
4031
4032
4033
4034
4035 d->map[t_id] = c_id;
4036 }
4037 }
4038}
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id)
4063{
4064 struct btf_type *cand_type, *t;
4065 struct hashmap_entry *hash_entry;
4066
4067 __u32 new_id = type_id;
4068 __u16 kind;
4069 long h;
4070
4071
4072 if (d->map[type_id] <= BTF_MAX_NR_TYPES)
4073 return 0;
4074
4075 t = btf_type_by_id(d->btf, type_id);
4076 kind = btf_kind(t);
4077
4078 if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION)
4079 return 0;
4080
4081 h = btf_hash_struct(t);
4082 for_each_dedup_cand(d, hash_entry, h) {
4083 __u32 cand_id = (__u32)(long)hash_entry->value;
4084 int eq;
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096 cand_type = btf_type_by_id(d->btf, cand_id);
4097 if (!btf_shallow_equal_struct(t, cand_type))
4098 continue;
4099
4100 btf_dedup_clear_hypot_map(d);
4101 eq = btf_dedup_is_equiv(d, type_id, cand_id);
4102 if (eq < 0)
4103 return eq;
4104 if (!eq)
4105 continue;
4106 btf_dedup_merge_hypot_map(d);
4107 if (d->hypot_adjust_canon)
4108 continue;
4109 new_id = cand_id;
4110 break;
4111 }
4112
4113 d->map[type_id] = new_id;
4114 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
4115 return -ENOMEM;
4116
4117 return 0;
4118}
4119
4120static int btf_dedup_struct_types(struct btf_dedup *d)
4121{
4122 int i, err;
4123
4124 for (i = 0; i < d->btf->nr_types; i++) {
4125 err = btf_dedup_struct_type(d, d->btf->start_id + i);
4126 if (err)
4127 return err;
4128 }
4129 return 0;
4130}
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
4157{
4158 struct hashmap_entry *hash_entry;
4159 __u32 new_id = type_id, cand_id;
4160 struct btf_type *t, *cand;
4161
4162 int ref_type_id;
4163 long h;
4164
4165 if (d->map[type_id] == BTF_IN_PROGRESS_ID)
4166 return -ELOOP;
4167 if (d->map[type_id] <= BTF_MAX_NR_TYPES)
4168 return resolve_type_id(d, type_id);
4169
4170 t = btf_type_by_id(d->btf, type_id);
4171 d->map[type_id] = BTF_IN_PROGRESS_ID;
4172
4173 switch (btf_kind(t)) {
4174 case BTF_KIND_CONST:
4175 case BTF_KIND_VOLATILE:
4176 case BTF_KIND_RESTRICT:
4177 case BTF_KIND_PTR:
4178 case BTF_KIND_TYPEDEF:
4179 case BTF_KIND_FUNC:
4180 ref_type_id = btf_dedup_ref_type(d, t->type);
4181 if (ref_type_id < 0)
4182 return ref_type_id;
4183 t->type = ref_type_id;
4184
4185 h = btf_hash_common(t);
4186 for_each_dedup_cand(d, hash_entry, h) {
4187 cand_id = (__u32)(long)hash_entry->value;
4188 cand = btf_type_by_id(d->btf, cand_id);
4189 if (btf_equal_common(t, cand)) {
4190 new_id = cand_id;
4191 break;
4192 }
4193 }
4194 break;
4195
4196 case BTF_KIND_ARRAY: {
4197 struct btf_array *info = btf_array(t);
4198
4199 ref_type_id = btf_dedup_ref_type(d, info->type);
4200 if (ref_type_id < 0)
4201 return ref_type_id;
4202 info->type = ref_type_id;
4203
4204 ref_type_id = btf_dedup_ref_type(d, info->index_type);
4205 if (ref_type_id < 0)
4206 return ref_type_id;
4207 info->index_type = ref_type_id;
4208
4209 h = btf_hash_array(t);
4210 for_each_dedup_cand(d, hash_entry, h) {
4211 cand_id = (__u32)(long)hash_entry->value;
4212 cand = btf_type_by_id(d->btf, cand_id);
4213 if (btf_equal_array(t, cand)) {
4214 new_id = cand_id;
4215 break;
4216 }
4217 }
4218 break;
4219 }
4220
4221 case BTF_KIND_FUNC_PROTO: {
4222 struct btf_param *param;
4223 __u16 vlen;
4224 int i;
4225
4226 ref_type_id = btf_dedup_ref_type(d, t->type);
4227 if (ref_type_id < 0)
4228 return ref_type_id;
4229 t->type = ref_type_id;
4230
4231 vlen = btf_vlen(t);
4232 param = btf_params(t);
4233 for (i = 0; i < vlen; i++) {
4234 ref_type_id = btf_dedup_ref_type(d, param->type);
4235 if (ref_type_id < 0)
4236 return ref_type_id;
4237 param->type = ref_type_id;
4238 param++;
4239 }
4240
4241 h = btf_hash_fnproto(t);
4242 for_each_dedup_cand(d, hash_entry, h) {
4243 cand_id = (__u32)(long)hash_entry->value;
4244 cand = btf_type_by_id(d->btf, cand_id);
4245 if (btf_equal_fnproto(t, cand)) {
4246 new_id = cand_id;
4247 break;
4248 }
4249 }
4250 break;
4251 }
4252
4253 default:
4254 return -EINVAL;
4255 }
4256
4257 d->map[type_id] = new_id;
4258 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
4259 return -ENOMEM;
4260
4261 return new_id;
4262}
4263
4264static int btf_dedup_ref_types(struct btf_dedup *d)
4265{
4266 int i, err;
4267
4268 for (i = 0; i < d->btf->nr_types; i++) {
4269 err = btf_dedup_ref_type(d, d->btf->start_id + i);
4270 if (err < 0)
4271 return err;
4272 }
4273
4274 hashmap__free(d->dedup_table);
4275 d->dedup_table = NULL;
4276 return 0;
4277}
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290static int btf_dedup_compact_types(struct btf_dedup *d)
4291{
4292 __u32 *new_offs;
4293 __u32 next_type_id = d->btf->start_id;
4294 const struct btf_type *t;
4295 void *p;
4296 int i, id, len;
4297
4298
4299 d->hypot_map[0] = 0;
4300
4301 for (id = 1; id < d->btf->start_id; id++)
4302 d->hypot_map[id] = id;
4303 for (i = 0, id = d->btf->start_id; i < d->btf->nr_types; i++, id++)
4304 d->hypot_map[id] = BTF_UNPROCESSED_ID;
4305
4306 p = d->btf->types_data;
4307
4308 for (i = 0, id = d->btf->start_id; i < d->btf->nr_types; i++, id++) {
4309 if (d->map[id] != id)
4310 continue;
4311
4312 t = btf__type_by_id(d->btf, id);
4313 len = btf_type_size(t);
4314 if (len < 0)
4315 return len;
4316
4317 memmove(p, t, len);
4318 d->hypot_map[id] = next_type_id;
4319 d->btf->type_offs[next_type_id - d->btf->start_id] = p - d->btf->types_data;
4320 p += len;
4321 next_type_id++;
4322 }
4323
4324
4325 d->btf->nr_types = next_type_id - d->btf->start_id;
4326 d->btf->type_offs_cap = d->btf->nr_types;
4327 d->btf->hdr->type_len = p - d->btf->types_data;
4328 new_offs = libbpf_reallocarray(d->btf->type_offs, d->btf->type_offs_cap,
4329 sizeof(*new_offs));
4330 if (d->btf->type_offs_cap && !new_offs)
4331 return -ENOMEM;
4332 d->btf->type_offs = new_offs;
4333 d->btf->hdr->str_off = d->btf->hdr->type_len;
4334 d->btf->raw_size = d->btf->hdr->hdr_len + d->btf->hdr->type_len + d->btf->hdr->str_len;
4335 return 0;
4336}
4337
4338
4339
4340
4341
4342
4343
4344static int btf_dedup_remap_type_id(__u32 *type_id, void *ctx)
4345{
4346 struct btf_dedup *d = ctx;
4347 __u32 resolved_type_id, new_type_id;
4348
4349 resolved_type_id = resolve_type_id(d, *type_id);
4350 new_type_id = d->hypot_map[resolved_type_id];
4351 if (new_type_id > BTF_MAX_NR_TYPES)
4352 return -EINVAL;
4353
4354 *type_id = new_type_id;
4355 return 0;
4356}
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368static int btf_dedup_remap_types(struct btf_dedup *d)
4369{
4370 int i, r;
4371
4372 for (i = 0; i < d->btf->nr_types; i++) {
4373 struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i);
4374
4375 r = btf_type_visit_type_ids(t, btf_dedup_remap_type_id, d);
4376 if (r)
4377 return r;
4378 }
4379
4380 if (!d->btf_ext)
4381 return 0;
4382
4383 r = btf_ext_visit_type_ids(d->btf_ext, btf_dedup_remap_type_id, d);
4384 if (r)
4385 return r;
4386
4387 return 0;
4388}
4389
4390
4391
4392
4393
4394struct btf *libbpf_find_kernel_btf(void)
4395{
4396 struct {
4397 const char *path_fmt;
4398 bool raw_btf;
4399 } locations[] = {
4400
4401 { "/sys/kernel/btf/vmlinux", true },
4402
4403 { "/boot/vmlinux-%1$s" },
4404 { "/lib/modules/%1$s/vmlinux-%1$s" },
4405 { "/lib/modules/%1$s/build/vmlinux" },
4406 { "/usr/lib/modules/%1$s/kernel/vmlinux" },
4407 { "/usr/lib/debug/boot/vmlinux-%1$s" },
4408 { "/usr/lib/debug/boot/vmlinux-%1$s.debug" },
4409 { "/usr/lib/debug/lib/modules/%1$s/vmlinux" },
4410 };
4411 char path[PATH_MAX + 1];
4412 struct utsname buf;
4413 struct btf *btf;
4414 int i;
4415
4416 uname(&buf);
4417
4418 for (i = 0; i < ARRAY_SIZE(locations); i++) {
4419 snprintf(path, PATH_MAX, locations[i].path_fmt, buf.release);
4420
4421 if (access(path, R_OK))
4422 continue;
4423
4424 if (locations[i].raw_btf)
4425 btf = btf__parse_raw(path);
4426 else
4427 btf = btf__parse_elf(path, NULL);
4428
4429 pr_debug("loading kernel BTF '%s': %ld\n",
4430 path, IS_ERR(btf) ? PTR_ERR(btf) : 0);
4431 if (IS_ERR(btf))
4432 continue;
4433
4434 return btf;
4435 }
4436
4437 pr_warn("failed to find valid kernel BTF\n");
4438 return ERR_PTR(-ESRCH);
4439}
4440
4441int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx)
4442{
4443 int i, n, err;
4444
4445 switch (btf_kind(t)) {
4446 case BTF_KIND_INT:
4447 case BTF_KIND_FLOAT:
4448 case BTF_KIND_ENUM:
4449 return 0;
4450
4451 case BTF_KIND_FWD:
4452 case BTF_KIND_CONST:
4453 case BTF_KIND_VOLATILE:
4454 case BTF_KIND_RESTRICT:
4455 case BTF_KIND_PTR:
4456 case BTF_KIND_TYPEDEF:
4457 case BTF_KIND_FUNC:
4458 case BTF_KIND_VAR:
4459 return visit(&t->type, ctx);
4460
4461 case BTF_KIND_ARRAY: {
4462 struct btf_array *a = btf_array(t);
4463
4464 err = visit(&a->type, ctx);
4465 err = err ?: visit(&a->index_type, ctx);
4466 return err;
4467 }
4468
4469 case BTF_KIND_STRUCT:
4470 case BTF_KIND_UNION: {
4471 struct btf_member *m = btf_members(t);
4472
4473 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4474 err = visit(&m->type, ctx);
4475 if (err)
4476 return err;
4477 }
4478 return 0;
4479 }
4480
4481 case BTF_KIND_FUNC_PROTO: {
4482 struct btf_param *m = btf_params(t);
4483
4484 err = visit(&t->type, ctx);
4485 if (err)
4486 return err;
4487 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4488 err = visit(&m->type, ctx);
4489 if (err)
4490 return err;
4491 }
4492 return 0;
4493 }
4494
4495 case BTF_KIND_DATASEC: {
4496 struct btf_var_secinfo *m = btf_var_secinfos(t);
4497
4498 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4499 err = visit(&m->type, ctx);
4500 if (err)
4501 return err;
4502 }
4503 return 0;
4504 }
4505
4506 default:
4507 return -EINVAL;
4508 }
4509}
4510
4511int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx)
4512{
4513 int i, n, err;
4514
4515 err = visit(&t->name_off, ctx);
4516 if (err)
4517 return err;
4518
4519 switch (btf_kind(t)) {
4520 case BTF_KIND_STRUCT:
4521 case BTF_KIND_UNION: {
4522 struct btf_member *m = btf_members(t);
4523
4524 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4525 err = visit(&m->name_off, ctx);
4526 if (err)
4527 return err;
4528 }
4529 break;
4530 }
4531 case BTF_KIND_ENUM: {
4532 struct btf_enum *m = btf_enum(t);
4533
4534 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4535 err = visit(&m->name_off, ctx);
4536 if (err)
4537 return err;
4538 }
4539 break;
4540 }
4541 case BTF_KIND_FUNC_PROTO: {
4542 struct btf_param *m = btf_params(t);
4543
4544 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4545 err = visit(&m->name_off, ctx);
4546 if (err)
4547 return err;
4548 }
4549 break;
4550 }
4551 default:
4552 break;
4553 }
4554
4555 return 0;
4556}
4557
4558int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx)
4559{
4560 const struct btf_ext_info *seg;
4561 struct btf_ext_info_sec *sec;
4562 int i, err;
4563
4564 seg = &btf_ext->func_info;
4565 for_each_btf_ext_sec(seg, sec) {
4566 struct bpf_func_info_min *rec;
4567
4568 for_each_btf_ext_rec(seg, sec, i, rec) {
4569 err = visit(&rec->type_id, ctx);
4570 if (err < 0)
4571 return err;
4572 }
4573 }
4574
4575 seg = &btf_ext->core_relo_info;
4576 for_each_btf_ext_sec(seg, sec) {
4577 struct bpf_core_relo *rec;
4578
4579 for_each_btf_ext_rec(seg, sec, i, rec) {
4580 err = visit(&rec->type_id, ctx);
4581 if (err < 0)
4582 return err;
4583 }
4584 }
4585
4586 return 0;
4587}
4588
4589int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx)
4590{
4591 const struct btf_ext_info *seg;
4592 struct btf_ext_info_sec *sec;
4593 int i, err;
4594
4595 seg = &btf_ext->func_info;
4596 for_each_btf_ext_sec(seg, sec) {
4597 err = visit(&sec->sec_name_off, ctx);
4598 if (err)
4599 return err;
4600 }
4601
4602 seg = &btf_ext->line_info;
4603 for_each_btf_ext_sec(seg, sec) {
4604 struct bpf_line_info_min *rec;
4605
4606 err = visit(&sec->sec_name_off, ctx);
4607 if (err)
4608 return err;
4609
4610 for_each_btf_ext_rec(seg, sec, i, rec) {
4611 err = visit(&rec->file_name_off, ctx);
4612 if (err)
4613 return err;
4614 err = visit(&rec->line_off, ctx);
4615 if (err)
4616 return err;
4617 }
4618 }
4619
4620 seg = &btf_ext->core_relo_info;
4621 for_each_btf_ext_sec(seg, sec) {
4622 struct bpf_core_relo *rec;
4623
4624 err = visit(&sec->sec_name_off, ctx);
4625 if (err)
4626 return err;
4627
4628 for_each_btf_ext_rec(seg, sec, i, rec) {
4629 err = visit(&rec->access_str_off, ctx);
4630 if (err)
4631 return err;
4632 }
4633 }
4634
4635 return 0;
4636}
4637