jlong Java_aura_rt_VM_getArrayValuesAddress(Env* env, Class* c, Array* array) { if (array->object.clazz == array_Z) { return PTR_TO_LONG(((BooleanArray*) array)->values); } if (array->object.clazz == array_B) { return PTR_TO_LONG(((ByteArray*) array)->values); } if (array->object.clazz == array_C) { return PTR_TO_LONG(((CharArray*) array)->values); } if (array->object.clazz == array_S) { return PTR_TO_LONG(((ShortArray*) array)->values); } if (array->object.clazz == array_I) { return PTR_TO_LONG(((IntArray*) array)->values); } if (array->object.clazz == array_J) { return PTR_TO_LONG(((LongArray*) array)->values); } if (array->object.clazz == array_F) { return PTR_TO_LONG(((FloatArray*) array)->values); } if (array->object.clazz == array_D) { return PTR_TO_LONG(((DoubleArray*) array)->values); } return PTR_TO_LONG(((ObjectArray*) array)->values); }
JNIEXPORT jlong JNICALL Java_pstore_Table_create(JNIEnv *env, jclass clazz, jstring name, jlong id) { const char *name0; void *ptr; name0 = (*env)->GetStringUTFChars(env, name, NULL); if (!name0) return PTR_TO_LONG(NULL); ptr = pstore_table_new(name0, id); (*env)->ReleaseStringUTFChars(env, name, name0); return PTR_TO_LONG(ptr); }
jlong rvmStartThread(Env* env, JavaThread* threadObj) { Env* newEnv = rvmCreateEnv(env->vm); if (!newEnv) { rvmThrowOutOfMemoryError(env); // rvmCreateEnv() doesn't throw OutOfMemoryError if allocation fails return 0; } rvmLockThreadsList(); if (threadObj->threadPtr != 0) { rvmThrowIllegalStateException(env, "thread has already been started"); rvmUnlockThreadsList(); return 0; } Thread* thread = allocThread(env); if (!thread) { rvmUnlockThreadsList(); return 0; } size_t stackSize = (size_t) threadObj->stackSize; if (stackSize == 0) { stackSize = THREAD_DEFAULT_STACK_SIZE; } else if (stackSize < THREAD_MIN_STACK_SIZE) { stackSize = THREAD_MIN_STACK_SIZE; } stackSize += THREAD_SIGNAL_STACK_SIZE; stackSize = (stackSize + THREAD_STACK_SIZE_MULTIPLE - 1) & ~(THREAD_STACK_SIZE_MULTIPLE - 1); pthread_attr_t threadAttr; pthread_attr_init(&threadAttr); pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&threadAttr, stackSize); pthread_attr_setguardsize(&threadAttr, THREAD_STACK_GUARD_SIZE); ThreadEntryPointArgs args = {0}; args.env = newEnv; args.thread = thread; args.threadObj = threadObj; int err = 0; if ((err = pthread_create(&thread->pThread, &threadAttr, startThreadEntryPoint, &args)) != 0) { rvmUnlockThreadsList(); rvmThrowInternalErrorErrno(env, err); return 0; } while (thread->status != THREAD_STARTING) { pthread_cond_wait(&threadStartCond, &threadsLock); } DL_PREPEND(threads, thread); pthread_cond_broadcast(&threadsChangedCond); thread->status = THREAD_VMWAIT; pthread_cond_broadcast(&threadStartCond); rvmUnlockThreadsList(); return PTR_TO_LONG(thread); }
jlong Java_aura_rt_VM_malloc(Env* env, Class* c, jint size) { void* m = malloc(size); if (!m) { rvmThrowOutOfMemoryError(env); return 0; } memset(m, 0, size); return PTR_TO_LONG(m); }
jlong Java_java_lang_Throwable_nativeFillInStackTrace(Env* env, Object* thiz) { if (rvmIsCriticalOutOfMemoryError(env, thiz)) { // nativeFillInStackTrace() was called on the shared criticalOutOfMemoryError. // Don't try to capture the call stack since it will most likely just // lead to another OOM and more recursion. return 0; } return PTR_TO_LONG(rvmCaptureCallStack(env)); }
Object* Java_java_lang_Class_getEnclosingMethod(Env* env, Class* thiz) { Method* method = rvmAttributeGetEnclosingMethod(env, thiz); if (!method || METHOD_IS_CONSTRUCTOR(method)) return NULL; Class* jlr_Method = rvmFindClassUsingLoader(env, "java/lang/reflect/Method", NULL); if (!jlr_Method) return NULL; Method* constructor = rvmGetInstanceMethod(env, jlr_Method, "<init>", "(J)V"); if (!constructor) return NULL; jvalue args[1]; args[0].j = PTR_TO_LONG(method); return rvmNewObjectA(env, jlr_Method, constructor, args); }
Object* createFieldObject(Env* env, Field* field) { if (!java_lang_reflect_Field) { java_lang_reflect_Field = rvmFindClassUsingLoader(env, "java/lang/reflect/Field", NULL); if (!java_lang_reflect_Field) return NULL; } if (!java_lang_reflect_Field_init) { java_lang_reflect_Field_init = rvmGetInstanceMethod(env, java_lang_reflect_Field, "<init>", "(J)V"); if (!java_lang_reflect_Field_init) return NULL; } jvalue initArgs[1]; initArgs[0].j = PTR_TO_LONG(field); return rvmNewObjectA(env, java_lang_reflect_Field, java_lang_reflect_Field_init, initArgs); }
Object* createConstructorObject(Env* env, Method* method) { if (!java_lang_reflect_Constructor) { java_lang_reflect_Constructor = rvmFindClassUsingLoader(env, "java/lang/reflect/Constructor", NULL); if (!java_lang_reflect_Constructor) return NULL; } if (!java_lang_reflect_Constructor_init) { java_lang_reflect_Constructor_init = rvmGetInstanceMethod(env, java_lang_reflect_Constructor, "<init>", "(J)V"); if (!java_lang_reflect_Constructor_init) return NULL; } jvalue initArgs[1]; initArgs[0].j = PTR_TO_LONG(method); return rvmNewObjectA(env, java_lang_reflect_Constructor, java_lang_reflect_Constructor_init, initArgs); }
static jboolean initThread(Env* env, Thread* thread, JavaThread* threadObj) { // NOTE: threadsLock must be held int err = 0; pthread_cond_init(&thread->waitCond, NULL); if ((err = rvmInitMutex(&thread->waitMutex)) != 0) { rvmThrowInternalErrorErrno(env, err); return FALSE; } thread->threadId = nextThreadId++; thread->threadObj = threadObj; threadObj->threadPtr = PTR_TO_LONG(thread); env->currentThread = thread; env->attachCount = 1; return TRUE; }
static void signalHandler_npe_so(int signum, siginfo_t* info, void* context) { // rvmGetEnv() uses pthread_getspecific() which isn't listed as // async-signal-safe. Others (e.g. mono) do this too so we assume it is safe // in practice. Env* env = rvmGetEnv(); if (env && rvmIsNonNativeFrame(env)) { // We now know the fault occurred in non-native code and not in our // native code or in any non-async-signal-safe system function. It // should be safe to do things here that would normally be unsafe to do // in a signal handler. void* faultAddr = info->si_addr; void* stackAddr = env->currentThread->stackAddr; Class* exClass = NULL; if (faultAddr < stackAddr && faultAddr >= (void*) (stackAddr - THREAD_STACK_GUARD_SIZE)) { // StackOverflowError exClass = java_lang_StackOverflowError; } else { // At least on Linux x86 it seems like si_addr isn't always 0x0 even // if a read of address 0x0 triggered SIGSEGV so we assume // everything that isn't a stack overflow is a read of address 0x0 // and throw NullPointerException. exClass = java_lang_NullPointerException; } if (exClass) { Object* throwable = rvmAllocateObject(env, exClass); if (!throwable) { throwable = rvmExceptionClear(env); } Frame fakeFrame; fakeFrame.prev = (Frame*) getFramePointer((ucontext_t*) context); fakeFrame.returnAddress = getPC((ucontext_t*) context); CallStack* callStack = captureCallStackFromFrame(env, &fakeFrame); rvmSetLongInstanceFieldValue(env, throwable, stackStateField, PTR_TO_LONG(callStack)); rvmRaiseException(env, throwable); } } struct sigaction sa; sa.sa_flags = 0; sa.sa_handler = SIG_DFL; sigaction(signum, &sa, NULL); kill(0, signum); }
jlong Java_org_robovm_rt_VM_getArrayValuesAddress(Env* env, Class* c, Array* array) { return PTR_TO_LONG(array->values); }
jlong Java_aura_rt_VM_getPointer(Env* env, Class* c, jlong address) { return PTR_TO_LONG(*((void**) LONG_TO_PTR(address))); }
jlong Java_aura_rt_VM_getStringUTFChars(Env* env, Class* c, Object* s) { return PTR_TO_LONG(rvmGetStringUTFChars(env, s)); }
jlong Java_aura_rt_VM_getFieldAddress(Env* env, Class* c, Object* fieldObject) { Field* field = (Field*) getFieldFromFieldObject(env, fieldObject); return PTR_TO_LONG(field); }
jlong Java_aura_rt_VM_getClassFieldAddress(Env* env, Class* c, jlong fieldPtr) { ClassField* field = (ClassField*) LONG_TO_PTR(fieldPtr); return PTR_TO_LONG(field->address); }
jlong Java_aura_rt_VM_getCallbackMethodImpl(Env* env, Class* c, Object* methodObject) { Method* method = getMethodFromMethodObject(env, methodObject); return PTR_TO_LONG(((CallbackMethod*) method)->callbackImpl); }
jlong Java_aura_rt_VM_getObjectAddress(Env* env, Class* c, Object* object) { return PTR_TO_LONG(object); }
jlong Java_aura_rt_VM_allocateMemoryAtomic(Env* env, Class* c, jint size) { return PTR_TO_LONG(rvmAllocateMemoryAtomic(env, size)); }
static jint attachThread(VM* vm, Env** envPtr, char* name, Object* group, jboolean daemon) { Env* env = *envPtr; // env is NULL if rvmAttachCurrentThread() was called. If non NULL rvmInitThreads() was called. if (!env) { // If the thread was already attached there's an Env* associated with the thread. env = (Env*) pthread_getspecific(tlsEnvKey); if (env) { env->attachCount++; *envPtr = env; return JNI_OK; } } if (!env) { env = rvmCreateEnv(vm); if (!env) goto error; } setThreadEnv(env); if (rvmExceptionOccurred(env)) goto error; Thread* thread = allocThread(env); if (!thread) goto error; thread->stackAddr = getStackAddress(); thread->pThread = pthread_self(); env->currentThread = thread; rvmChangeThreadStatus(env, thread, THREAD_RUNNING); JavaThread* threadObj = (JavaThread*) rvmAllocateObject(env, java_lang_Thread); if (!threadObj) goto error; rvmLockThreadsList(); if (!initThread(env, thread, threadObj)) { rvmUnlockThreadsList(); goto error; } if (!rvmSetupSignals(env)) { rvmUnlockThreadsList(); goto error; } DL_PREPEND(threads, thread); pthread_cond_broadcast(&threadsChangedCond); rvmUnlockThreadsList(); Object* threadName = NULL; if (name) { threadName = rvmNewStringUTF(env, name, -1); if (!threadName) goto error_remove; } Method* threadConstructor = rvmGetInstanceMethod2(env, java_lang_Thread, "<init>", "(JLjava/lang/String;Ljava/lang/ThreadGroup;Z)V"); if (!threadConstructor) goto error_remove; rvmCallNonvirtualVoidInstanceMethod(env, (Object*) threadObj, threadConstructor, PTR_TO_LONG(thread), threadName, group, daemon); if (rvmExceptionOccurred(env)) goto error_remove; *envPtr = env; return JNI_OK; error_remove: rvmLockThreadsList(); DL_DELETE(threads, thread); pthread_cond_broadcast(&threadsChangedCond); rvmTearDownSignals(env); rvmUnlockThreadsList(); error: if (env) env->currentThread = NULL; clearThreadEnv(); return JNI_ERR; }
jint Java_java_lang_System_identityHashCode(Env* env, Class* c, Object* o) { return (jint) PTR_TO_LONG(o); }
jlong Java_aura_rt_VM_allocateMemoryUncollectable(Env* env, Class* c, jint size) { return PTR_TO_LONG(rvmAllocateMemoryUncollectable(env, size)); }
int32_t nvmJitFill_Segments_Info(nvmByteCodeSegmentsInfo *segmentsInfo, nvmByteCode *bytecode, char* errbuf) { uint32_t i = 0, j = 0; uint8_t *segmentsByteCode = NULL; uint8_t *byte_stream = NULL; NETVM_ASSERT(segmentsInfo != NULL && bytecode != NULL, " NULL arguments"); segmentsByteCode = (uint8_t *)bytecode->Hdr; for (i = 0; i < bytecode->Hdr->FileHeader.NumberOfSections; i++) { switch (bytecode->SectionsTable[i].SectionFlag) { case BC_CODE_SCN|BC_PUSH_SCN: segmentsInfo->PushSegment.LocalsSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + LOCALS_SIZE_OFFS]); segmentsInfo->PushSegment.MaxStackSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + MAX_STACK_SIZE_OFFS]); segmentsInfo->PushSegment.ByteCode = (uint8_t *)&segmentsByteCode[bytecode->Hdr->FileHeader.AddressOfPushEntryPoint]; segmentsInfo->PushSegment.SegmentSize = bytecode->SectionsTable[i].SizeOfRawData - SEGMENT_HEADER_LEN; segmentsInfo->PushSegment.Name = (char*)bytecode->SectionsTable[i].Name; segmentsInfo->PushSegment.SegmentType = PUSH_SEGMENT; break; case BC_CODE_SCN|BC_PULL_SCN: segmentsInfo->PullSegment.LocalsSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + LOCALS_SIZE_OFFS]); segmentsInfo->PullSegment.MaxStackSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + MAX_STACK_SIZE_OFFS]); segmentsInfo->PullSegment.ByteCode = (uint8_t *)&segmentsByteCode[bytecode->Hdr->FileHeader.AddressOfPullEntryPoint]; segmentsInfo->PullSegment.SegmentSize = bytecode->SectionsTable[i].SizeOfRawData - SEGMENT_HEADER_LEN; segmentsInfo->PullSegment.Name = (char*)bytecode->SectionsTable[i].Name; segmentsInfo->PullSegment.SegmentType = PULL_SEGMENT; break; case BC_CODE_SCN|BC_INIT_SCN: segmentsInfo->InitSegment.LocalsSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + LOCALS_SIZE_OFFS]); segmentsInfo->InitSegment.MaxStackSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + MAX_STACK_SIZE_OFFS]); segmentsInfo->InitSegment.ByteCode = (uint8_t *)&segmentsByteCode[bytecode->Hdr->FileHeader.AddressOfInitEntryPoint]; segmentsInfo->InitSegment.SegmentSize = bytecode->SectionsTable[i].SizeOfRawData - SEGMENT_HEADER_LEN; segmentsInfo->InitSegment.Name = (char*)bytecode->SectionsTable[i].Name; segmentsInfo->InitSegment.SegmentType = INIT_SEGMENT; break; case BC_PORT_SCN: segmentsInfo->InitSegment.LocalsSize = 0; segmentsInfo->InitSegment.MaxStackSize = 0; segmentsInfo->InitSegment.ByteCode = (uint8_t *)&bytecode->Hdr[bytecode->SectionsTable[i].PointerToRawData]; segmentsInfo->InitSegment.SegmentSize = bytecode->SectionsTable[i].SizeOfRawData; segmentsInfo->InitSegment.Name = (char*)bytecode->SectionsTable[i].Name; segmentsInfo->InitSegment.SegmentType = PORT_SEGMENT; break; case BC_INSN_LINES_SCN|BC_PUSH_SCN: j = 0; byte_stream = (uint8_t *)&bytecode->Hdr[bytecode->SectionsTable[i].PointerToRawData]; while(j < bytecode->SectionsTable[i].SizeOfRawData) { uint32_t ip, line; ip = *(uint32_t*)&byte_stream[j]; line = *(uint32_t*)&byte_stream[j]; segmentsInfo->PushSegment.Insn2LineMap.insert(std::pair<uint32_t,uint32_t>(ip, line)); } break; case BC_INSN_LINES_SCN|BC_PULL_SCN: j = 0; byte_stream = (uint8_t *)&bytecode->Hdr[bytecode->SectionsTable[i].PointerToRawData]; while(j < bytecode->SectionsTable[i].SizeOfRawData) { uint32_t ip, line; ip = *(uint32_t*)&byte_stream[j]; line = *(uint32_t*)&byte_stream[j]; segmentsInfo->PullSegment.Insn2LineMap.insert(std::pair<uint32_t,uint32_t>(ip, line)); } break; case BC_INSN_LINES_SCN|BC_INIT_SCN: j = 0; byte_stream = (uint8_t *)&bytecode->Hdr[bytecode->SectionsTable[i].PointerToRawData]; while(j < bytecode->SectionsTable[i].SizeOfRawData) { uint32_t ip, line; ip = *(uint32_t*)&byte_stream[j]; line = *(uint32_t*)&byte_stream[j]; segmentsInfo->InitSegment.Insn2LineMap.insert(std::pair<uint32_t,uint32_t>(ip, line)); } break; } } return nvmSUCCESS; }
nvmRESULT nvmFillPEInfo(nvmNetPE *PE, nvmByteCode *bytecode, char *ErrBuf) { uint32_t i = 0, p = 0, port_table_len = 0, k, j,len; char name[MAX_COPRO_NAME]; uint8_t *copro_section_element; uint8_t *segmentsByteCode = NULL, *ptr; uint32_t *port_table = NULL; uint8_t *push_ILTable = NULL, *pull_ILTable = NULL, *init_ILTable = NULL; uint32_t push_ILTlen = 0, pull_ILTlen = 0, init_ILTlen = 0; NETVM_ASSERT(PE != NULL && bytecode != NULL && ErrBuf, " NULL arguments"); segmentsByteCode = (uint8_t *)bytecode->Hdr; for (i = 0; i < bytecode->Hdr->FileHeader.NumberOfSections; i++) { switch (bytecode->SectionsTable[i].SectionFlag) { case BC_CODE_SCN|BC_PUSH_SCN: PE->PushHandler = nvmAllocObject(sizeof(nvmPEHandler), ErrBuf); if (PE->PushHandler == NULL) { errsnprintf(ErrBuf, nvmERRBUF_SIZE, ALLOC_FAILURE); return nvmFAILURE; } PE->PushHandler->NumLocals = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + LOCALS_SIZE_OFFS]); PE->PushHandler->MaxStackSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + MAX_STACK_SIZE_OFFS]); PE->PushHandler->ByteCode = (uint8_t *)&segmentsByteCode[bytecode->Hdr->FileHeader.AddressOfPushEntryPoint]; PE->PushHandler->CodeSize = bytecode->SectionsTable[i].SizeOfRawData - SEGMENT_HEADER_LEN; PE->PushHandler->Name = (char*)bytecode->SectionsTable[i].Name; PE->PushHandler->HandlerType = PUSH_HANDLER; PE->PushHandler->OwnerPE = PE; PE->PushHandler->Insn2LineTable = NULL; PE->PushHandler->Insn2LineTLen = 0; break; case BC_INSN_LINES_SCN|BC_PUSH_SCN: push_ILTable = (uint8_t *)&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData]; push_ILTlen = bytecode->SectionsTable[i].SizeOfRawData; break; case BC_CODE_SCN|BC_PULL_SCN: PE->PullHandler = nvmAllocObject(sizeof(nvmPEHandler), ErrBuf); if (PE->PullHandler == NULL) { errsnprintf(ErrBuf, nvmERRBUF_SIZE, ALLOC_FAILURE); return nvmFAILURE; } PE->PullHandler->NumLocals = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + LOCALS_SIZE_OFFS]); PE->PullHandler->MaxStackSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + MAX_STACK_SIZE_OFFS]); PE->PullHandler->ByteCode = (uint8_t *)&segmentsByteCode[bytecode->Hdr->FileHeader.AddressOfPullEntryPoint]; PE->PullHandler->CodeSize = bytecode->SectionsTable[i].SizeOfRawData - SEGMENT_HEADER_LEN; PE->PullHandler->Name = (char*)bytecode->SectionsTable[i].Name; PE->PullHandler->HandlerType = PULL_HANDLER; PE->PullHandler->OwnerPE = PE; PE->PullHandler->Insn2LineTable = NULL; PE->PullHandler->Insn2LineTLen = 0; break; case BC_INSN_LINES_SCN|BC_PULL_SCN: pull_ILTable = (uint8_t *)&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData]; pull_ILTlen = bytecode->SectionsTable[i].SizeOfRawData; break; case BC_CODE_SCN|BC_INIT_SCN: PE->InitHandler = nvmAllocObject(sizeof(nvmPEHandler), ErrBuf); if (PE->InitHandler == NULL) { errsnprintf(ErrBuf, nvmERRBUF_SIZE, ALLOC_FAILURE); return nvmFAILURE; } PE->InitHandler->NumLocals = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + LOCALS_SIZE_OFFS]); PE->InitHandler->MaxStackSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + MAX_STACK_SIZE_OFFS]); PE->InitHandler->ByteCode = (uint8_t *)&segmentsByteCode[bytecode->Hdr->FileHeader.AddressOfInitEntryPoint]; PE->InitHandler->CodeSize = bytecode->SectionsTable[i].SizeOfRawData - SEGMENT_HEADER_LEN; PE->InitHandler->Name = (char*)bytecode->SectionsTable[i].Name; PE->InitHandler->HandlerType = INIT_HANDLER; PE->InitHandler->OwnerPE = PE; PE->InitHandler->Insn2LineTable = NULL; PE->InitHandler->Insn2LineTLen = 0; break; case BC_INSN_LINES_SCN|BC_INIT_SCN: init_ILTable = (uint8_t *)&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData]; init_ILTlen = bytecode->SectionsTable[i].SizeOfRawData; break; case BC_PORT_SCN: port_table_len = *(uint32_t *) ((int8_t*)bytecode->Hdr + bytecode->SectionsTable[i].PointerToRawData); port_table = (uint32_t *) ((int8_t*)bytecode->Hdr + bytecode->SectionsTable[i].PointerToRawData + PORT_TABLE_OFFS); PE->PortTable = calloc(port_table_len, sizeof(nvmPEPort)); if (PE->PortTable == NULL) { errsnprintf(ErrBuf, nvmERRBUF_SIZE, ALLOC_FAILURE); return nvmFAILURE; } for (p = 0; p < port_table_len; p++) { if (port_table[p] & nvmPORT_COLLECTOR) PORT_SET_TYPE_COLLECTOR(PE->PortTable[p].PortFlags); else PORT_SET_TYPE_EXPORTER(PE->PortTable[ p].PortFlags); if (port_table[p] & nvmCONNECTION_PULL) PORT_SET_DIR_PULL(PE->PortTable[p].PortFlags); else PORT_SET_DIR_PUSH(PE->PortTable[p].PortFlags); } PE->NPorts = port_table_len; break; case BC_INITIALIZED_DATA_SCN: PE->InitedMem = (uint8_t *) bytecode->Hdr + bytecode->SectionsTable[i].PointerToRawData; PE->InitedMemSize = bytecode->SectionsTable[i].SizeOfRawData; break; case BC_METADATA_SCN: /* 32bit for name length */ k = *(uint32_t *) ((int8_t*)bytecode->Hdr + bytecode->SectionsTable[i].PointerToRawData); /* k characters forming PE name */ ptr = (uint8_t *) ((int8_t*)bytecode->Hdr + bytecode->SectionsTable[i].PointerToRawData + 4); strncpy (PE->Name, (char*)ptr, k); PE->Name[k < MAX_NETPE_NAME ? k : MAX_NETPE_NAME] = '\0'; /* 32bit for data memory size */ PE->DataMemSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + 4 + k]); /* 32bit for info partition size */ PE->InfoPartitionSize = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + 4 + k + 4]); /* 32bit for coprocessor number */ PE->NCopros = PTR_TO_LONG(&segmentsByteCode[bytecode->SectionsTable[i].PointerToRawData + 4 + k + 4 + 4]); if (PE->NCopros > 0) { PE->Copros = calloc(PE->NCopros,4); /* For each coprocessor, 32 bit for coprocessor name length and thqt many characters for the actual name */ copro_section_element = (uint8_t *) ((int8_t*)bytecode->Hdr + bytecode->SectionsTable[i].PointerToRawData + 4 + k + 4 + 4 + 4); for (k = 0; k < PE->NCopros; k++) { len = *(uint32_t *)copro_section_element; copro_section_element += 4; memcpy (name, copro_section_element, len); name[len] = '\0'; copro_section_element += len; /* See if the requested coprocessor is available */ for (j = 0; j < AVAILABLE_COPROS_NO; j++) { if (strcmp (name, nvm_copro_map[j].copro_name) == 0) { PE->Copros[k]=j; break; } } if (j >= AVAILABLE_COPROS_NO) { errorprintf(__FILE__, __FUNCTION__, __LINE__, "Coprocessor '%s' is not available\n", name); return (nvmFAILURE); } } } break; default: errorprintf(__FILE__, __FUNCTION__, __LINE__, "Unsupported section in NetIL code\n"); return (nvmFAILURE); break; } for (p = 0; p < PE->NPorts; p++) { if (PORT_DIR(PE->PortTable[p].PortFlags) == PORT_DIR_PUSH\ && PORT_TYPE(PE->PortTable[p].PortFlags) == PORT_TYPE_EXPORTER) { if (PE->PushHandler == NULL) { errsnprintf(ErrBuf, nvmERRBUF_SIZE, "No valid handler available for PUSH COLLECTOR port"); return nvmFAILURE; } PE->PortTable[p].Handler = PE->PushHandler; } else if (PORT_DIR(PE->PortTable[p].PortFlags) == PORT_DIR_PULL\ && PORT_TYPE(PE->PortTable[p].PortFlags) == PORT_TYPE_EXPORTER) { if (PE->PullHandler == NULL) { errsnprintf(ErrBuf, nvmERRBUF_SIZE, "No valid handler available for PULL EXPORTER port"); return nvmFAILURE; } PE->PortTable[p].Handler = PE->PullHandler; } } } PE->InitHandler->Insn2LineTable = init_ILTable; PE->InitHandler->Insn2LineTLen = init_ILTlen; PE->PushHandler->Insn2LineTable = push_ILTable; PE->PushHandler->Insn2LineTLen = push_ILTlen; PE->PullHandler->Insn2LineTable = pull_ILTable; PE->PullHandler->Insn2LineTLen = pull_ILTlen; return nvmSUCCESS; }
jlong Java_org_robovm_rt_VM_allocateMemory(Env* env, Class* c, jint size) { return PTR_TO_LONG(rvmAllocateMemory(env, size)); }
jlong Java_com_bugvm_rt_Signals_saveSignals(Env* env, Class* c) { return PTR_TO_LONG(rvmSaveSignals(env)); }
static void signalHandler_npe_so(int signum, siginfo_t* info, void* context) { // SIGSEGV/SIGBUS are synchronous signals so we shouldn't have to worry about only calling // async-signal-safe functions here. Env* env = rvmGetEnv(); if (env && rvmIsNonNativeFrame(env)) { // We now know the fault occurred in non-native code. void* faultAddr = info->si_addr; void* stackAddr = env->currentThread->stackAddr; Class* exClass = NULL; if (faultAddr < stackAddr && faultAddr >= (void*) (stackAddr - THREAD_STACK_GUARD_SIZE)) { // StackOverflowError exClass = java_lang_StackOverflowError; } else { // At least on Linux x86 it seems like si_addr isn't always 0x0 even // if a read of address 0x0 triggered SIGSEGV so we assume // everything that isn't a stack overflow is a read of address 0x0 // and throw NullPointerException. exClass = java_lang_NullPointerException; } if (exClass) { Frame fakeFrame; fakeFrame.prev = (Frame*) getFramePointer((ucontext_t*) context); fakeFrame.returnAddress = getPC((ucontext_t*) context); Object* throwable = NULL; CallStack* callStack = captureCallStackFromFrame(env, &fakeFrame); if (callStack) { throwable = rvmAllocateObject(env, exClass); if (throwable) { rvmCallVoidClassMethod(env, exClass, throwableInitMethod, throwable, PTR_TO_LONG(callStack)); if (rvmExceptionCheck(env)) { throwable = NULL; } } } if (!throwable) { throwable = rvmExceptionClear(env); } rvmRaiseException(env, throwable); // Never returns! } } }