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 <errno.h>
14#include <linux/err.h>
15#include <linux/btf.h>
16#include "btf.h"
17#include "hashmap.h"
18#include "libbpf.h"
19#include "libbpf_internal.h"
20
21static const char PREFIXES[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
22static const size_t PREFIX_CNT = sizeof(PREFIXES) - 1;
23
24static const char *pfx(int lvl)
25{
26 return lvl >= PREFIX_CNT ? PREFIXES : &PREFIXES[PREFIX_CNT - lvl];
27}
28
29enum btf_dump_type_order_state {
30 NOT_ORDERED,
31 ORDERING,
32 ORDERED,
33};
34
35enum btf_dump_type_emit_state {
36 NOT_EMITTED,
37 EMITTING,
38 EMITTED,
39};
40
41
42struct btf_dump_type_aux_state {
43
44 enum btf_dump_type_order_state order_state: 2;
45
46 enum btf_dump_type_emit_state emit_state: 2;
47
48 __u8 fwd_emitted: 1;
49
50 __u8 name_resolved: 1;
51};
52
53struct btf_dump {
54 const struct btf *btf;
55 const struct btf_ext *btf_ext;
56 btf_dump_printf_fn_t printf_fn;
57 struct btf_dump_opts opts;
58
59
60 struct btf_dump_type_aux_state *type_states;
61
62 const char **cached_names;
63
64
65 __u32 *emit_queue;
66 int emit_queue_cap;
67 int emit_queue_cnt;
68
69
70
71
72
73 __u32 *decl_stack;
74 int decl_stack_cap;
75 int decl_stack_cnt;
76
77
78 struct hashmap *type_names;
79
80
81
82
83 struct hashmap *ident_names;
84};
85
86static size_t str_hash_fn(const void *key, void *ctx)
87{
88 const char *s = key;
89 size_t h = 0;
90
91 while (*s) {
92 h = h * 31 + *s;
93 s++;
94 }
95 return h;
96}
97
98static bool str_equal_fn(const void *a, const void *b, void *ctx)
99{
100 return strcmp(a, b) == 0;
101}
102
103static __u16 btf_kind_of(const struct btf_type *t)
104{
105 return BTF_INFO_KIND(t->info);
106}
107
108static __u16 btf_vlen_of(const struct btf_type *t)
109{
110 return BTF_INFO_VLEN(t->info);
111}
112
113static bool btf_kflag_of(const struct btf_type *t)
114{
115 return BTF_INFO_KFLAG(t->info);
116}
117
118static const char *btf_name_of(const struct btf_dump *d, __u32 name_off)
119{
120 return btf__name_by_offset(d->btf, name_off);
121}
122
123static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
124{
125 va_list args;
126
127 va_start(args, fmt);
128 d->printf_fn(d->opts.ctx, fmt, args);
129 va_end(args);
130}
131
132struct btf_dump *btf_dump__new(const struct btf *btf,
133 const struct btf_ext *btf_ext,
134 const struct btf_dump_opts *opts,
135 btf_dump_printf_fn_t printf_fn)
136{
137 struct btf_dump *d;
138 int err;
139
140 d = calloc(1, sizeof(struct btf_dump));
141 if (!d)
142 return ERR_PTR(-ENOMEM);
143
144 d->btf = btf;
145 d->btf_ext = btf_ext;
146 d->printf_fn = printf_fn;
147 d->opts.ctx = opts ? opts->ctx : NULL;
148
149 d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
150 if (IS_ERR(d->type_names)) {
151 err = PTR_ERR(d->type_names);
152 d->type_names = NULL;
153 btf_dump__free(d);
154 return ERR_PTR(err);
155 }
156 d->ident_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
157 if (IS_ERR(d->ident_names)) {
158 err = PTR_ERR(d->ident_names);
159 d->ident_names = NULL;
160 btf_dump__free(d);
161 return ERR_PTR(err);
162 }
163
164 return d;
165}
166
167void btf_dump__free(struct btf_dump *d)
168{
169 int i, cnt;
170
171 if (!d)
172 return;
173
174 free(d->type_states);
175 if (d->cached_names) {
176
177 for (i = 0, cnt = btf__get_nr_types(d->btf); i <= cnt; i++) {
178 if (d->cached_names[i])
179 free((void *)d->cached_names[i]);
180 }
181 }
182 free(d->cached_names);
183 free(d->emit_queue);
184 free(d->decl_stack);
185 hashmap__free(d->type_names);
186 hashmap__free(d->ident_names);
187
188 free(d);
189}
190
191static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr);
192static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id);
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210int btf_dump__dump_type(struct btf_dump *d, __u32 id)
211{
212 int err, i;
213
214 if (id > btf__get_nr_types(d->btf))
215 return -EINVAL;
216
217
218 if (!d->type_states) {
219 d->type_states = calloc(1 + btf__get_nr_types(d->btf),
220 sizeof(d->type_states[0]));
221 if (!d->type_states)
222 return -ENOMEM;
223 d->cached_names = calloc(1 + btf__get_nr_types(d->btf),
224 sizeof(d->cached_names[0]));
225 if (!d->cached_names)
226 return -ENOMEM;
227
228
229 d->type_states[0].order_state = ORDERED;
230 d->type_states[0].emit_state = EMITTED;
231 }
232
233 d->emit_queue_cnt = 0;
234 err = btf_dump_order_type(d, id, false);
235 if (err < 0)
236 return err;
237
238 for (i = 0; i < d->emit_queue_cnt; i++)
239 btf_dump_emit_type(d, d->emit_queue[i], 0 );
240
241 return 0;
242}
243
244static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
245{
246 __u32 *new_queue;
247 size_t new_cap;
248
249 if (d->emit_queue_cnt >= d->emit_queue_cap) {
250 new_cap = max(16, d->emit_queue_cap * 3 / 2);
251 new_queue = realloc(d->emit_queue,
252 new_cap * sizeof(new_queue[0]));
253 if (!new_queue)
254 return -ENOMEM;
255 d->emit_queue = new_queue;
256 d->emit_queue_cap = new_cap;
257 }
258
259 d->emit_queue[d->emit_queue_cnt++] = id;
260 return 0;
261}
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
338{
339
340
341
342
343
344
345
346
347
348
349
350 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
351 const struct btf_type *t;
352 __u16 kind, vlen;
353 int err, i;
354
355
356 if (tstate->order_state == ORDERED)
357 return 1;
358
359 t = btf__type_by_id(d->btf, id);
360 kind = btf_kind_of(t);
361
362 if (tstate->order_state == ORDERING) {
363
364 if ((kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION) &&
365 through_ptr && t->name_off != 0)
366 return 0;
367 pr_warning("unsatisfiable type cycle, id:[%u]\n", id);
368 return -ELOOP;
369 }
370
371 switch (kind) {
372 case BTF_KIND_INT:
373 tstate->order_state = ORDERED;
374 return 0;
375
376 case BTF_KIND_PTR:
377 err = btf_dump_order_type(d, t->type, true);
378 tstate->order_state = ORDERED;
379 return err;
380
381 case BTF_KIND_ARRAY: {
382 const struct btf_array *a = (void *)(t + 1);
383
384 return btf_dump_order_type(d, a->type, through_ptr);
385 }
386 case BTF_KIND_STRUCT:
387 case BTF_KIND_UNION: {
388 const struct btf_member *m = (void *)(t + 1);
389
390
391
392
393
394 if (through_ptr && t->name_off != 0)
395 return 0;
396
397 tstate->order_state = ORDERING;
398
399 vlen = btf_vlen_of(t);
400 for (i = 0; i < vlen; i++, m++) {
401 err = btf_dump_order_type(d, m->type, false);
402 if (err < 0)
403 return err;
404 }
405
406 if (t->name_off != 0) {
407 err = btf_dump_add_emit_queue_id(d, id);
408 if (err < 0)
409 return err;
410 }
411
412 tstate->order_state = ORDERED;
413 return 1;
414 }
415 case BTF_KIND_ENUM:
416 case BTF_KIND_FWD:
417 if (t->name_off != 0) {
418 err = btf_dump_add_emit_queue_id(d, id);
419 if (err)
420 return err;
421 }
422 tstate->order_state = ORDERED;
423 return 1;
424
425 case BTF_KIND_TYPEDEF: {
426 int is_strong;
427
428 is_strong = btf_dump_order_type(d, t->type, through_ptr);
429 if (is_strong < 0)
430 return is_strong;
431
432
433 if (through_ptr && !is_strong)
434 return 0;
435
436
437 err = btf_dump_add_emit_queue_id(d, id);
438 if (err)
439 return err;
440
441 d->type_states[id].order_state = ORDERED;
442 return 1;
443 }
444 case BTF_KIND_VOLATILE:
445 case BTF_KIND_CONST:
446 case BTF_KIND_RESTRICT:
447 return btf_dump_order_type(d, t->type, through_ptr);
448
449 case BTF_KIND_FUNC_PROTO: {
450 const struct btf_param *p = (void *)(t + 1);
451 bool is_strong;
452
453 err = btf_dump_order_type(d, t->type, through_ptr);
454 if (err < 0)
455 return err;
456 is_strong = err > 0;
457
458 vlen = btf_vlen_of(t);
459 for (i = 0; i < vlen; i++, p++) {
460 err = btf_dump_order_type(d, p->type, through_ptr);
461 if (err < 0)
462 return err;
463 if (err > 0)
464 is_strong = true;
465 }
466 return is_strong;
467 }
468 case BTF_KIND_FUNC:
469 case BTF_KIND_VAR:
470 case BTF_KIND_DATASEC:
471 d->type_states[id].order_state = ORDERED;
472 return 0;
473
474 default:
475 return -EINVAL;
476 }
477}
478
479static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
480 const struct btf_type *t);
481static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
482 const struct btf_type *t, int lvl);
483
484static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
485 const struct btf_type *t);
486static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
487 const struct btf_type *t, int lvl);
488
489static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
490 const struct btf_type *t);
491
492static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
493 const struct btf_type *t, int lvl);
494
495
496struct id_stack {
497 const __u32 *ids;
498 int cnt;
499};
500
501static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
502 const char *fname, int lvl);
503static void btf_dump_emit_type_chain(struct btf_dump *d,
504 struct id_stack *decl_stack,
505 const char *fname, int lvl);
506
507static const char *btf_dump_type_name(struct btf_dump *d, __u32 id);
508static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id);
509static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
510 const char *orig_name);
511
512static bool btf_dump_is_blacklisted(struct btf_dump *d, __u32 id)
513{
514 const struct btf_type *t = btf__type_by_id(d->btf, id);
515
516
517
518
519
520
521
522 if (t->name_off == 0)
523 return false;
524 return strcmp(btf_name_of(d, t->name_off), "__builtin_va_list") == 0;
525}
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
546{
547 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
548 bool top_level_def = cont_id == 0;
549 const struct btf_type *t;
550 __u16 kind;
551
552 if (tstate->emit_state == EMITTED)
553 return;
554
555 t = btf__type_by_id(d->btf, id);
556 kind = btf_kind_of(t);
557
558 if (top_level_def && t->name_off == 0) {
559 pr_warning("unexpected nameless definition, id:[%u]\n", id);
560 return;
561 }
562
563 if (tstate->emit_state == EMITTING) {
564 if (tstate->fwd_emitted)
565 return;
566
567 switch (kind) {
568 case BTF_KIND_STRUCT:
569 case BTF_KIND_UNION:
570
571
572
573
574 if (id == cont_id)
575 return;
576 if (t->name_off == 0) {
577 pr_warning("anonymous struct/union loop, id:[%u]\n",
578 id);
579 return;
580 }
581 btf_dump_emit_struct_fwd(d, id, t);
582 btf_dump_printf(d, ";\n\n");
583 tstate->fwd_emitted = 1;
584 break;
585 case BTF_KIND_TYPEDEF:
586
587
588
589
590
591 if (!btf_dump_is_blacklisted(d, id)) {
592 btf_dump_emit_typedef_def(d, id, t, 0);
593 btf_dump_printf(d, ";\n\n");
594 };
595 tstate->fwd_emitted = 1;
596 break;
597 default:
598 break;
599 }
600
601 return;
602 }
603
604 switch (kind) {
605 case BTF_KIND_INT:
606 tstate->emit_state = EMITTED;
607 break;
608 case BTF_KIND_ENUM:
609 if (top_level_def) {
610 btf_dump_emit_enum_def(d, id, t, 0);
611 btf_dump_printf(d, ";\n\n");
612 }
613 tstate->emit_state = EMITTED;
614 break;
615 case BTF_KIND_PTR:
616 case BTF_KIND_VOLATILE:
617 case BTF_KIND_CONST:
618 case BTF_KIND_RESTRICT:
619 btf_dump_emit_type(d, t->type, cont_id);
620 break;
621 case BTF_KIND_ARRAY: {
622 const struct btf_array *a = (void *)(t + 1);
623
624 btf_dump_emit_type(d, a->type, cont_id);
625 break;
626 }
627 case BTF_KIND_FWD:
628 btf_dump_emit_fwd_def(d, id, t);
629 btf_dump_printf(d, ";\n\n");
630 tstate->emit_state = EMITTED;
631 break;
632 case BTF_KIND_TYPEDEF:
633 tstate->emit_state = EMITTING;
634 btf_dump_emit_type(d, t->type, id);
635
636
637
638
639
640
641
642 if (!tstate->fwd_emitted && !btf_dump_is_blacklisted(d, id)) {
643 btf_dump_emit_typedef_def(d, id, t, 0);
644 btf_dump_printf(d, ";\n\n");
645 }
646 tstate->emit_state = EMITTED;
647 break;
648 case BTF_KIND_STRUCT:
649 case BTF_KIND_UNION:
650 tstate->emit_state = EMITTING;
651
652
653
654
655
656
657
658 if (top_level_def || t->name_off == 0) {
659 const struct btf_member *m = (void *)(t + 1);
660 __u16 vlen = btf_vlen_of(t);
661 int i, new_cont_id;
662
663 new_cont_id = t->name_off == 0 ? cont_id : id;
664 for (i = 0; i < vlen; i++, m++)
665 btf_dump_emit_type(d, m->type, new_cont_id);
666 } else if (!tstate->fwd_emitted && id != cont_id) {
667 btf_dump_emit_struct_fwd(d, id, t);
668 btf_dump_printf(d, ";\n\n");
669 tstate->fwd_emitted = 1;
670 }
671
672 if (top_level_def) {
673 btf_dump_emit_struct_def(d, id, t, 0);
674 btf_dump_printf(d, ";\n\n");
675 tstate->emit_state = EMITTED;
676 } else {
677 tstate->emit_state = NOT_EMITTED;
678 }
679 break;
680 case BTF_KIND_FUNC_PROTO: {
681 const struct btf_param *p = (void *)(t + 1);
682 __u16 vlen = btf_vlen_of(t);
683 int i;
684
685 btf_dump_emit_type(d, t->type, cont_id);
686 for (i = 0; i < vlen; i++, p++)
687 btf_dump_emit_type(d, p->type, cont_id);
688
689 break;
690 }
691 default:
692 break;
693 }
694}
695
696static int btf_align_of(const struct btf *btf, __u32 id)
697{
698 const struct btf_type *t = btf__type_by_id(btf, id);
699 __u16 kind = btf_kind_of(t);
700
701 switch (kind) {
702 case BTF_KIND_INT:
703 case BTF_KIND_ENUM:
704 return min(sizeof(void *), t->size);
705 case BTF_KIND_PTR:
706 return sizeof(void *);
707 case BTF_KIND_TYPEDEF:
708 case BTF_KIND_VOLATILE:
709 case BTF_KIND_CONST:
710 case BTF_KIND_RESTRICT:
711 return btf_align_of(btf, t->type);
712 case BTF_KIND_ARRAY: {
713 const struct btf_array *a = (void *)(t + 1);
714
715 return btf_align_of(btf, a->type);
716 }
717 case BTF_KIND_STRUCT:
718 case BTF_KIND_UNION: {
719 const struct btf_member *m = (void *)(t + 1);
720 __u16 vlen = btf_vlen_of(t);
721 int i, align = 1;
722
723 for (i = 0; i < vlen; i++, m++)
724 align = max(align, btf_align_of(btf, m->type));
725
726 return align;
727 }
728 default:
729 pr_warning("unsupported BTF_KIND:%u\n", btf_kind_of(t));
730 return 1;
731 }
732}
733
734static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
735 const struct btf_type *t)
736{
737 const struct btf_member *m;
738 int align, i, bit_sz;
739 __u16 vlen;
740 bool kflag;
741
742 align = btf_align_of(btf, id);
743
744 if (t->size % align)
745 return true;
746
747 m = (void *)(t + 1);
748 kflag = btf_kflag_of(t);
749 vlen = btf_vlen_of(t);
750
751 for (i = 0; i < vlen; i++, m++) {
752 align = btf_align_of(btf, m->type);
753 bit_sz = kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0;
754 if (bit_sz == 0 && m->offset % (8 * align) != 0)
755 return true;
756 }
757
758
759
760
761
762 return false;
763}
764
765static int chip_away_bits(int total, int at_most)
766{
767 return total % at_most ? : at_most;
768}
769
770static void btf_dump_emit_bit_padding(const struct btf_dump *d,
771 int cur_off, int m_off, int m_bit_sz,
772 int align, int lvl)
773{
774 int off_diff = m_off - cur_off;
775 int ptr_bits = sizeof(void *) * 8;
776
777 if (off_diff <= 0)
778
779 return;
780 if (m_bit_sz == 0 && off_diff < align * 8)
781
782 return;
783
784 while (off_diff > 0) {
785 const char *pad_type;
786 int pad_bits;
787
788 if (ptr_bits > 32 && off_diff > 32) {
789 pad_type = "long";
790 pad_bits = chip_away_bits(off_diff, ptr_bits);
791 } else if (off_diff > 16) {
792 pad_type = "int";
793 pad_bits = chip_away_bits(off_diff, 32);
794 } else if (off_diff > 8) {
795 pad_type = "short";
796 pad_bits = chip_away_bits(off_diff, 16);
797 } else {
798 pad_type = "char";
799 pad_bits = chip_away_bits(off_diff, 8);
800 }
801 btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits);
802 off_diff -= pad_bits;
803 }
804}
805
806static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
807 const struct btf_type *t)
808{
809 btf_dump_printf(d, "%s %s",
810 btf_kind_of(t) == BTF_KIND_STRUCT ? "struct" : "union",
811 btf_dump_type_name(d, id));
812}
813
814static void btf_dump_emit_struct_def(struct btf_dump *d,
815 __u32 id,
816 const struct btf_type *t,
817 int lvl)
818{
819 const struct btf_member *m = (void *)(t + 1);
820 bool kflag = btf_kflag_of(t), is_struct;
821 int align, i, packed, off = 0;
822 __u16 vlen = btf_vlen_of(t);
823
824 is_struct = btf_kind_of(t) == BTF_KIND_STRUCT;
825 packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0;
826 align = packed ? 1 : btf_align_of(d->btf, id);
827
828 btf_dump_printf(d, "%s%s%s {",
829 is_struct ? "struct" : "union",
830 t->name_off ? " " : "",
831 btf_dump_type_name(d, id));
832
833 for (i = 0; i < vlen; i++, m++) {
834 const char *fname;
835 int m_off, m_sz;
836
837 fname = btf_name_of(d, m->name_off);
838 m_sz = kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0;
839 m_off = kflag ? BTF_MEMBER_BIT_OFFSET(m->offset) : m->offset;
840 align = packed ? 1 : btf_align_of(d->btf, m->type);
841
842 btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1);
843 btf_dump_printf(d, "\n%s", pfx(lvl + 1));
844 btf_dump_emit_type_decl(d, m->type, fname, lvl + 1);
845
846 if (m_sz) {
847 btf_dump_printf(d, ": %d", m_sz);
848 off = m_off + m_sz;
849 } else {
850 m_sz = max(0, btf__resolve_size(d->btf, m->type));
851 off = m_off + m_sz * 8;
852 }
853 btf_dump_printf(d, ";");
854 }
855
856 if (vlen)
857 btf_dump_printf(d, "\n");
858 btf_dump_printf(d, "%s}", pfx(lvl));
859 if (packed)
860 btf_dump_printf(d, " __attribute__((packed))");
861}
862
863static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
864 const struct btf_type *t)
865{
866 btf_dump_printf(d, "enum %s", btf_dump_type_name(d, id));
867}
868
869static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
870 const struct btf_type *t,
871 int lvl)
872{
873 const struct btf_enum *v = (void *)(t+1);
874 __u16 vlen = btf_vlen_of(t);
875 const char *name;
876 size_t dup_cnt;
877 int i;
878
879 btf_dump_printf(d, "enum%s%s",
880 t->name_off ? " " : "",
881 btf_dump_type_name(d, id));
882
883 if (vlen) {
884 btf_dump_printf(d, " {");
885 for (i = 0; i < vlen; i++, v++) {
886 name = btf_name_of(d, v->name_off);
887
888 dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
889 if (dup_cnt > 1) {
890 btf_dump_printf(d, "\n%s%s___%zu = %d,",
891 pfx(lvl + 1), name, dup_cnt,
892 (__s32)v->val);
893 } else {
894 btf_dump_printf(d, "\n%s%s = %d,",
895 pfx(lvl + 1), name,
896 (__s32)v->val);
897 }
898 }
899 btf_dump_printf(d, "\n%s}", pfx(lvl));
900 }
901}
902
903static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
904 const struct btf_type *t)
905{
906 const char *name = btf_dump_type_name(d, id);
907
908 if (btf_kflag_of(t))
909 btf_dump_printf(d, "union %s", name);
910 else
911 btf_dump_printf(d, "struct %s", name);
912}
913
914static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
915 const struct btf_type *t, int lvl)
916{
917 const char *name = btf_dump_ident_name(d, id);
918
919 btf_dump_printf(d, "typedef ");
920 btf_dump_emit_type_decl(d, t->type, name, lvl);
921}
922
923static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
924{
925 __u32 *new_stack;
926 size_t new_cap;
927
928 if (d->decl_stack_cnt >= d->decl_stack_cap) {
929 new_cap = max(16, d->decl_stack_cap * 3 / 2);
930 new_stack = realloc(d->decl_stack,
931 new_cap * sizeof(new_stack[0]));
932 if (!new_stack)
933 return -ENOMEM;
934 d->decl_stack = new_stack;
935 d->decl_stack_cap = new_cap;
936 }
937
938 d->decl_stack[d->decl_stack_cnt++] = id;
939
940 return 0;
941}
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
985 const char *fname, int lvl)
986{
987 struct id_stack decl_stack;
988 const struct btf_type *t;
989 int err, stack_start;
990 __u16 kind;
991
992 stack_start = d->decl_stack_cnt;
993 for (;;) {
994 err = btf_dump_push_decl_stack_id(d, id);
995 if (err < 0) {
996
997
998
999
1000
1001 pr_warning("not enough memory for decl stack:%d", err);
1002 d->decl_stack_cnt = stack_start;
1003 return;
1004 }
1005
1006
1007 if (id == 0)
1008 break;
1009
1010 t = btf__type_by_id(d->btf, id);
1011 kind = btf_kind_of(t);
1012 switch (kind) {
1013 case BTF_KIND_PTR:
1014 case BTF_KIND_VOLATILE:
1015 case BTF_KIND_CONST:
1016 case BTF_KIND_RESTRICT:
1017 case BTF_KIND_FUNC_PROTO:
1018 id = t->type;
1019 break;
1020 case BTF_KIND_ARRAY: {
1021 const struct btf_array *a = (void *)(t + 1);
1022
1023 id = a->type;
1024 break;
1025 }
1026 case BTF_KIND_INT:
1027 case BTF_KIND_ENUM:
1028 case BTF_KIND_FWD:
1029 case BTF_KIND_STRUCT:
1030 case BTF_KIND_UNION:
1031 case BTF_KIND_TYPEDEF:
1032 goto done;
1033 default:
1034 pr_warning("unexpected type in decl chain, kind:%u, id:[%u]\n",
1035 kind, id);
1036 goto done;
1037 }
1038 }
1039done:
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 decl_stack.ids = d->decl_stack + stack_start;
1051 decl_stack.cnt = d->decl_stack_cnt - stack_start;
1052 btf_dump_emit_type_chain(d, &decl_stack, fname, lvl);
1053
1054
1055
1056
1057
1058
1059
1060
1061 d->decl_stack_cnt = stack_start;
1062}
1063
1064static void btf_dump_emit_mods(struct btf_dump *d, struct id_stack *decl_stack)
1065{
1066 const struct btf_type *t;
1067 __u32 id;
1068
1069 while (decl_stack->cnt) {
1070 id = decl_stack->ids[decl_stack->cnt - 1];
1071 t = btf__type_by_id(d->btf, id);
1072
1073 switch (btf_kind_of(t)) {
1074 case BTF_KIND_VOLATILE:
1075 btf_dump_printf(d, "volatile ");
1076 break;
1077 case BTF_KIND_CONST:
1078 btf_dump_printf(d, "const ");
1079 break;
1080 case BTF_KIND_RESTRICT:
1081 btf_dump_printf(d, "restrict ");
1082 break;
1083 default:
1084 return;
1085 }
1086 decl_stack->cnt--;
1087 }
1088}
1089
1090static bool btf_is_mod_kind(const struct btf *btf, __u32 id)
1091{
1092 const struct btf_type *t = btf__type_by_id(btf, id);
1093
1094 switch (btf_kind_of(t)) {
1095 case BTF_KIND_VOLATILE:
1096 case BTF_KIND_CONST:
1097 case BTF_KIND_RESTRICT:
1098 return true;
1099 default:
1100 return false;
1101 }
1102}
1103
1104static void btf_dump_emit_name(const struct btf_dump *d,
1105 const char *name, bool last_was_ptr)
1106{
1107 bool separate = name[0] && !last_was_ptr;
1108
1109 btf_dump_printf(d, "%s%s", separate ? " " : "", name);
1110}
1111
1112static void btf_dump_emit_type_chain(struct btf_dump *d,
1113 struct id_stack *decls,
1114 const char *fname, int lvl)
1115{
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125 bool last_was_ptr = true;
1126 const struct btf_type *t;
1127 const char *name;
1128 __u16 kind;
1129 __u32 id;
1130
1131 while (decls->cnt) {
1132 id = decls->ids[--decls->cnt];
1133 if (id == 0) {
1134
1135 btf_dump_emit_mods(d, decls);
1136 btf_dump_printf(d, "void");
1137 last_was_ptr = false;
1138 continue;
1139 }
1140
1141 t = btf__type_by_id(d->btf, id);
1142 kind = btf_kind_of(t);
1143
1144 switch (kind) {
1145 case BTF_KIND_INT:
1146 btf_dump_emit_mods(d, decls);
1147 name = btf_name_of(d, t->name_off);
1148 btf_dump_printf(d, "%s", name);
1149 break;
1150 case BTF_KIND_STRUCT:
1151 case BTF_KIND_UNION:
1152 btf_dump_emit_mods(d, decls);
1153
1154 if (t->name_off == 0)
1155 btf_dump_emit_struct_def(d, id, t, lvl);
1156 else
1157 btf_dump_emit_struct_fwd(d, id, t);
1158 break;
1159 case BTF_KIND_ENUM:
1160 btf_dump_emit_mods(d, decls);
1161
1162 if (t->name_off == 0)
1163 btf_dump_emit_enum_def(d, id, t, lvl);
1164 else
1165 btf_dump_emit_enum_fwd(d, id, t);
1166 break;
1167 case BTF_KIND_FWD:
1168 btf_dump_emit_mods(d, decls);
1169 btf_dump_emit_fwd_def(d, id, t);
1170 break;
1171 case BTF_KIND_TYPEDEF:
1172 btf_dump_emit_mods(d, decls);
1173 btf_dump_printf(d, "%s", btf_dump_ident_name(d, id));
1174 break;
1175 case BTF_KIND_PTR:
1176 btf_dump_printf(d, "%s", last_was_ptr ? "*" : " *");
1177 break;
1178 case BTF_KIND_VOLATILE:
1179 btf_dump_printf(d, " volatile");
1180 break;
1181 case BTF_KIND_CONST:
1182 btf_dump_printf(d, " const");
1183 break;
1184 case BTF_KIND_RESTRICT:
1185 btf_dump_printf(d, " restrict");
1186 break;
1187 case BTF_KIND_ARRAY: {
1188 const struct btf_array *a = (void *)(t + 1);
1189 const struct btf_type *next_t;
1190 __u32 next_id;
1191 bool multidim;
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202 while (decls->cnt) {
1203 next_id = decls->ids[decls->cnt - 1];
1204 if (btf_is_mod_kind(d->btf, next_id))
1205 decls->cnt--;
1206 else
1207 break;
1208 }
1209
1210 if (decls->cnt == 0) {
1211 btf_dump_emit_name(d, fname, last_was_ptr);
1212 btf_dump_printf(d, "[%u]", a->nelems);
1213 return;
1214 }
1215
1216 next_t = btf__type_by_id(d->btf, next_id);
1217 multidim = btf_kind_of(next_t) == BTF_KIND_ARRAY;
1218
1219 if (fname[0] && !last_was_ptr)
1220 btf_dump_printf(d, " ");
1221
1222 if (!multidim)
1223 btf_dump_printf(d, "(");
1224 btf_dump_emit_type_chain(d, decls, fname, lvl);
1225 if (!multidim)
1226 btf_dump_printf(d, ")");
1227 btf_dump_printf(d, "[%u]", a->nelems);
1228 return;
1229 }
1230 case BTF_KIND_FUNC_PROTO: {
1231 const struct btf_param *p = (void *)(t + 1);
1232 __u16 vlen = btf_vlen_of(t);
1233 int i;
1234
1235 btf_dump_emit_mods(d, decls);
1236 if (decls->cnt) {
1237 btf_dump_printf(d, " (");
1238 btf_dump_emit_type_chain(d, decls, fname, lvl);
1239 btf_dump_printf(d, ")");
1240 } else {
1241 btf_dump_emit_name(d, fname, last_was_ptr);
1242 }
1243 btf_dump_printf(d, "(");
1244
1245
1246
1247
1248
1249
1250 if (vlen == 1 && p->type == 0) {
1251 btf_dump_printf(d, ")");
1252 return;
1253 }
1254
1255 for (i = 0; i < vlen; i++, p++) {
1256 if (i > 0)
1257 btf_dump_printf(d, ", ");
1258
1259
1260 if (i == vlen - 1 && p->type == 0) {
1261 btf_dump_printf(d, "...");
1262 break;
1263 }
1264
1265 name = btf_name_of(d, p->name_off);
1266 btf_dump_emit_type_decl(d, p->type, name, lvl);
1267 }
1268
1269 btf_dump_printf(d, ")");
1270 return;
1271 }
1272 default:
1273 pr_warning("unexpected type in decl chain, kind:%u, id:[%u]\n",
1274 kind, id);
1275 return;
1276 }
1277
1278 last_was_ptr = kind == BTF_KIND_PTR;
1279 }
1280
1281 btf_dump_emit_name(d, fname, last_was_ptr);
1282}
1283
1284
1285static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
1286 const char *orig_name)
1287{
1288 size_t dup_cnt = 0;
1289
1290 hashmap__find(name_map, orig_name, (void **)&dup_cnt);
1291 dup_cnt++;
1292 hashmap__set(name_map, orig_name, (void *)dup_cnt, NULL, NULL);
1293
1294 return dup_cnt;
1295}
1296
1297static const char *btf_dump_resolve_name(struct btf_dump *d, __u32 id,
1298 struct hashmap *name_map)
1299{
1300 struct btf_dump_type_aux_state *s = &d->type_states[id];
1301 const struct btf_type *t = btf__type_by_id(d->btf, id);
1302 const char *orig_name = btf_name_of(d, t->name_off);
1303 const char **cached_name = &d->cached_names[id];
1304 size_t dup_cnt;
1305
1306 if (t->name_off == 0)
1307 return "";
1308
1309 if (s->name_resolved)
1310 return *cached_name ? *cached_name : orig_name;
1311
1312 dup_cnt = btf_dump_name_dups(d, name_map, orig_name);
1313 if (dup_cnt > 1) {
1314 const size_t max_len = 256;
1315 char new_name[max_len];
1316
1317 snprintf(new_name, max_len, "%s___%zu", orig_name, dup_cnt);
1318 *cached_name = strdup(new_name);
1319 }
1320
1321 s->name_resolved = 1;
1322 return *cached_name ? *cached_name : orig_name;
1323}
1324
1325static const char *btf_dump_type_name(struct btf_dump *d, __u32 id)
1326{
1327 return btf_dump_resolve_name(d, id, d->type_names);
1328}
1329
1330static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id)
1331{
1332 return btf_dump_resolve_name(d, id, d->ident_names);
1333}
1334