1
2
3
4
5
6
7
8
9#include <stdbool.h>
10#include <stddef.h>
11#include <stdlib.h>
12#include <string.h>
13#include <ctype.h>
14#include <endian.h>
15#include <errno.h>
16#include <linux/err.h>
17#include <linux/btf.h>
18#include <linux/kernel.h>
19#include "btf.h"
20#include "hashmap.h"
21#include "libbpf.h"
22#include "libbpf_internal.h"
23
24static const char PREFIXES[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
25static const size_t PREFIX_CNT = sizeof(PREFIXES) - 1;
26
27static const char *pfx(int lvl)
28{
29 return lvl >= PREFIX_CNT ? PREFIXES : &PREFIXES[PREFIX_CNT - lvl];
30}
31
32enum btf_dump_type_order_state {
33 NOT_ORDERED,
34 ORDERING,
35 ORDERED,
36};
37
38enum btf_dump_type_emit_state {
39 NOT_EMITTED,
40 EMITTING,
41 EMITTED,
42};
43
44
45struct btf_dump_type_aux_state {
46
47 enum btf_dump_type_order_state order_state: 2;
48
49 enum btf_dump_type_emit_state emit_state: 2;
50
51 __u8 fwd_emitted: 1;
52
53 __u8 name_resolved: 1;
54
55 __u8 referenced: 1;
56};
57
58
59#define BTF_DATA_INDENT_STR_LEN 32
60
61
62
63
64struct btf_dump_data {
65 const void *data_end;
66 bool compact;
67 bool skip_names;
68 bool emit_zeroes;
69 __u8 indent_lvl;
70 char indent_str[BTF_DATA_INDENT_STR_LEN];
71
72 int depth;
73 bool is_array_member;
74 bool is_array_terminated;
75 bool is_array_char;
76};
77
78struct btf_dump {
79 const struct btf *btf;
80 const struct btf_ext *btf_ext;
81 btf_dump_printf_fn_t printf_fn;
82 struct btf_dump_opts opts;
83 int ptr_sz;
84 bool strip_mods;
85 bool skip_anon_defs;
86 int last_id;
87
88
89 struct btf_dump_type_aux_state *type_states;
90 size_t type_states_cap;
91
92 const char **cached_names;
93 size_t cached_names_cap;
94
95
96 __u32 *emit_queue;
97 int emit_queue_cap;
98 int emit_queue_cnt;
99
100
101
102
103
104 __u32 *decl_stack;
105 int decl_stack_cap;
106 int decl_stack_cnt;
107
108
109 struct hashmap *type_names;
110
111
112
113
114 struct hashmap *ident_names;
115
116
117
118 struct btf_dump_data *typed_dump;
119};
120
121static size_t str_hash_fn(const void *key, void *ctx)
122{
123 return str_hash(key);
124}
125
126static bool str_equal_fn(const void *a, const void *b, void *ctx)
127{
128 return strcmp(a, b) == 0;
129}
130
131static const char *btf_name_of(const struct btf_dump *d, __u32 name_off)
132{
133 return btf__name_by_offset(d->btf, name_off);
134}
135
136static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
137{
138 va_list args;
139
140 va_start(args, fmt);
141 d->printf_fn(d->opts.ctx, fmt, args);
142 va_end(args);
143}
144
145static int btf_dump_mark_referenced(struct btf_dump *d);
146static int btf_dump_resize(struct btf_dump *d);
147
148struct btf_dump *btf_dump__new(const struct btf *btf,
149 const struct btf_ext *btf_ext,
150 const struct btf_dump_opts *opts,
151 btf_dump_printf_fn_t printf_fn)
152{
153 struct btf_dump *d;
154 int err;
155
156 d = calloc(1, sizeof(struct btf_dump));
157 if (!d)
158 return libbpf_err_ptr(-ENOMEM);
159
160 d->btf = btf;
161 d->btf_ext = btf_ext;
162 d->printf_fn = printf_fn;
163 d->opts.ctx = opts ? opts->ctx : NULL;
164 d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *);
165
166 d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
167 if (IS_ERR(d->type_names)) {
168 err = PTR_ERR(d->type_names);
169 d->type_names = NULL;
170 goto err;
171 }
172 d->ident_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
173 if (IS_ERR(d->ident_names)) {
174 err = PTR_ERR(d->ident_names);
175 d->ident_names = NULL;
176 goto err;
177 }
178
179 err = btf_dump_resize(d);
180 if (err)
181 goto err;
182
183 return d;
184err:
185 btf_dump__free(d);
186 return libbpf_err_ptr(err);
187}
188
189static int btf_dump_resize(struct btf_dump *d)
190{
191 int err, last_id = btf__get_nr_types(d->btf);
192
193 if (last_id <= d->last_id)
194 return 0;
195
196 if (libbpf_ensure_mem((void **)&d->type_states, &d->type_states_cap,
197 sizeof(*d->type_states), last_id + 1))
198 return -ENOMEM;
199 if (libbpf_ensure_mem((void **)&d->cached_names, &d->cached_names_cap,
200 sizeof(*d->cached_names), last_id + 1))
201 return -ENOMEM;
202
203 if (d->last_id == 0) {
204
205 d->type_states[0].order_state = ORDERED;
206 d->type_states[0].emit_state = EMITTED;
207 }
208
209
210 err = btf_dump_mark_referenced(d);
211 if (err)
212 return err;
213
214 d->last_id = last_id;
215 return 0;
216}
217
218void btf_dump__free(struct btf_dump *d)
219{
220 int i;
221
222 if (IS_ERR_OR_NULL(d))
223 return;
224
225 free(d->type_states);
226 if (d->cached_names) {
227
228 for (i = 0; i <= d->last_id; i++) {
229 if (d->cached_names[i])
230 free((void *)d->cached_names[i]);
231 }
232 }
233 free(d->cached_names);
234 free(d->emit_queue);
235 free(d->decl_stack);
236 hashmap__free(d->type_names);
237 hashmap__free(d->ident_names);
238
239 free(d);
240}
241
242static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr);
243static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id);
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261int btf_dump__dump_type(struct btf_dump *d, __u32 id)
262{
263 int err, i;
264
265 if (id > btf__get_nr_types(d->btf))
266 return libbpf_err(-EINVAL);
267
268 err = btf_dump_resize(d);
269 if (err)
270 return libbpf_err(err);
271
272 d->emit_queue_cnt = 0;
273 err = btf_dump_order_type(d, id, false);
274 if (err < 0)
275 return libbpf_err(err);
276
277 for (i = 0; i < d->emit_queue_cnt; i++)
278 btf_dump_emit_type(d, d->emit_queue[i], 0 );
279
280 return 0;
281}
282
283
284
285
286
287
288
289
290
291
292
293
294
295static int btf_dump_mark_referenced(struct btf_dump *d)
296{
297 int i, j, n = btf__get_nr_types(d->btf);
298 const struct btf_type *t;
299 __u16 vlen;
300
301 for (i = d->last_id + 1; i <= n; i++) {
302 t = btf__type_by_id(d->btf, i);
303 vlen = btf_vlen(t);
304
305 switch (btf_kind(t)) {
306 case BTF_KIND_INT:
307 case BTF_KIND_ENUM:
308 case BTF_KIND_FWD:
309 case BTF_KIND_FLOAT:
310 break;
311
312 case BTF_KIND_VOLATILE:
313 case BTF_KIND_CONST:
314 case BTF_KIND_RESTRICT:
315 case BTF_KIND_PTR:
316 case BTF_KIND_TYPEDEF:
317 case BTF_KIND_FUNC:
318 case BTF_KIND_VAR:
319 d->type_states[t->type].referenced = 1;
320 break;
321
322 case BTF_KIND_ARRAY: {
323 const struct btf_array *a = btf_array(t);
324
325 d->type_states[a->index_type].referenced = 1;
326 d->type_states[a->type].referenced = 1;
327 break;
328 }
329 case BTF_KIND_STRUCT:
330 case BTF_KIND_UNION: {
331 const struct btf_member *m = btf_members(t);
332
333 for (j = 0; j < vlen; j++, m++)
334 d->type_states[m->type].referenced = 1;
335 break;
336 }
337 case BTF_KIND_FUNC_PROTO: {
338 const struct btf_param *p = btf_params(t);
339
340 for (j = 0; j < vlen; j++, p++)
341 d->type_states[p->type].referenced = 1;
342 break;
343 }
344 case BTF_KIND_DATASEC: {
345 const struct btf_var_secinfo *v = btf_var_secinfos(t);
346
347 for (j = 0; j < vlen; j++, v++)
348 d->type_states[v->type].referenced = 1;
349 break;
350 }
351 default:
352 return -EINVAL;
353 }
354 }
355 return 0;
356}
357
358static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
359{
360 __u32 *new_queue;
361 size_t new_cap;
362
363 if (d->emit_queue_cnt >= d->emit_queue_cap) {
364 new_cap = max(16, d->emit_queue_cap * 3 / 2);
365 new_queue = libbpf_reallocarray(d->emit_queue, new_cap, sizeof(new_queue[0]));
366 if (!new_queue)
367 return -ENOMEM;
368 d->emit_queue = new_queue;
369 d->emit_queue_cap = new_cap;
370 }
371
372 d->emit_queue[d->emit_queue_cnt++] = id;
373 return 0;
374}
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
451{
452
453
454
455
456
457
458
459
460
461
462
463 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
464 const struct btf_type *t;
465 __u16 vlen;
466 int err, i;
467
468
469 if (tstate->order_state == ORDERED)
470 return 1;
471
472 t = btf__type_by_id(d->btf, id);
473
474 if (tstate->order_state == ORDERING) {
475
476 if (btf_is_composite(t) && through_ptr && t->name_off != 0)
477 return 0;
478 pr_warn("unsatisfiable type cycle, id:[%u]\n", id);
479 return -ELOOP;
480 }
481
482 switch (btf_kind(t)) {
483 case BTF_KIND_INT:
484 case BTF_KIND_FLOAT:
485 tstate->order_state = ORDERED;
486 return 0;
487
488 case BTF_KIND_PTR:
489 err = btf_dump_order_type(d, t->type, true);
490 tstate->order_state = ORDERED;
491 return err;
492
493 case BTF_KIND_ARRAY:
494 return btf_dump_order_type(d, btf_array(t)->type, false);
495
496 case BTF_KIND_STRUCT:
497 case BTF_KIND_UNION: {
498 const struct btf_member *m = btf_members(t);
499
500
501
502
503
504 if (through_ptr && t->name_off != 0)
505 return 0;
506
507 tstate->order_state = ORDERING;
508
509 vlen = btf_vlen(t);
510 for (i = 0; i < vlen; i++, m++) {
511 err = btf_dump_order_type(d, m->type, false);
512 if (err < 0)
513 return err;
514 }
515
516 if (t->name_off != 0) {
517 err = btf_dump_add_emit_queue_id(d, id);
518 if (err < 0)
519 return err;
520 }
521
522 tstate->order_state = ORDERED;
523 return 1;
524 }
525 case BTF_KIND_ENUM:
526 case BTF_KIND_FWD:
527
528
529
530
531
532 if (t->name_off != 0 || !tstate->referenced) {
533 err = btf_dump_add_emit_queue_id(d, id);
534 if (err)
535 return err;
536 }
537 tstate->order_state = ORDERED;
538 return 1;
539
540 case BTF_KIND_TYPEDEF: {
541 int is_strong;
542
543 is_strong = btf_dump_order_type(d, t->type, through_ptr);
544 if (is_strong < 0)
545 return is_strong;
546
547
548 if (through_ptr && !is_strong)
549 return 0;
550
551
552 err = btf_dump_add_emit_queue_id(d, id);
553 if (err)
554 return err;
555
556 d->type_states[id].order_state = ORDERED;
557 return 1;
558 }
559 case BTF_KIND_VOLATILE:
560 case BTF_KIND_CONST:
561 case BTF_KIND_RESTRICT:
562 return btf_dump_order_type(d, t->type, through_ptr);
563
564 case BTF_KIND_FUNC_PROTO: {
565 const struct btf_param *p = btf_params(t);
566 bool is_strong;
567
568 err = btf_dump_order_type(d, t->type, through_ptr);
569 if (err < 0)
570 return err;
571 is_strong = err > 0;
572
573 vlen = btf_vlen(t);
574 for (i = 0; i < vlen; i++, p++) {
575 err = btf_dump_order_type(d, p->type, through_ptr);
576 if (err < 0)
577 return err;
578 if (err > 0)
579 is_strong = true;
580 }
581 return is_strong;
582 }
583 case BTF_KIND_FUNC:
584 case BTF_KIND_VAR:
585 case BTF_KIND_DATASEC:
586 d->type_states[id].order_state = ORDERED;
587 return 0;
588
589 default:
590 return -EINVAL;
591 }
592}
593
594static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
595 const struct btf_type *t);
596
597static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
598 const struct btf_type *t);
599static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
600 const struct btf_type *t, int lvl);
601
602static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
603 const struct btf_type *t);
604static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
605 const struct btf_type *t, int lvl);
606
607static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
608 const struct btf_type *t);
609
610static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
611 const struct btf_type *t, int lvl);
612
613
614struct id_stack {
615 const __u32 *ids;
616 int cnt;
617};
618
619static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
620 const char *fname, int lvl);
621static void btf_dump_emit_type_chain(struct btf_dump *d,
622 struct id_stack *decl_stack,
623 const char *fname, int lvl);
624
625static const char *btf_dump_type_name(struct btf_dump *d, __u32 id);
626static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id);
627static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
628 const char *orig_name);
629
630static bool btf_dump_is_blacklisted(struct btf_dump *d, __u32 id)
631{
632 const struct btf_type *t = btf__type_by_id(d->btf, id);
633
634
635
636
637
638
639
640 if (t->name_off == 0)
641 return false;
642 return strcmp(btf_name_of(d, t->name_off), "__builtin_va_list") == 0;
643}
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
664{
665 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
666 bool top_level_def = cont_id == 0;
667 const struct btf_type *t;
668 __u16 kind;
669
670 if (tstate->emit_state == EMITTED)
671 return;
672
673 t = btf__type_by_id(d->btf, id);
674 kind = btf_kind(t);
675
676 if (tstate->emit_state == EMITTING) {
677 if (tstate->fwd_emitted)
678 return;
679
680 switch (kind) {
681 case BTF_KIND_STRUCT:
682 case BTF_KIND_UNION:
683
684
685
686
687 if (id == cont_id)
688 return;
689 if (t->name_off == 0) {
690 pr_warn("anonymous struct/union loop, id:[%u]\n",
691 id);
692 return;
693 }
694 btf_dump_emit_struct_fwd(d, id, t);
695 btf_dump_printf(d, ";\n\n");
696 tstate->fwd_emitted = 1;
697 break;
698 case BTF_KIND_TYPEDEF:
699
700
701
702
703
704 if (!btf_dump_is_blacklisted(d, id)) {
705 btf_dump_emit_typedef_def(d, id, t, 0);
706 btf_dump_printf(d, ";\n\n");
707 }
708 tstate->fwd_emitted = 1;
709 break;
710 default:
711 break;
712 }
713
714 return;
715 }
716
717 switch (kind) {
718 case BTF_KIND_INT:
719
720 btf_dump_emit_missing_aliases(d, id, t);
721
722 tstate->emit_state = EMITTED;
723 break;
724 case BTF_KIND_ENUM:
725 if (top_level_def) {
726 btf_dump_emit_enum_def(d, id, t, 0);
727 btf_dump_printf(d, ";\n\n");
728 }
729 tstate->emit_state = EMITTED;
730 break;
731 case BTF_KIND_PTR:
732 case BTF_KIND_VOLATILE:
733 case BTF_KIND_CONST:
734 case BTF_KIND_RESTRICT:
735 btf_dump_emit_type(d, t->type, cont_id);
736 break;
737 case BTF_KIND_ARRAY:
738 btf_dump_emit_type(d, btf_array(t)->type, cont_id);
739 break;
740 case BTF_KIND_FWD:
741 btf_dump_emit_fwd_def(d, id, t);
742 btf_dump_printf(d, ";\n\n");
743 tstate->emit_state = EMITTED;
744 break;
745 case BTF_KIND_TYPEDEF:
746 tstate->emit_state = EMITTING;
747 btf_dump_emit_type(d, t->type, id);
748
749
750
751
752
753
754
755 if (!tstate->fwd_emitted && !btf_dump_is_blacklisted(d, id)) {
756 btf_dump_emit_typedef_def(d, id, t, 0);
757 btf_dump_printf(d, ";\n\n");
758 }
759 tstate->emit_state = EMITTED;
760 break;
761 case BTF_KIND_STRUCT:
762 case BTF_KIND_UNION:
763 tstate->emit_state = EMITTING;
764
765
766
767
768
769
770
771 if (top_level_def || t->name_off == 0) {
772 const struct btf_member *m = btf_members(t);
773 __u16 vlen = btf_vlen(t);
774 int i, new_cont_id;
775
776 new_cont_id = t->name_off == 0 ? cont_id : id;
777 for (i = 0; i < vlen; i++, m++)
778 btf_dump_emit_type(d, m->type, new_cont_id);
779 } else if (!tstate->fwd_emitted && id != cont_id) {
780 btf_dump_emit_struct_fwd(d, id, t);
781 btf_dump_printf(d, ";\n\n");
782 tstate->fwd_emitted = 1;
783 }
784
785 if (top_level_def) {
786 btf_dump_emit_struct_def(d, id, t, 0);
787 btf_dump_printf(d, ";\n\n");
788 tstate->emit_state = EMITTED;
789 } else {
790 tstate->emit_state = NOT_EMITTED;
791 }
792 break;
793 case BTF_KIND_FUNC_PROTO: {
794 const struct btf_param *p = btf_params(t);
795 __u16 n = btf_vlen(t);
796 int i;
797
798 btf_dump_emit_type(d, t->type, cont_id);
799 for (i = 0; i < n; i++, p++)
800 btf_dump_emit_type(d, p->type, cont_id);
801
802 break;
803 }
804 default:
805 break;
806 }
807}
808
809static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
810 const struct btf_type *t)
811{
812 const struct btf_member *m;
813 int align, i, bit_sz;
814 __u16 vlen;
815
816 align = btf__align_of(btf, id);
817
818 if (align && t->size % align)
819 return true;
820
821 m = btf_members(t);
822 vlen = btf_vlen(t);
823
824 for (i = 0; i < vlen; i++, m++) {
825 align = btf__align_of(btf, m->type);
826 bit_sz = btf_member_bitfield_size(t, i);
827 if (align && bit_sz == 0 && m->offset % (8 * align) != 0)
828 return true;
829 }
830
831
832
833
834
835 return false;
836}
837
838static int chip_away_bits(int total, int at_most)
839{
840 return total % at_most ? : at_most;
841}
842
843static void btf_dump_emit_bit_padding(const struct btf_dump *d,
844 int cur_off, int m_off, int m_bit_sz,
845 int align, int lvl)
846{
847 int off_diff = m_off - cur_off;
848 int ptr_bits = d->ptr_sz * 8;
849
850 if (off_diff <= 0)
851
852 return;
853 if (m_bit_sz == 0 && off_diff < align * 8)
854
855 return;
856
857 while (off_diff > 0) {
858 const char *pad_type;
859 int pad_bits;
860
861 if (ptr_bits > 32 && off_diff > 32) {
862 pad_type = "long";
863 pad_bits = chip_away_bits(off_diff, ptr_bits);
864 } else if (off_diff > 16) {
865 pad_type = "int";
866 pad_bits = chip_away_bits(off_diff, 32);
867 } else if (off_diff > 8) {
868 pad_type = "short";
869 pad_bits = chip_away_bits(off_diff, 16);
870 } else {
871 pad_type = "char";
872 pad_bits = chip_away_bits(off_diff, 8);
873 }
874 btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits);
875 off_diff -= pad_bits;
876 }
877}
878
879static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
880 const struct btf_type *t)
881{
882 btf_dump_printf(d, "%s%s%s",
883 btf_is_struct(t) ? "struct" : "union",
884 t->name_off ? " " : "",
885 btf_dump_type_name(d, id));
886}
887
888static void btf_dump_emit_struct_def(struct btf_dump *d,
889 __u32 id,
890 const struct btf_type *t,
891 int lvl)
892{
893 const struct btf_member *m = btf_members(t);
894 bool is_struct = btf_is_struct(t);
895 int align, i, packed, off = 0;
896 __u16 vlen = btf_vlen(t);
897
898 packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0;
899
900 btf_dump_printf(d, "%s%s%s {",
901 is_struct ? "struct" : "union",
902 t->name_off ? " " : "",
903 btf_dump_type_name(d, id));
904
905 for (i = 0; i < vlen; i++, m++) {
906 const char *fname;
907 int m_off, m_sz;
908
909 fname = btf_name_of(d, m->name_off);
910 m_sz = btf_member_bitfield_size(t, i);
911 m_off = btf_member_bit_offset(t, i);
912 align = packed ? 1 : btf__align_of(d->btf, m->type);
913
914 btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1);
915 btf_dump_printf(d, "\n%s", pfx(lvl + 1));
916 btf_dump_emit_type_decl(d, m->type, fname, lvl + 1);
917
918 if (m_sz) {
919 btf_dump_printf(d, ": %d", m_sz);
920 off = m_off + m_sz;
921 } else {
922 m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));
923 off = m_off + m_sz * 8;
924 }
925 btf_dump_printf(d, ";");
926 }
927
928
929 if (is_struct) {
930 align = packed ? 1 : btf__align_of(d->btf, id);
931 btf_dump_emit_bit_padding(d, off, t->size * 8, 0, align,
932 lvl + 1);
933 }
934
935 if (vlen)
936 btf_dump_printf(d, "\n");
937 btf_dump_printf(d, "%s}", pfx(lvl));
938 if (packed)
939 btf_dump_printf(d, " __attribute__((packed))");
940}
941
942static const char *missing_base_types[][2] = {
943
944
945
946
947 { "__Poly8_t", "unsigned char" },
948 { "__Poly16_t", "unsigned short" },
949 { "__Poly64_t", "unsigned long long" },
950 { "__Poly128_t", "unsigned __int128" },
951};
952
953static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
954 const struct btf_type *t)
955{
956 const char *name = btf_dump_type_name(d, id);
957 int i;
958
959 for (i = 0; i < ARRAY_SIZE(missing_base_types); i++) {
960 if (strcmp(name, missing_base_types[i][0]) == 0) {
961 btf_dump_printf(d, "typedef %s %s;\n\n",
962 missing_base_types[i][1], name);
963 break;
964 }
965 }
966}
967
968static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
969 const struct btf_type *t)
970{
971 btf_dump_printf(d, "enum %s", btf_dump_type_name(d, id));
972}
973
974static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
975 const struct btf_type *t,
976 int lvl)
977{
978 const struct btf_enum *v = btf_enum(t);
979 __u16 vlen = btf_vlen(t);
980 const char *name;
981 size_t dup_cnt;
982 int i;
983
984 btf_dump_printf(d, "enum%s%s",
985 t->name_off ? " " : "",
986 btf_dump_type_name(d, id));
987
988 if (vlen) {
989 btf_dump_printf(d, " {");
990 for (i = 0; i < vlen; i++, v++) {
991 name = btf_name_of(d, v->name_off);
992
993 dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
994 if (dup_cnt > 1) {
995 btf_dump_printf(d, "\n%s%s___%zu = %u,",
996 pfx(lvl + 1), name, dup_cnt,
997 (__u32)v->val);
998 } else {
999 btf_dump_printf(d, "\n%s%s = %u,",
1000 pfx(lvl + 1), name,
1001 (__u32)v->val);
1002 }
1003 }
1004 btf_dump_printf(d, "\n%s}", pfx(lvl));
1005 }
1006}
1007
1008static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
1009 const struct btf_type *t)
1010{
1011 const char *name = btf_dump_type_name(d, id);
1012
1013 if (btf_kflag(t))
1014 btf_dump_printf(d, "union %s", name);
1015 else
1016 btf_dump_printf(d, "struct %s", name);
1017}
1018
1019static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
1020 const struct btf_type *t, int lvl)
1021{
1022 const char *name = btf_dump_ident_name(d, id);
1023
1024
1025
1026
1027
1028
1029
1030 if (t->type == 0 && strcmp(name, "__gnuc_va_list") == 0) {
1031 btf_dump_printf(d, "typedef __builtin_va_list __gnuc_va_list");
1032 return;
1033 }
1034
1035 btf_dump_printf(d, "typedef ");
1036 btf_dump_emit_type_decl(d, t->type, name, lvl);
1037}
1038
1039static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
1040{
1041 __u32 *new_stack;
1042 size_t new_cap;
1043
1044 if (d->decl_stack_cnt >= d->decl_stack_cap) {
1045 new_cap = max(16, d->decl_stack_cap * 3 / 2);
1046 new_stack = libbpf_reallocarray(d->decl_stack, new_cap, sizeof(new_stack[0]));
1047 if (!new_stack)
1048 return -ENOMEM;
1049 d->decl_stack = new_stack;
1050 d->decl_stack_cap = new_cap;
1051 }
1052
1053 d->decl_stack[d->decl_stack_cnt++] = id;
1054
1055 return 0;
1056}
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099int btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
1100 const struct btf_dump_emit_type_decl_opts *opts)
1101{
1102 const char *fname;
1103 int lvl, err;
1104
1105 if (!OPTS_VALID(opts, btf_dump_emit_type_decl_opts))
1106 return libbpf_err(-EINVAL);
1107
1108 err = btf_dump_resize(d);
1109 if (err)
1110 return libbpf_err(err);
1111
1112 fname = OPTS_GET(opts, field_name, "");
1113 lvl = OPTS_GET(opts, indent_level, 0);
1114 d->strip_mods = OPTS_GET(opts, strip_mods, false);
1115 btf_dump_emit_type_decl(d, id, fname, lvl);
1116 d->strip_mods = false;
1117 return 0;
1118}
1119
1120static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
1121 const char *fname, int lvl)
1122{
1123 struct id_stack decl_stack;
1124 const struct btf_type *t;
1125 int err, stack_start;
1126
1127 stack_start = d->decl_stack_cnt;
1128 for (;;) {
1129 t = btf__type_by_id(d->btf, id);
1130 if (d->strip_mods && btf_is_mod(t))
1131 goto skip_mod;
1132
1133 err = btf_dump_push_decl_stack_id(d, id);
1134 if (err < 0) {
1135
1136
1137
1138
1139
1140 pr_warn("not enough memory for decl stack:%d", err);
1141 d->decl_stack_cnt = stack_start;
1142 return;
1143 }
1144skip_mod:
1145
1146 if (id == 0)
1147 break;
1148
1149 switch (btf_kind(t)) {
1150 case BTF_KIND_PTR:
1151 case BTF_KIND_VOLATILE:
1152 case BTF_KIND_CONST:
1153 case BTF_KIND_RESTRICT:
1154 case BTF_KIND_FUNC_PROTO:
1155 id = t->type;
1156 break;
1157 case BTF_KIND_ARRAY:
1158 id = btf_array(t)->type;
1159 break;
1160 case BTF_KIND_INT:
1161 case BTF_KIND_ENUM:
1162 case BTF_KIND_FWD:
1163 case BTF_KIND_STRUCT:
1164 case BTF_KIND_UNION:
1165 case BTF_KIND_TYPEDEF:
1166 case BTF_KIND_FLOAT:
1167 goto done;
1168 default:
1169 pr_warn("unexpected type in decl chain, kind:%u, id:[%u]\n",
1170 btf_kind(t), id);
1171 goto done;
1172 }
1173 }
1174done:
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185 decl_stack.ids = d->decl_stack + stack_start;
1186 decl_stack.cnt = d->decl_stack_cnt - stack_start;
1187 btf_dump_emit_type_chain(d, &decl_stack, fname, lvl);
1188
1189
1190
1191
1192
1193
1194
1195
1196 d->decl_stack_cnt = stack_start;
1197}
1198
1199static void btf_dump_emit_mods(struct btf_dump *d, struct id_stack *decl_stack)
1200{
1201 const struct btf_type *t;
1202 __u32 id;
1203
1204 while (decl_stack->cnt) {
1205 id = decl_stack->ids[decl_stack->cnt - 1];
1206 t = btf__type_by_id(d->btf, id);
1207
1208 switch (btf_kind(t)) {
1209 case BTF_KIND_VOLATILE:
1210 btf_dump_printf(d, "volatile ");
1211 break;
1212 case BTF_KIND_CONST:
1213 btf_dump_printf(d, "const ");
1214 break;
1215 case BTF_KIND_RESTRICT:
1216 btf_dump_printf(d, "restrict ");
1217 break;
1218 default:
1219 return;
1220 }
1221 decl_stack->cnt--;
1222 }
1223}
1224
1225static void btf_dump_drop_mods(struct btf_dump *d, struct id_stack *decl_stack)
1226{
1227 const struct btf_type *t;
1228 __u32 id;
1229
1230 while (decl_stack->cnt) {
1231 id = decl_stack->ids[decl_stack->cnt - 1];
1232 t = btf__type_by_id(d->btf, id);
1233 if (!btf_is_mod(t))
1234 return;
1235 decl_stack->cnt--;
1236 }
1237}
1238
1239static void btf_dump_emit_name(const struct btf_dump *d,
1240 const char *name, bool last_was_ptr)
1241{
1242 bool separate = name[0] && !last_was_ptr;
1243
1244 btf_dump_printf(d, "%s%s", separate ? " " : "", name);
1245}
1246
1247static void btf_dump_emit_type_chain(struct btf_dump *d,
1248 struct id_stack *decls,
1249 const char *fname, int lvl)
1250{
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260 bool last_was_ptr = true;
1261 const struct btf_type *t;
1262 const char *name;
1263 __u16 kind;
1264 __u32 id;
1265
1266 while (decls->cnt) {
1267 id = decls->ids[--decls->cnt];
1268 if (id == 0) {
1269
1270 btf_dump_emit_mods(d, decls);
1271 btf_dump_printf(d, "void");
1272 last_was_ptr = false;
1273 continue;
1274 }
1275
1276 t = btf__type_by_id(d->btf, id);
1277 kind = btf_kind(t);
1278
1279 switch (kind) {
1280 case BTF_KIND_INT:
1281 case BTF_KIND_FLOAT:
1282 btf_dump_emit_mods(d, decls);
1283 name = btf_name_of(d, t->name_off);
1284 btf_dump_printf(d, "%s", name);
1285 break;
1286 case BTF_KIND_STRUCT:
1287 case BTF_KIND_UNION:
1288 btf_dump_emit_mods(d, decls);
1289
1290 if (t->name_off == 0 && !d->skip_anon_defs)
1291 btf_dump_emit_struct_def(d, id, t, lvl);
1292 else
1293 btf_dump_emit_struct_fwd(d, id, t);
1294 break;
1295 case BTF_KIND_ENUM:
1296 btf_dump_emit_mods(d, decls);
1297
1298 if (t->name_off == 0 && !d->skip_anon_defs)
1299 btf_dump_emit_enum_def(d, id, t, lvl);
1300 else
1301 btf_dump_emit_enum_fwd(d, id, t);
1302 break;
1303 case BTF_KIND_FWD:
1304 btf_dump_emit_mods(d, decls);
1305 btf_dump_emit_fwd_def(d, id, t);
1306 break;
1307 case BTF_KIND_TYPEDEF:
1308 btf_dump_emit_mods(d, decls);
1309 btf_dump_printf(d, "%s", btf_dump_ident_name(d, id));
1310 break;
1311 case BTF_KIND_PTR:
1312 btf_dump_printf(d, "%s", last_was_ptr ? "*" : " *");
1313 break;
1314 case BTF_KIND_VOLATILE:
1315 btf_dump_printf(d, " volatile");
1316 break;
1317 case BTF_KIND_CONST:
1318 btf_dump_printf(d, " const");
1319 break;
1320 case BTF_KIND_RESTRICT:
1321 btf_dump_printf(d, " restrict");
1322 break;
1323 case BTF_KIND_ARRAY: {
1324 const struct btf_array *a = btf_array(t);
1325 const struct btf_type *next_t;
1326 __u32 next_id;
1327 bool multidim;
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338 btf_dump_drop_mods(d, decls);
1339
1340 if (decls->cnt == 0) {
1341 btf_dump_emit_name(d, fname, last_was_ptr);
1342 btf_dump_printf(d, "[%u]", a->nelems);
1343 return;
1344 }
1345
1346 next_id = decls->ids[decls->cnt - 1];
1347 next_t = btf__type_by_id(d->btf, next_id);
1348 multidim = btf_is_array(next_t);
1349
1350 if (fname[0] && !last_was_ptr)
1351 btf_dump_printf(d, " ");
1352
1353 if (!multidim)
1354 btf_dump_printf(d, "(");
1355 btf_dump_emit_type_chain(d, decls, fname, lvl);
1356 if (!multidim)
1357 btf_dump_printf(d, ")");
1358 btf_dump_printf(d, "[%u]", a->nelems);
1359 return;
1360 }
1361 case BTF_KIND_FUNC_PROTO: {
1362 const struct btf_param *p = btf_params(t);
1363 __u16 vlen = btf_vlen(t);
1364 int i;
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374 btf_dump_drop_mods(d, decls);
1375 if (decls->cnt) {
1376 btf_dump_printf(d, " (");
1377 btf_dump_emit_type_chain(d, decls, fname, lvl);
1378 btf_dump_printf(d, ")");
1379 } else {
1380 btf_dump_emit_name(d, fname, last_was_ptr);
1381 }
1382 btf_dump_printf(d, "(");
1383
1384
1385
1386
1387
1388
1389 if (vlen == 1 && p->type == 0) {
1390 btf_dump_printf(d, ")");
1391 return;
1392 }
1393
1394 for (i = 0; i < vlen; i++, p++) {
1395 if (i > 0)
1396 btf_dump_printf(d, ", ");
1397
1398
1399 if (i == vlen - 1 && p->type == 0) {
1400 btf_dump_printf(d, "...");
1401 break;
1402 }
1403
1404 name = btf_name_of(d, p->name_off);
1405 btf_dump_emit_type_decl(d, p->type, name, lvl);
1406 }
1407
1408 btf_dump_printf(d, ")");
1409 return;
1410 }
1411 default:
1412 pr_warn("unexpected type in decl chain, kind:%u, id:[%u]\n",
1413 kind, id);
1414 return;
1415 }
1416
1417 last_was_ptr = kind == BTF_KIND_PTR;
1418 }
1419
1420 btf_dump_emit_name(d, fname, last_was_ptr);
1421}
1422
1423
1424static void btf_dump_emit_type_cast(struct btf_dump *d, __u32 id,
1425 bool top_level)
1426{
1427 const struct btf_type *t;
1428
1429
1430
1431
1432
1433 if (d->typed_dump->is_array_member)
1434 return;
1435
1436
1437
1438
1439 t = btf__type_by_id(d->btf, id);
1440 if (btf_is_var(t) || btf_is_datasec(t))
1441 return;
1442
1443 if (top_level)
1444 btf_dump_printf(d, "(");
1445
1446 d->skip_anon_defs = true;
1447 d->strip_mods = true;
1448 btf_dump_emit_type_decl(d, id, "", 0);
1449 d->strip_mods = false;
1450 d->skip_anon_defs = false;
1451
1452 if (top_level)
1453 btf_dump_printf(d, ")");
1454}
1455
1456
1457static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
1458 const char *orig_name)
1459{
1460 size_t dup_cnt = 0;
1461
1462 hashmap__find(name_map, orig_name, (void **)&dup_cnt);
1463 dup_cnt++;
1464 hashmap__set(name_map, orig_name, (void *)dup_cnt, NULL, NULL);
1465
1466 return dup_cnt;
1467}
1468
1469static const char *btf_dump_resolve_name(struct btf_dump *d, __u32 id,
1470 struct hashmap *name_map)
1471{
1472 struct btf_dump_type_aux_state *s = &d->type_states[id];
1473 const struct btf_type *t = btf__type_by_id(d->btf, id);
1474 const char *orig_name = btf_name_of(d, t->name_off);
1475 const char **cached_name = &d->cached_names[id];
1476 size_t dup_cnt;
1477
1478 if (t->name_off == 0)
1479 return "";
1480
1481 if (s->name_resolved)
1482 return *cached_name ? *cached_name : orig_name;
1483
1484 dup_cnt = btf_dump_name_dups(d, name_map, orig_name);
1485 if (dup_cnt > 1) {
1486 const size_t max_len = 256;
1487 char new_name[max_len];
1488
1489 snprintf(new_name, max_len, "%s___%zu", orig_name, dup_cnt);
1490 *cached_name = strdup(new_name);
1491 }
1492
1493 s->name_resolved = 1;
1494 return *cached_name ? *cached_name : orig_name;
1495}
1496
1497static const char *btf_dump_type_name(struct btf_dump *d, __u32 id)
1498{
1499 return btf_dump_resolve_name(d, id, d->type_names);
1500}
1501
1502static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id)
1503{
1504 return btf_dump_resolve_name(d, id, d->ident_names);
1505}
1506
1507static int btf_dump_dump_type_data(struct btf_dump *d,
1508 const char *fname,
1509 const struct btf_type *t,
1510 __u32 id,
1511 const void *data,
1512 __u8 bits_offset,
1513 __u8 bit_sz);
1514
1515static const char *btf_dump_data_newline(struct btf_dump *d)
1516{
1517 return d->typed_dump->compact || d->typed_dump->depth == 0 ? "" : "\n";
1518}
1519
1520static const char *btf_dump_data_delim(struct btf_dump *d)
1521{
1522 return d->typed_dump->depth == 0 ? "" : ",";
1523}
1524
1525static void btf_dump_data_pfx(struct btf_dump *d)
1526{
1527 int i, lvl = d->typed_dump->indent_lvl + d->typed_dump->depth;
1528
1529 if (d->typed_dump->compact)
1530 return;
1531
1532 for (i = 0; i < lvl; i++)
1533 btf_dump_printf(d, "%s", d->typed_dump->indent_str);
1534}
1535
1536
1537
1538
1539
1540
1541#define btf_dump_type_values(d, fmt, ...) \
1542 btf_dump_printf(d, fmt "%s%s", \
1543 ##__VA_ARGS__, \
1544 btf_dump_data_delim(d), \
1545 btf_dump_data_newline(d))
1546
1547static int btf_dump_unsupported_data(struct btf_dump *d,
1548 const struct btf_type *t,
1549 __u32 id)
1550{
1551 btf_dump_printf(d, "<unsupported kind:%u>", btf_kind(t));
1552 return -ENOTSUP;
1553}
1554
1555static int btf_dump_get_bitfield_value(struct btf_dump *d,
1556 const struct btf_type *t,
1557 const void *data,
1558 __u8 bits_offset,
1559 __u8 bit_sz,
1560 __u64 *value)
1561{
1562 __u16 left_shift_bits, right_shift_bits;
1563 __u8 nr_copy_bits, nr_copy_bytes;
1564 const __u8 *bytes = data;
1565 int sz = t->size;
1566 __u64 num = 0;
1567 int i;
1568
1569
1570 if (sz > 8) {
1571 pr_warn("unexpected bitfield size %d\n", sz);
1572 return -EINVAL;
1573 }
1574
1575
1576
1577
1578 nr_copy_bits = bit_sz + bits_offset;
1579 nr_copy_bytes = t->size;
1580#if __BYTE_ORDER == __LITTLE_ENDIAN
1581 for (i = nr_copy_bytes - 1; i >= 0; i--)
1582 num = num * 256 + bytes[i];
1583#elif __BYTE_ORDER == __BIG_ENDIAN
1584 for (i = 0; i < nr_copy_bytes; i++)
1585 num = num * 256 + bytes[i];
1586#else
1587# error "Unrecognized __BYTE_ORDER__"
1588#endif
1589 left_shift_bits = 64 - nr_copy_bits;
1590 right_shift_bits = 64 - bit_sz;
1591
1592 *value = (num << left_shift_bits) >> right_shift_bits;
1593
1594 return 0;
1595}
1596
1597static int btf_dump_bitfield_check_zero(struct btf_dump *d,
1598 const struct btf_type *t,
1599 const void *data,
1600 __u8 bits_offset,
1601 __u8 bit_sz)
1602{
1603 __u64 check_num;
1604 int err;
1605
1606 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz, &check_num);
1607 if (err)
1608 return err;
1609 if (check_num == 0)
1610 return -ENODATA;
1611 return 0;
1612}
1613
1614static int btf_dump_bitfield_data(struct btf_dump *d,
1615 const struct btf_type *t,
1616 const void *data,
1617 __u8 bits_offset,
1618 __u8 bit_sz)
1619{
1620 __u64 print_num;
1621 int err;
1622
1623 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz, &print_num);
1624 if (err)
1625 return err;
1626
1627 btf_dump_type_values(d, "0x%llx", (unsigned long long)print_num);
1628
1629 return 0;
1630}
1631
1632
1633static int btf_dump_base_type_check_zero(struct btf_dump *d,
1634 const struct btf_type *t,
1635 __u32 id,
1636 const void *data)
1637{
1638 static __u8 bytecmp[16] = {};
1639 int nr_bytes;
1640
1641
1642
1643
1644 if (btf_kind(t) == BTF_KIND_PTR)
1645 nr_bytes = d->ptr_sz;
1646 else
1647 nr_bytes = t->size;
1648
1649 if (nr_bytes < 1 || nr_bytes > 16) {
1650 pr_warn("unexpected size %d for id [%u]\n", nr_bytes, id);
1651 return -EINVAL;
1652 }
1653
1654 if (memcmp(data, bytecmp, nr_bytes) == 0)
1655 return -ENODATA;
1656 return 0;
1657}
1658
1659static bool ptr_is_aligned(const void *data, int data_sz)
1660{
1661 return ((uintptr_t)data) % data_sz == 0;
1662}
1663
1664static int btf_dump_int_data(struct btf_dump *d,
1665 const struct btf_type *t,
1666 __u32 type_id,
1667 const void *data,
1668 __u8 bits_offset)
1669{
1670 __u8 encoding = btf_int_encoding(t);
1671 bool sign = encoding & BTF_INT_SIGNED;
1672 int sz = t->size;
1673
1674 if (sz == 0) {
1675 pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
1676 return -EINVAL;
1677 }
1678
1679
1680
1681
1682 if (!ptr_is_aligned(data, sz))
1683 return btf_dump_bitfield_data(d, t, data, 0, 0);
1684
1685 switch (sz) {
1686 case 16: {
1687 const __u64 *ints = data;
1688 __u64 lsi, msi;
1689
1690
1691
1692
1693#if __BYTE_ORDER == __LITTLE_ENDIAN
1694 lsi = ints[0];
1695 msi = ints[1];
1696#elif __BYTE_ORDER == __BIG_ENDIAN
1697 lsi = ints[1];
1698 msi = ints[0];
1699#else
1700# error "Unrecognized __BYTE_ORDER__"
1701#endif
1702 if (msi == 0)
1703 btf_dump_type_values(d, "0x%llx", (unsigned long long)lsi);
1704 else
1705 btf_dump_type_values(d, "0x%llx%016llx", (unsigned long long)msi,
1706 (unsigned long long)lsi);
1707 break;
1708 }
1709 case 8:
1710 if (sign)
1711 btf_dump_type_values(d, "%lld", *(long long *)data);
1712 else
1713 btf_dump_type_values(d, "%llu", *(unsigned long long *)data);
1714 break;
1715 case 4:
1716 if (sign)
1717 btf_dump_type_values(d, "%d", *(__s32 *)data);
1718 else
1719 btf_dump_type_values(d, "%u", *(__u32 *)data);
1720 break;
1721 case 2:
1722 if (sign)
1723 btf_dump_type_values(d, "%d", *(__s16 *)data);
1724 else
1725 btf_dump_type_values(d, "%u", *(__u16 *)data);
1726 break;
1727 case 1:
1728 if (d->typed_dump->is_array_char) {
1729
1730 if (d->typed_dump->is_array_terminated)
1731 break;
1732 if (*(char *)data == '\0') {
1733 d->typed_dump->is_array_terminated = true;
1734 break;
1735 }
1736 if (isprint(*(char *)data)) {
1737 btf_dump_type_values(d, "'%c'", *(char *)data);
1738 break;
1739 }
1740 }
1741 if (sign)
1742 btf_dump_type_values(d, "%d", *(__s8 *)data);
1743 else
1744 btf_dump_type_values(d, "%u", *(__u8 *)data);
1745 break;
1746 default:
1747 pr_warn("unexpected sz %d for id [%u]\n", sz, type_id);
1748 return -EINVAL;
1749 }
1750 return 0;
1751}
1752
1753union float_data {
1754 long double ld;
1755 double d;
1756 float f;
1757};
1758
1759static int btf_dump_float_data(struct btf_dump *d,
1760 const struct btf_type *t,
1761 __u32 type_id,
1762 const void *data)
1763{
1764 const union float_data *flp = data;
1765 union float_data fl;
1766 int sz = t->size;
1767
1768
1769 if (!ptr_is_aligned(data, sz)) {
1770 memcpy(&fl, data, sz);
1771 flp = &fl;
1772 }
1773
1774 switch (sz) {
1775 case 16:
1776 btf_dump_type_values(d, "%Lf", flp->ld);
1777 break;
1778 case 8:
1779 btf_dump_type_values(d, "%lf", flp->d);
1780 break;
1781 case 4:
1782 btf_dump_type_values(d, "%f", flp->f);
1783 break;
1784 default:
1785 pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
1786 return -EINVAL;
1787 }
1788 return 0;
1789}
1790
1791static int btf_dump_var_data(struct btf_dump *d,
1792 const struct btf_type *v,
1793 __u32 id,
1794 const void *data)
1795{
1796 enum btf_func_linkage linkage = btf_var(v)->linkage;
1797 const struct btf_type *t;
1798 const char *l;
1799 __u32 type_id;
1800
1801 switch (linkage) {
1802 case BTF_FUNC_STATIC:
1803 l = "static ";
1804 break;
1805 case BTF_FUNC_EXTERN:
1806 l = "extern ";
1807 break;
1808 case BTF_FUNC_GLOBAL:
1809 default:
1810 l = "";
1811 break;
1812 }
1813
1814
1815
1816
1817 btf_dump_printf(d, "%s", l);
1818 type_id = v->type;
1819 t = btf__type_by_id(d->btf, type_id);
1820 btf_dump_emit_type_cast(d, type_id, false);
1821 btf_dump_printf(d, " %s = ", btf_name_of(d, v->name_off));
1822 return btf_dump_dump_type_data(d, NULL, t, type_id, data, 0, 0);
1823}
1824
1825static int btf_dump_array_data(struct btf_dump *d,
1826 const struct btf_type *t,
1827 __u32 id,
1828 const void *data)
1829{
1830 const struct btf_array *array = btf_array(t);
1831 const struct btf_type *elem_type;
1832 __u32 i, elem_size = 0, elem_type_id;
1833 bool is_array_member;
1834
1835 elem_type_id = array->type;
1836 elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
1837 elem_size = btf__resolve_size(d->btf, elem_type_id);
1838 if (elem_size <= 0) {
1839 pr_warn("unexpected elem size %d for array type [%u]\n", elem_size, id);
1840 return -EINVAL;
1841 }
1842
1843 if (btf_is_int(elem_type)) {
1844
1845
1846
1847
1848
1849 if (elem_size == 1)
1850 d->typed_dump->is_array_char = true;
1851 }
1852
1853
1854
1855
1856
1857
1858
1859
1860 d->typed_dump->depth++;
1861 btf_dump_printf(d, "[%s", btf_dump_data_newline(d));
1862
1863
1864
1865
1866 is_array_member = d->typed_dump->is_array_member;
1867 d->typed_dump->is_array_member = true;
1868 for (i = 0; i < array->nelems; i++, data += elem_size) {
1869 if (d->typed_dump->is_array_terminated)
1870 break;
1871 btf_dump_dump_type_data(d, NULL, elem_type, elem_type_id, data, 0, 0);
1872 }
1873 d->typed_dump->is_array_member = is_array_member;
1874 d->typed_dump->depth--;
1875 btf_dump_data_pfx(d);
1876 btf_dump_type_values(d, "]");
1877
1878 return 0;
1879}
1880
1881static int btf_dump_struct_data(struct btf_dump *d,
1882 const struct btf_type *t,
1883 __u32 id,
1884 const void *data)
1885{
1886 const struct btf_member *m = btf_members(t);
1887 __u16 n = btf_vlen(t);
1888 int i, err;
1889
1890
1891
1892
1893
1894
1895
1896
1897 d->typed_dump->depth++;
1898 btf_dump_printf(d, "{%s", btf_dump_data_newline(d));
1899
1900 for (i = 0; i < n; i++, m++) {
1901 const struct btf_type *mtype;
1902 const char *mname;
1903 __u32 moffset;
1904 __u8 bit_sz;
1905
1906 mtype = btf__type_by_id(d->btf, m->type);
1907 mname = btf_name_of(d, m->name_off);
1908 moffset = btf_member_bit_offset(t, i);
1909
1910 bit_sz = btf_member_bitfield_size(t, i);
1911 err = btf_dump_dump_type_data(d, mname, mtype, m->type, data + moffset / 8,
1912 moffset % 8, bit_sz);
1913 if (err < 0)
1914 return err;
1915 }
1916 d->typed_dump->depth--;
1917 btf_dump_data_pfx(d);
1918 btf_dump_type_values(d, "}");
1919 return err;
1920}
1921
1922union ptr_data {
1923 unsigned int p;
1924 unsigned long long lp;
1925};
1926
1927static int btf_dump_ptr_data(struct btf_dump *d,
1928 const struct btf_type *t,
1929 __u32 id,
1930 const void *data)
1931{
1932 if (ptr_is_aligned(data, d->ptr_sz) && d->ptr_sz == sizeof(void *)) {
1933 btf_dump_type_values(d, "%p", *(void **)data);
1934 } else {
1935 union ptr_data pt;
1936
1937 memcpy(&pt, data, d->ptr_sz);
1938 if (d->ptr_sz == 4)
1939 btf_dump_type_values(d, "0x%x", pt.p);
1940 else
1941 btf_dump_type_values(d, "0x%llx", pt.lp);
1942 }
1943 return 0;
1944}
1945
1946static int btf_dump_get_enum_value(struct btf_dump *d,
1947 const struct btf_type *t,
1948 const void *data,
1949 __u32 id,
1950 __s64 *value)
1951{
1952 int sz = t->size;
1953
1954
1955 if (!ptr_is_aligned(data, sz)) {
1956 __u64 val;
1957 int err;
1958
1959 err = btf_dump_get_bitfield_value(d, t, data, 0, 0, &val);
1960 if (err)
1961 return err;
1962 *value = (__s64)val;
1963 return 0;
1964 }
1965
1966 switch (t->size) {
1967 case 8:
1968 *value = *(__s64 *)data;
1969 return 0;
1970 case 4:
1971 *value = *(__s32 *)data;
1972 return 0;
1973 case 2:
1974 *value = *(__s16 *)data;
1975 return 0;
1976 case 1:
1977 *value = *(__s8 *)data;
1978 return 0;
1979 default:
1980 pr_warn("unexpected size %d for enum, id:[%u]\n", t->size, id);
1981 return -EINVAL;
1982 }
1983}
1984
1985static int btf_dump_enum_data(struct btf_dump *d,
1986 const struct btf_type *t,
1987 __u32 id,
1988 const void *data)
1989{
1990 const struct btf_enum *e;
1991 __s64 value;
1992 int i, err;
1993
1994 err = btf_dump_get_enum_value(d, t, data, id, &value);
1995 if (err)
1996 return err;
1997
1998 for (i = 0, e = btf_enum(t); i < btf_vlen(t); i++, e++) {
1999 if (value != e->val)
2000 continue;
2001 btf_dump_type_values(d, "%s", btf_name_of(d, e->name_off));
2002 return 0;
2003 }
2004
2005 btf_dump_type_values(d, "%d", value);
2006 return 0;
2007}
2008
2009static int btf_dump_datasec_data(struct btf_dump *d,
2010 const struct btf_type *t,
2011 __u32 id,
2012 const void *data)
2013{
2014 const struct btf_var_secinfo *vsi;
2015 const struct btf_type *var;
2016 __u32 i;
2017 int err;
2018
2019 btf_dump_type_values(d, "SEC(\"%s\") ", btf_name_of(d, t->name_off));
2020
2021 for (i = 0, vsi = btf_var_secinfos(t); i < btf_vlen(t); i++, vsi++) {
2022 var = btf__type_by_id(d->btf, vsi->type);
2023 err = btf_dump_dump_type_data(d, NULL, var, vsi->type, data + vsi->offset, 0, 0);
2024 if (err < 0)
2025 return err;
2026 btf_dump_printf(d, ";");
2027 }
2028 return 0;
2029}
2030
2031
2032static int btf_dump_type_data_check_overflow(struct btf_dump *d,
2033 const struct btf_type *t,
2034 __u32 id,
2035 const void *data,
2036 __u8 bits_offset)
2037{
2038 __s64 size = btf__resolve_size(d->btf, id);
2039
2040 if (size < 0 || size >= INT_MAX) {
2041 pr_warn("unexpected size [%zu] for id [%u]\n",
2042 (size_t)size, id);
2043 return -EINVAL;
2044 }
2045
2046
2047
2048
2049
2050
2051
2052
2053 t = skip_mods_and_typedefs(d->btf, id, NULL);
2054 if (!t) {
2055 pr_warn("unexpected error skipping mods/typedefs for id [%u]\n",
2056 id);
2057 return -EINVAL;
2058 }
2059
2060 switch (btf_kind(t)) {
2061 case BTF_KIND_INT:
2062 case BTF_KIND_FLOAT:
2063 case BTF_KIND_PTR:
2064 case BTF_KIND_ENUM:
2065 if (data + bits_offset / 8 + size > d->typed_dump->data_end)
2066 return -E2BIG;
2067 break;
2068 default:
2069 break;
2070 }
2071 return (int)size;
2072}
2073
2074static int btf_dump_type_data_check_zero(struct btf_dump *d,
2075 const struct btf_type *t,
2076 __u32 id,
2077 const void *data,
2078 __u8 bits_offset,
2079 __u8 bit_sz)
2080{
2081 __s64 value;
2082 int i, err;
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095 if (d->typed_dump->emit_zeroes || d->typed_dump->depth == 0 ||
2096 (d->typed_dump->is_array_member &&
2097 !d->typed_dump->is_array_char))
2098 return 0;
2099
2100 t = skip_mods_and_typedefs(d->btf, id, NULL);
2101
2102 switch (btf_kind(t)) {
2103 case BTF_KIND_INT:
2104 if (bit_sz)
2105 return btf_dump_bitfield_check_zero(d, t, data, bits_offset, bit_sz);
2106 return btf_dump_base_type_check_zero(d, t, id, data);
2107 case BTF_KIND_FLOAT:
2108 case BTF_KIND_PTR:
2109 return btf_dump_base_type_check_zero(d, t, id, data);
2110 case BTF_KIND_ARRAY: {
2111 const struct btf_array *array = btf_array(t);
2112 const struct btf_type *elem_type;
2113 __u32 elem_type_id, elem_size;
2114 bool ischar;
2115
2116 elem_type_id = array->type;
2117 elem_size = btf__resolve_size(d->btf, elem_type_id);
2118 elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
2119
2120 ischar = btf_is_int(elem_type) && elem_size == 1;
2121
2122
2123
2124
2125
2126
2127
2128 for (i = 0; i < array->nelems; i++) {
2129 if (i == 0 && ischar && *(char *)data == 0)
2130 return -ENODATA;
2131 err = btf_dump_type_data_check_zero(d, elem_type,
2132 elem_type_id,
2133 data +
2134 (i * elem_size),
2135 bits_offset, 0);
2136 if (err != -ENODATA)
2137 return err;
2138 }
2139 return -ENODATA;
2140 }
2141 case BTF_KIND_STRUCT:
2142 case BTF_KIND_UNION: {
2143 const struct btf_member *m = btf_members(t);
2144 __u16 n = btf_vlen(t);
2145
2146
2147
2148
2149 for (i = 0; i < n; i++, m++) {
2150 const struct btf_type *mtype;
2151 __u32 moffset;
2152
2153 mtype = btf__type_by_id(d->btf, m->type);
2154 moffset = btf_member_bit_offset(t, i);
2155
2156
2157
2158
2159
2160 bit_sz = btf_member_bitfield_size(t, i);
2161 err = btf_dump_type_data_check_zero(d, mtype, m->type, data + moffset / 8,
2162 moffset % 8, bit_sz);
2163 if (err != ENODATA)
2164 return err;
2165 }
2166 return -ENODATA;
2167 }
2168 case BTF_KIND_ENUM:
2169 err = btf_dump_get_enum_value(d, t, data, id, &value);
2170 if (err)
2171 return err;
2172 if (value == 0)
2173 return -ENODATA;
2174 return 0;
2175 default:
2176 return 0;
2177 }
2178}
2179
2180
2181static int btf_dump_dump_type_data(struct btf_dump *d,
2182 const char *fname,
2183 const struct btf_type *t,
2184 __u32 id,
2185 const void *data,
2186 __u8 bits_offset,
2187 __u8 bit_sz)
2188{
2189 int size, err;
2190
2191 size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset);
2192 if (size < 0)
2193 return size;
2194 err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);
2195 if (err) {
2196
2197
2198
2199 if (err == -ENODATA)
2200 return size;
2201 return err;
2202 }
2203 btf_dump_data_pfx(d);
2204
2205 if (!d->typed_dump->skip_names) {
2206 if (fname && strlen(fname) > 0)
2207 btf_dump_printf(d, ".%s = ", fname);
2208 btf_dump_emit_type_cast(d, id, true);
2209 }
2210
2211 t = skip_mods_and_typedefs(d->btf, id, NULL);
2212
2213 switch (btf_kind(t)) {
2214 case BTF_KIND_UNKN:
2215 case BTF_KIND_FWD:
2216 case BTF_KIND_FUNC:
2217 case BTF_KIND_FUNC_PROTO:
2218 err = btf_dump_unsupported_data(d, t, id);
2219 break;
2220 case BTF_KIND_INT:
2221 if (bit_sz)
2222 err = btf_dump_bitfield_data(d, t, data, bits_offset, bit_sz);
2223 else
2224 err = btf_dump_int_data(d, t, id, data, bits_offset);
2225 break;
2226 case BTF_KIND_FLOAT:
2227 err = btf_dump_float_data(d, t, id, data);
2228 break;
2229 case BTF_KIND_PTR:
2230 err = btf_dump_ptr_data(d, t, id, data);
2231 break;
2232 case BTF_KIND_ARRAY:
2233 err = btf_dump_array_data(d, t, id, data);
2234 break;
2235 case BTF_KIND_STRUCT:
2236 case BTF_KIND_UNION:
2237 err = btf_dump_struct_data(d, t, id, data);
2238 break;
2239 case BTF_KIND_ENUM:
2240
2241 if (bit_sz) {
2242 __u64 print_num;
2243 __s64 enum_val;
2244
2245 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz,
2246 &print_num);
2247 if (err)
2248 break;
2249 enum_val = (__s64)print_num;
2250 err = btf_dump_enum_data(d, t, id, &enum_val);
2251 } else
2252 err = btf_dump_enum_data(d, t, id, data);
2253 break;
2254 case BTF_KIND_VAR:
2255 err = btf_dump_var_data(d, t, id, data);
2256 break;
2257 case BTF_KIND_DATASEC:
2258 err = btf_dump_datasec_data(d, t, id, data);
2259 break;
2260 default:
2261 pr_warn("unexpected kind [%u] for id [%u]\n",
2262 BTF_INFO_KIND(t->info), id);
2263 return -EINVAL;
2264 }
2265 if (err < 0)
2266 return err;
2267 return size;
2268}
2269
2270int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
2271 const void *data, size_t data_sz,
2272 const struct btf_dump_type_data_opts *opts)
2273{
2274 struct btf_dump_data typed_dump = {};
2275 const struct btf_type *t;
2276 int ret;
2277
2278 if (!OPTS_VALID(opts, btf_dump_type_data_opts))
2279 return libbpf_err(-EINVAL);
2280
2281 t = btf__type_by_id(d->btf, id);
2282 if (!t)
2283 return libbpf_err(-ENOENT);
2284
2285 d->typed_dump = &typed_dump;
2286 d->typed_dump->data_end = data + data_sz;
2287 d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0);
2288
2289
2290 if (!opts->indent_str)
2291 d->typed_dump->indent_str[0] = '\t';
2292 else
2293 strncat(d->typed_dump->indent_str, opts->indent_str,
2294 sizeof(d->typed_dump->indent_str) - 1);
2295
2296 d->typed_dump->compact = OPTS_GET(opts, compact, false);
2297 d->typed_dump->skip_names = OPTS_GET(opts, skip_names, false);
2298 d->typed_dump->emit_zeroes = OPTS_GET(opts, emit_zeroes, false);
2299
2300 ret = btf_dump_dump_type_data(d, NULL, t, id, data, 0, 0);
2301
2302 d->typed_dump = NULL;
2303
2304 return libbpf_err(ret);
2305}
2306