Lines Matching +full:d +full:-

1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
4 * BTF-to-C type converter.
26 static const size_t PREFIX_CNT = sizeof(PREFIXES) - 1;
30 return lvl >= PREFIX_CNT ? PREFIXES : &PREFIXES[PREFIX_CNT - lvl];
45 /* per-type auxiliary state */
53 /* whether unique non-duplicate name was already assigned */
88 /* per-type auxiliary state */
91 /* per-type optional cached unique name, must be freed, if present */
95 /* topo-sorted list of dependent type definitions */
131 static const char *btf_name_of(const struct btf_dump *d, __u32 name_off)
133 return btf__name_by_offset(d->btf, name_off);
136 static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
141 d->printf_fn(d->cb_ctx, fmt, args);
145 static int btf_dump_mark_referenced(struct btf_dump *d);
146 static int btf_dump_resize(struct btf_dump *d);
153 struct btf_dump *d;
157 return libbpf_err_ptr(-EINVAL);
160 return libbpf_err_ptr(-EINVAL);
162 d = calloc(1, sizeof(struct btf_dump));
163 if (!d)
164 return libbpf_err_ptr(-ENOMEM);
166 d->btf = btf;
167 d->printf_fn = printf_fn;
168 d->cb_ctx = ctx;
169 d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *);
171 d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
172 if (IS_ERR(d->type_names)) {
173 err = PTR_ERR(d->type_names);
174 d->type_names = NULL;
177 d->ident_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
178 if (IS_ERR(d->ident_names)) {
179 err = PTR_ERR(d->ident_names);
180 d->ident_names = NULL;
184 err = btf_dump_resize(d);
188 return d;
190 btf_dump__free(d);
194 static int btf_dump_resize(struct btf_dump *d)
196 int err, last_id = btf__type_cnt(d->btf) - 1;
198 if (last_id <= d->last_id)
201 if (libbpf_ensure_mem((void **)&d->type_states, &d->type_states_cap,
202 sizeof(*d->type_states), last_id + 1))
203 return -ENOMEM;
204 if (libbpf_ensure_mem((void **)&d->cached_names, &d->cached_names_cap,
205 sizeof(*d->cached_names), last_id + 1))
206 return -ENOMEM;
208 if (d->last_id == 0) {
210 d->type_states[0].order_state = ORDERED;
211 d->type_states[0].emit_state = EMITTED;
215 err = btf_dump_mark_referenced(d);
219 d->last_id = last_id;
229 free((void *)cur->pkey);
234 void btf_dump__free(struct btf_dump *d)
238 if (IS_ERR_OR_NULL(d))
241 free(d->type_states);
242 if (d->cached_names) {
244 for (i = 0; i <= d->last_id; i++) {
245 if (d->cached_names[i])
246 free((void *)d->cached_names[i]);
249 free(d->cached_names);
250 free(d->emit_queue);
251 free(d->decl_stack);
252 btf_dump_free_names(d->type_names);
253 btf_dump_free_names(d->ident_names);
255 free(d);
258 static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr);
259 static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id);
266 * filter out BTF types according to user-defined criterias and emitted only
271 * Dumping is done in two high-level passes:
277 int btf_dump__dump_type(struct btf_dump *d, __u32 id)
281 if (id >= btf__type_cnt(d->btf))
282 return libbpf_err(-EINVAL);
284 err = btf_dump_resize(d);
288 d->emit_queue_cnt = 0;
289 err = btf_dump_order_type(d, id, false);
293 for (i = 0; i < d->emit_queue_cnt; i++)
294 btf_dump_emit_type(d, d->emit_queue[i], 0 /*top-level*/);
301 * determine top-level anonymous enums that need to be emitted as an
305 * type declaration; or as a top-level anonymous enum, typically used for
308 * top-level anonymous enum won't be referenced by anything, while embedded
311 static int btf_dump_mark_referenced(struct btf_dump *d)
313 int i, j, n = btf__type_cnt(d->btf);
317 for (i = d->last_id + 1; i < n; i++) {
318 t = btf__type_by_id(d->btf, i);
338 d->type_states[t->type].referenced = 1;
344 d->type_states[a->index_type].referenced = 1;
345 d->type_states[a->type].referenced = 1;
353 d->type_states[m->type].referenced = 1;
360 d->type_states[p->type].referenced = 1;
367 d->type_states[v->type].referenced = 1;
371 return -EINVAL;
377 static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
382 if (d->emit_queue_cnt >= d->emit_queue_cap) {
383 new_cap = max(16, d->emit_queue_cap * 3 / 2);
384 new_queue = libbpf_reallocarray(d->emit_queue, new_cap, sizeof(new_queue[0]));
386 return -ENOMEM;
387 d->emit_queue = new_queue;
388 d->emit_queue_cap = new_cap;
391 d->emit_queue[d->emit_queue_cnt++] = id;
418 * struct A {}; // if this was forward-declaration: compilation error
430 * between struct A and struct B. If struct A was forward-declared before
437 * - weak link (relationship) between X and Y, if Y *CAN* be
438 * forward-declared at the point of X definition;
439 * - strong link, if Y *HAS* to be fully-defined before X can be defined.
442 * BTF_KIND_PTR type in the chain and at least one non-anonymous type
457 * marked as ORDERED. We can mark PTR as ORDERED as well, as it semi-forces
463 * - 1, if type is part of strong link (so there is strong topological
465 * - 0, if type is part of weak link (so can be satisfied through forward
467 * - <0, on error (e.g., unsatisfiable type loop detected).
469 static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
474 * stand-alone fwd decl, enum, typedef, struct, union). Ptrs, arrays,
478 * So for all non-defining kinds, we never even set ordering state,
482 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
488 if (tstate->order_state == ORDERED)
491 t = btf__type_by_id(d->btf, id);
493 if (tstate->order_state == ORDERING) {
495 if (btf_is_composite(t) && through_ptr && t->name_off != 0)
498 return -ELOOP;
504 tstate->order_state = ORDERED;
508 err = btf_dump_order_type(d, t->type, true);
509 tstate->order_state = ORDERED;
513 return btf_dump_order_type(d, btf_array(t)->type, false);
523 if (through_ptr && t->name_off != 0)
526 tstate->order_state = ORDERING;
530 err = btf_dump_order_type(d, m->type, false);
535 if (t->name_off != 0) {
536 err = btf_dump_add_emit_queue_id(d, id);
541 tstate->order_state = ORDERED;
548 * non-anonymous or non-referenced enums are top-level
552 if (t->name_off != 0 || !tstate->referenced) {
553 err = btf_dump_add_emit_queue_id(d, id);
557 tstate->order_state = ORDERED;
563 is_strong = btf_dump_order_type(d, t->type, through_ptr);
567 /* typedef is similar to struct/union w.r.t. fwd-decls */
572 err = btf_dump_add_emit_queue_id(d, id);
576 d->type_states[id].order_state = ORDERED;
583 return btf_dump_order_type(d, t->type, through_ptr);
589 err = btf_dump_order_type(d, t->type, through_ptr);
596 err = btf_dump_order_type(d, p->type, through_ptr);
608 d->type_states[id].order_state = ORDERED;
612 return -EINVAL;
616 static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
619 static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
621 static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
624 static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
626 static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
629 static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
632 static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
641 static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
643 static void btf_dump_emit_type_chain(struct btf_dump *d,
647 static const char *btf_dump_type_name(struct btf_dump *d, __u32 id);
648 static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id);
649 static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
652 static bool btf_dump_is_blacklisted(struct btf_dump *d, __u32 id)
654 const struct btf_type *t = btf__type_by_id(d->btf, id);
656 /* __builtin_va_list is a compiler built-in, which causes compilation
659 * C header from BTF). As it is built-in, it should be already defined
662 if (t->name_off == 0)
664 return strcmp(btf_name_of(d, t->name_off), "__builtin_va_list") == 0;
668 * Emit C-syntax definitions of types from chains of BTF types.
670 * High-level handling of determining necessary forward declarations are handled
671 * by btf_dump_emit_type() itself, but all nitty-gritty details of emitting type
685 static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
687 struct btf_dump_type_aux_state *tstate = &d->type_states[id];
692 if (tstate->emit_state == EMITTED)
695 t = btf__type_by_id(d->btf, id);
698 if (tstate->emit_state == EMITTING) {
699 if (tstate->fwd_emitted)
707 * part of - then no need for fwd declaration
711 if (t->name_off == 0) {
716 btf_dump_emit_struct_fwd(d, id, t);
717 btf_dump_printf(d, ";\n\n");
718 tstate->fwd_emitted = 1;
726 if (!btf_dump_is_blacklisted(d, id)) {
727 btf_dump_emit_typedef_def(d, id, t, 0);
728 btf_dump_printf(d, ";\n\n");
730 tstate->fwd_emitted = 1;
742 btf_dump_emit_missing_aliases(d, id, t);
744 tstate->emit_state = EMITTED;
749 btf_dump_emit_enum_def(d, id, t, 0);
750 btf_dump_printf(d, ";\n\n");
752 tstate->emit_state = EMITTED;
759 btf_dump_emit_type(d, t->type, cont_id);
762 btf_dump_emit_type(d, btf_array(t)->type, cont_id);
765 btf_dump_emit_fwd_def(d, id, t);
766 btf_dump_printf(d, ";\n\n");
767 tstate->emit_state = EMITTED;
770 tstate->emit_state = EMITTING;
771 btf_dump_emit_type(d, t->type, id);
779 if (!tstate->fwd_emitted && !btf_dump_is_blacklisted(d, id)) {
780 btf_dump_emit_typedef_def(d, id, t, 0);
781 btf_dump_printf(d, ";\n\n");
783 tstate->emit_state = EMITTED;
787 tstate->emit_state = EMITTING;
788 /* if it's a top-level struct/union definition or struct/union
792 * members have necessary forward-declarations, where
795 if (top_level_def || t->name_off == 0) {
800 new_cont_id = t->name_off == 0 ? cont_id : id;
802 btf_dump_emit_type(d, m->type, new_cont_id);
803 } else if (!tstate->fwd_emitted && id != cont_id) {
804 btf_dump_emit_struct_fwd(d, id, t);
805 btf_dump_printf(d, ";\n\n");
806 tstate->fwd_emitted = 1;
810 btf_dump_emit_struct_def(d, id, t, 0);
811 btf_dump_printf(d, ";\n\n");
812 tstate->emit_state = EMITTED;
814 tstate->emit_state = NOT_EMITTED;
822 btf_dump_emit_type(d, t->type, cont_id);
824 btf_dump_emit_type(d, p->type, cont_id);
842 /* all non-bitfield fields have to be naturally aligned */
844 align = btf__align_of(btf, m->type);
846 if (align && bit_sz == 0 && m->offset % (8 * align) != 0)
850 /* size of a non-packed struct has to be a multiple of its alignment */
851 if (t->size % max_align != 0)
860 static void btf_dump_emit_bit_padding(const struct btf_dump *d,
868 {"long", d->ptr_sz * 8}, {"int", 32}, {"short", 16}, {"char", 8}
885 * that even if struct itself has, let's say 4-byte alignment
886 * (i.e., it only uses up to int-aligned types), using `long:
915 (new_off != next_off && next_off - new_off <= new_off - cur_off))
917 btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type,
918 in_bitfield ? new_off - cur_off : 0);
929 bits = min(next_off - cur_off, pad_bits);
931 btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits);
941 for (i = ARRAY_SIZE(pads) - 1; i >= 0; i--) {
947 btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, bits);
954 static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
957 btf_dump_printf(d, "%s%s%s",
959 t->name_off ? " " : "",
960 btf_dump_type_name(d, id));
963 static void btf_dump_emit_struct_def(struct btf_dump *d,
974 align = btf__align_of(d->btf, id);
975 packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0;
977 btf_dump_printf(d, "%s%s%s {",
979 t->name_off ? " " : "",
980 btf_dump_type_name(d, id));
987 fname = btf_name_of(d, m->name_off);
990 m_align = packed ? 1 : btf__align_of(d->btf, m->type);
994 btf_dump_emit_bit_padding(d, off, m_off, m_align, in_bitfield, lvl + 1);
995 btf_dump_printf(d, "\n%s", pfx(lvl + 1));
996 btf_dump_emit_type_decl(d, m->type, fname, lvl + 1);
999 btf_dump_printf(d, ": %d", m_sz);
1003 m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));
1008 btf_dump_printf(d, ";");
1013 btf_dump_emit_bit_padding(d, off, t->size * 8, align, false, lvl + 1);
1019 if (vlen || t->size) {
1020 btf_dump_printf(d, "\n");
1021 btf_dump_printf(d, "%s}", pfx(lvl));
1023 btf_dump_printf(d, "}");
1026 btf_dump_printf(d, " __attribute__((packed))");
1040 static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
1043 const char *name = btf_dump_type_name(d, id);
1048 btf_dump_printf(d, "typedef %s %s;\n\n",
1055 static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
1058 btf_dump_printf(d, "enum %s", btf_dump_type_name(d, id));
1061 static void btf_dump_emit_enum32_val(struct btf_dump *d,
1073 name = btf_name_of(d, v->name_off);
1075 dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
1077 fmt_str = is_signed ? "\n%s%s___%zd = %d," : "\n%s%s___%zd = %u,";
1078 btf_dump_printf(d, fmt_str, pfx(lvl + 1), name, dup_cnt, v->val);
1080 fmt_str = is_signed ? "\n%s%s = %d," : "\n%s%s = %u,";
1081 btf_dump_printf(d, fmt_str, pfx(lvl + 1), name, v->val);
1086 static void btf_dump_emit_enum64_val(struct btf_dump *d,
1099 name = btf_name_of(d, v->name_off);
1100 dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
1105 btf_dump_printf(d, fmt_str,
1111 btf_dump_printf(d, fmt_str,
1117 static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
1123 btf_dump_printf(d, "enum%s%s",
1124 t->name_off ? " " : "",
1125 btf_dump_type_name(d, id));
1130 btf_dump_printf(d, " {");
1132 btf_dump_emit_enum32_val(d, t, lvl, vlen);
1134 btf_dump_emit_enum64_val(d, t, lvl, vlen);
1135 btf_dump_printf(d, "\n%s}", pfx(lvl));
1138 if (t->size == 1) {
1139 /* one-byte enums can be forced with mode(byte) attribute */
1140 btf_dump_printf(d, " __attribute__((mode(byte)))");
1141 } else if (t->size == 8 && d->ptr_sz == 8) {
1142 /* enum can be 8-byte sized if one of the enumerator values
1143 * doesn't fit in 32-bit integer, or by adding mode(word)
1144 * attribute (but probably only on 64-bit architectures); do
1151 /* enum can't represent 64-bit values, so we need word mode */
1155 * non-zero upper 32-bits (which means that all values
1156 * fit in 32-bit integers and won't cause compiler to
1157 * bump enum to be 64-bit naturally
1170 btf_dump_printf(d, " __attribute__((mode(word)))");
1175 static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id,
1178 const char *name = btf_dump_type_name(d, id);
1181 btf_dump_printf(d, "union %s", name);
1183 btf_dump_printf(d, "struct %s", name);
1186 static void btf_dump_emit_typedef_def(struct btf_dump *d, __u32 id,
1189 const char *name = btf_dump_ident_name(d, id);
1197 if (t->type == 0 && strcmp(name, "__gnuc_va_list") == 0) {
1198 btf_dump_printf(d, "typedef __builtin_va_list __gnuc_va_list");
1202 btf_dump_printf(d, "typedef ");
1203 btf_dump_emit_type_decl(d, t->type, name, lvl);
1206 static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
1211 if (d->decl_stack_cnt >= d->decl_stack_cap) {
1212 new_cap = max(16, d->decl_stack_cap * 3 / 2);
1213 new_stack = libbpf_reallocarray(d->decl_stack, new_cap, sizeof(new_stack[0]));
1215 return -ENOMEM;
1216 d->decl_stack = new_stack;
1217 d->decl_stack_cap = new_cap;
1220 d->decl_stack[d->decl_stack_cnt++] = id;
1231 * - function prototypes (especially nesting of function prototypes);
1232 * - arrays;
1233 * - const/volatile/restrict for pointers vs other types.
1247 * [typedef] -> [array] -> [ptr] -> [const] -> [ptr] -> [const] -> [int]
1266 int btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
1273 return libbpf_err(-EINVAL);
1275 err = btf_dump_resize(d);
1281 d->strip_mods = OPTS_GET(opts, strip_mods, false);
1282 btf_dump_emit_type_decl(d, id, fname, lvl);
1283 d->strip_mods = false;
1287 static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
1294 stack_start = d->decl_stack_cnt;
1296 t = btf__type_by_id(d->btf, id);
1297 if (d->strip_mods && btf_is_mod(t))
1300 err = btf_dump_push_decl_stack_id(d, id);
1307 pr_warn("not enough memory for decl stack:%d", err);
1308 d->decl_stack_cnt = stack_start;
1323 id = t->type;
1326 id = btf_array(t)->type;
1348 * emitting of declarations. Those stack frames are non-overlapping
1349 * portions of shared btf_dump->decl_stack. To make it a bit nicer to
1354 decl_stack.ids = d->decl_stack + stack_start;
1355 decl_stack.cnt = d->decl_stack_cnt - stack_start;
1356 btf_dump_emit_type_chain(d, &decl_stack, fname, lvl);
1359 * frame before returning. But it works with a read-only view into
1361 * perspective of shared btf_dump->decl_stack, per se. We need to
1365 d->decl_stack_cnt = stack_start;
1368 static void btf_dump_emit_mods(struct btf_dump *d, struct id_stack *decl_stack)
1373 while (decl_stack->cnt) {
1374 id = decl_stack->ids[decl_stack->cnt - 1];
1375 t = btf__type_by_id(d->btf, id);
1379 btf_dump_printf(d, "volatile ");
1382 btf_dump_printf(d, "const ");
1385 btf_dump_printf(d, "restrict ");
1390 decl_stack->cnt--;
1394 static void btf_dump_drop_mods(struct btf_dump *d, struct id_stack *decl_stack)
1399 while (decl_stack->cnt) {
1400 id = decl_stack->ids[decl_stack->cnt - 1];
1401 t = btf__type_by_id(d->btf, id);
1404 decl_stack->cnt--;
1408 static void btf_dump_emit_name(const struct btf_dump *d,
1413 btf_dump_printf(d, "%s%s", separate ? " " : "", name);
1416 static void btf_dump_emit_type_chain(struct btf_dump *d,
1424 * for cases where we have single pointer in a chain. E.g., in ptr ->
1435 while (decls->cnt) {
1436 id = decls->ids[--decls->cnt];
1439 btf_dump_emit_mods(d, decls);
1440 btf_dump_printf(d, "void");
1445 t = btf__type_by_id(d->btf, id);
1451 btf_dump_emit_mods(d, decls);
1452 name = btf_name_of(d, t->name_off);
1453 btf_dump_printf(d, "%s", name);
1457 btf_dump_emit_mods(d, decls);
1459 if (t->name_off == 0 && !d->skip_anon_defs)
1460 btf_dump_emit_struct_def(d, id, t, lvl);
1462 btf_dump_emit_struct_fwd(d, id, t);
1466 btf_dump_emit_mods(d, decls);
1468 if (t->name_off == 0 && !d->skip_anon_defs)
1469 btf_dump_emit_enum_def(d, id, t, lvl);
1471 btf_dump_emit_enum_fwd(d, id, t);
1474 btf_dump_emit_mods(d, decls);
1475 btf_dump_emit_fwd_def(d, id, t);
1478 btf_dump_emit_mods(d, decls);
1479 btf_dump_printf(d, "%s", btf_dump_ident_name(d, id));
1482 btf_dump_printf(d, "%s", last_was_ptr ? "*" : " *");
1485 btf_dump_printf(d, " volatile");
1488 btf_dump_printf(d, " const");
1491 btf_dump_printf(d, " restrict");
1494 btf_dump_emit_mods(d, decls);
1495 name = btf_name_of(d, t->name_off);
1496 btf_dump_printf(d, " __attribute__((btf_type_tag(\"%s\")))", name);
1513 btf_dump_drop_mods(d, decls);
1515 if (decls->cnt == 0) {
1516 btf_dump_emit_name(d, fname, last_was_ptr);
1517 btf_dump_printf(d, "[%u]", a->nelems);
1521 next_id = decls->ids[decls->cnt - 1];
1522 next_t = btf__type_by_id(d->btf, next_id);
1524 /* we need space if we have named non-pointer */
1526 btf_dump_printf(d, " ");
1527 /* no parentheses for multi-dimensional array */
1529 btf_dump_printf(d, "(");
1530 btf_dump_emit_type_chain(d, decls, fname, lvl);
1532 btf_dump_printf(d, ")");
1533 btf_dump_printf(d, "[%u]", a->nelems);
1549 btf_dump_drop_mods(d, decls);
1550 if (decls->cnt) {
1551 btf_dump_printf(d, " (");
1552 btf_dump_emit_type_chain(d, decls, fname, lvl);
1553 btf_dump_printf(d, ")");
1555 btf_dump_emit_name(d, fname, last_was_ptr);
1557 btf_dump_printf(d, "(");
1564 * no args case can be special-cased here as well.
1566 if (vlen == 0 || (vlen == 1 && p->type == 0)) {
1567 btf_dump_printf(d, "void)");
1573 btf_dump_printf(d, ", ");
1576 if (i == vlen - 1 && p->type == 0) {
1577 btf_dump_printf(d, "...");
1581 name = btf_name_of(d, p->name_off);
1582 btf_dump_emit_type_decl(d, p->type, name, lvl);
1585 btf_dump_printf(d, ")");
1597 btf_dump_emit_name(d, fname, last_was_ptr);
1601 static void btf_dump_emit_type_cast(struct btf_dump *d, __u32 id,
1610 if (d->typed_dump->is_array_member)
1616 t = btf__type_by_id(d->btf, id);
1621 btf_dump_printf(d, "(");
1623 d->skip_anon_defs = true;
1624 d->strip_mods = true;
1625 btf_dump_emit_type_decl(d, id, "", 0);
1626 d->strip_mods = false;
1627 d->skip_anon_defs = false;
1630 btf_dump_printf(d, ")");
1634 static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
1657 static const char *btf_dump_resolve_name(struct btf_dump *d, __u32 id,
1660 struct btf_dump_type_aux_state *s = &d->type_states[id];
1661 const struct btf_type *t = btf__type_by_id(d->btf, id);
1662 const char *orig_name = btf_name_of(d, t->name_off);
1663 const char **cached_name = &d->cached_names[id];
1666 if (t->name_off == 0)
1669 if (s->name_resolved)
1673 s->name_resolved = 1;
1677 dup_cnt = btf_dump_name_dups(d, name_map, orig_name);
1686 s->name_resolved = 1;
1690 static const char *btf_dump_type_name(struct btf_dump *d, __u32 id)
1692 return btf_dump_resolve_name(d, id, d->type_names);
1695 static const char *btf_dump_ident_name(struct btf_dump *d, __u32 id)
1697 return btf_dump_resolve_name(d, id, d->ident_names);
1700 static int btf_dump_dump_type_data(struct btf_dump *d,
1708 static const char *btf_dump_data_newline(struct btf_dump *d)
1710 return d->typed_dump->compact || d->typed_dump->depth == 0 ? "" : "\n";
1713 static const char *btf_dump_data_delim(struct btf_dump *d)
1715 return d->typed_dump->depth == 0 ? "" : ",";
1718 static void btf_dump_data_pfx(struct btf_dump *d)
1720 int i, lvl = d->typed_dump->indent_lvl + d->typed_dump->depth;
1722 if (d->typed_dump->compact)
1726 btf_dump_printf(d, "%s", d->typed_dump->indent_str);
1734 #define btf_dump_type_values(d, fmt, ...) \
1735 btf_dump_printf(d, fmt "%s%s", \
1737 btf_dump_data_delim(d), \
1738 btf_dump_data_newline(d))
1740 static int btf_dump_unsupported_data(struct btf_dump *d,
1744 btf_dump_printf(d, "<unsupported kind:%u>", btf_kind(t));
1745 return -ENOTSUP;
1748 static int btf_dump_get_bitfield_value(struct btf_dump *d,
1762 if (t->size > 8) {
1763 pr_warn("unexpected bitfield size %d\n", t->size);
1764 return -EINVAL;
1771 for (i = t->size - 1; i >= 0; i--)
1775 for (i = 0; i < t->size; i++)
1777 nr_copy_bits = t->size * 8 - bits_offset;
1781 left_shift_bits = 64 - nr_copy_bits;
1782 right_shift_bits = 64 - bit_sz;
1789 static int btf_dump_bitfield_check_zero(struct btf_dump *d,
1798 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz, &check_num);
1802 return -ENODATA;
1806 static int btf_dump_bitfield_data(struct btf_dump *d,
1815 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz, &print_num);
1819 btf_dump_type_values(d, "0x%llx", (unsigned long long)print_num);
1825 static int btf_dump_base_type_check_zero(struct btf_dump *d,
1833 /* For pointer types, pointer size is not defined on a per-type basis.
1837 nr_bytes = d->ptr_sz;
1839 nr_bytes = t->size;
1842 pr_warn("unexpected size %d for id [%u]\n", nr_bytes, id);
1843 return -EINVAL;
1847 return -ENODATA;
1862 static int btf_dump_int_data(struct btf_dump *d,
1871 int sz = t->size;
1874 pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
1875 return -EINVAL;
1878 /* handle packed int data - accesses of integers not aligned on
1881 if (!ptr_is_aligned(d->btf, type_id, data)) {
1891 /* avoid use of __int128 as some 32-bit platforms do not
1904 btf_dump_type_values(d, "0x%llx", (unsigned long long)lsi);
1906 btf_dump_type_values(d, "0x%llx%016llx", (unsigned long long)msi,
1912 btf_dump_type_values(d, "%lld", *(long long *)data);
1914 btf_dump_type_values(d, "%llu", *(unsigned long long *)data);
1918 btf_dump_type_values(d, "%d", *(__s32 *)data);
1920 btf_dump_type_values(d, "%u", *(__u32 *)data);
1924 btf_dump_type_values(d, "%d", *(__s16 *)data);
1926 btf_dump_type_values(d, "%u", *(__u16 *)data);
1929 if (d->typed_dump->is_array_char) {
1931 if (d->typed_dump->is_array_terminated)
1934 btf_dump_type_values(d, "'\\0'");
1935 d->typed_dump->is_array_terminated = true;
1939 btf_dump_type_values(d, "'%c'", *(char *)data);
1944 btf_dump_type_values(d, "%d", *(__s8 *)data);
1946 btf_dump_type_values(d, "%u", *(__u8 *)data);
1949 pr_warn("unexpected sz %d for id [%u]\n", sz, type_id);
1950 return -EINVAL;
1957 double d;
1961 static int btf_dump_float_data(struct btf_dump *d,
1968 int sz = t->size;
1971 if (!ptr_is_aligned(d->btf, type_id, data)) {
1978 btf_dump_type_values(d, "%Lf", flp->ld);
1981 btf_dump_type_values(d, "%lf", flp->d);
1984 btf_dump_type_values(d, "%f", flp->f);
1987 pr_warn("unexpected size %d for id [%u]\n", sz, type_id);
1988 return -EINVAL;
1993 static int btf_dump_var_data(struct btf_dump *d,
1998 enum btf_func_linkage linkage = btf_var(v)->linkage;
2019 btf_dump_printf(d, "%s", l);
2020 type_id = v->type;
2021 t = btf__type_by_id(d->btf, type_id);
2022 btf_dump_emit_type_cast(d, type_id, false);
2023 btf_dump_printf(d, " %s = ", btf_name_of(d, v->name_off));
2024 return btf_dump_dump_type_data(d, NULL, t, type_id, data, 0, 0);
2027 static int btf_dump_array_data(struct btf_dump *d,
2039 elem_type_id = array->type;
2040 elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
2041 elem_size = btf__resolve_size(d->btf, elem_type_id);
2045 return -EINVAL;
2055 d->typed_dump->is_array_char = true;
2065 d->typed_dump->depth++;
2066 btf_dump_printf(d, "[%s", btf_dump_data_newline(d));
2071 is_array_member = d->typed_dump->is_array_member;
2072 d->typed_dump->is_array_member = true;
2073 is_array_terminated = d->typed_dump->is_array_terminated;
2074 d->typed_dump->is_array_terminated = false;
2075 for (i = 0; i < array->nelems; i++, data += elem_size) {
2076 if (d->typed_dump->is_array_terminated)
2078 btf_dump_dump_type_data(d, NULL, elem_type, elem_type_id, data, 0, 0);
2080 d->typed_dump->is_array_member = is_array_member;
2081 d->typed_dump->is_array_terminated = is_array_terminated;
2082 d->typed_dump->depth--;
2083 btf_dump_data_pfx(d);
2084 btf_dump_type_values(d, "]");
2089 static int btf_dump_struct_data(struct btf_dump *d,
2105 d->typed_dump->depth++;
2106 btf_dump_printf(d, "{%s", btf_dump_data_newline(d));
2114 mtype = btf__type_by_id(d->btf, m->type);
2115 mname = btf_name_of(d, m->name_off);
2119 err = btf_dump_dump_type_data(d, mname, mtype, m->type, data + moffset / 8,
2124 d->typed_dump->depth--;
2125 btf_dump_data_pfx(d);
2126 btf_dump_type_values(d, "}");
2135 static int btf_dump_ptr_data(struct btf_dump *d,
2140 if (ptr_is_aligned(d->btf, id, data) && d->ptr_sz == sizeof(void *)) {
2141 btf_dump_type_values(d, "%p", *(void **)data);
2145 memcpy(&pt, data, d->ptr_sz);
2146 if (d->ptr_sz == 4)
2147 btf_dump_type_values(d, "0x%x", pt.p);
2149 btf_dump_type_values(d, "0x%llx", pt.lp);
2154 static int btf_dump_get_enum_value(struct btf_dump *d,
2162 if (!ptr_is_aligned(d->btf, id, data)) {
2166 err = btf_dump_get_bitfield_value(d, t, data, 0, 0, &val);
2173 switch (t->size) {
2187 pr_warn("unexpected size %d for enum, id:[%u]\n", t->size, id);
2188 return -EINVAL;
2192 static int btf_dump_enum_data(struct btf_dump *d,
2201 err = btf_dump_get_enum_value(d, t, data, id, &value);
2210 if (value != e->val)
2212 btf_dump_type_values(d, "%s", btf_name_of(d, e->name_off));
2216 btf_dump_type_values(d, is_signed ? "%d" : "%u", value);
2223 btf_dump_type_values(d, "%s", btf_name_of(d, e->name_off));
2227 btf_dump_type_values(d, is_signed ? "%lldLL" : "%lluULL",
2233 static int btf_dump_datasec_data(struct btf_dump *d,
2243 btf_dump_type_values(d, "SEC(\"%s\") ", btf_name_of(d, t->name_off));
2246 var = btf__type_by_id(d->btf, vsi->type);
2247 err = btf_dump_dump_type_data(d, NULL, var, vsi->type, data + vsi->offset, 0, 0);
2250 btf_dump_printf(d, ";");
2255 /* return size of type, or if base type overflows, return -E2BIG. */
2256 static int btf_dump_type_data_check_overflow(struct btf_dump *d,
2275 return data + nr_bytes > d->typed_dump->data_end ? -E2BIG : nr_bytes;
2278 size = btf__resolve_size(d->btf, id);
2283 return -EINVAL;
2293 t = skip_mods_and_typedefs(d->btf, id, NULL);
2297 return -EINVAL;
2306 if (data + bits_offset / 8 + size > d->typed_dump->data_end)
2307 return -E2BIG;
2315 static int btf_dump_type_data_check_zero(struct btf_dump *d,
2326 * - we ask for them (emit_zeros)
2327 * - if we are at top-level so we see "struct empty { }"
2328 * - or if we are an array member and the array is non-empty and
2330 * have an integer array 0, 1, 0, 1 and only show non-zero values.
2332 * with a '\0', the array-level check_zero() will prevent showing it;
2336 if (d->typed_dump->emit_zeroes || d->typed_dump->depth == 0 ||
2337 (d->typed_dump->is_array_member &&
2338 !d->typed_dump->is_array_char))
2341 t = skip_mods_and_typedefs(d->btf, id, NULL);
2346 return btf_dump_bitfield_check_zero(d, t, data, bits_offset, bit_sz);
2347 return btf_dump_base_type_check_zero(d, t, id, data);
2350 return btf_dump_base_type_check_zero(d, t, id, data);
2357 elem_type_id = array->type;
2358 elem_size = btf__resolve_size(d->btf, elem_type_id);
2359 elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
2367 * non-zero because the string is terminated.
2369 for (i = 0; i < array->nelems; i++) {
2371 return -ENODATA;
2372 err = btf_dump_type_data_check_zero(d, elem_type,
2377 if (err != -ENODATA)
2380 return -ENODATA;
2387 /* if any struct/union member is non-zero, the struct/union
2388 * is considered non-zero and dumped.
2394 mtype = btf__type_by_id(d->btf, m->type);
2402 err = btf_dump_type_data_check_zero(d, mtype, m->type, data + moffset / 8,
2407 return -ENODATA;
2411 err = btf_dump_get_enum_value(d, t, data, id, &value);
2415 return -ENODATA;
2423 static int btf_dump_dump_type_data(struct btf_dump *d,
2433 size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset, bit_sz);
2436 err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);
2441 if (err == -ENODATA)
2445 btf_dump_data_pfx(d);
2447 if (!d->typed_dump->skip_names) {
2449 btf_dump_printf(d, ".%s = ", fname);
2450 btf_dump_emit_type_cast(d, id, true);
2453 t = skip_mods_and_typedefs(d->btf, id, NULL);
2461 err = btf_dump_unsupported_data(d, t, id);
2465 err = btf_dump_bitfield_data(d, t, data, bits_offset, bit_sz);
2467 err = btf_dump_int_data(d, t, id, data, bits_offset);
2470 err = btf_dump_float_data(d, t, id, data);
2473 err = btf_dump_ptr_data(d, t, id, data);
2476 err = btf_dump_array_data(d, t, id, data);
2480 err = btf_dump_struct_data(d, t, id, data);
2489 err = btf_dump_get_bitfield_value(d, t, data, bits_offset, bit_sz,
2494 err = btf_dump_enum_data(d, t, id, &enum_val);
2496 err = btf_dump_enum_data(d, t, id, data);
2499 err = btf_dump_var_data(d, t, id, data);
2502 err = btf_dump_datasec_data(d, t, id, data);
2506 BTF_INFO_KIND(t->info), id);
2507 return -EINVAL;
2514 int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
2523 return libbpf_err(-EINVAL);
2525 t = btf__type_by_id(d->btf, id);
2527 return libbpf_err(-ENOENT);
2529 d->typed_dump = &typed_dump;
2530 d->typed_dump->data_end = data + data_sz;
2531 d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0);
2535 d->typed_dump->indent_str[0] = '\t';
2537 libbpf_strlcpy(d->typed_dump->indent_str, opts->indent_str,
2538 sizeof(d->typed_dump->indent_str));
2540 d->typed_dump->compact = OPTS_GET(opts, compact, false);
2541 d->typed_dump->skip_names = OPTS_GET(opts, skip_names, false);
2542 d->typed_dump->emit_zeroes = OPTS_GET(opts, emit_zeroes, false);
2544 ret = btf_dump_dump_type_data(d, NULL, t, id, data, 0, 0);
2546 d->typed_dump = NULL;