^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (c) 2018 Facebook */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <stdio.h> /* for (FILE *) used by json_writer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/btf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <bpf/btf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <bpf/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "json_writer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define BITS_PER_BYTE_MASKED(bits) ((bits) & BITS_PER_BYTE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define BITS_ROUNDUP_BYTES(bits) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) (BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) __u8 bit_offset, const void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int btf_dump_func(const struct btf *btf, char *func_sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const struct btf_type *func_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) const struct btf_type *func, int pos, int size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) const struct btf_type *func_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __u32 prog_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct bpf_prog_info_linear *prog_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const struct btf_type *func_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) const char *prog_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct bpf_func_info *finfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct btf *prog_btf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct bpf_prog_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int prog_fd, func_sig_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) char prog_str[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Get the ptr's func_proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) func_sig_len = btf_dump_func(d->btf, prog_str, func_proto, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) sizeof(prog_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (func_sig_len == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!prog_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) goto print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Get the bpf_prog's name. Obtain from func_info. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) prog_fd = bpf_prog_get_fd_by_id(prog_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (prog_fd == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) goto print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) prog_info = bpf_program__get_prog_info_linear(prog_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 1UL << BPF_PROG_INFO_FUNC_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) close(prog_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (IS_ERR(prog_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) prog_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) goto print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) info = &prog_info->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!info->btf_id || !info->nr_func_info ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) btf__get_from_id(info->btf_id, &prog_btf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) goto print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) finfo = u64_to_ptr(info->func_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) func_type = btf__type_by_id(prog_btf, finfo->type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (!func_type || !btf_is_func(func_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) goto print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) prog_name = btf__name_by_offset(prog_btf, func_type->name_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) print:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!prog_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) snprintf(&prog_str[func_sig_len],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) sizeof(prog_str) - func_sig_len, " 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else if (prog_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) snprintf(&prog_str[func_sig_len],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) sizeof(prog_str) - func_sig_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) " %s/prog_id:%u", prog_name, prog_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) snprintf(&prog_str[func_sig_len],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) sizeof(prog_str) - func_sig_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) " <unknown_prog_name>/prog_id:%u", prog_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) prog_str[sizeof(prog_str) - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) jsonw_string(d->jw, prog_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) btf__free(prog_btf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) free(prog_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void btf_dumper_ptr(const struct btf_dumper *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) const struct btf_type *t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long value = *(unsigned long *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const struct btf_type *ptr_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __s32 ptr_type_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!d->prog_id_as_func_ptr || value > UINT32_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto print_ptr_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ptr_type_id = btf__resolve_type(d->btf, t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (ptr_type_id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto print_ptr_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ptr_type = btf__type_by_id(d->btf, ptr_type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (!ptr_type || !btf_is_func_proto(ptr_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) goto print_ptr_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!dump_prog_id_as_func_ptr(d, ptr_type, value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) print_ptr_value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (d->is_plain_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) jsonw_printf(d->jw, "%p", (void *)value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) jsonw_printf(d->jw, "%lu", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) __u8 bit_offset, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int actual_type_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) actual_type_id = btf__resolve_type(d->btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (actual_type_id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return actual_type_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return btf_dumper_do_type(d, actual_type_id, bit_offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int btf_dumper_enum(const struct btf_dumper *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) const struct btf_type *t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) const struct btf_enum *enums = btf_enum(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) __s64 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) __u16 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) switch (t->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) value = *(__s64 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) value = *(__s32 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) value = *(__s16 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) value = *(__s8 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (i = 0; i < btf_vlen(t); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (value == enums[i].val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) jsonw_string(d->jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) btf__name_by_offset(d->btf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) enums[i].name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) jsonw_int(d->jw, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static bool is_str_array(const struct btf *btf, const struct btf_array *arr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) const struct btf_type *elem_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) const char *end_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (!arr->nelems)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) elem_type = btf__type_by_id(btf, arr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Not skipping typedef. typedef to char does not count as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * a string now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) while (elem_type && btf_is_mod(elem_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) elem_type = btf__type_by_id(btf, elem_type->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (!elem_type || !btf_is_int(elem_type) || elem_type->size != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (btf_int_encoding(elem_type) != BTF_INT_CHAR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) strcmp("char", btf__name_by_offset(btf, elem_type->name_off)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) end_s = s + arr->nelems;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) while (s < end_s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (*s <= 0x1f || *s >= 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* '\0' is not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) const struct btf_type *t = btf__type_by_id(d->btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct btf_array *arr = (struct btf_array *)(t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) long long elem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) __u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (is_str_array(d->btf, arr, data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) jsonw_string(d->jw, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) elem_size = btf__resolve_size(d->btf, arr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (elem_size < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return elem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) jsonw_start_array(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) for (i = 0; i < arr->nelems; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = btf_dumper_do_type(d, arr->type, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) data + i * elem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) jsonw_end_array(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static void btf_int128_print(json_writer_t *jw, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) bool is_plain_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* data points to a __int128 number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * Suppose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * int128_num = *(__int128 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * The below formulas shows what upper_num and lower_num represents:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * upper_num = int128_num >> 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * lower_num = int128_num & 0xffffffffFFFFFFFFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) __u64 upper_num, lower_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) upper_num = *(__u64 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) lower_num = *(__u64 *)(data + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) upper_num = *(__u64 *)(data + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) lower_num = *(__u64 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (is_plain_text) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (upper_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) jsonw_printf(jw, "0x%llx", lower_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) jsonw_printf(jw, "0x%llx%016llx", upper_num, lower_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (upper_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) jsonw_printf(jw, "\"0x%llx\"", lower_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) jsonw_printf(jw, "\"0x%llx%016llx\"", upper_num, lower_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static void btf_int128_shift(__u64 *print_num, __u16 left_shift_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) __u16 right_shift_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) __u64 upper_num, lower_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) upper_num = print_num[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) lower_num = print_num[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) upper_num = print_num[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) lower_num = print_num[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* shake out un-needed bits by shift/or operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (left_shift_bits >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) upper_num = lower_num << (left_shift_bits - 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) lower_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) upper_num = (upper_num << left_shift_bits) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) (lower_num >> (64 - left_shift_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) lower_num = lower_num << left_shift_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (right_shift_bits >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) lower_num = upper_num >> (right_shift_bits - 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) upper_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) lower_num = (lower_num >> right_shift_bits) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) (upper_num << (64 - right_shift_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) upper_num = upper_num >> right_shift_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) print_num[0] = upper_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) print_num[1] = lower_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) print_num[0] = lower_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) print_num[1] = upper_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static void btf_dumper_bitfield(__u32 nr_bits, __u8 bit_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) const void *data, json_writer_t *jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) bool is_plain_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int left_shift_bits, right_shift_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) __u64 print_num[2] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int bytes_to_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int bits_to_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) bits_to_copy = bit_offset + nr_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) memcpy(print_num, data, bytes_to_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #if defined(__BIG_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) left_shift_bits = bit_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #elif defined(__LITTLE_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) left_shift_bits = 128 - bits_to_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #error neither big nor little endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) right_shift_bits = 128 - nr_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) btf_int128_shift(print_num, left_shift_bits, right_shift_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) btf_int128_print(jw, print_num, is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const void *data, json_writer_t *jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) bool is_plain_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int nr_bits = BTF_INT_BITS(int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int total_bits_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* bits_offset is at most 7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * BTF_INT_OFFSET() cannot exceed 128 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) btf_dumper_bitfield(nr_bits, bit_offset, data, jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) const void *data, json_writer_t *jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) bool is_plain_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) __u32 *int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) __u32 nr_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int_type = (__u32 *)(t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) nr_bits = BTF_INT_BITS(*int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* if this is bit field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (bit_offset || BTF_INT_OFFSET(*int_type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) BITS_PER_BYTE_MASKED(nr_bits)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) btf_dumper_int_bits(*int_type, bit_offset, data, jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (nr_bits == 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) btf_int128_print(jw, data, is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) switch (BTF_INT_ENCODING(*int_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (BTF_INT_BITS(*int_type) == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) jsonw_printf(jw, "%llu", *(__u64 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) else if (BTF_INT_BITS(*int_type) == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) jsonw_printf(jw, "%u", *(__u32 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) else if (BTF_INT_BITS(*int_type) == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) jsonw_printf(jw, "%hu", *(__u16 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) else if (BTF_INT_BITS(*int_type) == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) jsonw_printf(jw, "%hhu", *(__u8 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) btf_dumper_int_bits(*int_type, bit_offset, data, jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case BTF_INT_SIGNED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (BTF_INT_BITS(*int_type) == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) jsonw_printf(jw, "%lld", *(long long *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) else if (BTF_INT_BITS(*int_type) == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) jsonw_printf(jw, "%d", *(int *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) else if (BTF_INT_BITS(*int_type) == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) jsonw_printf(jw, "%hd", *(short *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) else if (BTF_INT_BITS(*int_type) == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) jsonw_printf(jw, "%hhd", *(char *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) btf_dumper_int_bits(*int_type, bit_offset, data, jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case BTF_INT_CHAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (isprint(*(char *)data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) jsonw_printf(jw, "\"%c\"", *(char *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (is_plain_text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) jsonw_printf(jw, "0x%hhx", *(char *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) jsonw_printf(jw, "\"\\u00%02hhx\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) *(char *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case BTF_INT_BOOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) jsonw_bool(jw, *(int *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* shouldn't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) const struct btf_type *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct btf_member *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) const void *data_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int kind_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int i, vlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) t = btf__type_by_id(d->btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) kind_flag = BTF_INFO_KFLAG(t->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) vlen = BTF_INFO_VLEN(t->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) jsonw_start_object(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) m = (struct btf_member *)(t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) for (i = 0; i < vlen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) __u32 bit_offset = m[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) __u32 bitfield_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (kind_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (bitfield_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) btf_dumper_bitfield(bitfield_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) BITS_PER_BYTE_MASKED(bit_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) data_off, d->jw, d->is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = btf_dumper_do_type(d, m[i].type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) BITS_PER_BYTE_MASKED(bit_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) data_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) jsonw_end_object(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int btf_dumper_var(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) __u8 bit_offset, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) const struct btf_type *t = btf__type_by_id(d->btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) jsonw_start_object(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = btf_dumper_do_type(d, t->type, bit_offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) jsonw_end_object(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static int btf_dumper_datasec(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct btf_var_secinfo *vsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) const struct btf_type *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int ret = 0, i, vlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) t = btf__type_by_id(d->btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) vlen = BTF_INFO_VLEN(t->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) vsi = (struct btf_var_secinfo *)(t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) jsonw_start_object(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) jsonw_start_array(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) for (i = 0; i < vlen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = btf_dumper_do_type(d, vsi[i].type, 0, data + vsi[i].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) jsonw_end_array(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) jsonw_end_object(d->jw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) __u8 bit_offset, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) const struct btf_type *t = btf__type_by_id(d->btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) switch (BTF_INFO_KIND(t->info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) case BTF_KIND_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return btf_dumper_int(t, bit_offset, data, d->jw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) d->is_plain_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) case BTF_KIND_STRUCT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case BTF_KIND_UNION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return btf_dumper_struct(d, type_id, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) case BTF_KIND_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return btf_dumper_array(d, type_id, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case BTF_KIND_ENUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return btf_dumper_enum(d, t, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case BTF_KIND_PTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) btf_dumper_ptr(d, t, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) case BTF_KIND_UNKN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) jsonw_printf(d->jw, "(unknown)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) case BTF_KIND_FWD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* map key or value can't be forward */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) jsonw_printf(d->jw, "(fwd-kind-invalid)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case BTF_KIND_TYPEDEF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case BTF_KIND_VOLATILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case BTF_KIND_CONST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) case BTF_KIND_RESTRICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return btf_dumper_modifier(d, type_id, bit_offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) case BTF_KIND_VAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return btf_dumper_var(d, type_id, bit_offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) case BTF_KIND_DATASEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return btf_dumper_datasec(d, type_id, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) jsonw_printf(d->jw, "(unsupported-kind");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int btf_dumper_type(const struct btf_dumper *d, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return btf_dumper_do_type(d, type_id, 0, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #define BTF_PRINT_ARG(...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) pos += snprintf(func_sig + pos, size - pos, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) __VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (pos >= size) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) #define BTF_PRINT_TYPE(type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) pos = __btf_dumper_type_only(btf, type, func_sig, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pos, size); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (pos == -1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) char *func_sig, int pos, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) const struct btf_type *proto_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) const struct btf_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) const struct btf_var *var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) const struct btf_type *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (!type_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) BTF_PRINT_ARG("void ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) t = btf__type_by_id(btf, type_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) switch (BTF_INFO_KIND(t->info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) case BTF_KIND_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) case BTF_KIND_TYPEDEF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) case BTF_KIND_STRUCT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) BTF_PRINT_ARG("struct %s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case BTF_KIND_UNION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) BTF_PRINT_ARG("union %s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case BTF_KIND_ENUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) BTF_PRINT_ARG("enum %s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case BTF_KIND_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) array = (struct btf_array *)(t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) BTF_PRINT_TYPE(array->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) BTF_PRINT_ARG("[%d]", array->nelems);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case BTF_KIND_PTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) BTF_PRINT_TYPE(t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) BTF_PRINT_ARG("* ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case BTF_KIND_FWD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) BTF_PRINT_ARG("%s %s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) BTF_INFO_KFLAG(t->info) ? "union" : "struct",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case BTF_KIND_VOLATILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) BTF_PRINT_ARG("volatile ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) BTF_PRINT_TYPE(t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case BTF_KIND_CONST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) BTF_PRINT_ARG("const ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) BTF_PRINT_TYPE(t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case BTF_KIND_RESTRICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) BTF_PRINT_ARG("restrict ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) BTF_PRINT_TYPE(t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case BTF_KIND_FUNC_PROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) pos = btf_dump_func(btf, func_sig, t, NULL, pos, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case BTF_KIND_FUNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) proto_type = btf__type_by_id(btf, t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pos = btf_dump_func(btf, func_sig, proto_type, t, pos, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) case BTF_KIND_VAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) var = (struct btf_var *)(t + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (var->linkage == BTF_VAR_STATIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) BTF_PRINT_ARG("static ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) BTF_PRINT_TYPE(t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) BTF_PRINT_ARG(" %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case BTF_KIND_DATASEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) BTF_PRINT_ARG("section (\"%s\") ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) btf__name_by_offset(btf, t->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case BTF_KIND_UNKN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static int btf_dump_func(const struct btf *btf, char *func_sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) const struct btf_type *func_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) const struct btf_type *func, int pos, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int i, vlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) BTF_PRINT_TYPE(func_proto->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) BTF_PRINT_ARG("%s(", btf__name_by_offset(btf, func->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) BTF_PRINT_ARG("(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) vlen = BTF_INFO_VLEN(func_proto->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) for (i = 0; i < vlen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct btf_param *arg = &((struct btf_param *)(func_proto + 1))[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) BTF_PRINT_ARG(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (arg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) BTF_PRINT_TYPE(arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (arg->name_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) BTF_PRINT_ARG("%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) btf__name_by_offset(btf, arg->name_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) else if (pos && func_sig[pos - 1] == ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* Remove unnecessary space for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * FUNC_PROTO that does not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * arg->name_off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) func_sig[--pos] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) BTF_PRINT_ARG("...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) BTF_PRINT_ARG(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) void btf_dumper_type_only(const struct btf *btf, __u32 type_id, char *func_sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) func_sig[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (!btf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) err = __btf_dumper_type_only(btf, type_id, func_sig, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) func_sig[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static const char *ltrim(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) while (isspace(*s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) void btf_dump_linfo_plain(const struct btf *btf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) const struct bpf_line_info *linfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) const char *prefix, bool linum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) const char *line = btf__name_by_offset(btf, linfo->line_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (!line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) line = ltrim(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (!prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) prefix = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (linum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) const char *file = btf__name_by_offset(btf, linfo->file_name_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* More forgiving on file because linum option is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * expected to provide more info than the already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * available src line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) file = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) printf("%s%s [file:%s line_num:%u line_col:%u]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) prefix, line, file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) BPF_LINE_INFO_LINE_NUM(linfo->line_col),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) BPF_LINE_INFO_LINE_COL(linfo->line_col));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) printf("%s%s\n", prefix, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) void btf_dump_linfo_json(const struct btf *btf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) const struct bpf_line_info *linfo, bool linum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) const char *line = btf__name_by_offset(btf, linfo->line_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) jsonw_string_field(json_wtr, "src", ltrim(line));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (linum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) const char *file = btf__name_by_offset(btf, linfo->file_name_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) jsonw_string_field(json_wtr, "file", file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (BPF_LINE_INFO_LINE_NUM(linfo->line_col))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) jsonw_int_field(json_wtr, "line_num",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) BPF_LINE_INFO_LINE_NUM(linfo->line_col));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (BPF_LINE_INFO_LINE_COL(linfo->line_col))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) jsonw_int_field(json_wtr, "line_col",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) BPF_LINE_INFO_LINE_COL(linfo->line_col));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }