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 struct hashmap *str_off_map;
1624};
1625
1626static int btf_rewrite_str(__u32 *str_off, void *ctx)
1627{
1628 struct btf_pipe *p = ctx;
1629 void *mapped_off;
1630 int off, err;
1631
1632 if (!*str_off)
1633 return 0;
1634
1635 if (p->str_off_map &&
1636 hashmap__find(p->str_off_map, (void *)(long)*str_off, &mapped_off)) {
1637 *str_off = (__u32)(long)mapped_off;
1638 return 0;
1639 }
1640
1641 off = btf__add_str(p->dst, btf__str_by_offset(p->src, *str_off));
1642 if (off < 0)
1643 return off;
1644
1645
1646
1647
1648 if (p->str_off_map) {
1649 err = hashmap__append(p->str_off_map, (void *)(long)*str_off, (void *)(long)off);
1650 if (err)
1651 return err;
1652 }
1653
1654 *str_off = off;
1655 return 0;
1656}
1657
1658int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_type *src_type)
1659{
1660 struct btf_pipe p = { .src = src_btf, .dst = btf };
1661 struct btf_type *t;
1662 int sz, err;
1663
1664 sz = btf_type_size(src_type);
1665 if (sz < 0)
1666 return libbpf_err(sz);
1667
1668
1669 if (btf_ensure_modifiable(btf))
1670 return libbpf_err(-ENOMEM);
1671
1672 t = btf_add_type_mem(btf, sz);
1673 if (!t)
1674 return libbpf_err(-ENOMEM);
1675
1676 memcpy(t, src_type, sz);
1677
1678 err = btf_type_visit_str_offs(t, btf_rewrite_str, &p);
1679 if (err)
1680 return libbpf_err(err);
1681
1682 return btf_commit_type(btf, sz);
1683}
1684
1685static int btf_rewrite_type_ids(__u32 *type_id, void *ctx)
1686{
1687 struct btf *btf = ctx;
1688
1689 if (!*type_id)
1690 return 0;
1691
1692
1693
1694
1695
1696 *type_id += btf->start_id + btf->nr_types - 1;
1697 return 0;
1698}
1699
1700static size_t btf_dedup_identity_hash_fn(const void *key, void *ctx);
1701static bool btf_dedup_equal_fn(const void *k1, const void *k2, void *ctx);
1702
1703int btf__add_btf(struct btf *btf, const struct btf *src_btf)
1704{
1705 struct btf_pipe p = { .src = src_btf, .dst = btf };
1706 int data_sz, sz, cnt, i, err, old_strs_len;
1707 __u32 *off;
1708 void *t;
1709
1710
1711 if (src_btf->base_btf)
1712 return libbpf_err(-ENOTSUP);
1713
1714
1715 if (btf_ensure_modifiable(btf))
1716 return libbpf_err(-ENOMEM);
1717
1718
1719
1720
1721 old_strs_len = btf->hdr->str_len;
1722
1723 data_sz = src_btf->hdr->type_len;
1724 cnt = btf__type_cnt(src_btf) - 1;
1725
1726
1727 t = btf_add_type_mem(btf, data_sz);
1728 if (!t)
1729 return libbpf_err(-ENOMEM);
1730
1731
1732 off = btf_add_type_offs_mem(btf, cnt);
1733 if (!off)
1734 return libbpf_err(-ENOMEM);
1735
1736
1737 p.str_off_map = hashmap__new(btf_dedup_identity_hash_fn, btf_dedup_equal_fn, NULL);
1738 if (IS_ERR(p.str_off_map))
1739 return libbpf_err(-ENOMEM);
1740
1741
1742 memcpy(t, src_btf->types_data, data_sz);
1743
1744 for (i = 0; i < cnt; i++) {
1745 sz = btf_type_size(t);
1746 if (sz < 0) {
1747
1748 err = sz;
1749 goto err_out;
1750 }
1751
1752
1753 *off = t - btf->types_data;
1754
1755
1756 err = btf_type_visit_str_offs(t, btf_rewrite_str, &p);
1757 if (err)
1758 goto err_out;
1759
1760
1761 err = btf_type_visit_type_ids(t, btf_rewrite_type_ids, btf);
1762 if (err)
1763 goto err_out;
1764
1765
1766 t += sz;
1767 off++;
1768 }
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778 btf->hdr->type_len += data_sz;
1779 btf->hdr->str_off += data_sz;
1780 btf->nr_types += cnt;
1781
1782 hashmap__free(p.str_off_map);
1783
1784
1785 return btf->start_id + btf->nr_types - cnt;
1786err_out:
1787
1788
1789
1790 memset(btf->types_data + btf->hdr->type_len, 0, data_sz);
1791 memset(btf->strs_data + old_strs_len, 0, btf->hdr->str_len - old_strs_len);
1792
1793
1794
1795 btf->hdr->str_len = old_strs_len;
1796
1797 hashmap__free(p.str_off_map);
1798
1799 return libbpf_err(err);
1800}
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding)
1812{
1813 struct btf_type *t;
1814 int sz, name_off;
1815
1816
1817 if (!name || !name[0])
1818 return libbpf_err(-EINVAL);
1819
1820 if (!byte_sz || (byte_sz & (byte_sz - 1)) || byte_sz > 16)
1821 return libbpf_err(-EINVAL);
1822 if (encoding & ~(BTF_INT_SIGNED | BTF_INT_CHAR | BTF_INT_BOOL))
1823 return libbpf_err(-EINVAL);
1824
1825
1826 if (btf_ensure_modifiable(btf))
1827 return libbpf_err(-ENOMEM);
1828
1829 sz = sizeof(struct btf_type) + sizeof(int);
1830 t = btf_add_type_mem(btf, sz);
1831 if (!t)
1832 return libbpf_err(-ENOMEM);
1833
1834
1835
1836
1837
1838 name_off = btf__add_str(btf, name);
1839 if (name_off < 0)
1840 return name_off;
1841
1842 t->name_off = name_off;
1843 t->info = btf_type_info(BTF_KIND_INT, 0, 0);
1844 t->size = byte_sz;
1845
1846 *(__u32 *)(t + 1) = (encoding << 24) | (byte_sz * 8);
1847
1848 return btf_commit_type(btf, sz);
1849}
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859int btf__add_float(struct btf *btf, const char *name, size_t byte_sz)
1860{
1861 struct btf_type *t;
1862 int sz, name_off;
1863
1864
1865 if (!name || !name[0])
1866 return libbpf_err(-EINVAL);
1867
1868
1869 if (byte_sz != 2 && byte_sz != 4 && byte_sz != 8 && byte_sz != 12 &&
1870 byte_sz != 16)
1871 return libbpf_err(-EINVAL);
1872
1873 if (btf_ensure_modifiable(btf))
1874 return libbpf_err(-ENOMEM);
1875
1876 sz = sizeof(struct btf_type);
1877 t = btf_add_type_mem(btf, sz);
1878 if (!t)
1879 return libbpf_err(-ENOMEM);
1880
1881 name_off = btf__add_str(btf, name);
1882 if (name_off < 0)
1883 return name_off;
1884
1885 t->name_off = name_off;
1886 t->info = btf_type_info(BTF_KIND_FLOAT, 0, 0);
1887 t->size = byte_sz;
1888
1889 return btf_commit_type(btf, sz);
1890}
1891
1892
1893
1894
1895
1896static int validate_type_id(int id)
1897{
1898 if (id < 0 || id > BTF_MAX_NR_TYPES)
1899 return -EINVAL;
1900 return 0;
1901}
1902
1903
1904static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id)
1905{
1906 struct btf_type *t;
1907 int sz, name_off = 0;
1908
1909 if (validate_type_id(ref_type_id))
1910 return libbpf_err(-EINVAL);
1911
1912 if (btf_ensure_modifiable(btf))
1913 return libbpf_err(-ENOMEM);
1914
1915 sz = sizeof(struct btf_type);
1916 t = btf_add_type_mem(btf, sz);
1917 if (!t)
1918 return libbpf_err(-ENOMEM);
1919
1920 if (name && name[0]) {
1921 name_off = btf__add_str(btf, name);
1922 if (name_off < 0)
1923 return name_off;
1924 }
1925
1926 t->name_off = name_off;
1927 t->info = btf_type_info(kind, 0, 0);
1928 t->type = ref_type_id;
1929
1930 return btf_commit_type(btf, sz);
1931}
1932
1933
1934
1935
1936
1937
1938
1939
1940int btf__add_ptr(struct btf *btf, int ref_type_id)
1941{
1942 return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id);
1943}
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954int btf__add_array(struct btf *btf, int index_type_id, int elem_type_id, __u32 nr_elems)
1955{
1956 struct btf_type *t;
1957 struct btf_array *a;
1958 int sz;
1959
1960 if (validate_type_id(index_type_id) || validate_type_id(elem_type_id))
1961 return libbpf_err(-EINVAL);
1962
1963 if (btf_ensure_modifiable(btf))
1964 return libbpf_err(-ENOMEM);
1965
1966 sz = sizeof(struct btf_type) + sizeof(struct btf_array);
1967 t = btf_add_type_mem(btf, sz);
1968 if (!t)
1969 return libbpf_err(-ENOMEM);
1970
1971 t->name_off = 0;
1972 t->info = btf_type_info(BTF_KIND_ARRAY, 0, 0);
1973 t->size = 0;
1974
1975 a = btf_array(t);
1976 a->type = elem_type_id;
1977 a->index_type = index_type_id;
1978 a->nelems = nr_elems;
1979
1980 return btf_commit_type(btf, sz);
1981}
1982
1983
1984static int btf_add_composite(struct btf *btf, int kind, const char *name, __u32 bytes_sz)
1985{
1986 struct btf_type *t;
1987 int sz, name_off = 0;
1988
1989 if (btf_ensure_modifiable(btf))
1990 return libbpf_err(-ENOMEM);
1991
1992 sz = sizeof(struct btf_type);
1993 t = btf_add_type_mem(btf, sz);
1994 if (!t)
1995 return libbpf_err(-ENOMEM);
1996
1997 if (name && name[0]) {
1998 name_off = btf__add_str(btf, name);
1999 if (name_off < 0)
2000 return name_off;
2001 }
2002
2003
2004
2005
2006 t->name_off = name_off;
2007 t->info = btf_type_info(kind, 0, 0);
2008 t->size = bytes_sz;
2009
2010 return btf_commit_type(btf, sz);
2011}
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025int btf__add_struct(struct btf *btf, const char *name, __u32 byte_sz)
2026{
2027 return btf_add_composite(btf, BTF_KIND_STRUCT, name, byte_sz);
2028}
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043int btf__add_union(struct btf *btf, const char *name, __u32 byte_sz)
2044{
2045 return btf_add_composite(btf, BTF_KIND_UNION, name, byte_sz);
2046}
2047
2048static struct btf_type *btf_last_type(struct btf *btf)
2049{
2050 return btf_type_by_id(btf, btf__type_cnt(btf) - 1);
2051}
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063int btf__add_field(struct btf *btf, const char *name, int type_id,
2064 __u32 bit_offset, __u32 bit_size)
2065{
2066 struct btf_type *t;
2067 struct btf_member *m;
2068 bool is_bitfield;
2069 int sz, name_off = 0;
2070
2071
2072 if (btf->nr_types == 0)
2073 return libbpf_err(-EINVAL);
2074 t = btf_last_type(btf);
2075 if (!btf_is_composite(t))
2076 return libbpf_err(-EINVAL);
2077
2078 if (validate_type_id(type_id))
2079 return libbpf_err(-EINVAL);
2080
2081 is_bitfield = bit_size || (bit_offset % 8 != 0);
2082 if (is_bitfield && (bit_size == 0 || bit_size > 255 || bit_offset > 0xffffff))
2083 return libbpf_err(-EINVAL);
2084
2085
2086 if (btf_is_union(t) && bit_offset)
2087 return libbpf_err(-EINVAL);
2088
2089
2090 if (btf_ensure_modifiable(btf))
2091 return libbpf_err(-ENOMEM);
2092
2093 sz = sizeof(struct btf_member);
2094 m = btf_add_type_mem(btf, sz);
2095 if (!m)
2096 return libbpf_err(-ENOMEM);
2097
2098 if (name && name[0]) {
2099 name_off = btf__add_str(btf, name);
2100 if (name_off < 0)
2101 return name_off;
2102 }
2103
2104 m->name_off = name_off;
2105 m->type = type_id;
2106 m->offset = bit_offset | (bit_size << 24);
2107
2108
2109 t = btf_last_type(btf);
2110
2111 t->info = btf_type_info(btf_kind(t), btf_vlen(t) + 1, is_bitfield || btf_kflag(t));
2112
2113 btf->hdr->type_len += sz;
2114 btf->hdr->str_off += sz;
2115 return 0;
2116}
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131int btf__add_enum(struct btf *btf, const char *name, __u32 byte_sz)
2132{
2133 struct btf_type *t;
2134 int sz, name_off = 0;
2135
2136
2137 if (!byte_sz || (byte_sz & (byte_sz - 1)) || byte_sz > 8)
2138 return libbpf_err(-EINVAL);
2139
2140 if (btf_ensure_modifiable(btf))
2141 return libbpf_err(-ENOMEM);
2142
2143 sz = sizeof(struct btf_type);
2144 t = btf_add_type_mem(btf, sz);
2145 if (!t)
2146 return libbpf_err(-ENOMEM);
2147
2148 if (name && name[0]) {
2149 name_off = btf__add_str(btf, name);
2150 if (name_off < 0)
2151 return name_off;
2152 }
2153
2154
2155 t->name_off = name_off;
2156 t->info = btf_type_info(BTF_KIND_ENUM, 0, 0);
2157 t->size = byte_sz;
2158
2159 return btf_commit_type(btf, sz);
2160}
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170int btf__add_enum_value(struct btf *btf, const char *name, __s64 value)
2171{
2172 struct btf_type *t;
2173 struct btf_enum *v;
2174 int sz, name_off;
2175
2176
2177 if (btf->nr_types == 0)
2178 return libbpf_err(-EINVAL);
2179 t = btf_last_type(btf);
2180 if (!btf_is_enum(t))
2181 return libbpf_err(-EINVAL);
2182
2183
2184 if (!name || !name[0])
2185 return libbpf_err(-EINVAL);
2186 if (value < INT_MIN || value > UINT_MAX)
2187 return libbpf_err(-E2BIG);
2188
2189
2190 if (btf_ensure_modifiable(btf))
2191 return libbpf_err(-ENOMEM);
2192
2193 sz = sizeof(struct btf_enum);
2194 v = btf_add_type_mem(btf, sz);
2195 if (!v)
2196 return libbpf_err(-ENOMEM);
2197
2198 name_off = btf__add_str(btf, name);
2199 if (name_off < 0)
2200 return name_off;
2201
2202 v->name_off = name_off;
2203 v->val = value;
2204
2205
2206 t = btf_last_type(btf);
2207 btf_type_inc_vlen(t);
2208
2209 btf->hdr->type_len += sz;
2210 btf->hdr->str_off += sz;
2211 return 0;
2212}
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind)
2224{
2225 if (!name || !name[0])
2226 return libbpf_err(-EINVAL);
2227
2228 switch (fwd_kind) {
2229 case BTF_FWD_STRUCT:
2230 case BTF_FWD_UNION: {
2231 struct btf_type *t;
2232 int id;
2233
2234 id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0);
2235 if (id <= 0)
2236 return id;
2237 t = btf_type_by_id(btf, id);
2238 t->info = btf_type_info(BTF_KIND_FWD, 0, fwd_kind == BTF_FWD_UNION);
2239 return id;
2240 }
2241 case BTF_FWD_ENUM:
2242
2243
2244
2245 return btf__add_enum(btf, name, sizeof(int));
2246 default:
2247 return libbpf_err(-EINVAL);
2248 }
2249}
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id)
2260{
2261 if (!name || !name[0])
2262 return libbpf_err(-EINVAL);
2263
2264 return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id);
2265}
2266
2267
2268
2269
2270
2271
2272
2273
2274int btf__add_volatile(struct btf *btf, int ref_type_id)
2275{
2276 return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id);
2277}
2278
2279
2280
2281
2282
2283
2284
2285
2286int btf__add_const(struct btf *btf, int ref_type_id)
2287{
2288 return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id);
2289}
2290
2291
2292
2293
2294
2295
2296
2297
2298int btf__add_restrict(struct btf *btf, int ref_type_id)
2299{
2300 return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id);
2301}
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id)
2312{
2313 if (!value|| !value[0])
2314 return libbpf_err(-EINVAL);
2315
2316 return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id);
2317}
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327int btf__add_func(struct btf *btf, const char *name,
2328 enum btf_func_linkage linkage, int proto_type_id)
2329{
2330 int id;
2331
2332 if (!name || !name[0])
2333 return libbpf_err(-EINVAL);
2334 if (linkage != BTF_FUNC_STATIC && linkage != BTF_FUNC_GLOBAL &&
2335 linkage != BTF_FUNC_EXTERN)
2336 return libbpf_err(-EINVAL);
2337
2338 id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id);
2339 if (id > 0) {
2340 struct btf_type *t = btf_type_by_id(btf, id);
2341
2342 t->info = btf_type_info(BTF_KIND_FUNC, linkage, 0);
2343 }
2344 return libbpf_err(id);
2345}
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359int btf__add_func_proto(struct btf *btf, int ret_type_id)
2360{
2361 struct btf_type *t;
2362 int sz;
2363
2364 if (validate_type_id(ret_type_id))
2365 return libbpf_err(-EINVAL);
2366
2367 if (btf_ensure_modifiable(btf))
2368 return libbpf_err(-ENOMEM);
2369
2370 sz = sizeof(struct btf_type);
2371 t = btf_add_type_mem(btf, sz);
2372 if (!t)
2373 return libbpf_err(-ENOMEM);
2374
2375
2376
2377
2378 t->name_off = 0;
2379 t->info = btf_type_info(BTF_KIND_FUNC_PROTO, 0, 0);
2380 t->type = ret_type_id;
2381
2382 return btf_commit_type(btf, sz);
2383}
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393int btf__add_func_param(struct btf *btf, const char *name, int type_id)
2394{
2395 struct btf_type *t;
2396 struct btf_param *p;
2397 int sz, name_off = 0;
2398
2399 if (validate_type_id(type_id))
2400 return libbpf_err(-EINVAL);
2401
2402
2403 if (btf->nr_types == 0)
2404 return libbpf_err(-EINVAL);
2405 t = btf_last_type(btf);
2406 if (!btf_is_func_proto(t))
2407 return libbpf_err(-EINVAL);
2408
2409
2410 if (btf_ensure_modifiable(btf))
2411 return libbpf_err(-ENOMEM);
2412
2413 sz = sizeof(struct btf_param);
2414 p = btf_add_type_mem(btf, sz);
2415 if (!p)
2416 return libbpf_err(-ENOMEM);
2417
2418 if (name && name[0]) {
2419 name_off = btf__add_str(btf, name);
2420 if (name_off < 0)
2421 return name_off;
2422 }
2423
2424 p->name_off = name_off;
2425 p->type = type_id;
2426
2427
2428 t = btf_last_type(btf);
2429 btf_type_inc_vlen(t);
2430
2431 btf->hdr->type_len += sz;
2432 btf->hdr->str_off += sz;
2433 return 0;
2434}
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446int btf__add_var(struct btf *btf, const char *name, int linkage, int type_id)
2447{
2448 struct btf_type *t;
2449 struct btf_var *v;
2450 int sz, name_off;
2451
2452
2453 if (!name || !name[0])
2454 return libbpf_err(-EINVAL);
2455 if (linkage != BTF_VAR_STATIC && linkage != BTF_VAR_GLOBAL_ALLOCATED &&
2456 linkage != BTF_VAR_GLOBAL_EXTERN)
2457 return libbpf_err(-EINVAL);
2458 if (validate_type_id(type_id))
2459 return libbpf_err(-EINVAL);
2460
2461
2462 if (btf_ensure_modifiable(btf))
2463 return libbpf_err(-ENOMEM);
2464
2465 sz = sizeof(struct btf_type) + sizeof(struct btf_var);
2466 t = btf_add_type_mem(btf, sz);
2467 if (!t)
2468 return libbpf_err(-ENOMEM);
2469
2470 name_off = btf__add_str(btf, name);
2471 if (name_off < 0)
2472 return name_off;
2473
2474 t->name_off = name_off;
2475 t->info = btf_type_info(BTF_KIND_VAR, 0, 0);
2476 t->type = type_id;
2477
2478 v = btf_var(t);
2479 v->linkage = linkage;
2480
2481 return btf_commit_type(btf, sz);
2482}
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496int btf__add_datasec(struct btf *btf, const char *name, __u32 byte_sz)
2497{
2498 struct btf_type *t;
2499 int sz, name_off;
2500
2501
2502 if (!name || !name[0])
2503 return libbpf_err(-EINVAL);
2504
2505 if (btf_ensure_modifiable(btf))
2506 return libbpf_err(-ENOMEM);
2507
2508 sz = sizeof(struct btf_type);
2509 t = btf_add_type_mem(btf, sz);
2510 if (!t)
2511 return libbpf_err(-ENOMEM);
2512
2513 name_off = btf__add_str(btf, name);
2514 if (name_off < 0)
2515 return name_off;
2516
2517
2518 t->name_off = name_off;
2519 t->info = btf_type_info(BTF_KIND_DATASEC, 0, 0);
2520 t->size = byte_sz;
2521
2522 return btf_commit_type(btf, sz);
2523}
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __u32 byte_sz)
2536{
2537 struct btf_type *t;
2538 struct btf_var_secinfo *v;
2539 int sz;
2540
2541
2542 if (btf->nr_types == 0)
2543 return libbpf_err(-EINVAL);
2544 t = btf_last_type(btf);
2545 if (!btf_is_datasec(t))
2546 return libbpf_err(-EINVAL);
2547
2548 if (validate_type_id(var_type_id))
2549 return libbpf_err(-EINVAL);
2550
2551
2552 if (btf_ensure_modifiable(btf))
2553 return libbpf_err(-ENOMEM);
2554
2555 sz = sizeof(struct btf_var_secinfo);
2556 v = btf_add_type_mem(btf, sz);
2557 if (!v)
2558 return libbpf_err(-ENOMEM);
2559
2560 v->type = var_type_id;
2561 v->offset = offset;
2562 v->size = byte_sz;
2563
2564
2565 t = btf_last_type(btf);
2566 btf_type_inc_vlen(t);
2567
2568 btf->hdr->type_len += sz;
2569 btf->hdr->str_off += sz;
2570 return 0;
2571}
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id,
2584 int component_idx)
2585{
2586 struct btf_type *t;
2587 int sz, value_off;
2588
2589 if (!value || !value[0] || component_idx < -1)
2590 return libbpf_err(-EINVAL);
2591
2592 if (validate_type_id(ref_type_id))
2593 return libbpf_err(-EINVAL);
2594
2595 if (btf_ensure_modifiable(btf))
2596 return libbpf_err(-ENOMEM);
2597
2598 sz = sizeof(struct btf_type) + sizeof(struct btf_decl_tag);
2599 t = btf_add_type_mem(btf, sz);
2600 if (!t)
2601 return libbpf_err(-ENOMEM);
2602
2603 value_off = btf__add_str(btf, value);
2604 if (value_off < 0)
2605 return value_off;
2606
2607 t->name_off = value_off;
2608 t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, false);
2609 t->type = ref_type_id;
2610 btf_decl_tag(t)->component_idx = component_idx;
2611
2612 return btf_commit_type(btf, sz);
2613}
2614
2615struct btf_ext_sec_setup_param {
2616 __u32 off;
2617 __u32 len;
2618 __u32 min_rec_size;
2619 struct btf_ext_info *ext_info;
2620 const char *desc;
2621};
2622
2623static int btf_ext_setup_info(struct btf_ext *btf_ext,
2624 struct btf_ext_sec_setup_param *ext_sec)
2625{
2626 const struct btf_ext_info_sec *sinfo;
2627 struct btf_ext_info *ext_info;
2628 __u32 info_left, record_size;
2629
2630 void *info;
2631
2632 if (ext_sec->len == 0)
2633 return 0;
2634
2635 if (ext_sec->off & 0x03) {
2636 pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
2637 ext_sec->desc);
2638 return -EINVAL;
2639 }
2640
2641 info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
2642 info_left = ext_sec->len;
2643
2644 if (btf_ext->data + btf_ext->data_size < info + ext_sec->len) {
2645 pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
2646 ext_sec->desc, ext_sec->off, ext_sec->len);
2647 return -EINVAL;
2648 }
2649
2650
2651 if (info_left < sizeof(__u32)) {
2652 pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc);
2653 return -EINVAL;
2654 }
2655
2656
2657 record_size = *(__u32 *)info;
2658 if (record_size < ext_sec->min_rec_size ||
2659 record_size & 0x03) {
2660 pr_debug("%s section in .BTF.ext has invalid record size %u\n",
2661 ext_sec->desc, record_size);
2662 return -EINVAL;
2663 }
2664
2665 sinfo = info + sizeof(__u32);
2666 info_left -= sizeof(__u32);
2667
2668
2669 if (!info_left) {
2670 pr_debug("%s section in .BTF.ext has no records", ext_sec->desc);
2671 return -EINVAL;
2672 }
2673
2674 while (info_left) {
2675 unsigned int sec_hdrlen = sizeof(struct btf_ext_info_sec);
2676 __u64 total_record_size;
2677 __u32 num_records;
2678
2679 if (info_left < sec_hdrlen) {
2680 pr_debug("%s section header is not found in .BTF.ext\n",
2681 ext_sec->desc);
2682 return -EINVAL;
2683 }
2684
2685 num_records = sinfo->num_info;
2686 if (num_records == 0) {
2687 pr_debug("%s section has incorrect num_records in .BTF.ext\n",
2688 ext_sec->desc);
2689 return -EINVAL;
2690 }
2691
2692 total_record_size = sec_hdrlen +
2693 (__u64)num_records * record_size;
2694 if (info_left < total_record_size) {
2695 pr_debug("%s section has incorrect num_records in .BTF.ext\n",
2696 ext_sec->desc);
2697 return -EINVAL;
2698 }
2699
2700 info_left -= total_record_size;
2701 sinfo = (void *)sinfo + total_record_size;
2702 }
2703
2704 ext_info = ext_sec->ext_info;
2705 ext_info->len = ext_sec->len - sizeof(__u32);
2706 ext_info->rec_size = record_size;
2707 ext_info->info = info + sizeof(__u32);
2708
2709 return 0;
2710}
2711
2712static int btf_ext_setup_func_info(struct btf_ext *btf_ext)
2713{
2714 struct btf_ext_sec_setup_param param = {
2715 .off = btf_ext->hdr->func_info_off,
2716 .len = btf_ext->hdr->func_info_len,
2717 .min_rec_size = sizeof(struct bpf_func_info_min),
2718 .ext_info = &btf_ext->func_info,
2719 .desc = "func_info"
2720 };
2721
2722 return btf_ext_setup_info(btf_ext, ¶m);
2723}
2724
2725static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
2726{
2727 struct btf_ext_sec_setup_param param = {
2728 .off = btf_ext->hdr->line_info_off,
2729 .len = btf_ext->hdr->line_info_len,
2730 .min_rec_size = sizeof(struct bpf_line_info_min),
2731 .ext_info = &btf_ext->line_info,
2732 .desc = "line_info",
2733 };
2734
2735 return btf_ext_setup_info(btf_ext, ¶m);
2736}
2737
2738static int btf_ext_setup_core_relos(struct btf_ext *btf_ext)
2739{
2740 struct btf_ext_sec_setup_param param = {
2741 .off = btf_ext->hdr->core_relo_off,
2742 .len = btf_ext->hdr->core_relo_len,
2743 .min_rec_size = sizeof(struct bpf_core_relo),
2744 .ext_info = &btf_ext->core_relo_info,
2745 .desc = "core_relo",
2746 };
2747
2748 return btf_ext_setup_info(btf_ext, ¶m);
2749}
2750
2751static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
2752{
2753 const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
2754
2755 if (data_size < offsetofend(struct btf_ext_header, hdr_len) ||
2756 data_size < hdr->hdr_len) {
2757 pr_debug("BTF.ext header not found");
2758 return -EINVAL;
2759 }
2760
2761 if (hdr->magic == bswap_16(BTF_MAGIC)) {
2762 pr_warn("BTF.ext in non-native endianness is not supported\n");
2763 return -ENOTSUP;
2764 } else if (hdr->magic != BTF_MAGIC) {
2765 pr_debug("Invalid BTF.ext magic:%x\n", hdr->magic);
2766 return -EINVAL;
2767 }
2768
2769 if (hdr->version != BTF_VERSION) {
2770 pr_debug("Unsupported BTF.ext version:%u\n", hdr->version);
2771 return -ENOTSUP;
2772 }
2773
2774 if (hdr->flags) {
2775 pr_debug("Unsupported BTF.ext flags:%x\n", hdr->flags);
2776 return -ENOTSUP;
2777 }
2778
2779 if (data_size == hdr->hdr_len) {
2780 pr_debug("BTF.ext has no data\n");
2781 return -EINVAL;
2782 }
2783
2784 return 0;
2785}
2786
2787void btf_ext__free(struct btf_ext *btf_ext)
2788{
2789 if (IS_ERR_OR_NULL(btf_ext))
2790 return;
2791 free(btf_ext->data);
2792 free(btf_ext);
2793}
2794
2795struct btf_ext *btf_ext__new(const __u8 *data, __u32 size)
2796{
2797 struct btf_ext *btf_ext;
2798 int err;
2799
2800 btf_ext = calloc(1, sizeof(struct btf_ext));
2801 if (!btf_ext)
2802 return libbpf_err_ptr(-ENOMEM);
2803
2804 btf_ext->data_size = size;
2805 btf_ext->data = malloc(size);
2806 if (!btf_ext->data) {
2807 err = -ENOMEM;
2808 goto done;
2809 }
2810 memcpy(btf_ext->data, data, size);
2811
2812 err = btf_ext_parse_hdr(btf_ext->data, size);
2813 if (err)
2814 goto done;
2815
2816 if (btf_ext->hdr->hdr_len < offsetofend(struct btf_ext_header, line_info_len)) {
2817 err = -EINVAL;
2818 goto done;
2819 }
2820
2821 err = btf_ext_setup_func_info(btf_ext);
2822 if (err)
2823 goto done;
2824
2825 err = btf_ext_setup_line_info(btf_ext);
2826 if (err)
2827 goto done;
2828
2829 if (btf_ext->hdr->hdr_len < offsetofend(struct btf_ext_header, core_relo_len)) {
2830 err = -EINVAL;
2831 goto done;
2832 }
2833
2834 err = btf_ext_setup_core_relos(btf_ext);
2835 if (err)
2836 goto done;
2837
2838done:
2839 if (err) {
2840 btf_ext__free(btf_ext);
2841 return libbpf_err_ptr(err);
2842 }
2843
2844 return btf_ext;
2845}
2846
2847const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size)
2848{
2849 *size = btf_ext->data_size;
2850 return btf_ext->data;
2851}
2852
2853static int btf_ext_reloc_info(const struct btf *btf,
2854 const struct btf_ext_info *ext_info,
2855 const char *sec_name, __u32 insns_cnt,
2856 void **info, __u32 *cnt)
2857{
2858 __u32 sec_hdrlen = sizeof(struct btf_ext_info_sec);
2859 __u32 i, record_size, existing_len, records_len;
2860 struct btf_ext_info_sec *sinfo;
2861 const char *info_sec_name;
2862 __u64 remain_len;
2863 void *data;
2864
2865 record_size = ext_info->rec_size;
2866 sinfo = ext_info->info;
2867 remain_len = ext_info->len;
2868 while (remain_len > 0) {
2869 records_len = sinfo->num_info * record_size;
2870 info_sec_name = btf__name_by_offset(btf, sinfo->sec_name_off);
2871 if (strcmp(info_sec_name, sec_name)) {
2872 remain_len -= sec_hdrlen + records_len;
2873 sinfo = (void *)sinfo + sec_hdrlen + records_len;
2874 continue;
2875 }
2876
2877 existing_len = (*cnt) * record_size;
2878 data = realloc(*info, existing_len + records_len);
2879 if (!data)
2880 return libbpf_err(-ENOMEM);
2881
2882 memcpy(data + existing_len, sinfo->data, records_len);
2883
2884
2885
2886 for (i = 0; i < sinfo->num_info; i++) {
2887 __u32 *insn_off;
2888
2889 insn_off = data + existing_len + (i * record_size);
2890 *insn_off = *insn_off / sizeof(struct bpf_insn) + insns_cnt;
2891 }
2892 *info = data;
2893 *cnt += sinfo->num_info;
2894 return 0;
2895 }
2896
2897 return libbpf_err(-ENOENT);
2898}
2899
2900int btf_ext__reloc_func_info(const struct btf *btf,
2901 const struct btf_ext *btf_ext,
2902 const char *sec_name, __u32 insns_cnt,
2903 void **func_info, __u32 *cnt)
2904{
2905 return btf_ext_reloc_info(btf, &btf_ext->func_info, sec_name,
2906 insns_cnt, func_info, cnt);
2907}
2908
2909int btf_ext__reloc_line_info(const struct btf *btf,
2910 const struct btf_ext *btf_ext,
2911 const char *sec_name, __u32 insns_cnt,
2912 void **line_info, __u32 *cnt)
2913{
2914 return btf_ext_reloc_info(btf, &btf_ext->line_info, sec_name,
2915 insns_cnt, line_info, cnt);
2916}
2917
2918__u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext)
2919{
2920 return btf_ext->func_info.rec_size;
2921}
2922
2923__u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext)
2924{
2925 return btf_ext->line_info.rec_size;
2926}
2927
2928struct btf_dedup;
2929
2930static struct btf_dedup *btf_dedup_new(struct btf *btf, const struct btf_dedup_opts *opts);
2931static void btf_dedup_free(struct btf_dedup *d);
2932static int btf_dedup_prep(struct btf_dedup *d);
2933static int btf_dedup_strings(struct btf_dedup *d);
2934static int btf_dedup_prim_types(struct btf_dedup *d);
2935static int btf_dedup_struct_types(struct btf_dedup *d);
2936static int btf_dedup_ref_types(struct btf_dedup *d);
2937static int btf_dedup_compact_types(struct btf_dedup *d);
2938static int btf_dedup_remap_types(struct btf_dedup *d);
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
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078DEFAULT_VERSION(btf__dedup_v0_6_0, btf__dedup, LIBBPF_0.6.0)
3079int btf__dedup_v0_6_0(struct btf *btf, const struct btf_dedup_opts *opts)
3080{
3081 struct btf_dedup *d;
3082 int err;
3083
3084 if (!OPTS_VALID(opts, btf_dedup_opts))
3085 return libbpf_err(-EINVAL);
3086
3087 d = btf_dedup_new(btf, opts);
3088 if (IS_ERR(d)) {
3089 pr_debug("btf_dedup_new failed: %ld", PTR_ERR(d));
3090 return libbpf_err(-EINVAL);
3091 }
3092
3093 if (btf_ensure_modifiable(btf)) {
3094 err = -ENOMEM;
3095 goto done;
3096 }
3097
3098 err = btf_dedup_prep(d);
3099 if (err) {
3100 pr_debug("btf_dedup_prep failed:%d\n", err);
3101 goto done;
3102 }
3103 err = btf_dedup_strings(d);
3104 if (err < 0) {
3105 pr_debug("btf_dedup_strings failed:%d\n", err);
3106 goto done;
3107 }
3108 err = btf_dedup_prim_types(d);
3109 if (err < 0) {
3110 pr_debug("btf_dedup_prim_types failed:%d\n", err);
3111 goto done;
3112 }
3113 err = btf_dedup_struct_types(d);
3114 if (err < 0) {
3115 pr_debug("btf_dedup_struct_types failed:%d\n", err);
3116 goto done;
3117 }
3118 err = btf_dedup_ref_types(d);
3119 if (err < 0) {
3120 pr_debug("btf_dedup_ref_types failed:%d\n", err);
3121 goto done;
3122 }
3123 err = btf_dedup_compact_types(d);
3124 if (err < 0) {
3125 pr_debug("btf_dedup_compact_types failed:%d\n", err);
3126 goto done;
3127 }
3128 err = btf_dedup_remap_types(d);
3129 if (err < 0) {
3130 pr_debug("btf_dedup_remap_types failed:%d\n", err);
3131 goto done;
3132 }
3133
3134done:
3135 btf_dedup_free(d);
3136 return libbpf_err(err);
3137}
3138
3139COMPAT_VERSION(btf__dedup_deprecated, btf__dedup, LIBBPF_0.0.2)
3140int btf__dedup_deprecated(struct btf *btf, struct btf_ext *btf_ext, const void *unused_opts)
3141{
3142 LIBBPF_OPTS(btf_dedup_opts, opts, .btf_ext = btf_ext);
3143
3144 if (unused_opts) {
3145 pr_warn("please use new version of btf__dedup() that supports options\n");
3146 return libbpf_err(-ENOTSUP);
3147 }
3148
3149 return btf__dedup(btf, &opts);
3150}
3151
3152#define BTF_UNPROCESSED_ID ((__u32)-1)
3153#define BTF_IN_PROGRESS_ID ((__u32)-2)
3154
3155struct btf_dedup {
3156
3157 struct btf *btf;
3158
3159
3160
3161
3162 struct btf_ext *btf_ext;
3163
3164
3165
3166
3167
3168
3169
3170 struct hashmap *dedup_table;
3171
3172 __u32 *map;
3173
3174 __u32 *hypot_map;
3175 __u32 *hypot_list;
3176 size_t hypot_cnt;
3177 size_t hypot_cap;
3178
3179
3180
3181
3182
3183
3184 bool hypot_adjust_canon;
3185
3186 struct btf_dedup_opts opts;
3187
3188 struct strset *strs_set;
3189};
3190
3191static long hash_combine(long h, long value)
3192{
3193 return h * 31 + value;
3194}
3195
3196#define for_each_dedup_cand(d, node, hash) \
3197 hashmap__for_each_key_entry(d->dedup_table, node, (void *)hash)
3198
3199static int btf_dedup_table_add(struct btf_dedup *d, long hash, __u32 type_id)
3200{
3201 return hashmap__append(d->dedup_table,
3202 (void *)hash, (void *)(long)type_id);
3203}
3204
3205static int btf_dedup_hypot_map_add(struct btf_dedup *d,
3206 __u32 from_id, __u32 to_id)
3207{
3208 if (d->hypot_cnt == d->hypot_cap) {
3209 __u32 *new_list;
3210
3211 d->hypot_cap += max((size_t)16, d->hypot_cap / 2);
3212 new_list = libbpf_reallocarray(d->hypot_list, d->hypot_cap, sizeof(__u32));
3213 if (!new_list)
3214 return -ENOMEM;
3215 d->hypot_list = new_list;
3216 }
3217 d->hypot_list[d->hypot_cnt++] = from_id;
3218 d->hypot_map[from_id] = to_id;
3219 return 0;
3220}
3221
3222static void btf_dedup_clear_hypot_map(struct btf_dedup *d)
3223{
3224 int i;
3225
3226 for (i = 0; i < d->hypot_cnt; i++)
3227 d->hypot_map[d->hypot_list[i]] = BTF_UNPROCESSED_ID;
3228 d->hypot_cnt = 0;
3229 d->hypot_adjust_canon = false;
3230}
3231
3232static void btf_dedup_free(struct btf_dedup *d)
3233{
3234 hashmap__free(d->dedup_table);
3235 d->dedup_table = NULL;
3236
3237 free(d->map);
3238 d->map = NULL;
3239
3240 free(d->hypot_map);
3241 d->hypot_map = NULL;
3242
3243 free(d->hypot_list);
3244 d->hypot_list = NULL;
3245
3246 free(d);
3247}
3248
3249static size_t btf_dedup_identity_hash_fn(const void *key, void *ctx)
3250{
3251 return (size_t)key;
3252}
3253
3254static size_t btf_dedup_collision_hash_fn(const void *key, void *ctx)
3255{
3256 return 0;
3257}
3258
3259static bool btf_dedup_equal_fn(const void *k1, const void *k2, void *ctx)
3260{
3261 return k1 == k2;
3262}
3263
3264static struct btf_dedup *btf_dedup_new(struct btf *btf, const struct btf_dedup_opts *opts)
3265{
3266 struct btf_dedup *d = calloc(1, sizeof(struct btf_dedup));
3267 hashmap_hash_fn hash_fn = btf_dedup_identity_hash_fn;
3268 int i, err = 0, type_cnt;
3269
3270 if (!d)
3271 return ERR_PTR(-ENOMEM);
3272
3273 if (OPTS_GET(opts, force_collisions, false))
3274 hash_fn = btf_dedup_collision_hash_fn;
3275
3276 d->btf = btf;
3277 d->btf_ext = OPTS_GET(opts, btf_ext, NULL);
3278
3279 d->dedup_table = hashmap__new(hash_fn, btf_dedup_equal_fn, NULL);
3280 if (IS_ERR(d->dedup_table)) {
3281 err = PTR_ERR(d->dedup_table);
3282 d->dedup_table = NULL;
3283 goto done;
3284 }
3285
3286 type_cnt = btf__type_cnt(btf);
3287 d->map = malloc(sizeof(__u32) * type_cnt);
3288 if (!d->map) {
3289 err = -ENOMEM;
3290 goto done;
3291 }
3292
3293 d->map[0] = 0;
3294 for (i = 1; i < type_cnt; i++) {
3295 struct btf_type *t = btf_type_by_id(d->btf, i);
3296
3297
3298 if (btf_is_var(t) || btf_is_datasec(t))
3299 d->map[i] = i;
3300 else
3301 d->map[i] = BTF_UNPROCESSED_ID;
3302 }
3303
3304 d->hypot_map = malloc(sizeof(__u32) * type_cnt);
3305 if (!d->hypot_map) {
3306 err = -ENOMEM;
3307 goto done;
3308 }
3309 for (i = 0; i < type_cnt; i++)
3310 d->hypot_map[i] = BTF_UNPROCESSED_ID;
3311
3312done:
3313 if (err) {
3314 btf_dedup_free(d);
3315 return ERR_PTR(err);
3316 }
3317
3318 return d;
3319}
3320
3321
3322
3323
3324
3325static int btf_for_each_str_off(struct btf_dedup *d, str_off_visit_fn fn, void *ctx)
3326{
3327 int i, r;
3328
3329 for (i = 0; i < d->btf->nr_types; i++) {
3330 struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i);
3331
3332 r = btf_type_visit_str_offs(t, fn, ctx);
3333 if (r)
3334 return r;
3335 }
3336
3337 if (!d->btf_ext)
3338 return 0;
3339
3340 r = btf_ext_visit_str_offs(d->btf_ext, fn, ctx);
3341 if (r)
3342 return r;
3343
3344 return 0;
3345}
3346
3347static int strs_dedup_remap_str_off(__u32 *str_off_ptr, void *ctx)
3348{
3349 struct btf_dedup *d = ctx;
3350 __u32 str_off = *str_off_ptr;
3351 const char *s;
3352 int off, err;
3353
3354
3355 if (str_off == 0 || str_off < d->btf->start_str_off)
3356 return 0;
3357
3358 s = btf__str_by_offset(d->btf, str_off);
3359 if (d->btf->base_btf) {
3360 err = btf__find_str(d->btf->base_btf, s);
3361 if (err >= 0) {
3362 *str_off_ptr = err;
3363 return 0;
3364 }
3365 if (err != -ENOENT)
3366 return err;
3367 }
3368
3369 off = strset__add_str(d->strs_set, s);
3370 if (off < 0)
3371 return off;
3372
3373 *str_off_ptr = d->btf->start_str_off + off;
3374 return 0;
3375}
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388static int btf_dedup_strings(struct btf_dedup *d)
3389{
3390 int err;
3391
3392 if (d->btf->strs_deduped)
3393 return 0;
3394
3395 d->strs_set = strset__new(BTF_MAX_STR_OFFSET, NULL, 0);
3396 if (IS_ERR(d->strs_set)) {
3397 err = PTR_ERR(d->strs_set);
3398 goto err_out;
3399 }
3400
3401 if (!d->btf->base_btf) {
3402
3403
3404
3405 err = strset__add_str(d->strs_set, "");
3406 if (err < 0)
3407 goto err_out;
3408 }
3409
3410
3411 err = btf_for_each_str_off(d, strs_dedup_remap_str_off, d);
3412 if (err)
3413 goto err_out;
3414
3415
3416 strset__free(d->btf->strs_set);
3417 d->btf->hdr->str_len = strset__data_size(d->strs_set);
3418 d->btf->strs_set = d->strs_set;
3419 d->strs_set = NULL;
3420 d->btf->strs_deduped = true;
3421 return 0;
3422
3423err_out:
3424 strset__free(d->strs_set);
3425 d->strs_set = NULL;
3426
3427 return err;
3428}
3429
3430static long btf_hash_common(struct btf_type *t)
3431{
3432 long h;
3433
3434 h = hash_combine(0, t->name_off);
3435 h = hash_combine(h, t->info);
3436 h = hash_combine(h, t->size);
3437 return h;
3438}
3439
3440static bool btf_equal_common(struct btf_type *t1, struct btf_type *t2)
3441{
3442 return t1->name_off == t2->name_off &&
3443 t1->info == t2->info &&
3444 t1->size == t2->size;
3445}
3446
3447
3448static long btf_hash_int_decl_tag(struct btf_type *t)
3449{
3450 __u32 info = *(__u32 *)(t + 1);
3451 long h;
3452
3453 h = btf_hash_common(t);
3454 h = hash_combine(h, info);
3455 return h;
3456}
3457
3458
3459static bool btf_equal_int_tag(struct btf_type *t1, struct btf_type *t2)
3460{
3461 __u32 info1, info2;
3462
3463 if (!btf_equal_common(t1, t2))
3464 return false;
3465 info1 = *(__u32 *)(t1 + 1);
3466 info2 = *(__u32 *)(t2 + 1);
3467 return info1 == info2;
3468}
3469
3470
3471static long btf_hash_enum(struct btf_type *t)
3472{
3473 long h;
3474
3475
3476 h = hash_combine(0, t->name_off);
3477 h = hash_combine(h, t->info & ~0xffff);
3478 h = hash_combine(h, t->size);
3479 return h;
3480}
3481
3482
3483static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2)
3484{
3485 const struct btf_enum *m1, *m2;
3486 __u16 vlen;
3487 int i;
3488
3489 if (!btf_equal_common(t1, t2))
3490 return false;
3491
3492 vlen = btf_vlen(t1);
3493 m1 = btf_enum(t1);
3494 m2 = btf_enum(t2);
3495 for (i = 0; i < vlen; i++) {
3496 if (m1->name_off != m2->name_off || m1->val != m2->val)
3497 return false;
3498 m1++;
3499 m2++;
3500 }
3501 return true;
3502}
3503
3504static inline bool btf_is_enum_fwd(struct btf_type *t)
3505{
3506 return btf_is_enum(t) && btf_vlen(t) == 0;
3507}
3508
3509static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
3510{
3511 if (!btf_is_enum_fwd(t1) && !btf_is_enum_fwd(t2))
3512 return btf_equal_enum(t1, t2);
3513
3514 return t1->name_off == t2->name_off &&
3515 (t1->info & ~0xffff) == (t2->info & ~0xffff) &&
3516 t1->size == t2->size;
3517}
3518
3519
3520
3521
3522
3523
3524static long btf_hash_struct(struct btf_type *t)
3525{
3526 const struct btf_member *member = btf_members(t);
3527 __u32 vlen = btf_vlen(t);
3528 long h = btf_hash_common(t);
3529 int i;
3530
3531 for (i = 0; i < vlen; i++) {
3532 h = hash_combine(h, member->name_off);
3533 h = hash_combine(h, member->offset);
3534
3535 member++;
3536 }
3537 return h;
3538}
3539
3540
3541
3542
3543
3544
3545static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2)
3546{
3547 const struct btf_member *m1, *m2;
3548 __u16 vlen;
3549 int i;
3550
3551 if (!btf_equal_common(t1, t2))
3552 return false;
3553
3554 vlen = btf_vlen(t1);
3555 m1 = btf_members(t1);
3556 m2 = btf_members(t2);
3557 for (i = 0; i < vlen; i++) {
3558 if (m1->name_off != m2->name_off || m1->offset != m2->offset)
3559 return false;
3560 m1++;
3561 m2++;
3562 }
3563 return true;
3564}
3565
3566
3567
3568
3569
3570
3571static long btf_hash_array(struct btf_type *t)
3572{
3573 const struct btf_array *info = btf_array(t);
3574 long h = btf_hash_common(t);
3575
3576 h = hash_combine(h, info->type);
3577 h = hash_combine(h, info->index_type);
3578 h = hash_combine(h, info->nelems);
3579 return h;
3580}
3581
3582
3583
3584
3585
3586
3587
3588
3589static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2)
3590{
3591 const struct btf_array *info1, *info2;
3592
3593 if (!btf_equal_common(t1, t2))
3594 return false;
3595
3596 info1 = btf_array(t1);
3597 info2 = btf_array(t2);
3598 return info1->type == info2->type &&
3599 info1->index_type == info2->index_type &&
3600 info1->nelems == info2->nelems;
3601}
3602
3603
3604
3605
3606
3607
3608static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2)
3609{
3610 if (!btf_equal_common(t1, t2))
3611 return false;
3612
3613 return btf_array(t1)->nelems == btf_array(t2)->nelems;
3614}
3615
3616
3617
3618
3619
3620
3621static long btf_hash_fnproto(struct btf_type *t)
3622{
3623 const struct btf_param *member = btf_params(t);
3624 __u16 vlen = btf_vlen(t);
3625 long h = btf_hash_common(t);
3626 int i;
3627
3628 for (i = 0; i < vlen; i++) {
3629 h = hash_combine(h, member->name_off);
3630 h = hash_combine(h, member->type);
3631 member++;
3632 }
3633 return h;
3634}
3635
3636
3637
3638
3639
3640
3641
3642
3643static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
3644{
3645 const struct btf_param *m1, *m2;
3646 __u16 vlen;
3647 int i;
3648
3649 if (!btf_equal_common(t1, t2))
3650 return false;
3651
3652 vlen = btf_vlen(t1);
3653 m1 = btf_params(t1);
3654 m2 = btf_params(t2);
3655 for (i = 0; i < vlen; i++) {
3656 if (m1->name_off != m2->name_off || m1->type != m2->type)
3657 return false;
3658 m1++;
3659 m2++;
3660 }
3661 return true;
3662}
3663
3664
3665
3666
3667
3668
3669static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2)
3670{
3671 const struct btf_param *m1, *m2;
3672 __u16 vlen;
3673 int i;
3674
3675
3676 if (t1->name_off != t2->name_off || t1->info != t2->info)
3677 return false;
3678
3679 vlen = btf_vlen(t1);
3680 m1 = btf_params(t1);
3681 m2 = btf_params(t2);
3682 for (i = 0; i < vlen; i++) {
3683 if (m1->name_off != m2->name_off)
3684 return false;
3685 m1++;
3686 m2++;
3687 }
3688 return true;
3689}
3690
3691
3692
3693
3694
3695static int btf_dedup_prep(struct btf_dedup *d)
3696{
3697 struct btf_type *t;
3698 int type_id;
3699 long h;
3700
3701 if (!d->btf->base_btf)
3702 return 0;
3703
3704 for (type_id = 1; type_id < d->btf->start_id; type_id++) {
3705 t = btf_type_by_id(d->btf, type_id);
3706
3707
3708 d->map[type_id] = type_id;
3709
3710 switch (btf_kind(t)) {
3711 case BTF_KIND_VAR:
3712 case BTF_KIND_DATASEC:
3713
3714 continue;
3715 case BTF_KIND_CONST:
3716 case BTF_KIND_VOLATILE:
3717 case BTF_KIND_RESTRICT:
3718 case BTF_KIND_PTR:
3719 case BTF_KIND_FWD:
3720 case BTF_KIND_TYPEDEF:
3721 case BTF_KIND_FUNC:
3722 case BTF_KIND_FLOAT:
3723 case BTF_KIND_TYPE_TAG:
3724 h = btf_hash_common(t);
3725 break;
3726 case BTF_KIND_INT:
3727 case BTF_KIND_DECL_TAG:
3728 h = btf_hash_int_decl_tag(t);
3729 break;
3730 case BTF_KIND_ENUM:
3731 h = btf_hash_enum(t);
3732 break;
3733 case BTF_KIND_STRUCT:
3734 case BTF_KIND_UNION:
3735 h = btf_hash_struct(t);
3736 break;
3737 case BTF_KIND_ARRAY:
3738 h = btf_hash_array(t);
3739 break;
3740 case BTF_KIND_FUNC_PROTO:
3741 h = btf_hash_fnproto(t);
3742 break;
3743 default:
3744 pr_debug("unknown kind %d for type [%d]\n", btf_kind(t), type_id);
3745 return -EINVAL;
3746 }
3747 if (btf_dedup_table_add(d, h, type_id))
3748 return -ENOMEM;
3749 }
3750
3751 return 0;
3752}
3753
3754
3755
3756
3757
3758
3759
3760static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
3761{
3762 struct btf_type *t = btf_type_by_id(d->btf, type_id);
3763 struct hashmap_entry *hash_entry;
3764 struct btf_type *cand;
3765
3766 __u32 new_id = type_id;
3767 __u32 cand_id;
3768 long h;
3769
3770 switch (btf_kind(t)) {
3771 case BTF_KIND_CONST:
3772 case BTF_KIND_VOLATILE:
3773 case BTF_KIND_RESTRICT:
3774 case BTF_KIND_PTR:
3775 case BTF_KIND_TYPEDEF:
3776 case BTF_KIND_ARRAY:
3777 case BTF_KIND_STRUCT:
3778 case BTF_KIND_UNION:
3779 case BTF_KIND_FUNC:
3780 case BTF_KIND_FUNC_PROTO:
3781 case BTF_KIND_VAR:
3782 case BTF_KIND_DATASEC:
3783 case BTF_KIND_DECL_TAG:
3784 case BTF_KIND_TYPE_TAG:
3785 return 0;
3786
3787 case BTF_KIND_INT:
3788 h = btf_hash_int_decl_tag(t);
3789 for_each_dedup_cand(d, hash_entry, h) {
3790 cand_id = (__u32)(long)hash_entry->value;
3791 cand = btf_type_by_id(d->btf, cand_id);
3792 if (btf_equal_int_tag(t, cand)) {
3793 new_id = cand_id;
3794 break;
3795 }
3796 }
3797 break;
3798
3799 case BTF_KIND_ENUM:
3800 h = btf_hash_enum(t);
3801 for_each_dedup_cand(d, hash_entry, h) {
3802 cand_id = (__u32)(long)hash_entry->value;
3803 cand = btf_type_by_id(d->btf, cand_id);
3804 if (btf_equal_enum(t, cand)) {
3805 new_id = cand_id;
3806 break;
3807 }
3808 if (btf_compat_enum(t, cand)) {
3809 if (btf_is_enum_fwd(t)) {
3810
3811 new_id = cand_id;
3812 break;
3813 }
3814
3815 d->map[cand_id] = type_id;
3816 }
3817 }
3818 break;
3819
3820 case BTF_KIND_FWD:
3821 case BTF_KIND_FLOAT:
3822 h = btf_hash_common(t);
3823 for_each_dedup_cand(d, hash_entry, h) {
3824 cand_id = (__u32)(long)hash_entry->value;
3825 cand = btf_type_by_id(d->btf, cand_id);
3826 if (btf_equal_common(t, cand)) {
3827 new_id = cand_id;
3828 break;
3829 }
3830 }
3831 break;
3832
3833 default:
3834 return -EINVAL;
3835 }
3836
3837 d->map[type_id] = new_id;
3838 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
3839 return -ENOMEM;
3840
3841 return 0;
3842}
3843
3844static int btf_dedup_prim_types(struct btf_dedup *d)
3845{
3846 int i, err;
3847
3848 for (i = 0; i < d->btf->nr_types; i++) {
3849 err = btf_dedup_prim_type(d, d->btf->start_id + i);
3850 if (err)
3851 return err;
3852 }
3853 return 0;
3854}
3855
3856
3857
3858
3859static inline bool is_type_mapped(struct btf_dedup *d, uint32_t type_id)
3860{
3861 return d->map[type_id] <= BTF_MAX_NR_TYPES;
3862}
3863
3864
3865
3866
3867
3868
3869static inline __u32 resolve_type_id(struct btf_dedup *d, __u32 type_id)
3870{
3871 while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
3872 type_id = d->map[type_id];
3873 return type_id;
3874}
3875
3876
3877
3878
3879
3880static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id)
3881{
3882 __u32 orig_type_id = type_id;
3883
3884 if (!btf_is_fwd(btf__type_by_id(d->btf, type_id)))
3885 return type_id;
3886
3887 while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
3888 type_id = d->map[type_id];
3889
3890 if (!btf_is_fwd(btf__type_by_id(d->btf, type_id)))
3891 return type_id;
3892
3893 return orig_type_id;
3894}
3895
3896
3897static inline __u16 btf_fwd_kind(struct btf_type *t)
3898{
3899 return btf_kflag(t) ? BTF_KIND_UNION : BTF_KIND_STRUCT;
3900}
3901
3902
3903static int btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
3904{
3905 struct btf_type *t1, *t2;
3906
3907 t1 = btf_type_by_id(d->btf, id1);
3908 t2 = btf_type_by_id(d->btf, id2);
3909 if (!btf_is_array(t1) || !btf_is_array(t2))
3910 return 0;
3911
3912 return btf_equal_array(t1, t2);
3913}
3914
3915
3916static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id2)
3917{
3918 const struct btf_member *m1, *m2;
3919 struct btf_type *t1, *t2;
3920 int n, i;
3921
3922 t1 = btf_type_by_id(d->btf, id1);
3923 t2 = btf_type_by_id(d->btf, id2);
3924
3925 if (!btf_is_composite(t1) || btf_kind(t1) != btf_kind(t2))
3926 return false;
3927
3928 if (!btf_shallow_equal_struct(t1, t2))
3929 return false;
3930
3931 m1 = btf_members(t1);
3932 m2 = btf_members(t2);
3933 for (i = 0, n = btf_vlen(t1); i < n; i++, m1++, m2++) {
3934 if (m1->type != m2->type)
3935 return false;
3936 }
3937 return true;
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
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
4034 __u32 canon_id)
4035{
4036 struct btf_type *cand_type;
4037 struct btf_type *canon_type;
4038 __u32 hypot_type_id;
4039 __u16 cand_kind;
4040 __u16 canon_kind;
4041 int i, eq;
4042
4043
4044 if (resolve_type_id(d, cand_id) == resolve_type_id(d, canon_id))
4045 return 1;
4046
4047 canon_id = resolve_fwd_id(d, canon_id);
4048
4049 hypot_type_id = d->hypot_map[canon_id];
4050 if (hypot_type_id <= BTF_MAX_NR_TYPES) {
4051 if (hypot_type_id == cand_id)
4052 return 1;
4053
4054
4055
4056
4057
4058
4059
4060
4061 if (btf_dedup_identical_arrays(d, hypot_type_id, cand_id))
4062 return 1;
4063
4064
4065
4066
4067
4068
4069
4070 if (btf_dedup_identical_structs(d, hypot_type_id, cand_id))
4071 return 1;
4072 return 0;
4073 }
4074
4075 if (btf_dedup_hypot_map_add(d, canon_id, cand_id))
4076 return -ENOMEM;
4077
4078 cand_type = btf_type_by_id(d->btf, cand_id);
4079 canon_type = btf_type_by_id(d->btf, canon_id);
4080 cand_kind = btf_kind(cand_type);
4081 canon_kind = btf_kind(canon_type);
4082
4083 if (cand_type->name_off != canon_type->name_off)
4084 return 0;
4085
4086
4087 if ((cand_kind == BTF_KIND_FWD || canon_kind == BTF_KIND_FWD)
4088 && cand_kind != canon_kind) {
4089 __u16 real_kind;
4090 __u16 fwd_kind;
4091
4092 if (cand_kind == BTF_KIND_FWD) {
4093 real_kind = canon_kind;
4094 fwd_kind = btf_fwd_kind(cand_type);
4095 } else {
4096 real_kind = cand_kind;
4097 fwd_kind = btf_fwd_kind(canon_type);
4098
4099 if (fwd_kind == real_kind && canon_id < d->btf->start_id)
4100 d->hypot_adjust_canon = true;
4101 }
4102 return fwd_kind == real_kind;
4103 }
4104
4105 if (cand_kind != canon_kind)
4106 return 0;
4107
4108 switch (cand_kind) {
4109 case BTF_KIND_INT:
4110 return btf_equal_int_tag(cand_type, canon_type);
4111
4112 case BTF_KIND_ENUM:
4113 return btf_compat_enum(cand_type, canon_type);
4114
4115 case BTF_KIND_FWD:
4116 case BTF_KIND_FLOAT:
4117 return btf_equal_common(cand_type, canon_type);
4118
4119 case BTF_KIND_CONST:
4120 case BTF_KIND_VOLATILE:
4121 case BTF_KIND_RESTRICT:
4122 case BTF_KIND_PTR:
4123 case BTF_KIND_TYPEDEF:
4124 case BTF_KIND_FUNC:
4125 case BTF_KIND_TYPE_TAG:
4126 if (cand_type->info != canon_type->info)
4127 return 0;
4128 return btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
4129
4130 case BTF_KIND_ARRAY: {
4131 const struct btf_array *cand_arr, *canon_arr;
4132
4133 if (!btf_compat_array(cand_type, canon_type))
4134 return 0;
4135 cand_arr = btf_array(cand_type);
4136 canon_arr = btf_array(canon_type);
4137 eq = btf_dedup_is_equiv(d, cand_arr->index_type, canon_arr->index_type);
4138 if (eq <= 0)
4139 return eq;
4140 return btf_dedup_is_equiv(d, cand_arr->type, canon_arr->type);
4141 }
4142
4143 case BTF_KIND_STRUCT:
4144 case BTF_KIND_UNION: {
4145 const struct btf_member *cand_m, *canon_m;
4146 __u16 vlen;
4147
4148 if (!btf_shallow_equal_struct(cand_type, canon_type))
4149 return 0;
4150 vlen = btf_vlen(cand_type);
4151 cand_m = btf_members(cand_type);
4152 canon_m = btf_members(canon_type);
4153 for (i = 0; i < vlen; i++) {
4154 eq = btf_dedup_is_equiv(d, cand_m->type, canon_m->type);
4155 if (eq <= 0)
4156 return eq;
4157 cand_m++;
4158 canon_m++;
4159 }
4160
4161 return 1;
4162 }
4163
4164 case BTF_KIND_FUNC_PROTO: {
4165 const struct btf_param *cand_p, *canon_p;
4166 __u16 vlen;
4167
4168 if (!btf_compat_fnproto(cand_type, canon_type))
4169 return 0;
4170 eq = btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
4171 if (eq <= 0)
4172 return eq;
4173 vlen = btf_vlen(cand_type);
4174 cand_p = btf_params(cand_type);
4175 canon_p = btf_params(canon_type);
4176 for (i = 0; i < vlen; i++) {
4177 eq = btf_dedup_is_equiv(d, cand_p->type, canon_p->type);
4178 if (eq <= 0)
4179 return eq;
4180 cand_p++;
4181 canon_p++;
4182 }
4183 return 1;
4184 }
4185
4186 default:
4187 return -EINVAL;
4188 }
4189 return 0;
4190}
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218static void btf_dedup_merge_hypot_map(struct btf_dedup *d)
4219{
4220 __u32 canon_type_id, targ_type_id;
4221 __u16 t_kind, c_kind;
4222 __u32 t_id, c_id;
4223 int i;
4224
4225 for (i = 0; i < d->hypot_cnt; i++) {
4226 canon_type_id = d->hypot_list[i];
4227 targ_type_id = d->hypot_map[canon_type_id];
4228 t_id = resolve_type_id(d, targ_type_id);
4229 c_id = resolve_type_id(d, canon_type_id);
4230 t_kind = btf_kind(btf__type_by_id(d->btf, t_id));
4231 c_kind = btf_kind(btf__type_by_id(d->btf, c_id));
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252 if (t_kind != BTF_KIND_FWD && c_kind == BTF_KIND_FWD)
4253 d->map[c_id] = t_id;
4254
4255
4256
4257
4258
4259
4260 if (d->hypot_adjust_canon)
4261 continue;
4262
4263 if (t_kind == BTF_KIND_FWD && c_kind != BTF_KIND_FWD)
4264 d->map[t_id] = c_id;
4265
4266 if ((t_kind == BTF_KIND_STRUCT || t_kind == BTF_KIND_UNION) &&
4267 c_kind != BTF_KIND_FWD &&
4268 is_type_mapped(d, c_id) &&
4269 !is_type_mapped(d, t_id)) {
4270
4271
4272
4273
4274
4275
4276 d->map[t_id] = c_id;
4277 }
4278 }
4279}
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id)
4304{
4305 struct btf_type *cand_type, *t;
4306 struct hashmap_entry *hash_entry;
4307
4308 __u32 new_id = type_id;
4309 __u16 kind;
4310 long h;
4311
4312
4313 if (d->map[type_id] <= BTF_MAX_NR_TYPES)
4314 return 0;
4315
4316 t = btf_type_by_id(d->btf, type_id);
4317 kind = btf_kind(t);
4318
4319 if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION)
4320 return 0;
4321
4322 h = btf_hash_struct(t);
4323 for_each_dedup_cand(d, hash_entry, h) {
4324 __u32 cand_id = (__u32)(long)hash_entry->value;
4325 int eq;
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337 cand_type = btf_type_by_id(d->btf, cand_id);
4338 if (!btf_shallow_equal_struct(t, cand_type))
4339 continue;
4340
4341 btf_dedup_clear_hypot_map(d);
4342 eq = btf_dedup_is_equiv(d, type_id, cand_id);
4343 if (eq < 0)
4344 return eq;
4345 if (!eq)
4346 continue;
4347 btf_dedup_merge_hypot_map(d);
4348 if (d->hypot_adjust_canon)
4349 continue;
4350 new_id = cand_id;
4351 break;
4352 }
4353
4354 d->map[type_id] = new_id;
4355 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
4356 return -ENOMEM;
4357
4358 return 0;
4359}
4360
4361static int btf_dedup_struct_types(struct btf_dedup *d)
4362{
4363 int i, err;
4364
4365 for (i = 0; i < d->btf->nr_types; i++) {
4366 err = btf_dedup_struct_type(d, d->btf->start_id + i);
4367 if (err)
4368 return err;
4369 }
4370 return 0;
4371}
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
4398{
4399 struct hashmap_entry *hash_entry;
4400 __u32 new_id = type_id, cand_id;
4401 struct btf_type *t, *cand;
4402
4403 int ref_type_id;
4404 long h;
4405
4406 if (d->map[type_id] == BTF_IN_PROGRESS_ID)
4407 return -ELOOP;
4408 if (d->map[type_id] <= BTF_MAX_NR_TYPES)
4409 return resolve_type_id(d, type_id);
4410
4411 t = btf_type_by_id(d->btf, type_id);
4412 d->map[type_id] = BTF_IN_PROGRESS_ID;
4413
4414 switch (btf_kind(t)) {
4415 case BTF_KIND_CONST:
4416 case BTF_KIND_VOLATILE:
4417 case BTF_KIND_RESTRICT:
4418 case BTF_KIND_PTR:
4419 case BTF_KIND_TYPEDEF:
4420 case BTF_KIND_FUNC:
4421 case BTF_KIND_TYPE_TAG:
4422 ref_type_id = btf_dedup_ref_type(d, t->type);
4423 if (ref_type_id < 0)
4424 return ref_type_id;
4425 t->type = ref_type_id;
4426
4427 h = btf_hash_common(t);
4428 for_each_dedup_cand(d, hash_entry, h) {
4429 cand_id = (__u32)(long)hash_entry->value;
4430 cand = btf_type_by_id(d->btf, cand_id);
4431 if (btf_equal_common(t, cand)) {
4432 new_id = cand_id;
4433 break;
4434 }
4435 }
4436 break;
4437
4438 case BTF_KIND_DECL_TAG:
4439 ref_type_id = btf_dedup_ref_type(d, t->type);
4440 if (ref_type_id < 0)
4441 return ref_type_id;
4442 t->type = ref_type_id;
4443
4444 h = btf_hash_int_decl_tag(t);
4445 for_each_dedup_cand(d, hash_entry, h) {
4446 cand_id = (__u32)(long)hash_entry->value;
4447 cand = btf_type_by_id(d->btf, cand_id);
4448 if (btf_equal_int_tag(t, cand)) {
4449 new_id = cand_id;
4450 break;
4451 }
4452 }
4453 break;
4454
4455 case BTF_KIND_ARRAY: {
4456 struct btf_array *info = btf_array(t);
4457
4458 ref_type_id = btf_dedup_ref_type(d, info->type);
4459 if (ref_type_id < 0)
4460 return ref_type_id;
4461 info->type = ref_type_id;
4462
4463 ref_type_id = btf_dedup_ref_type(d, info->index_type);
4464 if (ref_type_id < 0)
4465 return ref_type_id;
4466 info->index_type = ref_type_id;
4467
4468 h = btf_hash_array(t);
4469 for_each_dedup_cand(d, hash_entry, h) {
4470 cand_id = (__u32)(long)hash_entry->value;
4471 cand = btf_type_by_id(d->btf, cand_id);
4472 if (btf_equal_array(t, cand)) {
4473 new_id = cand_id;
4474 break;
4475 }
4476 }
4477 break;
4478 }
4479
4480 case BTF_KIND_FUNC_PROTO: {
4481 struct btf_param *param;
4482 __u16 vlen;
4483 int i;
4484
4485 ref_type_id = btf_dedup_ref_type(d, t->type);
4486 if (ref_type_id < 0)
4487 return ref_type_id;
4488 t->type = ref_type_id;
4489
4490 vlen = btf_vlen(t);
4491 param = btf_params(t);
4492 for (i = 0; i < vlen; i++) {
4493 ref_type_id = btf_dedup_ref_type(d, param->type);
4494 if (ref_type_id < 0)
4495 return ref_type_id;
4496 param->type = ref_type_id;
4497 param++;
4498 }
4499
4500 h = btf_hash_fnproto(t);
4501 for_each_dedup_cand(d, hash_entry, h) {
4502 cand_id = (__u32)(long)hash_entry->value;
4503 cand = btf_type_by_id(d->btf, cand_id);
4504 if (btf_equal_fnproto(t, cand)) {
4505 new_id = cand_id;
4506 break;
4507 }
4508 }
4509 break;
4510 }
4511
4512 default:
4513 return -EINVAL;
4514 }
4515
4516 d->map[type_id] = new_id;
4517 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
4518 return -ENOMEM;
4519
4520 return new_id;
4521}
4522
4523static int btf_dedup_ref_types(struct btf_dedup *d)
4524{
4525 int i, err;
4526
4527 for (i = 0; i < d->btf->nr_types; i++) {
4528 err = btf_dedup_ref_type(d, d->btf->start_id + i);
4529 if (err < 0)
4530 return err;
4531 }
4532
4533 hashmap__free(d->dedup_table);
4534 d->dedup_table = NULL;
4535 return 0;
4536}
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549static int btf_dedup_compact_types(struct btf_dedup *d)
4550{
4551 __u32 *new_offs;
4552 __u32 next_type_id = d->btf->start_id;
4553 const struct btf_type *t;
4554 void *p;
4555 int i, id, len;
4556
4557
4558 d->hypot_map[0] = 0;
4559
4560 for (id = 1; id < d->btf->start_id; id++)
4561 d->hypot_map[id] = id;
4562 for (i = 0, id = d->btf->start_id; i < d->btf->nr_types; i++, id++)
4563 d->hypot_map[id] = BTF_UNPROCESSED_ID;
4564
4565 p = d->btf->types_data;
4566
4567 for (i = 0, id = d->btf->start_id; i < d->btf->nr_types; i++, id++) {
4568 if (d->map[id] != id)
4569 continue;
4570
4571 t = btf__type_by_id(d->btf, id);
4572 len = btf_type_size(t);
4573 if (len < 0)
4574 return len;
4575
4576 memmove(p, t, len);
4577 d->hypot_map[id] = next_type_id;
4578 d->btf->type_offs[next_type_id - d->btf->start_id] = p - d->btf->types_data;
4579 p += len;
4580 next_type_id++;
4581 }
4582
4583
4584 d->btf->nr_types = next_type_id - d->btf->start_id;
4585 d->btf->type_offs_cap = d->btf->nr_types;
4586 d->btf->hdr->type_len = p - d->btf->types_data;
4587 new_offs = libbpf_reallocarray(d->btf->type_offs, d->btf->type_offs_cap,
4588 sizeof(*new_offs));
4589 if (d->btf->type_offs_cap && !new_offs)
4590 return -ENOMEM;
4591 d->btf->type_offs = new_offs;
4592 d->btf->hdr->str_off = d->btf->hdr->type_len;
4593 d->btf->raw_size = d->btf->hdr->hdr_len + d->btf->hdr->type_len + d->btf->hdr->str_len;
4594 return 0;
4595}
4596
4597
4598
4599
4600
4601
4602
4603static int btf_dedup_remap_type_id(__u32 *type_id, void *ctx)
4604{
4605 struct btf_dedup *d = ctx;
4606 __u32 resolved_type_id, new_type_id;
4607
4608 resolved_type_id = resolve_type_id(d, *type_id);
4609 new_type_id = d->hypot_map[resolved_type_id];
4610 if (new_type_id > BTF_MAX_NR_TYPES)
4611 return -EINVAL;
4612
4613 *type_id = new_type_id;
4614 return 0;
4615}
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627static int btf_dedup_remap_types(struct btf_dedup *d)
4628{
4629 int i, r;
4630
4631 for (i = 0; i < d->btf->nr_types; i++) {
4632 struct btf_type *t = btf_type_by_id(d->btf, d->btf->start_id + i);
4633
4634 r = btf_type_visit_type_ids(t, btf_dedup_remap_type_id, d);
4635 if (r)
4636 return r;
4637 }
4638
4639 if (!d->btf_ext)
4640 return 0;
4641
4642 r = btf_ext_visit_type_ids(d->btf_ext, btf_dedup_remap_type_id, d);
4643 if (r)
4644 return r;
4645
4646 return 0;
4647}
4648
4649
4650
4651
4652
4653struct btf *btf__load_vmlinux_btf(void)
4654{
4655 struct {
4656 const char *path_fmt;
4657 bool raw_btf;
4658 } locations[] = {
4659
4660 { "/sys/kernel/btf/vmlinux", true },
4661
4662 { "/boot/vmlinux-%1$s" },
4663 { "/lib/modules/%1$s/vmlinux-%1$s" },
4664 { "/lib/modules/%1$s/build/vmlinux" },
4665 { "/usr/lib/modules/%1$s/kernel/vmlinux" },
4666 { "/usr/lib/debug/boot/vmlinux-%1$s" },
4667 { "/usr/lib/debug/boot/vmlinux-%1$s.debug" },
4668 { "/usr/lib/debug/lib/modules/%1$s/vmlinux" },
4669 };
4670 char path[PATH_MAX + 1];
4671 struct utsname buf;
4672 struct btf *btf;
4673 int i, err;
4674
4675 uname(&buf);
4676
4677 for (i = 0; i < ARRAY_SIZE(locations); i++) {
4678 snprintf(path, PATH_MAX, locations[i].path_fmt, buf.release);
4679
4680 if (access(path, R_OK))
4681 continue;
4682
4683 if (locations[i].raw_btf)
4684 btf = btf__parse_raw(path);
4685 else
4686 btf = btf__parse_elf(path, NULL);
4687 err = libbpf_get_error(btf);
4688 pr_debug("loading kernel BTF '%s': %d\n", path, err);
4689 if (err)
4690 continue;
4691
4692 return btf;
4693 }
4694
4695 pr_warn("failed to find valid kernel BTF\n");
4696 return libbpf_err_ptr(-ESRCH);
4697}
4698
4699struct btf *libbpf_find_kernel_btf(void) __attribute__((alias("btf__load_vmlinux_btf")));
4700
4701struct btf *btf__load_module_btf(const char *module_name, struct btf *vmlinux_btf)
4702{
4703 char path[80];
4704
4705 snprintf(path, sizeof(path), "/sys/kernel/btf/%s", module_name);
4706 return btf__parse_split(path, vmlinux_btf);
4707}
4708
4709int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx)
4710{
4711 int i, n, err;
4712
4713 switch (btf_kind(t)) {
4714 case BTF_KIND_INT:
4715 case BTF_KIND_FLOAT:
4716 case BTF_KIND_ENUM:
4717 return 0;
4718
4719 case BTF_KIND_FWD:
4720 case BTF_KIND_CONST:
4721 case BTF_KIND_VOLATILE:
4722 case BTF_KIND_RESTRICT:
4723 case BTF_KIND_PTR:
4724 case BTF_KIND_TYPEDEF:
4725 case BTF_KIND_FUNC:
4726 case BTF_KIND_VAR:
4727 case BTF_KIND_DECL_TAG:
4728 case BTF_KIND_TYPE_TAG:
4729 return visit(&t->type, ctx);
4730
4731 case BTF_KIND_ARRAY: {
4732 struct btf_array *a = btf_array(t);
4733
4734 err = visit(&a->type, ctx);
4735 err = err ?: visit(&a->index_type, ctx);
4736 return err;
4737 }
4738
4739 case BTF_KIND_STRUCT:
4740 case BTF_KIND_UNION: {
4741 struct btf_member *m = btf_members(t);
4742
4743 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4744 err = visit(&m->type, ctx);
4745 if (err)
4746 return err;
4747 }
4748 return 0;
4749 }
4750
4751 case BTF_KIND_FUNC_PROTO: {
4752 struct btf_param *m = btf_params(t);
4753
4754 err = visit(&t->type, ctx);
4755 if (err)
4756 return err;
4757 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4758 err = visit(&m->type, ctx);
4759 if (err)
4760 return err;
4761 }
4762 return 0;
4763 }
4764
4765 case BTF_KIND_DATASEC: {
4766 struct btf_var_secinfo *m = btf_var_secinfos(t);
4767
4768 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4769 err = visit(&m->type, ctx);
4770 if (err)
4771 return err;
4772 }
4773 return 0;
4774 }
4775
4776 default:
4777 return -EINVAL;
4778 }
4779}
4780
4781int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx)
4782{
4783 int i, n, err;
4784
4785 err = visit(&t->name_off, ctx);
4786 if (err)
4787 return err;
4788
4789 switch (btf_kind(t)) {
4790 case BTF_KIND_STRUCT:
4791 case BTF_KIND_UNION: {
4792 struct btf_member *m = btf_members(t);
4793
4794 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4795 err = visit(&m->name_off, ctx);
4796 if (err)
4797 return err;
4798 }
4799 break;
4800 }
4801 case BTF_KIND_ENUM: {
4802 struct btf_enum *m = btf_enum(t);
4803
4804 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4805 err = visit(&m->name_off, ctx);
4806 if (err)
4807 return err;
4808 }
4809 break;
4810 }
4811 case BTF_KIND_FUNC_PROTO: {
4812 struct btf_param *m = btf_params(t);
4813
4814 for (i = 0, n = btf_vlen(t); i < n; i++, m++) {
4815 err = visit(&m->name_off, ctx);
4816 if (err)
4817 return err;
4818 }
4819 break;
4820 }
4821 default:
4822 break;
4823 }
4824
4825 return 0;
4826}
4827
4828int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx)
4829{
4830 const struct btf_ext_info *seg;
4831 struct btf_ext_info_sec *sec;
4832 int i, err;
4833
4834 seg = &btf_ext->func_info;
4835 for_each_btf_ext_sec(seg, sec) {
4836 struct bpf_func_info_min *rec;
4837
4838 for_each_btf_ext_rec(seg, sec, i, rec) {
4839 err = visit(&rec->type_id, ctx);
4840 if (err < 0)
4841 return err;
4842 }
4843 }
4844
4845 seg = &btf_ext->core_relo_info;
4846 for_each_btf_ext_sec(seg, sec) {
4847 struct bpf_core_relo *rec;
4848
4849 for_each_btf_ext_rec(seg, sec, i, rec) {
4850 err = visit(&rec->type_id, ctx);
4851 if (err < 0)
4852 return err;
4853 }
4854 }
4855
4856 return 0;
4857}
4858
4859int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx)
4860{
4861 const struct btf_ext_info *seg;
4862 struct btf_ext_info_sec *sec;
4863 int i, err;
4864
4865 seg = &btf_ext->func_info;
4866 for_each_btf_ext_sec(seg, sec) {
4867 err = visit(&sec->sec_name_off, ctx);
4868 if (err)
4869 return err;
4870 }
4871
4872 seg = &btf_ext->line_info;
4873 for_each_btf_ext_sec(seg, sec) {
4874 struct bpf_line_info_min *rec;
4875
4876 err = visit(&sec->sec_name_off, ctx);
4877 if (err)
4878 return err;
4879
4880 for_each_btf_ext_rec(seg, sec, i, rec) {
4881 err = visit(&rec->file_name_off, ctx);
4882 if (err)
4883 return err;
4884 err = visit(&rec->line_off, ctx);
4885 if (err)
4886 return err;
4887 }
4888 }
4889
4890 seg = &btf_ext->core_relo_info;
4891 for_each_btf_ext_sec(seg, sec) {
4892 struct bpf_core_relo *rec;
4893
4894 err = visit(&sec->sec_name_off, ctx);
4895 if (err)
4896 return err;
4897
4898 for_each_btf_ext_rec(seg, sec, i, rec) {
4899 err = visit(&rec->access_str_off, ctx);
4900 if (err)
4901 return err;
4902 }
4903 }
4904
4905 return 0;
4906}
4907