// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (c) 2018 Facebook */

#include <ctype.h>
#include <stdio.h> /* for (FILE *) used by json_writer */
#include <string.h>
#include <unistd.h>
#include <asm/byteorder.h>
#include <linux/bitops.h>
#include <linux/btf.h>
#include <linux/err.h>
#include <bpf/btf.h>
#include <bpf/bpf.h>

#include "json_writer.h"
#include "main.h"

#define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1)
#define BITS_PER_BYTE_MASKED(bits) ((bits) & BITS_PER_BYTE_MASK)
#define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3)
#define BITS_ROUNDUP_BYTES(bits) \
	(BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits))

static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
			      __u8 bit_offset, const void *data);

static int btf_dump_func(const struct btf *btf, char *func_sig,
			 const struct btf_type *func_proto,
			 const struct btf_type *func, int pos, int size);

static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
				    const struct btf_type *func_proto,
				    __u32 prog_id)
{
	const struct btf_type *func_type;
	int prog_fd = -1, func_sig_len;
	struct bpf_prog_info info = {};
	__u32 info_len = sizeof(info);
	const char *prog_name = NULL;
	struct btf *prog_btf = NULL;
	struct bpf_func_info finfo;
	__u32 finfo_rec_size;
	char prog_str[1024];
	int err;

	/* Get the ptr's func_proto */
	func_sig_len = btf_dump_func(d->btf, prog_str, func_proto, NULL, 0,
				     sizeof(prog_str));
	if (func_sig_len == -1)
		return -1;

	if (!prog_id)
		goto print;

	/* Get the bpf_prog's name.  Obtain from func_info. */
	prog_fd = bpf_prog_get_fd_by_id(prog_id);
	if (prog_fd < 0)
		goto print;

	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
	if (err)
		goto print;

	if (!info.btf_id || !info.nr_func_info)
		goto print;

	finfo_rec_size = info.func_info_rec_size;
	memset(&info, 0, sizeof(info));
	info.nr_func_info = 1;
	info.func_info_rec_size = finfo_rec_size;
	info.func_info = ptr_to_u64(&finfo);

	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
	if (err)
		goto print;

	prog_btf = btf__load_from_kernel_by_id(info.btf_id);
	if (!prog_btf)
		goto print;
	func_type = btf__type_by_id(prog_btf, finfo.type_id);
	if (!func_type || !btf_is_func(func_type))
		goto print;

	prog_name = btf__name_by_offset(prog_btf, func_type->name_off);

print:
	if (!prog_id)
		snprintf(&prog_str[func_sig_len],
			 sizeof(prog_str) - func_sig_len, " 0");
	else if (prog_name)
		snprintf(&prog_str[func_sig_len],
			 sizeof(prog_str) - func_sig_len,
			 " %s/prog_id:%u", prog_name, prog_id);
	else
		snprintf(&prog_str[func_sig_len],
			 sizeof(prog_str) - func_sig_len,
			 " <unknown_prog_name>/prog_id:%u", prog_id);

	prog_str[sizeof(prog_str) - 1] = '\0';
	jsonw_string(d->jw, prog_str);
	btf__free(prog_btf);
	if (prog_fd >= 0)
		close(prog_fd);
	return 0;
}

static void btf_dumper_ptr(const struct btf_dumper *d,
			   const struct btf_type *t,
			   const void *data)
{
	unsigned long value = *(unsigned long *)data;
	const struct btf_type *ptr_type;
	__s32 ptr_type_id;

	if (!d->prog_id_as_func_ptr || value > UINT32_MAX)
		goto print_ptr_value;

	ptr_type_id = btf__resolve_type(d->btf, t->type);
	if (ptr_type_id < 0)
		goto print_ptr_value;
	ptr_type = btf__type_by_id(d->btf, ptr_type_id);
	if (!ptr_type || !btf_is_func_proto(ptr_type))
		goto print_ptr_value;

	if (!dump_prog_id_as_func_ptr(d, ptr_type, value))
		return;

print_ptr_value:
	if (d->is_plain_text)
		jsonw_printf(d->jw, "\"%p\"", (void *)value);
	else
		jsonw_printf(d->jw, "%lu", value);
}

static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id,
			       __u8 bit_offset, const void *data)
{
	int actual_type_id;

	actual_type_id = btf__resolve_type(d->btf, type_id);
	if (actual_type_id < 0)
		return actual_type_id;

	return btf_dumper_do_type(d, actual_type_id, bit_offset, data);
}

static int btf_dumper_enum(const struct btf_dumper *d,
			    const struct btf_type *t,
			    const void *data)
{
	const struct btf_enum *enums = btf_enum(t);
	__s64 value;
	__u16 i;

	switch (t->size) {
	case 8:
		value = *(__s64 *)data;
		break;
	case 4:
		value = *(__s32 *)data;
		break;
	case 2:
		value = *(__s16 *)data;
		break;
	case 1:
		value = *(__s8 *)data;
		break;
	default:
		return -EINVAL;
	}

	for (i = 0; i < btf_vlen(t); i++) {
		if (value == enums[i].val) {
			jsonw_string(d->jw,
				     btf__name_by_offset(d->btf,
							 enums[i].name_off));
			return 0;
		}
	}

	jsonw_int(d->jw, value);
	return 0;
}

static int btf_dumper_enum64(const struct btf_dumper *d,
			     const struct btf_type *t,
			     const void *data)
{
	const struct btf_enum64 *enums = btf_enum64(t);
	__u32 val_lo32, val_hi32;
	__u64 value;
	__u16 i;

	value = *(__u64 *)data;
	val_lo32 = (__u32)value;
	val_hi32 = value >> 32;

	for (i = 0; i < btf_vlen(t); i++) {
		if (val_lo32 == enums[i].val_lo32 && val_hi32 == enums[i].val_hi32) {
			jsonw_string(d->jw,
				     btf__name_by_offset(d->btf,
							 enums[i].name_off));
			return 0;
		}
	}

	jsonw_int(d->jw, value);
	return 0;
}

static bool is_str_array(const struct btf *btf, const struct btf_array *arr,
			 const char *s)
{
	const struct btf_type *elem_type;
	const char *end_s;

	if (!arr->nelems)
		return false;

	elem_type = btf__type_by_id(btf, arr->type);
	/* Not skipping typedef.  typedef to char does not count as
	 * a string now.
	 */
	while (elem_type && btf_is_mod(elem_type))
		elem_type = btf__type_by_id(btf, elem_type->type);

	if (!elem_type || !btf_is_int(elem_type) || elem_type->size != 1)
		return false;

	if (btf_int_encoding(elem_type) != BTF_INT_CHAR &&
	    strcmp("char", btf__name_by_offset(btf, elem_type->name_off)))
		return false;

	end_s = s + arr->nelems;
	while (s < end_s) {
		if (!*s)
			return true;
		if (*s <= 0x1f || *s >= 0x7f)
			return false;
		s++;
	}

	/* '\0' is not found */
	return false;
}

static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
			    const void *data)
{
	const struct btf_type *t = btf__type_by_id(d->btf, type_id);
	struct btf_array *arr = (struct btf_array *)(t + 1);
	long long elem_size;
	int ret = 0;
	__u32 i;

	if (is_str_array(d->btf, arr, data)) {
		jsonw_string(d->jw, data);
		return 0;
	}

	elem_size = btf__resolve_size(d->btf, arr->type);
	if (elem_size < 0)
		return elem_size;

	jsonw_start_array(d->jw);
	for (i = 0; i < arr->nelems; i++) {
		ret = btf_dumper_do_type(d, arr->type, 0,
					 data + i * elem_size);
		if (ret)
			break;
	}

	jsonw_end_array(d->jw);
	return ret;
}

static void btf_int128_print(json_writer_t *jw, const void *data,
			     bool is_plain_text)
{
	/* data points to a __int128 number.
	 * Suppose
	 *     int128_num = *(__int128 *)data;
	 * The below formulas shows what upper_num and lower_num represents:
	 *     upper_num = int128_num >> 64;
	 *     lower_num = int128_num & 0xffffffffFFFFFFFFULL;
	 */
	__u64 upper_num, lower_num;

#ifdef __BIG_ENDIAN_BITFIELD
	upper_num = *(__u64 *)data;
	lower_num = *(__u64 *)(data + 8);
#else
	upper_num = *(__u64 *)(data + 8);
	lower_num = *(__u64 *)data;
#endif

	if (is_plain_text) {
		if (upper_num == 0)
			jsonw_printf(jw, "0x%llx", lower_num);
		else
			jsonw_printf(jw, "0x%llx%016llx", upper_num, lower_num);
	} else {
		if (upper_num == 0)
			jsonw_printf(jw, "\"0x%llx\"", lower_num);
		else
			jsonw_printf(jw, "\"0x%llx%016llx\"", upper_num, lower_num);
	}
}

static void btf_int128_shift(__u64 *print_num, __u16 left_shift_bits,
			     __u16 right_shift_bits)
{
	__u64 upper_num, lower_num;

#ifdef __BIG_ENDIAN_BITFIELD
	upper_num = print_num[0];
	lower_num = print_num[1];
#else
	upper_num = print_num[1];
	lower_num = print_num[0];
#endif

	/* shake out un-needed bits by shift/or operations */
	if (left_shift_bits >= 64) {
		upper_num = lower_num << (left_shift_bits - 64);
		lower_num = 0;
	} else {
		upper_num = (upper_num << left_shift_bits) |
			    (lower_num >> (64 - left_shift_bits));
		lower_num = lower_num << left_shift_bits;
	}

	if (right_shift_bits >= 64) {
		lower_num = upper_num >> (right_shift_bits - 64);
		upper_num = 0;
	} else {
		lower_num = (lower_num >> right_shift_bits) |
			    (upper_num << (64 - right_shift_bits));
		upper_num = upper_num >> right_shift_bits;
	}

#ifdef __BIG_ENDIAN_BITFIELD
	print_num[0] = upper_num;
	print_num[1] = lower_num;
#else
	print_num[0] = lower_num;
	print_num[1] = upper_num;
#endif
}

static void btf_dumper_bitfield(__u32 nr_bits, __u8 bit_offset,
				const void *data, json_writer_t *jw,
				bool is_plain_text)
{
	int left_shift_bits, right_shift_bits;
	__u64 print_num[2] = {};
	int bytes_to_copy;
	int bits_to_copy;

	bits_to_copy = bit_offset + nr_bits;
	bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy);

	memcpy(print_num, data, bytes_to_copy);
#if defined(__BIG_ENDIAN_BITFIELD)
	left_shift_bits = bit_offset;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
	left_shift_bits = 128 - bits_to_copy;
#else
#error neither big nor little endian
#endif
	right_shift_bits = 128 - nr_bits;

	btf_int128_shift(print_num, left_shift_bits, right_shift_bits);
	btf_int128_print(jw, print_num, is_plain_text);
}


static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
				const void *data, json_writer_t *jw,
				bool is_plain_text)
{
	int nr_bits = BTF_INT_BITS(int_type);
	int total_bits_offset;

	/* bits_offset is at most 7.
	 * BTF_INT_OFFSET() cannot exceed 128 bits.
	 */
	total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
	data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
	bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
	btf_dumper_bitfield(nr_bits, bit_offset, data, jw,
			    is_plain_text);
}

static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
			  const void *data, json_writer_t *jw,
			  bool is_plain_text)
{
	__u32 *int_type;
	__u32 nr_bits;

	int_type = (__u32 *)(t + 1);
	nr_bits = BTF_INT_BITS(*int_type);
	/* if this is bit field */
	if (bit_offset || BTF_INT_OFFSET(*int_type) ||
	    BITS_PER_BYTE_MASKED(nr_bits)) {
		btf_dumper_int_bits(*int_type, bit_offset, data, jw,
				    is_plain_text);
		return 0;
	}

	if (nr_bits == 128) {
		btf_int128_print(jw, data, is_plain_text);
		return 0;
	}

	switch (BTF_INT_ENCODING(*int_type)) {
	case 0:
		if (BTF_INT_BITS(*int_type) == 64)
			jsonw_printf(jw, "%llu", *(__u64 *)data);
		else if (BTF_INT_BITS(*int_type) == 32)
			jsonw_printf(jw, "%u", *(__u32 *)data);
		else if (BTF_INT_BITS(*int_type) == 16)
			jsonw_printf(jw, "%hu", *(__u16 *)data);
		else if (BTF_INT_BITS(*int_type) == 8)
			jsonw_printf(jw, "%hhu", *(__u8 *)data);
		else
			btf_dumper_int_bits(*int_type, bit_offset, data, jw,
					    is_plain_text);
		break;
	case BTF_INT_SIGNED:
		if (BTF_INT_BITS(*int_type) == 64)
			jsonw_printf(jw, "%lld", *(long long *)data);
		else if (BTF_INT_BITS(*int_type) == 32)
			jsonw_printf(jw, "%d", *(int *)data);
		else if (BTF_INT_BITS(*int_type) == 16)
			jsonw_printf(jw, "%hd", *(short *)data);
		else if (BTF_INT_BITS(*int_type) == 8)
			jsonw_printf(jw, "%hhd", *(char *)data);
		else
			btf_dumper_int_bits(*int_type, bit_offset, data, jw,
					    is_plain_text);
		break;
	case BTF_INT_CHAR:
		if (isprint(*(char *)data))
			jsonw_printf(jw, "\"%c\"", *(char *)data);
		else
			if (is_plain_text)
				jsonw_printf(jw, "0x%hhx", *(char *)data);
			else
				jsonw_printf(jw, "\"\\u00%02hhx\"",
					     *(char *)data);
		break;
	case BTF_INT_BOOL:
		jsonw_bool(jw, *(bool *)data);
		break;
	default:
		/* shouldn't happen */
		return -EINVAL;
	}

	return 0;
}

static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
			     const void *data)
{
	const struct btf_type *t;
	struct btf_member *m;
	const void *data_off;
	int kind_flag;
	int ret = 0;
	int i, vlen;

	t = btf__type_by_id(d->btf, type_id);
	if (!t)
		return -EINVAL;

	kind_flag = BTF_INFO_KFLAG(t->info);
	vlen = BTF_INFO_VLEN(t->info);
	jsonw_start_object(d->jw);
	m = (struct btf_member *)(t + 1);

	for (i = 0; i < vlen; i++) {
		__u32 bit_offset = m[i].offset;
		__u32 bitfield_size = 0;

		if (kind_flag) {
			bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
			bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
		}

		jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
		data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
		if (bitfield_size) {
			btf_dumper_bitfield(bitfield_size,
					    BITS_PER_BYTE_MASKED(bit_offset),
					    data_off, d->jw, d->is_plain_text);
		} else {
			ret = btf_dumper_do_type(d, m[i].type,
						 BITS_PER_BYTE_MASKED(bit_offset),
						 data_off);
			if (ret)
				break;
		}
	}

	jsonw_end_object(d->jw);

	return ret;
}

static int btf_dumper_var(const struct btf_dumper *d, __u32 type_id,
			  __u8 bit_offset, const void *data)
{
	const struct btf_type *t = btf__type_by_id(d->btf, type_id);
	int ret;

	jsonw_start_object(d->jw);
	jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
	ret = btf_dumper_do_type(d, t->type, bit_offset, data);
	jsonw_end_object(d->jw);

	return ret;
}

static int btf_dumper_datasec(const struct btf_dumper *d, __u32 type_id,
			      const void *data)
{
	struct btf_var_secinfo *vsi;
	const struct btf_type *t;
	int ret = 0, i, vlen;

	t = btf__type_by_id(d->btf, type_id);
	if (!t)
		return -EINVAL;

	vlen = BTF_INFO_VLEN(t->info);
	vsi = (struct btf_var_secinfo *)(t + 1);

	jsonw_start_object(d->jw);
	jsonw_name(d->jw, btf__name_by_offset(d->btf, t->name_off));
	jsonw_start_array(d->jw);
	for (i = 0; i < vlen; i++) {
		ret = btf_dumper_do_type(d, vsi[i].type, 0, data + vsi[i].offset);
		if (ret)
			break;
	}
	jsonw_end_array(d->jw);
	jsonw_end_object(d->jw);

	return ret;
}

static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,
			      __u8 bit_offset, const void *data)
{
	const struct btf_type *t = btf__type_by_id(d->btf, type_id);

	switch (BTF_INFO_KIND(t->info)) {
	case BTF_KIND_INT:
		return btf_dumper_int(t, bit_offset, data, d->jw,
				     d->is_plain_text);
	case BTF_KIND_STRUCT:
	case BTF_KIND_UNION:
		return btf_dumper_struct(d, type_id, data);
	case BTF_KIND_ARRAY:
		return btf_dumper_array(d, type_id, data);
	case BTF_KIND_ENUM:
		return btf_dumper_enum(d, t, data);
	case BTF_KIND_ENUM64:
		return btf_dumper_enum64(d, t, data);
	case BTF_KIND_PTR:
		btf_dumper_ptr(d, t, data);
		return 0;
	case BTF_KIND_UNKN:
		jsonw_printf(d->jw, "(unknown)");
		return 0;
	case BTF_KIND_FWD:
		/* map key or value can't be forward */
		jsonw_printf(d->jw, "(fwd-kind-invalid)");
		return -EINVAL;
	case BTF_KIND_TYPEDEF:
	case BTF_KIND_VOLATILE:
	case BTF_KIND_CONST:
	case BTF_KIND_RESTRICT:
		return btf_dumper_modifier(d, type_id, bit_offset, data);
	case BTF_KIND_VAR:
		return btf_dumper_var(d, type_id, bit_offset, data);
	case BTF_KIND_DATASEC:
		return btf_dumper_datasec(d, type_id, data);
	default:
		jsonw_printf(d->jw, "(unsupported-kind");
		return -EINVAL;
	}
}

int btf_dumper_type(const struct btf_dumper *d, __u32 type_id,
		    const void *data)
{
	return btf_dumper_do_type(d, type_id, 0, data);
}

#define BTF_PRINT_ARG(...)						\
	do {								\
		pos += snprintf(func_sig + pos, size - pos,		\
				__VA_ARGS__);				\
		if (pos >= size)					\
			return -1;					\
	} while (0)
#define BTF_PRINT_TYPE(type)					\
	do {								\
		pos = __btf_dumper_type_only(btf, type, func_sig,	\
					     pos, size);		\
		if (pos == -1)						\
			return -1;					\
	} while (0)

static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
				  char *func_sig, int pos, int size)
{
	const struct btf_type *proto_type;
	const struct btf_array *array;
	const struct btf_var *var;
	const struct btf_type *t;

	if (!type_id) {
		BTF_PRINT_ARG("void ");
		return pos;
	}

	t = btf__type_by_id(btf, type_id);

	switch (BTF_INFO_KIND(t->info)) {
	case BTF_KIND_INT:
	case BTF_KIND_TYPEDEF:
	case BTF_KIND_FLOAT:
		BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_STRUCT:
		BTF_PRINT_ARG("struct %s ",
			      btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_UNION:
		BTF_PRINT_ARG("union %s ",
			      btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_ENUM:
	case BTF_KIND_ENUM64:
		BTF_PRINT_ARG("enum %s ",
			      btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_ARRAY:
		array = (struct btf_array *)(t + 1);
		BTF_PRINT_TYPE(array->type);
		BTF_PRINT_ARG("[%d]", array->nelems);
		break;
	case BTF_KIND_PTR:
		BTF_PRINT_TYPE(t->type);
		BTF_PRINT_ARG("* ");
		break;
	case BTF_KIND_FWD:
		BTF_PRINT_ARG("%s %s ",
			      BTF_INFO_KFLAG(t->info) ? "union" : "struct",
			      btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_VOLATILE:
		BTF_PRINT_ARG("volatile ");
		BTF_PRINT_TYPE(t->type);
		break;
	case BTF_KIND_CONST:
		BTF_PRINT_ARG("const ");
		BTF_PRINT_TYPE(t->type);
		break;
	case BTF_KIND_RESTRICT:
		BTF_PRINT_ARG("restrict ");
		BTF_PRINT_TYPE(t->type);
		break;
	case BTF_KIND_FUNC_PROTO:
		pos = btf_dump_func(btf, func_sig, t, NULL, pos, size);
		if (pos == -1)
			return -1;
		break;
	case BTF_KIND_FUNC:
		proto_type = btf__type_by_id(btf, t->type);
		pos = btf_dump_func(btf, func_sig, proto_type, t, pos, size);
		if (pos == -1)
			return -1;
		break;
	case BTF_KIND_VAR:
		var = (struct btf_var *)(t + 1);
		if (var->linkage == BTF_VAR_STATIC)
			BTF_PRINT_ARG("static ");
		BTF_PRINT_TYPE(t->type);
		BTF_PRINT_ARG(" %s",
			      btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_DATASEC:
		BTF_PRINT_ARG("section (\"%s\") ",
			      btf__name_by_offset(btf, t->name_off));
		break;
	case BTF_KIND_UNKN:
	default:
		return -1;
	}

	return pos;
}

static int btf_dump_func(const struct btf *btf, char *func_sig,
			 const struct btf_type *func_proto,
			 const struct btf_type *func, int pos, int size)
{
	int i, vlen;

	BTF_PRINT_TYPE(func_proto->type);
	if (func)
		BTF_PRINT_ARG("%s(", btf__name_by_offset(btf, func->name_off));
	else
		BTF_PRINT_ARG("(");
	vlen = BTF_INFO_VLEN(func_proto->info);
	for (i = 0; i < vlen; i++) {
		struct btf_param *arg = &((struct btf_param *)(func_proto + 1))[i];

		if (i)
			BTF_PRINT_ARG(", ");
		if (arg->type) {
			BTF_PRINT_TYPE(arg->type);
			if (arg->name_off)
				BTF_PRINT_ARG("%s",
					      btf__name_by_offset(btf, arg->name_off));
			else if (pos && func_sig[pos - 1] == ' ')
				/* Remove unnecessary space for
				 * FUNC_PROTO that does not have
				 * arg->name_off
				 */
				func_sig[--pos] = '\0';
		} else {
			BTF_PRINT_ARG("...");
		}
	}
	BTF_PRINT_ARG(")");

	return pos;
}

void btf_dumper_type_only(const struct btf *btf, __u32 type_id, char *func_sig,
			  int size)
{
	int err;

	func_sig[0] = '\0';
	if (!btf)
		return;

	err = __btf_dumper_type_only(btf, type_id, func_sig, 0, size);
	if (err < 0)
		func_sig[0] = '\0';
}

static const char *ltrim(const char *s)
{
	while (isspace(*s))
		s++;

	return s;
}

void btf_dump_linfo_plain(const struct btf *btf,
			  const struct bpf_line_info *linfo,
			  const char *prefix, bool linum)
{
	const char *line = btf__name_by_offset(btf, linfo->line_off);

	if (!line)
		return;
	line = ltrim(line);

	if (!prefix)
		prefix = "";

	if (linum) {
		const char *file = btf__name_by_offset(btf, linfo->file_name_off);

		/* More forgiving on file because linum option is
		 * expected to provide more info than the already
		 * available src line.
		 */
		if (!file)
			file = "";

		printf("%s%s [file:%s line_num:%u line_col:%u]\n",
		       prefix, line, file,
		       BPF_LINE_INFO_LINE_NUM(linfo->line_col),
		       BPF_LINE_INFO_LINE_COL(linfo->line_col));
	} else {
		printf("%s%s\n", prefix, line);
	}
}

void btf_dump_linfo_json(const struct btf *btf,
			 const struct bpf_line_info *linfo, bool linum)
{
	const char *line = btf__name_by_offset(btf, linfo->line_off);

	if (line)
		jsonw_string_field(json_wtr, "src", ltrim(line));

	if (linum) {
		const char *file = btf__name_by_offset(btf, linfo->file_name_off);

		if (file)
			jsonw_string_field(json_wtr, "file", file);

		if (BPF_LINE_INFO_LINE_NUM(linfo->line_col))
			jsonw_int_field(json_wtr, "line_num",
					BPF_LINE_INFO_LINE_NUM(linfo->line_col));

		if (BPF_LINE_INFO_LINE_COL(linfo->line_col))
			jsonw_int_field(json_wtr, "line_col",
					BPF_LINE_INFO_LINE_COL(linfo->line_col));
	}
}

static void dotlabel_puts(const char *s)
{
	for (; *s; ++s) {
		switch (*s) {
		case '\\':
		case '"':
		case '{':
		case '}':
		case '<':
		case '>':
		case '|':
		case ' ':
			putchar('\\');
			fallthrough;
		default:
			putchar(*s);
		}
	}
}

static const char *shorten_path(const char *path)
{
	const unsigned int MAX_PATH_LEN = 32;
	size_t len = strlen(path);
	const char *shortpath;

	if (len <= MAX_PATH_LEN)
		return path;

	/* Search for last '/' under the MAX_PATH_LEN limit */
	shortpath = strchr(path + len - MAX_PATH_LEN, '/');
	if (shortpath) {
		if (shortpath < path + strlen("..."))
			/* We removed a very short prefix, e.g. "/w", and we'll
			 * make the path longer by prefixing with the ellipsis.
			 * Not worth it, keep initial path.
			 */
			return path;
		return shortpath;
	}

	/* File base name length is > MAX_PATH_LEN, search for last '/' */
			shortpath = strrchr(path, '/');
	if (shortpath)
		return shortpath;

	return path;
}

void btf_dump_linfo_dotlabel(const struct btf *btf,
			     const struct bpf_line_info *linfo, bool linum)
{
	const char *line = btf__name_by_offset(btf, linfo->line_off);

	if (!line || !strlen(line))
		return;
	line = ltrim(line);

	if (linum) {
		const char *file = btf__name_by_offset(btf, linfo->file_name_off);
		const char *shortfile;

		/* More forgiving on file because linum option is
		 * expected to provide more info than the already
		 * available src line.
		 */
		if (!file)
			shortfile = "";
		else
			shortfile = shorten_path(file);

		printf("; [%s", shortfile > file ? "..." : "");
		dotlabel_puts(shortfile);
		printf(" line:%u col:%u]\\l\\\n",
		       BPF_LINE_INFO_LINE_NUM(linfo->line_col),
		       BPF_LINE_INFO_LINE_COL(linfo->line_col));
	}

	printf("; ");
	dotlabel_puts(line);
	printf("\\l\\\n");
}
