// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <linux/string.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include <jvmti.h>
#ifdef HAVE_JVMTI_CMLR
#include <jvmticmlr.h>
#endif
#include <limits.h>

#include "jvmti_agent.h"

static int has_line_numbers;
void *jvmti_agent;

static void print_error(jvmtiEnv *jvmti, const char *msg, jvmtiError ret)
{
	char *err_msg = NULL;
	jvmtiError err;
	err = (*jvmti)->GetErrorName(jvmti, ret, &err_msg);
	if (err == JVMTI_ERROR_NONE) {
		warnx("%s failed with %s", msg, err_msg);
		(*jvmti)->Deallocate(jvmti, (unsigned char *)err_msg);
	} else {
		warnx("%s failed with an unknown error %d", msg, ret);
	}
}

#ifdef HAVE_JVMTI_CMLR
static jvmtiError
do_get_line_numbers(jvmtiEnv *jvmti, void *pc, jmethodID m, jint bci,
		    jvmti_line_info_t *tab, jint *nr)
{
	jint i, lines = 0;
	jint nr_lines = 0;
	jvmtiLineNumberEntry *loc_tab = NULL;
	jvmtiError ret;

	ret = (*jvmti)->GetLineNumberTable(jvmti, m, &nr_lines, &loc_tab);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetLineNumberTable", ret);
		return ret;
	}

	for (i = 0; i < nr_lines; i++) {
		if (loc_tab[i].start_location < bci) {
			tab[lines].pc = (unsigned long)pc;
			tab[lines].line_number = loc_tab[i].line_number;
			tab[lines].discrim = 0; /* not yet used */
			tab[lines].methodID = m;
			lines++;
		} else {
			break;
		}
	}
	(*jvmti)->Deallocate(jvmti, (unsigned char *)loc_tab);
	*nr = lines;
	return JVMTI_ERROR_NONE;
}

static jvmtiError
get_line_numbers(jvmtiEnv *jvmti, const void *compile_info, jvmti_line_info_t **tab, int *nr_lines)
{
	const jvmtiCompiledMethodLoadRecordHeader *hdr;
	jvmtiCompiledMethodLoadInlineRecord *rec;
	jvmtiLineNumberEntry *lne = NULL;
	PCStackInfo *c;
	jint nr, ret;
	int nr_total = 0;
	int i, lines_total = 0;

	if (!(tab && nr_lines))
		return JVMTI_ERROR_NULL_POINTER;

	/*
	 * Phase 1 -- get the number of lines necessary
	 */
	for (hdr = compile_info; hdr != NULL; hdr = hdr->next) {
		if (hdr->kind == JVMTI_CMLR_INLINE_INFO) {
			rec = (jvmtiCompiledMethodLoadInlineRecord *)hdr;
			for (i = 0; i < rec->numpcs; i++) {
				c = rec->pcinfo + i;
				nr = 0;
				/*
				 * unfortunately, need a tab to get the number of lines!
				 */
				ret = (*jvmti)->GetLineNumberTable(jvmti, c->methods[0], &nr, &lne);
				if (ret == JVMTI_ERROR_NONE) {
					/* free what was allocated for nothing */
					(*jvmti)->Deallocate(jvmti, (unsigned char *)lne);
					nr_total += (int)nr;
				} else {
					print_error(jvmti, "GetLineNumberTable", ret);
				}
			}
		}
	}

	if (nr_total == 0)
		return JVMTI_ERROR_NOT_FOUND;

	/*
	 * Phase 2 -- allocate big enough line table
	 */
	*tab = malloc(nr_total * sizeof(**tab));
	if (!*tab)
		return JVMTI_ERROR_OUT_OF_MEMORY;

	for (hdr = compile_info; hdr != NULL; hdr = hdr->next) {
		if (hdr->kind == JVMTI_CMLR_INLINE_INFO) {
			rec = (jvmtiCompiledMethodLoadInlineRecord *)hdr;
			for (i = 0; i < rec->numpcs; i++) {
				c = rec->pcinfo + i;
				nr = 0;
				ret = do_get_line_numbers(jvmti, c->pc,
							  c->methods[0],
							  c->bcis[0],
							  *tab + lines_total,
							  &nr);
				if (ret == JVMTI_ERROR_NONE)
					lines_total += nr;
			}
		}
	}
	*nr_lines = lines_total;
	return JVMTI_ERROR_NONE;
}
#else /* HAVE_JVMTI_CMLR */

static jvmtiError
get_line_numbers(jvmtiEnv *jvmti __maybe_unused, const void *compile_info __maybe_unused,
		 jvmti_line_info_t **tab __maybe_unused, int *nr_lines __maybe_unused)
{
	return JVMTI_ERROR_NONE;
}
#endif /* HAVE_JVMTI_CMLR */

static void
copy_class_filename(const char * class_sign, const char * file_name, char * result, size_t max_length)
{
	/*
	* Assume path name is class hierarchy, this is a common practice with Java programs
	*/
	if (*class_sign == 'L') {
		int j, i = 0;
		char *p = strrchr(class_sign, '/');
		if (p) {
			/* drop the 'L' prefix and copy up to the final '/' */
			for (i = 0; i < (p - class_sign); i++)
				result[i] = class_sign[i+1];
		}
		/*
		* append file name, we use loops and not string ops to avoid modifying
		* class_sign which is used later for the symbol name
		*/
		for (j = 0; i < (max_length - 1) && file_name && j < strlen(file_name); j++, i++)
			result[i] = file_name[j];

		result[i] = '\0';
	} else {
		/* fallback case */
		strlcpy(result, file_name, max_length);
	}
}

static jvmtiError
get_source_filename(jvmtiEnv *jvmti, jmethodID methodID, char ** buffer)
{
	jvmtiError ret;
	jclass decl_class;
	char *file_name = NULL;
	char *class_sign = NULL;
	char fn[PATH_MAX];
	size_t len;

	ret = (*jvmti)->GetMethodDeclaringClass(jvmti, methodID, &decl_class);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetMethodDeclaringClass", ret);
		return ret;
	}

	ret = (*jvmti)->GetSourceFileName(jvmti, decl_class, &file_name);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetSourceFileName", ret);
		return ret;
	}

	ret = (*jvmti)->GetClassSignature(jvmti, decl_class, &class_sign, NULL);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetClassSignature", ret);
		goto free_file_name_error;
	}

	copy_class_filename(class_sign, file_name, fn, PATH_MAX);
	len = strlen(fn);
	*buffer = malloc((len + 1) * sizeof(char));
	if (!*buffer) {
		print_error(jvmti, "GetClassSignature", ret);
		ret = JVMTI_ERROR_OUT_OF_MEMORY;
		goto free_class_sign_error;
	}
	strcpy(*buffer, fn);
	ret = JVMTI_ERROR_NONE;

free_class_sign_error:
	(*jvmti)->Deallocate(jvmti, (unsigned char *)class_sign);
free_file_name_error:
	(*jvmti)->Deallocate(jvmti, (unsigned char *)file_name);

	return ret;
}

static jvmtiError
fill_source_filenames(jvmtiEnv *jvmti, int nr_lines,
		      const jvmti_line_info_t * line_tab,
		      char ** file_names)
{
	int index;
	jvmtiError ret;

	for (index = 0; index < nr_lines; ++index) {
		ret = get_source_filename(jvmti, line_tab[index].methodID, &(file_names[index]));
		if (ret != JVMTI_ERROR_NONE)
			return ret;
	}

	return JVMTI_ERROR_NONE;
}

static void JNICALL
compiled_method_load_cb(jvmtiEnv *jvmti,
			jmethodID method,
			jint code_size,
			void const *code_addr,
			jint map_length,
			jvmtiAddrLocationMap const *map,
			const void *compile_info)
{
	jvmti_line_info_t *line_tab = NULL;
	char ** line_file_names = NULL;
	jclass decl_class;
	char *class_sign = NULL;
	char *func_name = NULL;
	char *func_sign = NULL;
	char *file_name = NULL;
	char fn[PATH_MAX];
	uint64_t addr = (uint64_t)(uintptr_t)code_addr;
	jvmtiError ret;
	int nr_lines = 0; /* in line_tab[] */
	size_t len;
	int output_debug_info = 0;

	ret = (*jvmti)->GetMethodDeclaringClass(jvmti, method,
						&decl_class);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetMethodDeclaringClass", ret);
		return;
	}

	if (has_line_numbers && map && map_length) {
		ret = get_line_numbers(jvmti, compile_info, &line_tab, &nr_lines);
		if (ret != JVMTI_ERROR_NONE) {
			warnx("jvmti: cannot get line table for method");
			nr_lines = 0;
		} else if (nr_lines > 0) {
			line_file_names = malloc(sizeof(char*) * nr_lines);
			if (!line_file_names) {
				warnx("jvmti: cannot allocate space for line table method names");
			} else {
				memset(line_file_names, 0, sizeof(char*) * nr_lines);
				ret = fill_source_filenames(jvmti, nr_lines, line_tab, line_file_names);
				if (ret != JVMTI_ERROR_NONE) {
					warnx("jvmti: fill_source_filenames failed");
				} else {
					output_debug_info = 1;
				}
			}
		}
	}

	ret = (*jvmti)->GetSourceFileName(jvmti, decl_class, &file_name);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetSourceFileName", ret);
		goto error;
	}

	ret = (*jvmti)->GetClassSignature(jvmti, decl_class,
					  &class_sign, NULL);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetClassSignature", ret);
		goto error;
	}

	ret = (*jvmti)->GetMethodName(jvmti, method, &func_name,
				      &func_sign, NULL);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetMethodName", ret);
		goto error;
	}

	copy_class_filename(class_sign, file_name, fn, PATH_MAX);

	/*
	 * write source line info record if we have it
	 */
	if (output_debug_info)
		if (jvmti_write_debug_info(jvmti_agent, addr, nr_lines, line_tab, (const char * const *) line_file_names))
			warnx("jvmti: write_debug_info() failed");

	len = strlen(func_name) + strlen(class_sign) + strlen(func_sign) + 2;
	{
		char str[len];
		snprintf(str, len, "%s%s%s", class_sign, func_name, func_sign);

		if (jvmti_write_code(jvmti_agent, str, addr, code_addr, code_size))
			warnx("jvmti: write_code() failed");
	}
error:
	(*jvmti)->Deallocate(jvmti, (unsigned char *)func_name);
	(*jvmti)->Deallocate(jvmti, (unsigned char *)func_sign);
	(*jvmti)->Deallocate(jvmti, (unsigned char *)class_sign);
	(*jvmti)->Deallocate(jvmti, (unsigned char *)file_name);
	free(line_tab);
	while (line_file_names && (nr_lines > 0)) {
	    if (line_file_names[nr_lines - 1]) {
	        free(line_file_names[nr_lines - 1]);
	    }
	    nr_lines -= 1;
	}
	free(line_file_names);
}

static void JNICALL
code_generated_cb(jvmtiEnv *jvmti,
		  char const *name,
		  void const *code_addr,
		  jint code_size)
{
	uint64_t addr = (uint64_t)(unsigned long)code_addr;
	int ret;

	ret = jvmti_write_code(jvmti_agent, name, addr, code_addr, code_size);
	if (ret)
		warnx("jvmti: write_code() failed for code_generated");
}

JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *jvm, char *options, void *reserved __maybe_unused)
{
	jvmtiEventCallbacks cb;
	jvmtiCapabilities caps1;
	jvmtiJlocationFormat format;
	jvmtiEnv *jvmti = NULL;
	jint ret;

	jvmti_agent = jvmti_open();
	if (!jvmti_agent) {
		warnx("jvmti: open_agent failed");
		return -1;
	}

	/*
	 * Request a JVMTI interface version 1 environment
	 */
	ret = (*jvm)->GetEnv(jvm, (void *)&jvmti, JVMTI_VERSION_1);
	if (ret != JNI_OK) {
		warnx("jvmti: jvmti version 1 not supported");
		return -1;
	}

	/*
	 * acquire method_load capability, we require it
	 * request line numbers (optional)
	 */
	memset(&caps1, 0, sizeof(caps1));
	caps1.can_generate_compiled_method_load_events = 1;

	ret = (*jvmti)->AddCapabilities(jvmti, &caps1);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "AddCapabilities", ret);
		return -1;
	}
	ret = (*jvmti)->GetJLocationFormat(jvmti, &format);
        if (ret == JVMTI_ERROR_NONE && format == JVMTI_JLOCATION_JVMBCI) {
                memset(&caps1, 0, sizeof(caps1));
                caps1.can_get_line_numbers = 1;
                caps1.can_get_source_file_name = 1;
		ret = (*jvmti)->AddCapabilities(jvmti, &caps1);
                if (ret == JVMTI_ERROR_NONE)
                        has_line_numbers = 1;
        } else if (ret != JVMTI_ERROR_NONE)
		print_error(jvmti, "GetJLocationFormat", ret);


	memset(&cb, 0, sizeof(cb));

	cb.CompiledMethodLoad   = compiled_method_load_cb;
	cb.DynamicCodeGenerated = code_generated_cb;

	ret = (*jvmti)->SetEventCallbacks(jvmti, &cb, sizeof(cb));
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "SetEventCallbacks", ret);
		return -1;
	}

	ret = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
			JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "SetEventNotificationMode(METHOD_LOAD)", ret);
		return -1;
	}

	ret = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
			JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "SetEventNotificationMode(CODE_GENERATED)", ret);
		return -1;
	}
	return 0;
}

JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *jvm __maybe_unused)
{
	int ret;

	ret = jvmti_close(jvmti_agent);
	if (ret)
		errx(1, "Error: op_close_agent()");
}
