示例#1
0
/*
 * static final native String mapLibraryName(String)
 */
_jc_object * _JC_JCNI_ATTR
JCNI_java_lang_VMRuntime_mapLibraryName(_jc_env *env, _jc_object *string)
{
	size_t name_len;
	char *fname;
	char *name;

	/* Check for null */
	if (string == NULL) {
		_jc_post_exception(env, _JC_NullPointerException);
		_jc_throw_exception(env);
	}

	/* Decode string */
	name_len = _jc_decode_string_utf8(env, string, NULL);
	if ((name = _JC_STACK_ALLOC(env, name_len + 1)) == NULL) {
		_jc_post_exception_info(env);
		_jc_throw_exception(env);
	}
	_jc_decode_string_utf8(env, string, name);

	/* Format filename */
	if ((fname = _JC_FORMAT_STRING(env, _JC_LIBRARY_FMT, name)) == NULL) {
		_jc_post_exception_info(env);
		_jc_throw_exception(env);
	}

	/* Create new String object */
	if ((string = _jc_new_string(env, fname, strlen(fname))) == NULL)
		_jc_throw_exception(env);

	/* Done */
	return string;
}
示例#2
0
/*
 * public static final native boolean compileClasses(String)
 */
jboolean _JC_JCNI_ATTR
JCNI_java_lang_VMCompiler_compileClasses(_jc_env *env, _jc_object *string)
{
	_jc_jvm *const vm = env->vm;
	size_t slen;
	char *name;

	/* Decode string */
	slen = _jc_decode_string_utf8(env, string, NULL);
	if ((name = _JC_STACK_ALLOC(env, slen + 1)) == NULL) {
		_jc_post_exception_info(env);
		_jc_throw_exception(env);
	}
	_jc_decode_string_utf8(env, string, name);

	/* XXX we are supposed to do some kind of pattern matching... */

	/* Generate ELF object */
	if (_jc_generate_object(env, vm->boot.loader, name) != JNI_OK)
		_jc_throw_exception(env);
	return JNI_TRUE;
}
示例#3
0
/*
 * static final native int nativeLoad(String, ClassLoader)
 */
jint _JC_JCNI_ATTR
JCNI_java_lang_VMRuntime_nativeLoad(_jc_env *env,
	_jc_object *string, _jc_object *clobj)
{
	_jc_jvm *const vm = env->vm;
	_jc_class_loader *loader;
	char *filename;
	size_t len;

	/* Check for null */
	if (string == NULL) {
		_jc_post_exception(env, _JC_NullPointerException);
		_jc_throw_exception(env);
	}

	/* Convert String to UTF-8 */
	len = _jc_decode_string_utf8(env, string, NULL);
	if ((filename = _JC_STACK_ALLOC(env, len + 1)) == NULL) {
		_jc_post_exception_info(env);
		_jc_throw_exception(env);
	}
	_jc_decode_string_utf8(env, string, filename);

	/* Get class loader */
	if (clobj == NULL)
		loader = vm->boot.loader;
	else if ((loader = _jc_get_loader(env, clobj)) == NULL)
		_jc_throw_exception(env);

	/* Open native library */
	if (_jc_load_native_library(env, loader, filename) != JNI_OK) {
		_jc_post_exception_info(env);
		_jc_throw_exception(env);
	}

	/* OK */
	return 1;
}
示例#4
0
/*
 * Process DWARF2 line number information.
 *
 * If unsuccessful an exception is stored.
 */
jint
_jc_debug_line_dwarf2(_jc_env *env, _jc_elf *elf, _jc_splay_tree *tree)
{
	_jc_elf_info *const info = elf->info;
	const Elf_Shdr *const shdr = info->debug_lines.loadable.shdr;
	const u_char *ptr = (const u_char *)info->map_base + shdr->sh_offset;
	const u_char *const section_end = ptr + shdr->sh_size;
	jboolean using64bit = JNI_FALSE;
	_jc_dwarf2_line_hdr *hdr;
	_jc_method_node **nodes;
	_jc_map_state state;
	_jc_method *method;
	unsigned long totlen;
	union _jc_value jvalue;
	int node_index;
	const u_char *ptr_end;
	const u_char *pc;
	int num_nodes;
	int cline;
	int i;

	/* Put nodes in a list and elide methods with no line number table */
	if ((nodes = _JC_STACK_ALLOC(env,
	    tree->size * sizeof(*nodes))) == NULL)
		goto fail;
	_jc_splay_list(tree, (void **)nodes);
	for (i = num_nodes = 0; i < tree->size; i++) {
		_jc_method_node *const node = nodes[i];
		_jc_method *const method = node->method;

		_JC_ASSERT(method != NULL);
		_JC_ASSERT(method->function != NULL);
		_JC_ASSERT(!_JC_ACC_TEST(method, INTERP));
		_JC_ASSERT(method->u.exec.function_end != NULL);
		if (method->u.exec.u.linenum.len > 0)
			nodes[num_nodes++] = nodes[i];
	}

	/* Anything to do? */
	if (num_nodes == 0)
		return JNI_OK;

	/* Sort methods by starting address */
	qsort(nodes, num_nodes, sizeof(*nodes), _jc_method_addr_cmp);

	/* Initialize map state */
	memset(&state, 0, sizeof(state));
	node_index = 0;
	method = NULL;

again:
	/* Read prologue header */
	memcpy(&jvalue, ptr, sizeof(jint));
	ptr += sizeof(jint);
	totlen = jvalue.i;
	if (totlen == 0xffffffff) {
		memcpy(&jvalue, ptr, sizeof(jlong));
		ptr += sizeof(jlong);
		totlen = jvalue.j;
		using64bit = JNI_TRUE;
	} else if (totlen == 0) {
		memcpy(&jvalue, ptr, sizeof(jint));
		ptr += sizeof(jint);
		totlen = jvalue.i;
		using64bit = JNI_TRUE;
	}
	ptr_end = ptr + totlen;
	ptr += 2;					/* skip version */
	ptr += 4;					/* skip header len */
	if (using64bit)
		ptr += 4;
	hdr = (_jc_dwarf2_line_hdr *)ptr;
	ptr += sizeof(*hdr) + hdr->opcode_base - 1;

	/* Skip over directory table */
	while (*ptr++ != '\0')
		ptr += strlen((const char *)ptr) + 1;

	/* Skip over file name table */
	while (*ptr++ != '\0') {
		ptr += strlen((const char *)ptr) + 1;
		(void)_jc_read_leb128(&ptr, JNI_FALSE);
		(void)_jc_read_leb128(&ptr, JNI_FALSE);
		(void)_jc_read_leb128(&ptr, JNI_FALSE);
	}

	/* Initialize statement program state */
	pc = NULL;
	cline = 1;

	/* Process statement program */
	while (ptr < ptr_end) {
		jboolean writeout = JNI_FALSE;
		jboolean reset = JNI_FALSE;
		u_char opcode;

		if ((opcode = *ptr++) >= hdr->opcode_base) {	/* special */
			opcode -= hdr->opcode_base;
			pc += (opcode / hdr->line_range)
			    * hdr->minimum_instruction_length;
			cline += hdr->line_base + opcode % hdr->line_range;
			writeout = JNI_TRUE;
		} else if (opcode == 0) {			/* extended */
			unsigned int oplen;
			u_char exop;

			oplen = _jc_read_leb128(&ptr, JNI_FALSE);
			exop = *ptr++;
			switch (exop) {
			case DW_LNE_end_sequence:
				reset = JNI_TRUE;
				writeout = JNI_TRUE;
				break;
			case DW_LNE_set_address:
			    {
				const u_char *new_pc;

				/* Get new PC */
				memcpy(&new_pc, ptr, sizeof(new_pc));

				/* We don't support out-of-spec reversals */
				if (new_pc < pc) {
					_JC_EX_STORE(env, LinkageError,
					    "address reversals in .debug_line"
					    " section are not supported");
					goto fail;
				}

				/* OK */
				pc = new_pc;
				break;
			    }
			default:
				break;
			}
			ptr += oplen - 1;
		} else {					/* standard */
			switch (opcode) {
			case DW_LNS_copy:
				writeout = JNI_TRUE;
				break;
			case DW_LNS_advance_pc:
				pc += _jc_read_leb128(&ptr, JNI_FALSE)
				    * hdr->minimum_instruction_length;
				break;
			case DW_LNS_advance_line:
				cline += _jc_read_leb128(&ptr, JNI_TRUE);
				break;
			case DW_LNS_const_add_pc:
				pc += ((255 - hdr->opcode_base)
				      / hdr->line_range)
				    * hdr->minimum_instruction_length;
				break;
			case DW_LNS_fixed_advance_pc:
			    {
				uint16_t advance;

				memcpy(&advance, ptr, 2);
				pc += advance;
				ptr += 2;
				break;
			    }
			default:
				for (i = 0; i < hdr->standard_opcode_lengths[
				    opcode - 1]; i++)
					_jc_read_leb128(&ptr, JNI_FALSE);
				break;
			}
		}

		/* Have we reached the next method? */
		if (method == NULL
		    && (const void *)pc
		      >= nodes[node_index]->method->function) {

			/* Initialize state for this method */
			_JC_ASSERT(state.pc_map.len == 0);
			_JC_ASSERT(state.last_linenum == 0);
			_JC_ASSERT(state.last_map == 0);
			method = nodes[node_index]->method;
			_JC_ASSERT(!_JC_ACC_TEST(method, INTERP));
			state.linenum = method->u.exec.u.linenum;
			memset(&method->u.exec.u, 0, sizeof(method->u.exec.u));
		}

		/* Finished with the current method? */
		if (method != NULL
		    && (const void *)pc >= method->u.exec.function_end) {

			/* Finalize map for current method */
			if (_jc_debug_line_finish(env,
			    method, elf->loader, &state) != JNI_OK)
				goto fail;
			method = NULL;

			/* Look for next method */
			if (++node_index == num_nodes)
				goto done;
		}

		/* Write matrix row */
		if (writeout && method != NULL) {
			if (_jc_debug_line_add(env,
			    &state, pc, cline) != JNI_OK)
				goto fail;
		}

		/* Reset after DW_LNE_end_sequence */
		if (reset) {
			pc = NULL;
			cline = 1;
		}
	}
	if (ptr < section_end)
		goto again;

done:
	/* Sanity check */
	_JC_ASSERT(method == NULL);
#ifndef NDEBUG
	for (i = 0; i < num_nodes; i++) {
		_jc_method_node *const node = nodes[i];
		_jc_method *const method = node->method;

		_JC_ASSERT(!_JC_ACC_TEST(method, INTERP));
		_JC_ASSERT(method->u.exec.u.pc_map.map != NULL);
	}
#endif

	/* Done */
	return JNI_OK;

fail:
	/* Failed */
	return JNI_ERR;
}