0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <stdbool.h>
0010 #include <stddef.h>
0011 #include <stdlib.h>
0012 #include <string.h>
0013 #include <ctype.h>
0014 #include <endian.h>
0015 #include <errno.h>
0016 #include <linux/err.h>
0017 #include <linux/btf.h>
0018 #include <linux/kernel.h>
0019 #include "btf.h"
0020 #include "hashmap.h"
0021 #include "libbpf.h"
0022 #include "libbpf_internal.h"
0023
0024 static const char PREFIXES[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
0025 static const size_t PREFIX_CNT = sizeof(PREFIXES) - 1;
0026
0027 static const char *pfx(int lvl)
0028 {
0029 return lvl >= PREFIX_CNT ? PREFIXES : &PREFIXES[PREFIX_CNT - lvl];
0030 }
0031
0032 enum btf_dump_type_order_state {
0033 NOT_ORDERED,
0034 ORDERING,
0035 ORDERED,
0036 };
0037
0038 enum btf_dump_type_emit_state {
0039 NOT_EMITTED,
0040 EMITTING,
0041 EMITTED,
0042 };
0043
0044
0045 struct btf_dump_type_aux_state {
0046
0047 enum btf_dump_type_order_state order_state: 2;
0048
0049 enum btf_dump_type_emit_state emit_state: 2;
0050
0051 __u8 fwd_emitted: 1;
0052
0053 __u8 name_resolved: 1;
0054
0055 __u8 referenced: 1;
0056 };
0057
0058
0059 #define BTF_DATA_INDENT_STR_LEN 32
0060
0061
0062
0063
0064 struct btf_dump_data {
0065 const void *data_end;
0066 bool compact;
0067 bool skip_names;
0068 bool emit_zeroes;
0069 __u8 indent_lvl;
0070 char indent_str[BTF_DATA_INDENT_STR_LEN];
0071
0072 int depth;
0073 bool is_array_member;
0074 bool is_array_terminated;
0075 bool is_array_char;
0076 };
0077
0078 struct btf_dump {
0079 const struct btf *btf;
0080 btf_dump_printf_fn_t printf_fn;
0081 void *cb_ctx;
0082 int ptr_sz;
0083 bool strip_mods;
0084 bool skip_anon_defs;
0085 int last_id;
0086
0087
0088 struct btf_dump_type_aux_state *type_states;
0089 size_t type_states_cap;
0090
0091 const char **cached_names;
0092 size_t cached_names_cap;
0093
0094
0095 __u32 *emit_queue;
0096 int emit_queue_cap;
0097 int emit_queue_cnt;
0098
0099
0100
0101
0102
0103 __u32 *decl_stack;
0104 int decl_stack_cap;
0105 int decl_stack_cnt;
0106
0107
0108 struct hashmap *type_names;
0109
0110
0111
0112
0113 struct hashmap *ident_names;
0114
0115
0116
0117 struct btf_dump_data *typed_dump;
0118 };
0119
0120 static size_t str_hash_fn(const void *key, void *ctx)
0121 {
0122 return str_hash(key);
0123 }
0124
0125 static bool str_equal_fn(const void *a, const void *b, void *ctx)
0126 {
0127 return strcmp(a, b) == 0;
0128 }
0129
0130 static const char *btf_name_of(const struct btf_dump *d, __u32 name_off)
0131 {
0132 return btf__name_by_offset(d->btf, name_off);
0133 }
0134
0135 static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
0136 {
0137 va_list args;
0138
0139 va_start(args, fmt);
0140 d->printf_fn(d->cb_ctx, fmt, args);
0141 va_end(args);
0142 }
0143
0144 static int btf_dump_mark_referenced(struct btf_dump *d);
0145 static int btf_dump_resize(struct btf_dump *d);
0146
0147 struct btf_dump *btf_dump__new(const struct btf *btf,
0148 btf_dump_printf_fn_t printf_fn,
0149 void *ctx,
0150 const struct btf_dump_opts *opts)
0151 {
0152 struct btf_dump *d;
0153 int err;
0154
0155 if (!OPTS_VALID(opts, btf_dump_opts))
0156 return libbpf_err_ptr(-EINVAL);
0157
0158 if (!printf_fn)
0159 return libbpf_err_ptr(-EINVAL);
0160
0161 d = calloc(1, sizeof(struct btf_dump));
0162 if (!d)
0163 return libbpf_err_ptr(-ENOMEM);
0164
0165 d->btf = btf;
0166 d->printf_fn = printf_fn;
0167 d->cb_ctx = ctx;
0168 d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *);
0169
0170 d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
0171 if (IS_ERR(d->type_names)) {
0172 err = PTR_ERR(d->type_names);
0173 d->type_names = NULL;
0174 goto err;
0175 }
0176 d->ident_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
0177 if (IS_ERR(d->ident_names)) {
0178 err = PTR_ERR(d->ident_names);
0179 d->ident_names = NULL;
0180 goto err;
0181 }
0182
0183 err = btf_dump_resize(d);
0184 if (err)
0185 goto err;
0186
0187 return d;
0188 err:
0189 btf_dump__free(d);
0190 return libbpf_err_ptr(err);
0191 }
0192
0193 static int btf_dump_resize(struct btf_dump *d)
0194 {
0195 int err, last_id = btf__type_cnt(d->btf) - 1;
0196
0197 if (last_id <= d->last_id)
0198 return 0;
0199
0200 if (libbpf_ensure_mem((void **)&d->type_states, &d->type_states_cap,
0201 sizeof(*d->type_states), last_id + 1))
0202 return -ENOMEM;
0203 if (libbpf_ensure_mem((void **)&d->cached_names, &d->cached_names_cap,
0204 sizeof(*d->cached_names), last_id + 1))
0205 return -ENOMEM;
0206
0207 if (d->last_id == 0) {
0208
0209 d->type_states[0].order_state = ORDERED;
0210 d->type_states[0].emit_state = EMITTED;
0211 }
0212
0213
0214 err = btf_dump_mark_referenced(d);
0215 if (err)
0216 return err;
0217
0218 d->last_id = last_id;
0219 return 0;
0220 }
0221
0222 void btf_dump__free(struct btf_dump *d)
0223 {
0224 int i;
0225
0226 if (IS_ERR_OR_NULL(d))
0227 return;
0228
0229 free(d->type_states);
0230 if (d->cached_names) {
0231
0232 for (i = 0; i <= d->last_id; i++) {
0233 if (d->cached_names[i])
0234 free((void *)d->cached_names[i]);
0235 }
0236 }
0237 free(d->cached_names);
0238 free(d->emit_queue);
0239 free(d->decl_stack);
0240 hashmap__free(d->type_names);
0241 hashmap__free(d->ident_names);
0242
0243 free(d);
0244 }
0245
0246 static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr);
0247 static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id);
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 int btf_dump__dump_type(struct btf_dump *d, __u32 id)
0266 {
0267 int err, i;
0268
0269 if (id >= btf__type_cnt(d->btf))
0270 return libbpf_err(-EINVAL);
0271
0272 err = btf_dump_resize(d);
0273 if (err)
0274 return libbpf_err(err);
0275
0276 d->emit_queue_cnt = 0;
0277 err = btf_dump_order_type(d, id, false);
0278 if (err < 0)
0279 return libbpf_err(err);
0280
0281 for (i = 0; i < d->emit_queue_cnt; i++)
0282 btf_dump_emit_type(d, d->emit_queue[i], 0 );
0283
0284 return 0;
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 static int btf_dump_mark_referenced(struct btf_dump *d)
0300 {
0301 int i, j, n = btf__type_cnt(d->btf);
0302 const struct btf_type *t;
0303 __u16 vlen;
0304
0305 for (i = d->last_id + 1; i < n; i++) {
0306 t = btf__type_by_id(d->btf, i);
0307 vlen = btf_vlen(t);
0308
0309 switch (btf_kind(t)) {
0310 case BTF_KIND_INT:
0311 case BTF_KIND_ENUM:
0312 case BTF_KIND_ENUM64:
0313 case BTF_KIND_FWD:
0314 case BTF_KIND_FLOAT:
0315 break;
0316
0317 case BTF_KIND_VOLATILE:
0318 case BTF_KIND_CONST:
0319 case BTF_KIND_RESTRICT:
0320 case BTF_KIND_PTR:
0321 case BTF_KIND_TYPEDEF:
0322 case BTF_KIND_FUNC:
0323 case BTF_KIND_VAR:
0324 case BTF_KIND_DECL_TAG:
0325 case BTF_KIND_TYPE_TAG:
0326 d->type_states[t->type].referenced = 1;
0327 break;
0328
0329 case BTF_KIND_ARRAY: {
0330 const struct btf_array *a = btf_array(t);
0331
0332 d->type_states[a->index_type].referenced = 1;
0333 d->type_states[a->type].referenced = 1;
0334 break;
0335 }
0336 case BTF_KIND_STRUCT:
0337 case BTF_KIND_UNION: {
0338 const struct btf_member *m = btf_members(t);
0339
0340 for (j = 0; j < vlen; j++, m++)
0341 d->type_states[m->type].referenced = 1;
0342 break;
0343 }
0344 case BTF_KIND_FUNC_PROTO: {
0345 const struct btf_param *p = btf_params(t);
0346
0347 for (j = 0; j < vlen; j++, p++)
0348 d->type_states[p->type].referenced = 1;
0349 break;
0350 }
0351 case BTF_KIND_DATASEC: {
0352 const struct btf_var_secinfo *v = btf_var_secinfos(t);
0353
0354 for (j = 0; j < vlen; j++, v++)
0355 d->type_states[v->type].referenced = 1;
0356 break;
0357 }
0358 default:
0359 return -EINVAL;
0360 }
0361 }
0362 return 0;
0363 }
0364
0365 static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
0366 {
0367 __u32 *new_queue;
0368 size_t new_cap;
0369
0370 if (d->emit_queue_cnt >= d->emit_queue_cap) {
0371 new_cap = max(16, d->emit_queue_cap * 3 / 2);
0372 new_queue = libbpf_reallocarray(d->emit_queue, new_cap, sizeof(new_queue[0]));
0373 if (!new_queue)
0374 return -ENOMEM;
0375 d->emit_queue = new_queue;
0376 d->emit_queue_cap = new_cap;
0377 }
0378
0379 d->emit_queue[d->emit_queue_cnt++] = id;
0380 return 0;
0381 }
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457 static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
0458 {
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
0471 const struct btf_type *t;
0472 __u16 vlen;
0473 int err, i;
0474
0475
0476 if (tstate->order_state == ORDERED)
0477 return 1;
0478
0479 t = btf__type_by_id(d->btf, id);
0480
0481 if (tstate->order_state == ORDERING) {
0482
0483 if (btf_is_composite(t) && through_ptr && t->name_off != 0)
0484 return 0;
0485 pr_warn("unsatisfiable type cycle, id:[%u]\n", id);
0486 return -ELOOP;
0487 }
0488
0489 switch (btf_kind(t)) {
0490 case BTF_KIND_INT:
0491 case BTF_KIND_FLOAT:
0492 tstate->order_state = ORDERED;
0493 return 0;
0494
0495 case BTF_KIND_PTR:
0496 err = btf_dump_order_type(d, t->type, true);
0497 tstate->order_state = ORDERED;
0498 return err;
0499
0500 case BTF_KIND_ARRAY:
0501 return btf_dump_order_type(d, btf_array(t)->type, false);
0502
0503 case BTF_KIND_STRUCT:
0504 case BTF_KIND_UNION: {
0505 const struct btf_member *m = btf_members(t);
0506
0507
0508
0509
0510
0511 if (through_ptr && t->name_off != 0)
0512 return 0;
0513
0514 tstate->order_state = ORDERING;
0515
0516 vlen = btf_vlen(t);
0517 for (i = 0; i < vlen; i++, m++) {
0518 err = btf_dump_order_type(d, m->type, false);
0519 if (err < 0)
0520 return err;
0521 }
0522
0523 if (t->name_off != 0) {
0524 err = btf_dump_add_emit_queue_id(d, id);
0525 if (err < 0)
0526 return err;
0527 }
0528
0529 tstate->order_state = ORDERED;
0530 return 1;
0531 }
0532 case BTF_KIND_ENUM:
0533 case BTF_KIND_ENUM64:
0534 case BTF_KIND_FWD:
0535
0536
0537
0538
0539
0540 if (t->name_off != 0 || !tstate->referenced) {
0541 err = btf_dump_add_emit_queue_id(d, id);
0542 if (err)
0543 return err;
0544 }
0545 tstate->order_state = ORDERED;
0546 return 1;
0547
0548 case BTF_KIND_TYPEDEF: {
0549 int is_strong;
0550
0551 is_strong = btf_dump_order_type(d, t->type, through_ptr);
0552 if (is_strong < 0)
0553 return is_strong;
0554
0555
0556 if (through_ptr && !is_strong)
0557 return 0;
0558
0559
0560 err = btf_dump_add_emit_queue_id(d, id);
0561 if (err)
0562 return err;
0563
0564 d->type_states[id].order_state = ORDERED;
0565 return 1;
0566 }
0567 case BTF_KIND_VOLATILE:
0568 case BTF_KIND_CONST:
0569 case BTF_KIND_RESTRICT:
0570 case BTF_KIND_TYPE_TAG:
0571 return btf_dump_order_type(d, t->type, through_ptr);
0572
0573 case BTF_KIND_FUNC_PROTO: {
0574 const struct btf_param *p = btf_params(t);
0575 bool is_strong;
0576
0577 err = btf_dump_order_type(d, t->type, through_ptr);
0578 if (err < 0)
0579 return err;
0580 is_strong = err > 0;
0581
0582 vlen = btf_vlen(t);
0583 for (i = 0; i < vlen; i++, p++) {
0584 err = btf_dump_order_type(d, p->type, through_ptr);
0585 if (err < 0)
0586 return err;
0587 if (err > 0)
0588 is_strong = true;
0589 }
0590 return is_strong;
0591 }
0592 case BTF_KIND_FUNC:
0593 case BTF_KIND_VAR:
0594 case BTF_KIND_DATASEC:
0595 case BTF_KIND_DECL_TAG:
0596 d->type_states[id].order_state = ORDERED;
0597 return 0;
0598
0599 default:
0600 return -EINVAL;
0601 }
0602 }
0603
0604 static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
0605 const struct btf_type *t);
0606
0607 static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
0608 const struct btf_type *t);
0609 static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
0610 const struct btf_type *t, int lvl);
0611
0612 static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
0613 const struct btf_type *t);
0614 static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
0615 const struct btf_type *t, int lvl);
0616
0617 static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
0618 const struct btf_type *t);
0619
0620 static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
0621 const struct btf_type *t, int lvl);
0622
0623
0624 struct id_stack {
0625 const __u32 *ids;
0626 int cnt;
0627 };
0628
0629 static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
0630 const char *fname, int lvl);
0631 static void btf_dump_emit_type_chain(struct btf_dump *d,
0632 struct id_stack *decl_stack,
0633 const char *fname, int lvl);
0634
0635 static const char *btf_dump_type_name(struct btf_dump *d, __u32 id);
0636 static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id);
0637 static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
0638 const char *orig_name);
0639
0640 static bool btf_dump_is_blacklisted(struct btf_dump *d, __u32 id)
0641 {
0642 const struct btf_type *t = btf__type_by_id(d->btf, id);
0643
0644
0645
0646
0647
0648
0649
0650 if (t->name_off == 0)
0651 return false;
0652 return strcmp(btf_name_of(d, t->name_off), "__builtin_va_list") == 0;
0653 }
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673 static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
0674 {
0675 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
0676 bool top_level_def = cont_id == 0;
0677 const struct btf_type *t;
0678 __u16 kind;
0679
0680 if (tstate->emit_state == EMITTED)
0681 return;
0682
0683 t = btf__type_by_id(d->btf, id);
0684 kind = btf_kind(t);
0685
0686 if (tstate->emit_state == EMITTING) {
0687 if (tstate->fwd_emitted)
0688 return;
0689
0690 switch (kind) {
0691 case BTF_KIND_STRUCT:
0692 case BTF_KIND_UNION:
0693
0694
0695
0696
0697 if (id == cont_id)
0698 return;
0699 if (t->name_off == 0) {
0700 pr_warn("anonymous struct/union loop, id:[%u]\n",
0701 id);
0702 return;
0703 }
0704 btf_dump_emit_struct_fwd(d, id, t);
0705 btf_dump_printf(d, ";\n\n");
0706 tstate->fwd_emitted = 1;
0707 break;
0708 case BTF_KIND_TYPEDEF:
0709
0710
0711
0712
0713
0714 if (!btf_dump_is_blacklisted(d, id)) {
0715 btf_dump_emit_typedef_def(d, id, t, 0);
0716 btf_dump_printf(d, ";\n\n");
0717 }
0718 tstate->fwd_emitted = 1;
0719 break;
0720 default:
0721 break;
0722 }
0723
0724 return;
0725 }
0726
0727 switch (kind) {
0728 case BTF_KIND_INT:
0729
0730 btf_dump_emit_missing_aliases(d, id, t);
0731
0732 tstate->emit_state = EMITTED;
0733 break;
0734 case BTF_KIND_ENUM:
0735 case BTF_KIND_ENUM64:
0736 if (top_level_def) {
0737 btf_dump_emit_enum_def(d, id, t, 0);
0738 btf_dump_printf(d, ";\n\n");
0739 }
0740 tstate->emit_state = EMITTED;
0741 break;
0742 case BTF_KIND_PTR:
0743 case BTF_KIND_VOLATILE:
0744 case BTF_KIND_CONST:
0745 case BTF_KIND_RESTRICT:
0746 case BTF_KIND_TYPE_TAG:
0747 btf_dump_emit_type(d, t->type, cont_id);
0748 break;
0749 case BTF_KIND_ARRAY:
0750 btf_dump_emit_type(d, btf_array(t)->type, cont_id);
0751 break;
0752 case BTF_KIND_FWD:
0753 btf_dump_emit_fwd_def(d, id, t);
0754 btf_dump_printf(d, ";\n\n");
0755 tstate->emit_state = EMITTED;
0756 break;
0757 case BTF_KIND_TYPEDEF:
0758 tstate->emit_state = EMITTING;
0759 btf_dump_emit_type(d, t->type, id);
0760
0761
0762
0763
0764
0765
0766
0767 if (!tstate->fwd_emitted && !btf_dump_is_blacklisted(d, id)) {
0768 btf_dump_emit_typedef_def(d, id, t, 0);
0769 btf_dump_printf(d, ";\n\n");
0770 }
0771 tstate->emit_state = EMITTED;
0772 break;
0773 case BTF_KIND_STRUCT:
0774 case BTF_KIND_UNION:
0775 tstate->emit_state = EMITTING;
0776
0777
0778
0779
0780
0781
0782
0783 if (top_level_def || t->name_off == 0) {
0784 const struct btf_member *m = btf_members(t);
0785 __u16 vlen = btf_vlen(t);
0786 int i, new_cont_id;
0787
0788 new_cont_id = t->name_off == 0 ? cont_id : id;
0789 for (i = 0; i < vlen; i++, m++)
0790 btf_dump_emit_type(d, m->type, new_cont_id);
0791 } else if (!tstate->fwd_emitted && id != cont_id) {
0792 btf_dump_emit_struct_fwd(d, id, t);
0793 btf_dump_printf(d, ";\n\n");
0794 tstate->fwd_emitted = 1;
0795 }
0796
0797 if (top_level_def) {
0798 btf_dump_emit_struct_def(d, id, t, 0);
0799 btf_dump_printf(d, ";\n\n");
0800 tstate->emit_state = EMITTED;
0801 } else {
0802 tstate->emit_state = NOT_EMITTED;
0803 }
0804 break;
0805 case BTF_KIND_FUNC_PROTO: {
0806 const struct btf_param *p = btf_params(t);
0807 __u16 n = btf_vlen(t);
0808 int i;
0809
0810 btf_dump_emit_type(d, t->type, cont_id);
0811 for (i = 0; i < n; i++, p++)
0812 btf_dump_emit_type(d, p->type, cont_id);
0813
0814 break;
0815 }
0816 default:
0817 break;
0818 }
0819 }
0820
0821 static bool btf_is_struct_packed(const struct btf *btf, __u32 id,
0822 const struct btf_type *t)
0823 {
0824 const struct btf_member *m;
0825 int align, i, bit_sz;
0826 __u16 vlen;
0827
0828 align = btf__align_of(btf, id);
0829
0830 if (align && t->size % align)
0831 return true;
0832
0833 m = btf_members(t);
0834 vlen = btf_vlen(t);
0835
0836 for (i = 0; i < vlen; i++, m++) {
0837 align = btf__align_of(btf, m->type);
0838 bit_sz = btf_member_bitfield_size(t, i);
0839 if (align && bit_sz == 0 && m->offset % (8 * align) != 0)
0840 return true;
0841 }
0842
0843
0844
0845
0846
0847 return false;
0848 }
0849
0850 static int chip_away_bits(int total, int at_most)
0851 {
0852 return total % at_most ? : at_most;
0853 }
0854
0855 static void btf_dump_emit_bit_padding(const struct btf_dump *d,
0856 int cur_off, int m_off, int m_bit_sz,
0857 int align, int lvl)
0858 {
0859 int off_diff = m_off - cur_off;
0860 int ptr_bits = d->ptr_sz * 8;
0861
0862 if (off_diff <= 0)
0863
0864 return;
0865 if (m_bit_sz == 0 && off_diff < align * 8)
0866
0867 return;
0868
0869 while (off_diff > 0) {
0870 const char *pad_type;
0871 int pad_bits;
0872
0873 if (ptr_bits > 32 && off_diff > 32) {
0874 pad_type = "long";
0875 pad_bits = chip_away_bits(off_diff, ptr_bits);
0876 } else if (off_diff > 16) {
0877 pad_type = "int";
0878 pad_bits = chip_away_bits(off_diff, 32);
0879 } else if (off_diff > 8) {
0880 pad_type = "short";
0881 pad_bits = chip_away_bits(off_diff, 16);
0882 } else {
0883 pad_type = "char";
0884 pad_bits = chip_away_bits(off_diff, 8);
0885 }
0886 btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits);
0887 off_diff -= pad_bits;
0888 }
0889 }
0890
0891 static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
0892 const struct btf_type *t)
0893 {
0894 btf_dump_printf(d, "%s%s%s",
0895 btf_is_struct(t) ? "struct" : "union",
0896 t->name_off ? " " : "",
0897 btf_dump_type_name(d, id));
0898 }
0899
0900 static void btf_dump_emit_struct_def(struct btf_dump *d,
0901 __u32 id,
0902 const struct btf_type *t,
0903 int lvl)
0904 {
0905 const struct btf_member *m = btf_members(t);
0906 bool is_struct = btf_is_struct(t);
0907 int align, i, packed, off = 0;
0908 __u16 vlen = btf_vlen(t);
0909
0910 packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0;
0911
0912 btf_dump_printf(d, "%s%s%s {",
0913 is_struct ? "struct" : "union",
0914 t->name_off ? " " : "",
0915 btf_dump_type_name(d, id));
0916
0917 for (i = 0; i < vlen; i++, m++) {
0918 const char *fname;
0919 int m_off, m_sz;
0920
0921 fname = btf_name_of(d, m->name_off);
0922 m_sz = btf_member_bitfield_size(t, i);
0923 m_off = btf_member_bit_offset(t, i);
0924 align = packed ? 1 : btf__align_of(d->btf, m->type);
0925
0926 btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1);
0927 btf_dump_printf(d, "\n%s", pfx(lvl + 1));
0928 btf_dump_emit_type_decl(d, m->type, fname, lvl + 1);
0929
0930 if (m_sz) {
0931 btf_dump_printf(d, ": %d", m_sz);
0932 off = m_off + m_sz;
0933 } else {
0934 m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));
0935 off = m_off + m_sz * 8;
0936 }
0937 btf_dump_printf(d, ";");
0938 }
0939
0940
0941 if (is_struct) {
0942 align = packed ? 1 : btf__align_of(d->btf, id);
0943 btf_dump_emit_bit_padding(d, off, t->size * 8, 0, align,
0944 lvl + 1);
0945 }
0946
0947 if (vlen)
0948 btf_dump_printf(d, "\n");
0949 btf_dump_printf(d, "%s}", pfx(lvl));
0950 if (packed)
0951 btf_dump_printf(d, " __attribute__((packed))");
0952 }
0953
0954 static const char *missing_base_types[][2] = {
0955
0956
0957
0958
0959 { "__Poly8_t", "unsigned char" },
0960 { "__Poly16_t", "unsigned short" },
0961 { "__Poly64_t", "unsigned long long" },
0962 { "__Poly128_t", "unsigned __int128" },
0963 };
0964
0965 static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
0966 const struct btf_type *t)
0967 {
0968 const char *name = btf_dump_type_name(d, id);
0969 int i;
0970
0971 for (i = 0; i < ARRAY_SIZE(missing_base_types); i++) {
0972 if (strcmp(name, missing_base_types[i][0]) == 0) {
0973 btf_dump_printf(d, "typedef %s %s;\n\n",
0974 missing_base_types[i][1], name);
0975 break;
0976 }
0977 }
0978 }
0979
0980 static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
0981 const struct btf_type *t)
0982 {
0983 btf_dump_printf(d, "enum %s", btf_dump_type_name(d, id));
0984 }
0985
0986 static void btf_dump_emit_enum32_val(struct btf_dump *d,
0987 const struct btf_type *t,
0988 int lvl, __u16 vlen)
0989 {
0990 const struct btf_enum *v = btf_enum(t);
0991 bool is_signed = btf_kflag(t);
0992 const char *fmt_str;
0993 const char *name;
0994 size_t dup_cnt;
0995 int i;
0996
0997 for (i = 0; i < vlen; i++, v++) {
0998 name = btf_name_of(d, v->name_off);
0999
1000 dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
1001 if (dup_cnt > 1) {
1002 fmt_str = is_signed ? "\n%s%s___%zd = %d," : "\n%s%s___%zd = %u,";
1003 btf_dump_printf(d, fmt_str, pfx(lvl + 1), name, dup_cnt, v->val);
1004 } else {
1005 fmt_str = is_signed ? "\n%s%s = %d," : "\n%s%s = %u,";
1006 btf_dump_printf(d, fmt_str, pfx(lvl + 1), name, v->val);
1007 }
1008 }
1009 }
1010
1011 static void btf_dump_emit_enum64_val(struct btf_dump *d,
1012 const struct btf_type *t,
1013 int lvl, __u16 vlen)
1014 {
1015 const struct btf_enum64 *v = btf_enum64(t);
1016 bool is_signed = btf_kflag(t);
1017 const char *fmt_str;
1018 const char *name;
1019 size_t dup_cnt;
1020 __u64 val;
1021 int i;
1022
1023 for (i = 0; i < vlen; i++, v++) {
1024 name = btf_name_of(d, v->name_off);
1025 dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
1026 val = btf_enum64_value(v);
1027 if (dup_cnt > 1) {
1028 fmt_str = is_signed ? "\n%s%s___%zd = %lldLL,"
1029 : "\n%s%s___%zd = %lluULL,";
1030 btf_dump_printf(d, fmt_str,
1031 pfx(lvl + 1), name, dup_cnt,
1032 (unsigned long long)val);
1033 } else {
1034 fmt_str = is_signed ? "\n%s%s = %lldLL,"
1035 : "\n%s%s = %lluULL,";
1036 btf_dump_printf(d, fmt_str,
1037 pfx(lvl + 1), name,
1038 (unsigned long long)val);
1039 }
1040 }
1041 }
1042 static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
1043 const struct btf_type *t,
1044 int lvl)
1045 {
1046 __u16 vlen = btf_vlen(t);
1047
1048 btf_dump_printf(d, "enum%s%s",
1049 t->name_off ? " " : "",
1050 btf_dump_type_name(d, id));
1051
1052 if (!vlen)
1053 return;
1054
1055 btf_dump_printf(d, " {");
1056 if (btf_is_enum(t))
1057 btf_dump_emit_enum32_val(d, t, lvl, vlen);
1058 else
1059 btf_dump_emit_enum64_val(d, t, lvl, vlen);
1060 btf_dump_printf(d, "\n%s}", pfx(lvl));
1061 }
1062
1063 static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
1064 const struct btf_type *t)
1065 {
1066 const char *name = btf_dump_type_name(d, id);
1067
1068 if (btf_kflag(t))
1069 btf_dump_printf(d, "union %s", name);
1070 else
1071 btf_dump_printf(d, "struct %s", name);
1072 }
1073
1074 static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
1075 const struct btf_type *t, int lvl)
1076 {
1077 const char *name = btf_dump_ident_name(d, id);
1078
1079
1080
1081
1082
1083
1084
1085 if (t->type == 0 && strcmp(name, "__gnuc_va_list") == 0) {
1086 btf_dump_printf(d, "typedef __builtin_va_list __gnuc_va_list");
1087 return;
1088 }
1089
1090 btf_dump_printf(d, "typedef ");
1091 btf_dump_emit_type_decl(d, t->type, name, lvl);
1092 }
1093
1094 static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
1095 {
1096 __u32 *new_stack;
1097 size_t new_cap;
1098
1099 if (d->decl_stack_cnt >= d->decl_stack_cap) {
1100 new_cap = max(16, d->decl_stack_cap * 3 / 2);
1101 new_stack = libbpf_reallocarray(d->decl_stack, new_cap, sizeof(new_stack[0]));
1102 if (!new_stack)
1103 return -ENOMEM;
1104 d->decl_stack = new_stack;
1105 d->decl_stack_cap = new_cap;
1106 }
1107
1108 d->decl_stack[d->decl_stack_cnt++] = id;
1109
1110 return 0;
1111 }
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 int btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
1155 const struct btf_dump_emit_type_decl_opts *opts)
1156 {
1157 const char *fname;
1158 int lvl, err;
1159
1160 if (!OPTS_VALID(opts, btf_dump_emit_type_decl_opts))
1161 return libbpf_err(-EINVAL);
1162
1163 err = btf_dump_resize(d);
1164 if (err)
1165 return libbpf_err(err);
1166
1167 fname = OPTS_GET(opts, field_name, "");
1168 lvl = OPTS_GET(opts, indent_level, 0);
1169 d->strip_mods = OPTS_GET(opts, strip_mods, false);
1170 btf_dump_emit_type_decl(d, id, fname, lvl);
1171 d->strip_mods = false;
1172 return 0;
1173 }
1174
1175 static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
1176 const char *fname, int lvl)
1177 {
1178 struct id_stack decl_stack;
1179 const struct btf_type *t;
1180 int err, stack_start;
1181
1182 stack_start = d->decl_stack_cnt;
1183 for (;;) {
1184 t = btf__type_by_id(d->btf, id);
1185 if (d->strip_mods && btf_is_mod(t))
1186 goto skip_mod;
1187
1188 err = btf_dump_push_decl_stack_id(d, id);
1189 if (err < 0) {
1190
1191
1192
1193
1194
1195 pr_warn("not enough memory for decl stack:%d", err);
1196 d->decl_stack_cnt = stack_start;
1197 return;
1198 }
1199 skip_mod:
1200
1201 if (id == 0)
1202 break;
1203
1204 switch (btf_kind(t)) {
1205 case BTF_KIND_PTR:
1206 case BTF_KIND_VOLATILE:
1207 case BTF_KIND_CONST:
1208 case BTF_KIND_RESTRICT:
1209 case BTF_KIND_FUNC_PROTO:
1210 case BTF_KIND_TYPE_TAG:
1211 id = t->type;
1212 break;
1213 case BTF_KIND_ARRAY:
1214 id = btf_array(t)->type;
1215 break;
1216 case BTF_KIND_INT:
1217 case BTF_KIND_ENUM:
1218 case BTF_KIND_ENUM64:
1219 case BTF_KIND_FWD:
1220 case BTF_KIND_STRUCT:
1221 case BTF_KIND_UNION:
1222 case BTF_KIND_TYPEDEF:
1223 case BTF_KIND_FLOAT:
1224 goto done;
1225 default:
1226 pr_warn("unexpected type in decl chain, kind:%u, id:[%u]\n",
1227 btf_kind(t), id);
1228 goto done;
1229 }
1230 }
1231 done:
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242 decl_stack.ids = d->decl_stack + stack_start;
1243 decl_stack.cnt = d->decl_stack_cnt - stack_start;
1244 btf_dump_emit_type_chain(d, &decl_stack, fname, lvl);
1245
1246
1247
1248
1249
1250
1251
1252
1253 d->decl_stack_cnt = stack_start;
1254 }
1255
1256 static void btf_dump_emit_mods(struct btf_dump *d, struct id_stack *decl_stack)
1257 {
1258 const struct btf_type *t;
1259 __u32 id;
1260
1261 while (decl_stack->cnt) {
1262 id = decl_stack->ids[decl_stack->cnt - 1];
1263 t = btf__type_by_id(d->btf, id);
1264
1265 switch (btf_kind(t)) {
1266 case BTF_KIND_VOLATILE:
1267 btf_dump_printf(d, "volatile ");
1268 break;
1269 case BTF_KIND_CONST:
1270 btf_dump_printf(d, "const ");
1271 break;
1272 case BTF_KIND_RESTRICT:
1273 btf_dump_printf(d, "restrict ");
1274 break;
1275 default:
1276 return;
1277 }
1278 decl_stack->cnt--;
1279 }
1280 }
1281
1282 static void btf_dump_drop_mods(struct btf_dump *d, struct id_stack *decl_stack)
1283 {
1284 const struct btf_type *t;
1285 __u32 id;
1286
1287 while (decl_stack->cnt) {
1288 id = decl_stack->ids[decl_stack->cnt - 1];
1289 t = btf__type_by_id(d->btf, id);
1290 if (!btf_is_mod(t))
1291 return;
1292 decl_stack->cnt--;
1293 }
1294 }
1295
1296 static void btf_dump_emit_name(const struct btf_dump *d,
1297 const char *name, bool last_was_ptr)
1298 {
1299 bool separate = name[0] && !last_was_ptr;
1300
1301 btf_dump_printf(d, "%s%s", separate ? " " : "", name);
1302 }
1303
1304 static void btf_dump_emit_type_chain(struct btf_dump *d,
1305 struct id_stack *decls,
1306 const char *fname, int lvl)
1307 {
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317 bool last_was_ptr = true;
1318 const struct btf_type *t;
1319 const char *name;
1320 __u16 kind;
1321 __u32 id;
1322
1323 while (decls->cnt) {
1324 id = decls->ids[--decls->cnt];
1325 if (id == 0) {
1326
1327 btf_dump_emit_mods(d, decls);
1328 btf_dump_printf(d, "void");
1329 last_was_ptr = false;
1330 continue;
1331 }
1332
1333 t = btf__type_by_id(d->btf, id);
1334 kind = btf_kind(t);
1335
1336 switch (kind) {
1337 case BTF_KIND_INT:
1338 case BTF_KIND_FLOAT:
1339 btf_dump_emit_mods(d, decls);
1340 name = btf_name_of(d, t->name_off);
1341 btf_dump_printf(d, "%s", name);
1342 break;
1343 case BTF_KIND_STRUCT:
1344 case BTF_KIND_UNION:
1345 btf_dump_emit_mods(d, decls);
1346
1347 if (t->name_off == 0 && !d->skip_anon_defs)
1348 btf_dump_emit_struct_def(d, id, t, lvl);
1349 else
1350 btf_dump_emit_struct_fwd(d, id, t);
1351 break;
1352 case BTF_KIND_ENUM:
1353 case BTF_KIND_ENUM64:
1354 btf_dump_emit_mods(d, decls);
1355
1356 if (t->name_off == 0 && !d->skip_anon_defs)
1357 btf_dump_emit_enum_def(d, id, t, lvl);
1358 else
1359 btf_dump_emit_enum_fwd(d, id, t);
1360 break;
1361 case BTF_KIND_FWD:
1362 btf_dump_emit_mods(d, decls);
1363 btf_dump_emit_fwd_def(d, id, t);
1364 break;
1365 case BTF_KIND_TYPEDEF:
1366 btf_dump_emit_mods(d, decls);
1367 btf_dump_printf(d, "%s", btf_dump_ident_name(d, id));
1368 break;
1369 case BTF_KIND_PTR:
1370 btf_dump_printf(d, "%s", last_was_ptr ? "*" : " *");
1371 break;
1372 case BTF_KIND_VOLATILE:
1373 btf_dump_printf(d, " volatile");
1374 break;
1375 case BTF_KIND_CONST:
1376 btf_dump_printf(d, " const");
1377 break;
1378 case BTF_KIND_RESTRICT:
1379 btf_dump_printf(d, " restrict");
1380 break;
1381 case BTF_KIND_TYPE_TAG:
1382 btf_dump_emit_mods(d, decls);
1383 name = btf_name_of(d, t->name_off);
1384 btf_dump_printf(d, " __attribute__((btf_type_tag(\"%s\")))", name);
1385 break;
1386 case BTF_KIND_ARRAY: {
1387 const struct btf_array *a = btf_array(t);
1388 const struct btf_type *next_t;
1389 __u32 next_id;
1390 bool multidim;
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401 btf_dump_drop_mods(d, decls);
1402
1403 if (decls->cnt == 0) {
1404 btf_dump_emit_name(d, fname, last_was_ptr);
1405 btf_dump_printf(d, "[%u]", a->nelems);
1406 return;
1407 }
1408
1409 next_id = decls->ids[decls->cnt - 1];
1410 next_t = btf__type_by_id(d->btf, next_id);
1411 multidim = btf_is_array(next_t);
1412
1413 if (fname[0] && !last_was_ptr)
1414 btf_dump_printf(d, " ");
1415
1416 if (!multidim)
1417 btf_dump_printf(d, "(");
1418 btf_dump_emit_type_chain(d, decls, fname, lvl);
1419 if (!multidim)
1420 btf_dump_printf(d, ")");
1421 btf_dump_printf(d, "[%u]", a->nelems);
1422 return;
1423 }
1424 case BTF_KIND_FUNC_PROTO: {
1425 const struct btf_param *p = btf_params(t);
1426 __u16 vlen = btf_vlen(t);
1427 int i;
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437 btf_dump_drop_mods(d, decls);
1438 if (decls->cnt) {
1439 btf_dump_printf(d, " (");
1440 btf_dump_emit_type_chain(d, decls, fname, lvl);
1441 btf_dump_printf(d, ")");
1442 } else {
1443 btf_dump_emit_name(d, fname, last_was_ptr);
1444 }
1445 btf_dump_printf(d, "(");
1446
1447
1448
1449
1450
1451
1452 if (vlen == 1 && p->type == 0) {
1453 btf_dump_printf(d, ")");
1454 return;
1455 }
1456
1457 for (i = 0; i < vlen; i++, p++) {
1458 if (i > 0)
1459 btf_dump_printf(d, ", ");
1460
1461
1462 if (i == vlen - 1 && p->type == 0) {
1463 btf_dump_printf(d, "...");
1464 break;
1465 }
1466
1467 name = btf_name_of(d, p->name_off);
1468 btf_dump_emit_type_decl(d, p->type, name, lvl);
1469 }
1470
1471 btf_dump_printf(d, ")");
1472 return;
1473 }
1474 default:
1475 pr_warn("unexpected type in decl chain, kind:%u, id:[%u]\n",
1476 kind, id);
1477 return;
1478 }
1479
1480 last_was_ptr = kind == BTF_KIND_PTR;
1481 }
1482
1483 btf_dump_emit_name(d, fname, last_was_ptr);
1484 }
1485
1486
1487 static void btf_dump_emit_type_cast(struct btf_dump *d, __u32 id,
1488 bool top_level)
1489 {
1490 const struct btf_type *t;
1491
1492
1493
1494
1495
1496 if (d->typed_dump->is_array_member)
1497 return;
1498
1499
1500
1501
1502 t = btf__type_by_id(d->btf, id);
1503 if (btf_is_var(t) || btf_is_datasec(t))
1504 return;
1505
1506 if (top_level)
1507 btf_dump_printf(d, "(");
1508
1509 d->skip_anon_defs = true;
1510 d->strip_mods = true;
1511 btf_dump_emit_type_decl(d, id, "", 0);
1512 d->strip_mods = false;
1513 d->skip_anon_defs = false;
1514
1515 if (top_level)
1516 btf_dump_printf(d, ")");
1517 }
1518
1519
1520 static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
1521 const char *orig_name)
1522 {
1523 size_t dup_cnt = 0;
1524
1525 hashmap__find(name_map, orig_name, (void **)&dup_cnt);
1526 dup_cnt++;
1527 hashmap__set(name_map, orig_name, (void *)dup_cnt, NULL, NULL);
1528
1529 return dup_cnt;
1530 }
1531
1532 static const char *btf_dump_resolve_name(struct btf_dump *d, __u32 id,
1533 struct hashmap *name_map)
1534 {
1535 struct btf_dump_type_aux_state *s = &d->type_states[id];
1536 const struct btf_type *t = btf__type_by_id(d->btf, id);
1537 const char *orig_name = btf_name_of(d, t->name_off);
1538 const char **cached_name = &d->cached_names[id];
1539 size_t dup_cnt;
1540
1541 if (t->name_off == 0)
1542 return "";
1543
1544 if (s->name_resolved)
1545 return *cached_name ? *cached_name : orig_name;
1546
1547 if (btf_is_fwd(t) || (btf_is_enum(t) && btf_vlen(t) == 0)) {
1548 s->name_resolved = 1;
1549 return orig_name;
1550 }
1551
1552 dup_cnt = btf_dump_name_dups(d, name_map, orig_name);
1553 if (dup_cnt > 1) {
1554 const size_t max_len = 256;
1555 char new_name[max_len];
1556
1557 snprintf(new_name, max_len, "%s___%zu", orig_name, dup_cnt);
1558 *cached_name = strdup(new_name);
1559 }
1560
1561 s->name_resolved = 1;
1562 return *cached_name ? *cached_name : orig_name;
1563 }
1564
1565 static const char *btf_dump_type_name(struct btf_dump *d, __u32 id)
1566 {
1567 return btf_dump_resolve_name(d, id, d->type_names);
1568 }
1569
1570 static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id)
1571 {
1572 return btf_dump_resolve_name(d, id, d->ident_names);
1573 }
1574
1575 static int btf_dump_dump_type_data(struct btf_dump *d,
1576 const char *fname,
1577 const struct btf_type *t,
1578 __u32 id,
1579 const void *data,
1580 __u8 bits_offset,
1581 __u8 bit_sz);
1582
1583 static const char *btf_dump_data_newline(struct btf_dump *d)
1584 {
1585 return d->typed_dump->compact || d->typed_dump->depth == 0 ? "" : "\n";
1586 }
1587
1588 static const char *btf_dump_data_delim(struct btf_dump *d)
1589 {
1590 return d->typed_dump->depth == 0 ? "" : ",";
1591 }
1592
1593 static void btf_dump_data_pfx(struct btf_dump *d)
1594 {
1595 int i, lvl = d->typed_dump->indent_lvl + d->typed_dump->depth;
1596
1597 if (d->typed_dump->compact)
1598 return;
1599
1600 for (i = 0; i < lvl; i++)
1601 btf_dump_printf(d, "%s", d->typed_dump->indent_str);
1602 }
1603
1604
1605
1606
1607
1608
1609 #define btf_dump_type_values(d, fmt, ...) \
1610 btf_dump_printf(d, fmt "%s%s", \
1611 ##__VA_ARGS__, \
1612 btf_dump_data_delim(d), \
1613 btf_dump_data_newline(d))
1614
1615 static int btf_dump_unsupported_data(struct btf_dump *d,
1616 const struct btf_type *t,
1617 __u32 id)
1618 {
1619 btf_dump_printf(d, "<unsupported kind:%u>", btf_kind(t));
1620 return -ENOTSUP;
1621 }
1622
1623 static int btf_dump_get_bitfield_value(struct btf_dump *d,
1624 const struct btf_type *t,
1625 const void *data,
1626 __u8 bits_offset,
1627 __u8 bit_sz,
1628 __u64 *value)
1629 {
1630 __u16 left_shift_bits, right_shift_bits;
1631 const __u8 *bytes = data;
1632 __u8 nr_copy_bits;
1633 __u64 num = 0;
1634 int i;
1635
1636
1637 if (t->size > 8) {
1638 pr_warn("unexpected bitfield size %d\n", t->size);
1639 return -EINVAL;
1640 }
1641
1642
1643
1644
1645 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1646 for (i = t->size - 1; i >= 0; i--)
1647 num = num * 256 + bytes[i];
1648 nr_copy_bits = bit_sz + bits_offset;
1649 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1650 for (i = 0; i < t->size; i++)
1651 num = num * 256 + bytes[i];
1652 nr_copy_bits = t->size * 8 - bits_offset;
1653 #else
1654 # error "Unrecognized __BYTE_ORDER__"
1655 #endif
1656 left_shift_bits = 64 - nr_copy_bits;
1657 right_shift_bits = 64 - bit_sz;
1658
1659 *value = (num << left_shift_bits) >> right_shift_bits;
1660
1661 return 0;
1662 }
1663
1664 static int btf_dump_bitfield_check_zero(struct btf_dump *d,
1665 const struct btf_type *t,
1666 const void *data,
1667 __u8 bits_offset,
1668 __u8 bit_sz)
1669 {
1670 __u64 check_num;
1671 int err;
1672
1673 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz, &check_num);
1674 if (err)
1675 return err;
1676 if (check_num == 0)
1677 return -ENODATA;
1678 return 0;
1679 }
1680
1681 static int btf_dump_bitfield_data(struct btf_dump *d,
1682 const struct btf_type *t,
1683 const void *data,
1684 __u8 bits_offset,
1685 __u8 bit_sz)
1686 {
1687 __u64 print_num;
1688 int err;
1689
1690 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz, &print_num);
1691 if (err)
1692 return err;
1693
1694 btf_dump_type_values(d, "0x%llx", (unsigned long long)print_num);
1695
1696 return 0;
1697 }
1698
1699
1700 static int btf_dump_base_type_check_zero(struct btf_dump *d,
1701 const struct btf_type *t,
1702 __u32 id,
1703 const void *data)
1704 {
1705 static __u8 bytecmp[16] = {};
1706 int nr_bytes;
1707
1708
1709
1710
1711 if (btf_kind(t) == BTF_KIND_PTR)
1712 nr_bytes = d->ptr_sz;
1713 else
1714 nr_bytes = t->size;
1715
1716 if (nr_bytes < 1 || nr_bytes > 16) {
1717 pr_warn("unexpected size %d for id [%u]\n", nr_bytes, id);
1718 return -EINVAL;
1719 }
1720
1721 if (memcmp(data, bytecmp, nr_bytes) == 0)
1722 return -ENODATA;
1723 return 0;
1724 }
1725
1726 static bool ptr_is_aligned(const struct btf *btf, __u32 type_id,
1727 const void *data)
1728 {
1729 int alignment = btf__align_of(btf, type_id);
1730
1731 if (alignment == 0)
1732 return false;
1733
1734 return ((uintptr_t)data) % alignment == 0;
1735 }
1736
1737 static int btf_dump_int_data(struct btf_dump *d,
1738 const struct btf_type *t,
1739 __u32 type_id,
1740 const void *data,
1741 __u8 bits_offset)
1742 {
1743 __u8 encoding = btf_int_encoding(t);
1744 bool sign = encoding & BTF_INT_SIGNED;
1745 char buf[16] __attribute__((aligned(16)));
1746 int sz = t->size;
1747
1748 if (sz == 0 || sz > sizeof(buf)) {
1749 pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
1750 return -EINVAL;
1751 }
1752
1753
1754
1755
1756 if (!ptr_is_aligned(d->btf, type_id, data)) {
1757 memcpy(buf, data, sz);
1758 data = buf;
1759 }
1760
1761 switch (sz) {
1762 case 16: {
1763 const __u64 *ints = data;
1764 __u64 lsi, msi;
1765
1766
1767
1768
1769 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1770 lsi = ints[0];
1771 msi = ints[1];
1772 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1773 lsi = ints[1];
1774 msi = ints[0];
1775 #else
1776 # error "Unrecognized __BYTE_ORDER__"
1777 #endif
1778 if (msi == 0)
1779 btf_dump_type_values(d, "0x%llx", (unsigned long long)lsi);
1780 else
1781 btf_dump_type_values(d, "0x%llx%016llx", (unsigned long long)msi,
1782 (unsigned long long)lsi);
1783 break;
1784 }
1785 case 8:
1786 if (sign)
1787 btf_dump_type_values(d, "%lld", *(long long *)data);
1788 else
1789 btf_dump_type_values(d, "%llu", *(unsigned long long *)data);
1790 break;
1791 case 4:
1792 if (sign)
1793 btf_dump_type_values(d, "%d", *(__s32 *)data);
1794 else
1795 btf_dump_type_values(d, "%u", *(__u32 *)data);
1796 break;
1797 case 2:
1798 if (sign)
1799 btf_dump_type_values(d, "%d", *(__s16 *)data);
1800 else
1801 btf_dump_type_values(d, "%u", *(__u16 *)data);
1802 break;
1803 case 1:
1804 if (d->typed_dump->is_array_char) {
1805
1806 if (d->typed_dump->is_array_terminated)
1807 break;
1808 if (*(char *)data == '\0') {
1809 d->typed_dump->is_array_terminated = true;
1810 break;
1811 }
1812 if (isprint(*(char *)data)) {
1813 btf_dump_type_values(d, "'%c'", *(char *)data);
1814 break;
1815 }
1816 }
1817 if (sign)
1818 btf_dump_type_values(d, "%d", *(__s8 *)data);
1819 else
1820 btf_dump_type_values(d, "%u", *(__u8 *)data);
1821 break;
1822 default:
1823 pr_warn("unexpected sz %d for id [%u]\n", sz, type_id);
1824 return -EINVAL;
1825 }
1826 return 0;
1827 }
1828
1829 union float_data {
1830 long double ld;
1831 double d;
1832 float f;
1833 };
1834
1835 static int btf_dump_float_data(struct btf_dump *d,
1836 const struct btf_type *t,
1837 __u32 type_id,
1838 const void *data)
1839 {
1840 const union float_data *flp = data;
1841 union float_data fl;
1842 int sz = t->size;
1843
1844
1845 if (!ptr_is_aligned(d->btf, type_id, data)) {
1846 memcpy(&fl, data, sz);
1847 flp = &fl;
1848 }
1849
1850 switch (sz) {
1851 case 16:
1852 btf_dump_type_values(d, "%Lf", flp->ld);
1853 break;
1854 case 8:
1855 btf_dump_type_values(d, "%lf", flp->d);
1856 break;
1857 case 4:
1858 btf_dump_type_values(d, "%f", flp->f);
1859 break;
1860 default:
1861 pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
1862 return -EINVAL;
1863 }
1864 return 0;
1865 }
1866
1867 static int btf_dump_var_data(struct btf_dump *d,
1868 const struct btf_type *v,
1869 __u32 id,
1870 const void *data)
1871 {
1872 enum btf_func_linkage linkage = btf_var(v)->linkage;
1873 const struct btf_type *t;
1874 const char *l;
1875 __u32 type_id;
1876
1877 switch (linkage) {
1878 case BTF_FUNC_STATIC:
1879 l = "static ";
1880 break;
1881 case BTF_FUNC_EXTERN:
1882 l = "extern ";
1883 break;
1884 case BTF_FUNC_GLOBAL:
1885 default:
1886 l = "";
1887 break;
1888 }
1889
1890
1891
1892
1893 btf_dump_printf(d, "%s", l);
1894 type_id = v->type;
1895 t = btf__type_by_id(d->btf, type_id);
1896 btf_dump_emit_type_cast(d, type_id, false);
1897 btf_dump_printf(d, " %s = ", btf_name_of(d, v->name_off));
1898 return btf_dump_dump_type_data(d, NULL, t, type_id, data, 0, 0);
1899 }
1900
1901 static int btf_dump_array_data(struct btf_dump *d,
1902 const struct btf_type *t,
1903 __u32 id,
1904 const void *data)
1905 {
1906 const struct btf_array *array = btf_array(t);
1907 const struct btf_type *elem_type;
1908 __u32 i, elem_type_id;
1909 __s64 elem_size;
1910 bool is_array_member;
1911
1912 elem_type_id = array->type;
1913 elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
1914 elem_size = btf__resolve_size(d->btf, elem_type_id);
1915 if (elem_size <= 0) {
1916 pr_warn("unexpected elem size %zd for array type [%u]\n",
1917 (ssize_t)elem_size, id);
1918 return -EINVAL;
1919 }
1920
1921 if (btf_is_int(elem_type)) {
1922
1923
1924
1925
1926
1927 if (elem_size == 1)
1928 d->typed_dump->is_array_char = true;
1929 }
1930
1931
1932
1933
1934
1935
1936
1937
1938 d->typed_dump->depth++;
1939 btf_dump_printf(d, "[%s", btf_dump_data_newline(d));
1940
1941
1942
1943
1944 is_array_member = d->typed_dump->is_array_member;
1945 d->typed_dump->is_array_member = true;
1946 for (i = 0; i < array->nelems; i++, data += elem_size) {
1947 if (d->typed_dump->is_array_terminated)
1948 break;
1949 btf_dump_dump_type_data(d, NULL, elem_type, elem_type_id, data, 0, 0);
1950 }
1951 d->typed_dump->is_array_member = is_array_member;
1952 d->typed_dump->depth--;
1953 btf_dump_data_pfx(d);
1954 btf_dump_type_values(d, "]");
1955
1956 return 0;
1957 }
1958
1959 static int btf_dump_struct_data(struct btf_dump *d,
1960 const struct btf_type *t,
1961 __u32 id,
1962 const void *data)
1963 {
1964 const struct btf_member *m = btf_members(t);
1965 __u16 n = btf_vlen(t);
1966 int i, err;
1967
1968
1969
1970
1971
1972
1973
1974
1975 d->typed_dump->depth++;
1976 btf_dump_printf(d, "{%s", btf_dump_data_newline(d));
1977
1978 for (i = 0; i < n; i++, m++) {
1979 const struct btf_type *mtype;
1980 const char *mname;
1981 __u32 moffset;
1982 __u8 bit_sz;
1983
1984 mtype = btf__type_by_id(d->btf, m->type);
1985 mname = btf_name_of(d, m->name_off);
1986 moffset = btf_member_bit_offset(t, i);
1987
1988 bit_sz = btf_member_bitfield_size(t, i);
1989 err = btf_dump_dump_type_data(d, mname, mtype, m->type, data + moffset / 8,
1990 moffset % 8, bit_sz);
1991 if (err < 0)
1992 return err;
1993 }
1994 d->typed_dump->depth--;
1995 btf_dump_data_pfx(d);
1996 btf_dump_type_values(d, "}");
1997 return err;
1998 }
1999
2000 union ptr_data {
2001 unsigned int p;
2002 unsigned long long lp;
2003 };
2004
2005 static int btf_dump_ptr_data(struct btf_dump *d,
2006 const struct btf_type *t,
2007 __u32 id,
2008 const void *data)
2009 {
2010 if (ptr_is_aligned(d->btf, id, data) && d->ptr_sz == sizeof(void *)) {
2011 btf_dump_type_values(d, "%p", *(void **)data);
2012 } else {
2013 union ptr_data pt;
2014
2015 memcpy(&pt, data, d->ptr_sz);
2016 if (d->ptr_sz == 4)
2017 btf_dump_type_values(d, "0x%x", pt.p);
2018 else
2019 btf_dump_type_values(d, "0x%llx", pt.lp);
2020 }
2021 return 0;
2022 }
2023
2024 static int btf_dump_get_enum_value(struct btf_dump *d,
2025 const struct btf_type *t,
2026 const void *data,
2027 __u32 id,
2028 __s64 *value)
2029 {
2030 bool is_signed = btf_kflag(t);
2031
2032 if (!ptr_is_aligned(d->btf, id, data)) {
2033 __u64 val;
2034 int err;
2035
2036 err = btf_dump_get_bitfield_value(d, t, data, 0, 0, &val);
2037 if (err)
2038 return err;
2039 *value = (__s64)val;
2040 return 0;
2041 }
2042
2043 switch (t->size) {
2044 case 8:
2045 *value = *(__s64 *)data;
2046 return 0;
2047 case 4:
2048 *value = is_signed ? (__s64)*(__s32 *)data : *(__u32 *)data;
2049 return 0;
2050 case 2:
2051 *value = is_signed ? *(__s16 *)data : *(__u16 *)data;
2052 return 0;
2053 case 1:
2054 *value = is_signed ? *(__s8 *)data : *(__u8 *)data;
2055 return 0;
2056 default:
2057 pr_warn("unexpected size %d for enum, id:[%u]\n", t->size, id);
2058 return -EINVAL;
2059 }
2060 }
2061
2062 static int btf_dump_enum_data(struct btf_dump *d,
2063 const struct btf_type *t,
2064 __u32 id,
2065 const void *data)
2066 {
2067 bool is_signed;
2068 __s64 value;
2069 int i, err;
2070
2071 err = btf_dump_get_enum_value(d, t, data, id, &value);
2072 if (err)
2073 return err;
2074
2075 is_signed = btf_kflag(t);
2076 if (btf_is_enum(t)) {
2077 const struct btf_enum *e;
2078
2079 for (i = 0, e = btf_enum(t); i < btf_vlen(t); i++, e++) {
2080 if (value != e->val)
2081 continue;
2082 btf_dump_type_values(d, "%s", btf_name_of(d, e->name_off));
2083 return 0;
2084 }
2085
2086 btf_dump_type_values(d, is_signed ? "%d" : "%u", value);
2087 } else {
2088 const struct btf_enum64 *e;
2089
2090 for (i = 0, e = btf_enum64(t); i < btf_vlen(t); i++, e++) {
2091 if (value != btf_enum64_value(e))
2092 continue;
2093 btf_dump_type_values(d, "%s", btf_name_of(d, e->name_off));
2094 return 0;
2095 }
2096
2097 btf_dump_type_values(d, is_signed ? "%lldLL" : "%lluULL",
2098 (unsigned long long)value);
2099 }
2100 return 0;
2101 }
2102
2103 static int btf_dump_datasec_data(struct btf_dump *d,
2104 const struct btf_type *t,
2105 __u32 id,
2106 const void *data)
2107 {
2108 const struct btf_var_secinfo *vsi;
2109 const struct btf_type *var;
2110 __u32 i;
2111 int err;
2112
2113 btf_dump_type_values(d, "SEC(\"%s\") ", btf_name_of(d, t->name_off));
2114
2115 for (i = 0, vsi = btf_var_secinfos(t); i < btf_vlen(t); i++, vsi++) {
2116 var = btf__type_by_id(d->btf, vsi->type);
2117 err = btf_dump_dump_type_data(d, NULL, var, vsi->type, data + vsi->offset, 0, 0);
2118 if (err < 0)
2119 return err;
2120 btf_dump_printf(d, ";");
2121 }
2122 return 0;
2123 }
2124
2125
2126 static int btf_dump_type_data_check_overflow(struct btf_dump *d,
2127 const struct btf_type *t,
2128 __u32 id,
2129 const void *data,
2130 __u8 bits_offset)
2131 {
2132 __s64 size = btf__resolve_size(d->btf, id);
2133
2134 if (size < 0 || size >= INT_MAX) {
2135 pr_warn("unexpected size [%zu] for id [%u]\n",
2136 (size_t)size, id);
2137 return -EINVAL;
2138 }
2139
2140
2141
2142
2143
2144
2145
2146
2147 t = skip_mods_and_typedefs(d->btf, id, NULL);
2148 if (!t) {
2149 pr_warn("unexpected error skipping mods/typedefs for id [%u]\n",
2150 id);
2151 return -EINVAL;
2152 }
2153
2154 switch (btf_kind(t)) {
2155 case BTF_KIND_INT:
2156 case BTF_KIND_FLOAT:
2157 case BTF_KIND_PTR:
2158 case BTF_KIND_ENUM:
2159 case BTF_KIND_ENUM64:
2160 if (data + bits_offset / 8 + size > d->typed_dump->data_end)
2161 return -E2BIG;
2162 break;
2163 default:
2164 break;
2165 }
2166 return (int)size;
2167 }
2168
2169 static int btf_dump_type_data_check_zero(struct btf_dump *d,
2170 const struct btf_type *t,
2171 __u32 id,
2172 const void *data,
2173 __u8 bits_offset,
2174 __u8 bit_sz)
2175 {
2176 __s64 value;
2177 int i, err;
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190 if (d->typed_dump->emit_zeroes || d->typed_dump->depth == 0 ||
2191 (d->typed_dump->is_array_member &&
2192 !d->typed_dump->is_array_char))
2193 return 0;
2194
2195 t = skip_mods_and_typedefs(d->btf, id, NULL);
2196
2197 switch (btf_kind(t)) {
2198 case BTF_KIND_INT:
2199 if (bit_sz)
2200 return btf_dump_bitfield_check_zero(d, t, data, bits_offset, bit_sz);
2201 return btf_dump_base_type_check_zero(d, t, id, data);
2202 case BTF_KIND_FLOAT:
2203 case BTF_KIND_PTR:
2204 return btf_dump_base_type_check_zero(d, t, id, data);
2205 case BTF_KIND_ARRAY: {
2206 const struct btf_array *array = btf_array(t);
2207 const struct btf_type *elem_type;
2208 __u32 elem_type_id, elem_size;
2209 bool ischar;
2210
2211 elem_type_id = array->type;
2212 elem_size = btf__resolve_size(d->btf, elem_type_id);
2213 elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
2214
2215 ischar = btf_is_int(elem_type) && elem_size == 1;
2216
2217
2218
2219
2220
2221
2222
2223 for (i = 0; i < array->nelems; i++) {
2224 if (i == 0 && ischar && *(char *)data == 0)
2225 return -ENODATA;
2226 err = btf_dump_type_data_check_zero(d, elem_type,
2227 elem_type_id,
2228 data +
2229 (i * elem_size),
2230 bits_offset, 0);
2231 if (err != -ENODATA)
2232 return err;
2233 }
2234 return -ENODATA;
2235 }
2236 case BTF_KIND_STRUCT:
2237 case BTF_KIND_UNION: {
2238 const struct btf_member *m = btf_members(t);
2239 __u16 n = btf_vlen(t);
2240
2241
2242
2243
2244 for (i = 0; i < n; i++, m++) {
2245 const struct btf_type *mtype;
2246 __u32 moffset;
2247
2248 mtype = btf__type_by_id(d->btf, m->type);
2249 moffset = btf_member_bit_offset(t, i);
2250
2251
2252
2253
2254
2255 bit_sz = btf_member_bitfield_size(t, i);
2256 err = btf_dump_type_data_check_zero(d, mtype, m->type, data + moffset / 8,
2257 moffset % 8, bit_sz);
2258 if (err != ENODATA)
2259 return err;
2260 }
2261 return -ENODATA;
2262 }
2263 case BTF_KIND_ENUM:
2264 case BTF_KIND_ENUM64:
2265 err = btf_dump_get_enum_value(d, t, data, id, &value);
2266 if (err)
2267 return err;
2268 if (value == 0)
2269 return -ENODATA;
2270 return 0;
2271 default:
2272 return 0;
2273 }
2274 }
2275
2276
2277 static int btf_dump_dump_type_data(struct btf_dump *d,
2278 const char *fname,
2279 const struct btf_type *t,
2280 __u32 id,
2281 const void *data,
2282 __u8 bits_offset,
2283 __u8 bit_sz)
2284 {
2285 int size, err = 0;
2286
2287 size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset);
2288 if (size < 0)
2289 return size;
2290 err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);
2291 if (err) {
2292
2293
2294
2295 if (err == -ENODATA)
2296 return size;
2297 return err;
2298 }
2299 btf_dump_data_pfx(d);
2300
2301 if (!d->typed_dump->skip_names) {
2302 if (fname && strlen(fname) > 0)
2303 btf_dump_printf(d, ".%s = ", fname);
2304 btf_dump_emit_type_cast(d, id, true);
2305 }
2306
2307 t = skip_mods_and_typedefs(d->btf, id, NULL);
2308
2309 switch (btf_kind(t)) {
2310 case BTF_KIND_UNKN:
2311 case BTF_KIND_FWD:
2312 case BTF_KIND_FUNC:
2313 case BTF_KIND_FUNC_PROTO:
2314 case BTF_KIND_DECL_TAG:
2315 err = btf_dump_unsupported_data(d, t, id);
2316 break;
2317 case BTF_KIND_INT:
2318 if (bit_sz)
2319 err = btf_dump_bitfield_data(d, t, data, bits_offset, bit_sz);
2320 else
2321 err = btf_dump_int_data(d, t, id, data, bits_offset);
2322 break;
2323 case BTF_KIND_FLOAT:
2324 err = btf_dump_float_data(d, t, id, data);
2325 break;
2326 case BTF_KIND_PTR:
2327 err = btf_dump_ptr_data(d, t, id, data);
2328 break;
2329 case BTF_KIND_ARRAY:
2330 err = btf_dump_array_data(d, t, id, data);
2331 break;
2332 case BTF_KIND_STRUCT:
2333 case BTF_KIND_UNION:
2334 err = btf_dump_struct_data(d, t, id, data);
2335 break;
2336 case BTF_KIND_ENUM:
2337 case BTF_KIND_ENUM64:
2338
2339 if (bit_sz) {
2340 __u64 print_num;
2341 __s64 enum_val;
2342
2343 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz,
2344 &print_num);
2345 if (err)
2346 break;
2347 enum_val = (__s64)print_num;
2348 err = btf_dump_enum_data(d, t, id, &enum_val);
2349 } else
2350 err = btf_dump_enum_data(d, t, id, data);
2351 break;
2352 case BTF_KIND_VAR:
2353 err = btf_dump_var_data(d, t, id, data);
2354 break;
2355 case BTF_KIND_DATASEC:
2356 err = btf_dump_datasec_data(d, t, id, data);
2357 break;
2358 default:
2359 pr_warn("unexpected kind [%u] for id [%u]\n",
2360 BTF_INFO_KIND(t->info), id);
2361 return -EINVAL;
2362 }
2363 if (err < 0)
2364 return err;
2365 return size;
2366 }
2367
2368 int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
2369 const void *data, size_t data_sz,
2370 const struct btf_dump_type_data_opts *opts)
2371 {
2372 struct btf_dump_data typed_dump = {};
2373 const struct btf_type *t;
2374 int ret;
2375
2376 if (!OPTS_VALID(opts, btf_dump_type_data_opts))
2377 return libbpf_err(-EINVAL);
2378
2379 t = btf__type_by_id(d->btf, id);
2380 if (!t)
2381 return libbpf_err(-ENOENT);
2382
2383 d->typed_dump = &typed_dump;
2384 d->typed_dump->data_end = data + data_sz;
2385 d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0);
2386
2387
2388 if (!opts->indent_str)
2389 d->typed_dump->indent_str[0] = '\t';
2390 else
2391 libbpf_strlcpy(d->typed_dump->indent_str, opts->indent_str,
2392 sizeof(d->typed_dump->indent_str));
2393
2394 d->typed_dump->compact = OPTS_GET(opts, compact, false);
2395 d->typed_dump->skip_names = OPTS_GET(opts, skip_names, false);
2396 d->typed_dump->emit_zeroes = OPTS_GET(opts, emit_zeroes, false);
2397
2398 ret = btf_dump_dump_type_data(d, NULL, t, id, data, 0, 0);
2399
2400 d->typed_dump = NULL;
2401
2402 return libbpf_err(ret);
2403 }