Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }