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