// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
 * Copyright (C) 2015, Huawei Inc.
 */

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/zalloc.h>
#include "debug.h"
#include "llvm-utils.h"
#include "config.h"
#include "util.h"
#include <sys/wait.h>
#include <subcmd/exec-cmd.h>

#define CLANG_BPF_CMD_DEFAULT_TEMPLATE				\
		"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
		"-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE "	\
		"$CLANG_OPTIONS $PERF_BPF_INC_OPTIONS $KERNEL_INC_OPTIONS " \
		"-Wno-unused-value -Wno-pointer-sign "		\
		"-working-directory $WORKING_DIR "		\
		"-c \"$CLANG_SOURCE\" --target=bpf $CLANG_EMIT_LLVM -g -O2 -o - $LLVM_OPTIONS_PIPE"

struct llvm_param llvm_param = {
	.clang_path = "clang",
	.llc_path = "llc",
	.clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE,
	.clang_opt = NULL,
	.opts = NULL,
	.kbuild_dir = NULL,
	.kbuild_opts = NULL,
	.user_set_param = false,
};

static void version_notice(void);

int perf_llvm_config(const char *var, const char *value)
{
	if (!strstarts(var, "llvm."))
		return 0;
	var += sizeof("llvm.") - 1;

	if (!strcmp(var, "clang-path"))
		llvm_param.clang_path = strdup(value);
	else if (!strcmp(var, "clang-bpf-cmd-template"))
		llvm_param.clang_bpf_cmd_template = strdup(value);
	else if (!strcmp(var, "clang-opt"))
		llvm_param.clang_opt = strdup(value);
	else if (!strcmp(var, "kbuild-dir"))
		llvm_param.kbuild_dir = strdup(value);
	else if (!strcmp(var, "kbuild-opts"))
		llvm_param.kbuild_opts = strdup(value);
	else if (!strcmp(var, "dump-obj"))
		llvm_param.dump_obj = !!perf_config_bool(var, value);
	else if (!strcmp(var, "opts"))
		llvm_param.opts = strdup(value);
	else {
		pr_debug("Invalid LLVM config option: %s\n", value);
		return -1;
	}
	llvm_param.user_set_param = true;
	return 0;
}

static int
search_program(const char *def, const char *name,
	       char *output)
{
	char *env, *path, *tmp = NULL;
	char buf[PATH_MAX];
	int ret;

	output[0] = '\0';
	if (def && def[0] != '\0') {
		if (def[0] == '/') {
			if (access(def, F_OK) == 0) {
				strlcpy(output, def, PATH_MAX);
				return 0;
			}
		} else if (def[0] != '\0')
			name = def;
	}

	env = getenv("PATH");
	if (!env)
		return -1;
	env = strdup(env);
	if (!env)
		return -1;

	ret = -ENOENT;
	path = strtok_r(env, ":",  &tmp);
	while (path) {
		scnprintf(buf, sizeof(buf), "%s/%s", path, name);
		if (access(buf, F_OK) == 0) {
			strlcpy(output, buf, PATH_MAX);
			ret = 0;
			break;
		}
		path = strtok_r(NULL, ":", &tmp);
	}

	free(env);
	return ret;
}

static int search_program_and_warn(const char *def, const char *name,
				   char *output)
{
	int ret = search_program(def, name, output);

	if (ret) {
		pr_err("ERROR:\tunable to find %s.\n"
		       "Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH\n"
		       "     \tand '%s-path' option in [llvm] section of ~/.perfconfig.\n",
		       name, name);
		version_notice();
	}
	return ret;
}

#define READ_SIZE	4096
static int
read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
{
	int err = 0;
	void *buf = NULL;
	FILE *file = NULL;
	size_t read_sz = 0, buf_sz = 0;
	char serr[STRERR_BUFSIZE];

	file = popen(cmd, "r");
	if (!file) {
		pr_err("ERROR: unable to popen cmd: %s\n",
		       str_error_r(errno, serr, sizeof(serr)));
		return -EINVAL;
	}

	while (!feof(file) && !ferror(file)) {
		/*
		 * Make buf_sz always have obe byte extra space so we
		 * can put '\0' there.
		 */
		if (buf_sz - read_sz < READ_SIZE + 1) {
			void *new_buf;

			buf_sz = read_sz + READ_SIZE + 1;
			new_buf = realloc(buf, buf_sz);

			if (!new_buf) {
				pr_err("ERROR: failed to realloc memory\n");
				err = -ENOMEM;
				goto errout;
			}

			buf = new_buf;
		}
		read_sz += fread(buf + read_sz, 1, READ_SIZE, file);
	}

	if (buf_sz - read_sz < 1) {
		pr_err("ERROR: internal error\n");
		err = -EINVAL;
		goto errout;
	}

	if (ferror(file)) {
		pr_err("ERROR: error occurred when reading from pipe: %s\n",
		       str_error_r(errno, serr, sizeof(serr)));
		err = -EIO;
		goto errout;
	}

	err = WEXITSTATUS(pclose(file));
	file = NULL;
	if (err) {
		err = -EINVAL;
		goto errout;
	}

	/*
	 * If buf is string, give it terminal '\0' to make our life
	 * easier. If buf is not string, that '\0' is out of space
	 * indicated by read_sz so caller won't even notice it.
	 */
	((char *)buf)[read_sz] = '\0';

	if (!p_buf)
		free(buf);
	else
		*p_buf = buf;

	if (p_read_sz)
		*p_read_sz = read_sz;
	return 0;

errout:
	if (file)
		pclose(file);
	free(buf);
	if (p_buf)
		*p_buf = NULL;
	if (p_read_sz)
		*p_read_sz = 0;
	return err;
}

static inline void
force_set_env(const char *var, const char *value)
{
	if (value) {
		setenv(var, value, 1);
		pr_debug("set env: %s=%s\n", var, value);
	} else {
		unsetenv(var);
		pr_debug("unset env: %s\n", var);
	}
}

static void
version_notice(void)
{
	pr_err(
"     \tLLVM 3.7 or newer is required. Which can be found from http://llvm.org\n"
"     \tYou may want to try git trunk:\n"
"     \t\tgit clone http://llvm.org/git/llvm.git\n"
"     \t\t     and\n"
"     \t\tgit clone http://llvm.org/git/clang.git\n\n"
"     \tOr fetch the latest clang/llvm 3.7 from pre-built llvm packages for\n"
"     \tdebian/ubuntu:\n"
"     \t\thttps://apt.llvm.org/\n\n"
"     \tIf you are using old version of clang, change 'clang-bpf-cmd-template'\n"
"     \toption in [llvm] section of ~/.perfconfig to:\n\n"
"     \t  \"$CLANG_EXEC $CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS \\\n"
"     \t     -working-directory $WORKING_DIR -c $CLANG_SOURCE \\\n"
"     \t     -emit-llvm -o - | /path/to/llc -march=bpf -filetype=obj -o -\"\n"
"     \t(Replace /path/to/llc with path to your llc)\n\n"
);
}

static int detect_kbuild_dir(char **kbuild_dir)
{
	const char *test_dir = llvm_param.kbuild_dir;
	const char *prefix_dir = "";
	const char *suffix_dir = "";

	/* _UTSNAME_LENGTH is 65 */
	char release[128];

	char *autoconf_path;

	int err;

	if (!test_dir) {
		err = fetch_kernel_version(NULL, release,
					   sizeof(release));
		if (err)
			return -EINVAL;

		test_dir = release;
		prefix_dir = "/lib/modules/";
		suffix_dir = "/build";
	}

	err = asprintf(&autoconf_path, "%s%s%s/include/generated/autoconf.h",
		       prefix_dir, test_dir, suffix_dir);
	if (err < 0)
		return -ENOMEM;

	if (access(autoconf_path, R_OK) == 0) {
		free(autoconf_path);

		err = asprintf(kbuild_dir, "%s%s%s", prefix_dir, test_dir,
			       suffix_dir);
		if (err < 0)
			return -ENOMEM;
		return 0;
	}
	pr_debug("%s: Couldn't find \"%s\", missing kernel-devel package?.\n",
		 __func__, autoconf_path);
	free(autoconf_path);
	return -ENOENT;
}

static const char *kinc_fetch_script =
"#!/usr/bin/env sh\n"
"if ! test -d \"$KBUILD_DIR\"\n"
"then\n"
"	exit 1\n"
"fi\n"
"if ! test -f \"$KBUILD_DIR/include/generated/autoconf.h\"\n"
"then\n"
"	exit 1\n"
"fi\n"
"TMPDIR=`mktemp -d`\n"
"if test -z \"$TMPDIR\"\n"
"then\n"
"    exit 1\n"
"fi\n"
"cat << EOF > $TMPDIR/Makefile\n"
"obj-y := dummy.o\n"
"\\$(obj)/%.o: \\$(src)/%.c\n"
"\t@echo -n \"\\$(NOSTDINC_FLAGS) \\$(LINUXINCLUDE) \\$(EXTRA_CFLAGS)\"\n"
"\t\\$(CC) -c -o \\$@ \\$<\n"
"EOF\n"
"touch $TMPDIR/dummy.c\n"
"make -s -C $KBUILD_DIR M=$TMPDIR $KBUILD_OPTS dummy.o 2>/dev/null\n"
"RET=$?\n"
"rm -rf $TMPDIR\n"
"exit $RET\n";

void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
{
	static char *saved_kbuild_dir;
	static char *saved_kbuild_include_opts;
	int err;

	if (!kbuild_dir || !kbuild_include_opts)
		return;

	*kbuild_dir = NULL;
	*kbuild_include_opts = NULL;

	if (saved_kbuild_dir && saved_kbuild_include_opts &&
	    !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) {
		*kbuild_dir = strdup(saved_kbuild_dir);
		*kbuild_include_opts = strdup(saved_kbuild_include_opts);

		if (*kbuild_dir && *kbuild_include_opts)
			return;

		zfree(kbuild_dir);
		zfree(kbuild_include_opts);
		/*
		 * Don't fall through: it may breaks saved_kbuild_dir and
		 * saved_kbuild_include_opts if detect them again when
		 * memory is low.
		 */
		return;
	}

	if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
		pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n");
		pr_debug("Skip kbuild options detection.\n");
		goto errout;
	}

	err = detect_kbuild_dir(kbuild_dir);
	if (err) {
		pr_warning(
"WARNING:\tunable to get correct kernel building directory.\n"
"Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n"
"     \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n"
"     \tdetection.\n\n");
		goto errout;
	}

	pr_debug("Kernel build dir is set to %s\n", *kbuild_dir);
	force_set_env("KBUILD_DIR", *kbuild_dir);
	force_set_env("KBUILD_OPTS", llvm_param.kbuild_opts);
	err = read_from_pipe(kinc_fetch_script,
			     (void **)kbuild_include_opts,
			     NULL);
	if (err) {
		pr_warning(
"WARNING:\tunable to get kernel include directories from '%s'\n"
"Hint:\tTry set clang include options using 'clang-bpf-cmd-template'\n"
"     \toption in [llvm] section of ~/.perfconfig and set 'kbuild-dir'\n"
"     \toption in [llvm] to \"\" to suppress this detection.\n\n",
			*kbuild_dir);

		zfree(kbuild_dir);
		goto errout;
	}

	pr_debug("include option is set to %s\n", *kbuild_include_opts);

	saved_kbuild_dir = strdup(*kbuild_dir);
	saved_kbuild_include_opts = strdup(*kbuild_include_opts);

	if (!saved_kbuild_dir || !saved_kbuild_include_opts) {
		zfree(&saved_kbuild_dir);
		zfree(&saved_kbuild_include_opts);
	}
	return;
errout:
	saved_kbuild_dir = ERR_PTR(-EINVAL);
	saved_kbuild_include_opts = ERR_PTR(-EINVAL);
}

int llvm__get_nr_cpus(void)
{
	static int nr_cpus_avail = 0;
	char serr[STRERR_BUFSIZE];

	if (nr_cpus_avail > 0)
		return nr_cpus_avail;

	nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
	if (nr_cpus_avail <= 0) {
		pr_err(
"WARNING:\tunable to get available CPUs in this system: %s\n"
"        \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr)));
		nr_cpus_avail = 128;
	}
	return nr_cpus_avail;
}

void llvm__dump_obj(const char *path, void *obj_buf, size_t size)
{
	char *obj_path = strdup(path);
	FILE *fp;
	char *p;

	if (!obj_path) {
		pr_warning("WARNING: Not enough memory, skip object dumping\n");
		return;
	}

	p = strrchr(obj_path, '.');
	if (!p || (strcmp(p, ".c") != 0)) {
		pr_warning("WARNING: invalid llvm source path: '%s', skip object dumping\n",
			   obj_path);
		goto out;
	}

	p[1] = 'o';
	fp = fopen(obj_path, "wb");
	if (!fp) {
		pr_warning("WARNING: failed to open '%s': %s, skip object dumping\n",
			   obj_path, strerror(errno));
		goto out;
	}

	pr_debug("LLVM: dumping %s\n", obj_path);
	if (fwrite(obj_buf, size, 1, fp) != 1)
		pr_debug("WARNING: failed to write to file '%s': %s, skip object dumping\n", obj_path, strerror(errno));
	fclose(fp);
out:
	free(obj_path);
}

int llvm__compile_bpf(const char *path, void **p_obj_buf,
		      size_t *p_obj_buf_sz)
{
	size_t obj_buf_sz;
	void *obj_buf = NULL;
	int err, nr_cpus_avail;
	unsigned int kernel_version;
	char linux_version_code_str[64];
	const char *clang_opt = llvm_param.clang_opt;
	char clang_path[PATH_MAX], llc_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
	char serr[STRERR_BUFSIZE];
	char *kbuild_dir = NULL, *kbuild_include_opts = NULL,
	     *perf_bpf_include_opts = NULL;
	const char *template = llvm_param.clang_bpf_cmd_template;
	char *pipe_template = NULL;
	const char *opts = llvm_param.opts;
	char *command_echo = NULL, *command_out;
	char *libbpf_include_dir = system_path(LIBBPF_INCLUDE_DIR);

	if (path[0] != '-' && realpath(path, abspath) == NULL) {
		err = errno;
		pr_err("ERROR: problems with path %s: %s\n",
		       path, str_error_r(err, serr, sizeof(serr)));
		return -err;
	}

	if (!template)
		template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;

	err = search_program_and_warn(llvm_param.clang_path,
			     "clang", clang_path);
	if (err)
		return -ENOENT;

	/*
	 * This is an optional work. Even it fail we can continue our
	 * work. Needn't check error return.
	 */
	llvm__get_kbuild_opts(&kbuild_dir, &kbuild_include_opts);

	nr_cpus_avail = llvm__get_nr_cpus();
	snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
		 nr_cpus_avail);

	if (fetch_kernel_version(&kernel_version, NULL, 0))
		kernel_version = 0;

	snprintf(linux_version_code_str, sizeof(linux_version_code_str),
		 "0x%x", kernel_version);
	if (asprintf(&perf_bpf_include_opts, "-I%s/", libbpf_include_dir) < 0)
		goto errout;
	force_set_env("NR_CPUS", nr_cpus_avail_str);
	force_set_env("LINUX_VERSION_CODE", linux_version_code_str);
	force_set_env("CLANG_EXEC", clang_path);
	force_set_env("CLANG_OPTIONS", clang_opt);
	force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts);
	force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts);
	force_set_env("WORKING_DIR", kbuild_dir ? : ".");

	if (opts) {
		err = search_program_and_warn(llvm_param.llc_path, "llc", llc_path);
		if (err)
			goto errout;

		err = -ENOMEM;
		if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -",
			      template, llc_path, opts) < 0) {
			pr_err("ERROR:\tnot enough memory to setup command line\n");
			goto errout;
		}

		template = pipe_template;

	}

	/*
	 * Since we may reset clang's working dir, path of source file
	 * should be transferred into absolute path, except we want
	 * stdin to be source file (testing).
	 */
	force_set_env("CLANG_SOURCE",
		      (path[0] == '-') ? path : abspath);

	pr_debug("llvm compiling command template: %s\n", template);

	/*
	 * Below, substitute control characters for values that can cause the
	 * echo to misbehave, then substitute the values back.
	 */
	err = -ENOMEM;
	if (asprintf(&command_echo, "echo -n \a%s\a", template) < 0)
		goto errout;

#define SWAP_CHAR(a, b) do { if (*p == a) *p = b; } while (0)
	for (char *p = command_echo; *p; p++) {
		SWAP_CHAR('<', '\001');
		SWAP_CHAR('>', '\002');
		SWAP_CHAR('"', '\003');
		SWAP_CHAR('\'', '\004');
		SWAP_CHAR('|', '\005');
		SWAP_CHAR('&', '\006');
		SWAP_CHAR('\a', '"');
	}
	err = read_from_pipe(command_echo, (void **) &command_out, NULL);
	if (err)
		goto errout;

	for (char *p = command_out; *p; p++) {
		SWAP_CHAR('\001', '<');
		SWAP_CHAR('\002', '>');
		SWAP_CHAR('\003', '"');
		SWAP_CHAR('\004', '\'');
		SWAP_CHAR('\005', '|');
		SWAP_CHAR('\006', '&');
	}
#undef SWAP_CHAR
	pr_debug("llvm compiling command : %s\n", command_out);

	err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
	if (err) {
		pr_err("ERROR:\tunable to compile %s\n", path);
		pr_err("Hint:\tCheck error message shown above.\n");
		pr_err("Hint:\tYou can also pre-compile it into .o using:\n");
		pr_err("     \t\tclang --target=bpf -O2 -c %s\n", path);
		pr_err("     \twith proper -I and -D options.\n");
		goto errout;
	}

	free(command_echo);
	free(command_out);
	free(kbuild_dir);
	free(kbuild_include_opts);
	free(perf_bpf_include_opts);
	free(libbpf_include_dir);

	if (!p_obj_buf)
		free(obj_buf);
	else
		*p_obj_buf = obj_buf;

	if (p_obj_buf_sz)
		*p_obj_buf_sz = obj_buf_sz;
	return 0;
errout:
	free(command_echo);
	free(kbuild_dir);
	free(kbuild_include_opts);
	free(obj_buf);
	free(perf_bpf_include_opts);
	free(libbpf_include_dir);
	free(pipe_template);
	if (p_obj_buf)
		*p_obj_buf = NULL;
	if (p_obj_buf_sz)
		*p_obj_buf_sz = 0;
	return err;
}

int llvm__search_clang(void)
{
	char clang_path[PATH_MAX];

	return search_program_and_warn(llvm_param.clang_path, "clang", clang_path);
}
