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