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