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