// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <test_progs.h>

#ifdef HAVE_LLVM_SUPPORT

#include <llvm-c/Core.h>
#include <llvm-c/Disassembler.h>
#include <llvm-c/Target.h>
#include <llvm-c/TargetMachine.h>

/* The intent is to use get_jited_program_text() for small test
 * programs written in BPF assembly, thus assume that 32 local labels
 * would be sufficient.
 */
#define MAX_LOCAL_LABELS 32

/* Local labels are encoded as 'L42', this requires 4 bytes of storage:
 * 3 characters + zero byte
 */
#define LOCAL_LABEL_LEN 4

static bool llvm_initialized;

struct local_labels {
	bool print_phase;
	__u32 prog_len;
	__u32 cnt;
	__u32 pcs[MAX_LOCAL_LABELS];
	char names[MAX_LOCAL_LABELS][LOCAL_LABEL_LEN];
};

static const char *lookup_symbol(void *data, uint64_t ref_value, uint64_t *ref_type,
				 uint64_t ref_pc, const char **ref_name)
{
	struct local_labels *labels = data;
	uint64_t type = *ref_type;
	int i;

	*ref_type = LLVMDisassembler_ReferenceType_InOut_None;
	*ref_name = NULL;
	if (type != LLVMDisassembler_ReferenceType_In_Branch)
		return NULL;
	/* Depending on labels->print_phase either discover local labels or
	 * return a name assigned with local jump target:
	 * - if print_phase is true and ref_value is in labels->pcs,
	 *   return corresponding labels->name.
	 * - if print_phase is false, save program-local jump targets
	 *   in labels->pcs;
	 */
	if (labels->print_phase) {
		for (i = 0; i < labels->cnt; ++i)
			if (labels->pcs[i] == ref_value)
				return labels->names[i];
	} else {
		if (labels->cnt < MAX_LOCAL_LABELS && ref_value < labels->prog_len)
			labels->pcs[labels->cnt++] = ref_value;
	}
	return NULL;
}

static int disasm_insn(LLVMDisasmContextRef ctx, uint8_t *image, __u32 len, __u32 pc,
		       char *buf, __u32 buf_sz)
{
	int i, cnt;

	cnt = LLVMDisasmInstruction(ctx, image + pc, len - pc, pc,
				    buf, buf_sz);
	if (cnt > 0)
		return cnt;
	PRINT_FAIL("Can't disasm instruction at offset %d:", pc);
	for (i = 0; i < 16 && pc + i < len; ++i)
		printf(" %02x", image[pc + i]);
	printf("\n");
	return -EINVAL;
}

static int cmp_u32(const void *_a, const void *_b)
{
	__u32 a = *(__u32 *)_a;
	__u32 b = *(__u32 *)_b;

	if (a < b)
		return -1;
	if (a > b)
		return 1;
	return 0;
}

static int disasm_one_func(FILE *text_out, uint8_t *image, __u32 len)
{
	char *label, *colon, *triple = NULL;
	LLVMDisasmContextRef ctx = NULL;
	struct local_labels labels = {};
	__u32 *label_pc, pc;
	int i, cnt, err = 0;
	char buf[64];
	char *cpu, *features;

	triple = LLVMGetDefaultTargetTriple();

	cpu = LLVMGetHostCPUName();
	features = LLVMGetHostCPUFeatures();

	ctx = LLVMCreateDisasmCPUFeatures(triple, cpu, features, &labels, 0, NULL, lookup_symbol);

	LLVMDisposeMessage(cpu);
	LLVMDisposeMessage(features);

	if (!ASSERT_OK_PTR(ctx, "LLVMCreateDisasmCPUFeatures")) {
		err = -EINVAL;
		goto out;
	}

	cnt = LLVMSetDisasmOptions(ctx, LLVMDisassembler_Option_PrintImmHex);
	if (!ASSERT_EQ(cnt, 1, "LLVMSetDisasmOptions")) {
		err = -EINVAL;
		goto out;
	}

	/* discover labels */
	labels.prog_len = len;
	pc = 0;
	while (pc < len) {
		cnt = disasm_insn(ctx, image, len, pc, buf, 1);
		if (cnt < 0) {
			err = cnt;
			goto out;
		}
		pc += cnt;
	}
	qsort(labels.pcs, labels.cnt, sizeof(*labels.pcs), cmp_u32);
	/* gcc is unable to infer upper bound for labels.cnt and
	 * assumes it to be U32_MAX. U32_MAX takes 10 decimal digits.
	 * snprintf below prints into labels.names[*], which has space
	 * only for two digits and a letter.  To avoid truncation
	 * warning use (i < MAX_LOCAL_LABELS), which informs gcc about
	 * printed value upper bound.
	 */
	for (i = 0; i < labels.cnt && i < MAX_LOCAL_LABELS; ++i)
		snprintf(labels.names[i], sizeof(labels.names[i]), "L%d", i);

	/* now print with labels */
	labels.print_phase = true;
	pc = 0;
	while (pc < len) {
		cnt = disasm_insn(ctx, image, len, pc, buf, sizeof(buf));
		if (cnt < 0) {
			err = cnt;
			goto out;
		}
		label_pc = bsearch(&pc, labels.pcs, labels.cnt, sizeof(*labels.pcs), cmp_u32);
		label = "";
		colon = "";
		if (label_pc) {
			label = labels.names[label_pc - labels.pcs];
			colon = ":";
		}
		fprintf(text_out, "%x:\t", pc);
		for (i = 0; i < cnt; ++i)
			fprintf(text_out, "%02x ", image[pc + i]);
		for (i = cnt * 3; i < 12 * 3; ++i)
			fputc(' ', text_out);
		fprintf(text_out, "%s%s%s\n", label, colon, buf);
		pc += cnt;
	}

out:
	if (triple)
		LLVMDisposeMessage(triple);
	if (ctx)
		LLVMDisasmDispose(ctx);
	return err;
}

int get_jited_program_text(int fd, char *text, size_t text_sz)
{
	struct bpf_prog_info info = {};
	__u32 info_len = sizeof(info);
	__u32 jited_funcs, len, pc;
	__u32 *func_lens = NULL;
	FILE *text_out = NULL;
	uint8_t *image = NULL;
	int i, err = 0;

	if (!llvm_initialized) {
		LLVMInitializeAllTargetInfos();
		LLVMInitializeAllTargetMCs();
		LLVMInitializeAllDisassemblers();
		llvm_initialized = 1;
	}

	text_out = fmemopen(text, text_sz, "w");
	if (!ASSERT_OK_PTR(text_out, "open_memstream")) {
		err = -errno;
		goto out;
	}

	/* first call is to find out jited program len */
	err = bpf_prog_get_info_by_fd(fd, &info, &info_len);
	if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd #1"))
		goto out;

	len = info.jited_prog_len;
	image = malloc(len);
	if (!ASSERT_OK_PTR(image, "malloc(info.jited_prog_len)")) {
		err = -ENOMEM;
		goto out;
	}

	jited_funcs = info.nr_jited_func_lens;
	func_lens = malloc(jited_funcs * sizeof(__u32));
	if (!ASSERT_OK_PTR(func_lens, "malloc(info.nr_jited_func_lens)")) {
		err = -ENOMEM;
		goto out;
	}

	memset(&info, 0, sizeof(info));
	info.jited_prog_insns = (__u64)image;
	info.jited_prog_len = len;
	info.jited_func_lens = (__u64)func_lens;
	info.nr_jited_func_lens = jited_funcs;
	err = bpf_prog_get_info_by_fd(fd, &info, &info_len);
	if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd #2"))
		goto out;

	for (pc = 0, i = 0; i < jited_funcs; ++i) {
		fprintf(text_out, "func #%d:\n", i);
		disasm_one_func(text_out, image + pc, func_lens[i]);
		fprintf(text_out, "\n");
		pc += func_lens[i];
	}

out:
	if (text_out)
		fclose(text_out);
	if (image)
		free(image);
	if (func_lens)
		free(func_lens);
	return err;
}

#else /* HAVE_LLVM_SUPPORT */

int get_jited_program_text(int fd, char *text, size_t text_sz)
{
	if (env.verbosity >= VERBOSE_VERY)
		printf("compiled w/o llvm development libraries, can't dis-assembly binary code");
	return -EOPNOTSUPP;
}

#endif /* HAVE_LLVM_SUPPORT */
