// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include <jvmti.h>
#include <jvmticmlr.h>
#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);
	}
}

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;
}

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 */
		size_t file_name_len = strlen(file_name);
		strncpy(result, file_name, file_name_len < max_length ? file_name_len : 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()");
}
