WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.2% of users enabled 2FA.

Commit 53057e9d authored by Kunshan Wang's avatar Kunshan Wang
Browse files

C-initiater.

C programs can start Mu.
parent 8739b1c2
......@@ -39,18 +39,14 @@ lazy val root = (project in file(".")).settings(
antlr4GenVisitor in Antlr4 := false
)
lazy val jarList = taskKey[Seq[File]]("list dependency jars")
lazy val makeClasspathFile = taskKey[Unit]("write the run-time classpath to target/jars.txt as colon-separated list")
jarList := {
val cp: Seq[File] = (dependencyClasspath in Compile).value.files
cp
}
makeClasspathFile := {
val cp = (fullClasspath in Runtime).value.files
println("fullClasspath: \n" + cp.mkString("\n"))
lazy val makeJarListFile = taskKey[Unit]("write a list of dependency jar paths separated by colons (:) to target/jars.txt")
val cpStr = cp.mkString(":")
makeJarListFile := {
val jl = jarList.value
val jlStr = jl.mkString(":")
println("Dependency jars: " + jlStr)
IO.write(new java.io.File("cbinding/jars.txt"), jlStr)
IO.write(new java.io.File("cbinding/classpath.txt"), cpStr)
}
*.so
jars.txt
test_client
classpath.txt
classpath.h
CFLAGS += -std=gnu11
ifndef JAVA_HOME
$(error JAVA_HOME is required. Invoke with 'make JAVA_HOME=/path/to/java/home')
endif
CFLAGS += -I $(JAVA_HOME)/include
ifndef OS
uname := $(shell uname)
ifeq ($(uname),Darwin)
OS = OSX
else
ifeq ($(uname),Linux)
OS = LINUX
else
$(error Unrecognized operating system $(uname). I currently only worked on OSX and Linux.)
endif
endif
endif
ifeq ($(OS),OSX)
CFLAGS += -I $(JAVA_HOME)/include/darwin
endif
ifeq ($(OS),LINUX)
CFLAGS += -I $(JAVA_HOME)/include/linux
endif
LDFLAGS += -L $(JAVA_HOME)/jre/lib/server -l jvm -rpath $(JAVA_HOME)/jre/lib/server
.PHONY: all
all: libmurefimpl2start.so
all: libs tests
libmurefimpl2start.so: refimpl2-start.c cbinding.txt
.PHONY: libs
libs: libmurefimpl2start.so
libmurefimpl2start.so: refimpl2-start.c classpath.h
$(CC) -fPIC -shared $(CFLAGS) -o $@ $< $(LDFLAGS)
cbinding.txt: ../build.sbt
cd .. ; sbt makeJarListFile
classpath.txt: ../build.sbt
cd .. ; sbt makeClasspathFile
classpath.h: classpath.txt
xxd -i classpath.txt > classpath.h
.PHONY: clean
.PHONY: tests
tests: test_client
test_client: test_client.c libmurefimpl2start.so
$(CC) $(CFLAGS) -I . -o $@ $< -L . -l murefimpl2start
.PHONY: clean veryclean
clean:
rm *.so
rm *.so test_client
veryclean:
rm *.so test_client classpath.txt classpath.h
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include "refimpl2-start.h"
#include "classpath.h"
static JavaVM *jvm;
static JNIEnv *env;
static jclass cinitiater_cls;
static jmethodID new_mid;
static jmethodID new_ex_mid;
static jmethodID close_mid;
static char *cinitiater_class = "uvm/refimpl/nat/CInitiater";
static char *new_method = "mu_refimpl2_new";
static char *new_ex_method = "mu_refimpl2_new_ex";
static char *close_method = "mu_refimpl2_close";
static int refimpl2_start_debug;
static void init_jvm() {
char *debug_env = getenv("REFIMPL2_START_DEBUG");
if (debug_env != NULL) {
refimpl2_start_debug = 1;
}
JavaVMInitArgs vm_args;
JavaVMOption options[1];
char *cpoptionstr = (char*)calloc(classpath_txt_len + 100, 1);
strcat(cpoptionstr, "-Djava.class.path=");
strncat(cpoptionstr, (const char*)classpath_txt, classpath_txt_len);
options[0].optionString = cpoptionstr;
if (refimpl2_start_debug) {
printf("Classpath option: '%s'\n", cpoptionstr);
}
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_FALSE;
int rv = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (rv != JNI_OK) {
printf("ERROR: Failed to create JVM: %d\n", rv);
exit(1);
}
free(cpoptionstr);
jclass cinitiater_cls = (*env)->FindClass(env, cinitiater_class);
if (cinitiater_cls == NULL) {
printf("ERROR: class %s cannot be found.\n", cinitiater_class);
exit(1);
}
new_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, new_method, "()J");
if (new_mid == NULL) {
printf("ERROR: method %s cannot be found.\n", new_method);
exit(1);
}
new_ex_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, new_ex_method, "(JJJ)J");
if (new_ex_mid == NULL) {
printf("ERROR: method %s cannot be found.\n", new_ex_method);
exit(1);
}
close_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, close_method, "(J)V");
if (close_mid == NULL) {
printf("ERROR: method %s cannot be found.\n", close_method);
exit(1);
}
}
MuVM *mu_refimpl2_new() {
return NULL;
if (jvm == NULL) {
init_jvm();
}
uintptr_t rv = (*env)->CallStaticLongMethod(env, cinitiater_cls, new_mid);
return (MuVM*)rv;
}
MuVM *mu_refimpl2_new_ex(int64_t heap_size, int64_t global_size, int64_t stack_size) {
return NULL;
if (jvm == NULL) {
init_jvm();
}
uintptr_t rv = (*env)->CallStaticLongMethod(env, cinitiater_cls, new_ex_mid,
heap_size, global_size, stack_size);
return (MuVM*)rv;
}
void mu_refimpl2_close(MuVM *mvm) {
if (jvm == NULL) {
init_jvm();
}
(*env)->CallStaticVoidMethod(env, cinitiater_cls, close_mid, mvm);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // write
#include <refimpl2-start.h>
#include <muapi.h>
char *hw_string = "Hello world!\n";
int main() {
MuVM *mvm = mu_refimpl2_new_ex(1048576, 1048576, 32768);
MuCtx *ctx = mvm->new_context(mvm);
char *bundle1 =
".typedef @cint = int<32>\n"
".typedef @void = void\n"
".typedef @cvoidptr = uptr<@void>\n"
".typedef @csize_t = int<64>\n"
".funcsig @write.sig = (@cint @cvoidptr @csize_t) -> (@csize_t)\n"
".typedef @write.fp = ufuncptr<@write.sig>\n"
".const @the_fd <@cint> = 1\n"
;
char bundle2[256];
sprintf(bundle2,
".const @the_write <@write.fp> = 0x%lx\n"
".const @the_string <@cvoidptr> = 0x%lx\n"
".const @the_length <@csize_t> = 0x%lx\n"
, (uintptr_t)write, (uintptr_t)hw_string, (unsigned long)strlen(hw_string));
char *bundle3 =
".funcsig @v_v = ()->()\n"
".funcdef @hw VERSION %1 <@v_v> {\n"
" %entry():\n"
" %rv = CCALL #DEFAULT <@write.fp @write.sig> @the_write (@the_fd @the_string @the_length)\n"
" COMMINST @uvm.thread_exit\n"
"}\n"
;
printf("Loading bundles...\n");
printf("Bundle1:\n%s\n", bundle1);
ctx->load_bundle(ctx, bundle1, strlen(bundle1));
printf("Bundle2:\n%s\n", bundle2);
ctx->load_bundle(ctx, bundle2, strlen(bundle2));
printf("Bundle3:\n%s\n", bundle3);
ctx->load_bundle(ctx, bundle3, strlen(bundle3));
printf("Bundles loaded. Execute...\n");
MuFuncRefValue func = ctx->handle_from_func(ctx, ctx->id_of(ctx, "@hw"));
MuStackRefValue stack = ctx->new_stack(ctx, func);
MuThreadRefValue thread = ctx->new_thread(ctx, stack, MU_REBIND_PASS_VALUES,
NULL, 0, NULL);
mvm->execute(mvm);
mu_refimpl2_close(mvm);
return 0;
}
package uvm.refimpl.nat;
import uvm.refimpl.MicroVM;
import uvm.refimpl.MicroVM$;
/** Static functions for the convenient of C programs that start Mu via JNI. */
public class CInitiater {
/** Called by the native program, this function creates a Mu instance. */
static long mu_refimpl2_new() {
MicroVM mvm = new MicroVM(MicroVM$.MODULE$.DEFAULT_HEAP_SIZE(), MicroVM$.MODULE$.DEFAULT_GLOBAL_SIZE(),
MicroVM$.MODULE$.DEFAULT_STACK_SIZE());
long fak = NativeClientSupport$.MODULE$.exposeMicroVM(mvm);
return fak;
}
/**
* Called by the native program, this function creates a Mu instance with
* extra arguments.
*/
static long mu_refimpl2_new_ex(long heap_size, long global_size, long stack_size) {
MicroVM mvm = new MicroVM(heap_size, global_size, stack_size);
long fak = NativeClientSupport$.MODULE$.exposeMicroVM(mvm);
return fak;
}
/**
* Called by the native program, this function closes and deallocates a Mu
* instance.
*/
static void mu_refimpl2_close(long mvmFak) {
NativeClientSupport$.MODULE$.unexposeMicroVM(mvmFak);
// does not really deallocate it.
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment