/* src/native/vm/gnu/gnu_classpath_jdwp_VMVirtualMachine.c - jdwp->jvmti interface Copyright (C) 1996-2005, 2006, 2008 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include #include #include "toolbox/logging.hpp" #include "native/jni.hpp" #include "native/include/java_lang_Thread.h" #include "native/include/java_nio_ByteBuffer.h" #include "native/include/java_lang_Class.h" #include "native/include/java_lang_ClassLoader.h" #include "native/include/java_lang_reflect_Method.h" #include "native/include/gnu_classpath_jdwp_event_EventRequest.h" #include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h" #include "native/jvmti/jvmti.h" #include "native/jvmti/VMjdwp.h" /* * Class: gnu_classpath_jdwp_VMVirtualMachine * Method: suspendThread * Signature: (Ljava/lang/Thread;)V */ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) { jvmtiError err; err = (*jvmtienv)->SuspendThread(jvmtienv, (jthread) par1); printjvmtierror("VMVirtualMachine.suspendThread SuspendThread", err); } /* * Class: gnu_classpath_jdwp_VMVirtualMachine * Method: resumeThread * Signature: (Ljava/lang/Thread;)V */ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) { jvmtiError err; err = (*jvmtienv)->ResumeThread(jvmtienv, (jthread) par1); printjvmtierror("VMVirtualMachine.resumethread ResumeThread", err); } /* * Class: gnu_classpath_jdwp_VMVirtualMachine * Method: getSuspendCount * Signature: (Ljava/lang/Thread;)I */ JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) { log_text ("VMVirtualMachine_getSuspendCount: not supported"); return 1; } /* * Class: gnu_classpath_jdwp_VMVirtualMachine * Method: getAllLoadedClassesCount * Signature: ()I */ JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount(JNIEnv *env, jclass clazz) { jint count; jclass* classes; jvmtiError err; if (JVMTI_ERROR_NONE != (err= (*jvmtienv)-> GetLoadedClasses(jvmtienv, &count, &classes))) { printjvmtierror("VMVirtualMachine_getAllLoadedClassCount GetLoadedClasses",err); return 0; } (*jvmtienv)->Deallocate(jvmtienv,(unsigned char*)classes); return count; } /* * Class: gnu_classpath_jdwp_VMVirtualMachine * Method: getAllLoadedClasses * Signature: ()Ljava/util/Iterator */ JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasses(JNIEnv *env, jclass clazz) { jclass *classes, *cl; jint classcount; jobjectArray joa; /* jthrowable e;*/ jmethodID m; jobject *ol,*oi; int i; jvmtiError err; if (JVMTI_ERROR_NONE != (err= (*jvmtienv)-> GetLoadedClasses(jvmtienv, &classcount, &classes))) { printjvmtierror("VMVirtualMachine_getAllLoadedClasses GetLoadedClasses",err); /* we should throw JDWP Exception INTERNAL = 113;*/ /* env->ThrowNew(env,ec,"jvmti error occoured"); */ return NULL; } cl = (*env)->FindClass(env,"java.lang.Class"); if (!cl) return NULL; /* Arrays.asList(Object[] classes)->List.Iterator()->Iterator */ joa = (*env)->NewObjectArray(env, (jsize)classcount, cl , NULL); if (!joa) return NULL; for (i = 0; i < classcount; i++) (*env)->SetObjectArrayElement(env,joa,(jsize)i, (jobject)classes[i]); (*jvmtienv)->Deallocate(jvmtienv, (unsigned char*)classes); cl = (*env)->FindClass(env,"java.util.Arrays"); if (!cl) return NULL; m = (*env)->GetStaticMethodID(env, cl, "asList", "([Ljava/lang/Object;)Ljava/util/List;"); if (!m) return NULL; ol = (*env)->CallStaticObjectMethod(env,(jclass)cl,m,joa); if (!ol) return NULL; cl = (*env)->FindClass(env,"java.util.List"); if (!cl) return NULL; m = (*env)->GetMethodID(env,cl,"iterator","()Ljava/util/Iterator;"); if (!m) return NULL; oi = (*env)->CallObjectMethod(env,ol,m); return (struct java_util_Iterator*)oi; } /* Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getClassStatus * Signature: (Ljava/lang/Class;)I */ JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) { jint status; jvmtiError err; err = (*jvmtienv)->GetClassStatus(jvmtienv, (jclass) par1, &status); printjvmtierror("VMVirtualMachine_getClassStatus GetClassStatus", err); return status; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getAllClassMethods * Signature: (Ljava/lang/Class;)[Lgnu/classpath/jdwp/VMMethod; */ JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) { jint count; jmethodID* methodID, m; jvmtiError err; jclass *cl; jobject *ol; jobjectArray joa; int i; if (JVMTI_ERROR_NONE != (err= (*jvmtienv)-> GetClassMethods(jvmtienv, (jclass) par1, &count, &methodID))) { printjvmtierror("VMVirtualMachine_getAllClassMethods GetClassMethods", err); return NULL; } m = (*env)-> GetStaticMethodID(env, clazz, "getClassMethod", "(Ljava/lang/Class;J)Lgnu/classpath/jdwp/VMMethod;"); if (!m) return NULL; cl = (*env)->FindClass(env,"gnu.classpath.jdwp.VMMethod"); if (!cl) return NULL; joa = (*env)->NewObjectArray(env, (jsize)count, cl , NULL); if (!joa) return NULL; for (i = 0; i < count; i++) { ol = (*env)-> CallStaticObjectMethod(env,clazz,m,(jobject)par1, methodID[i]); if (!ol) return NULL; (*env)->SetObjectArrayElement(env,joa,(jsize)i, ol); } return joa; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getClassMethod * Signature: (Ljava/lang/Class;J)Lgnu/classpath/jdwp/VMMethod; */ JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod(JNIEnv *env, jclass clazz, struct java_lang_Class* par1, s8 par2) { jclass *cl; jmethodID m; jobject *ol; cl = (*env)->FindClass(env,"gnu.classpath.jdwp.VMMethod"); if (!cl) return NULL; m = (*env)->GetMethodID(env, cl, "", "(Ljava/lang/Class;J)V"); if (!m) return NULL; ol = (*env)->NewObject(env, cl, m, par1, par2); return (struct gnu_classpath_jdwp_VMMethod*)ol; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getFrames * Signature: (Ljava/lang/Thread;II)Ljava/util/ArrayList; */ JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, int32_t par2, int32_t par3) { log_text ("VMVirtualMachine_getFrames - IMPLEMENT ME!!!"); /* jclass ec = (*env)->FindClass(env,"gnu/classpath/jdwp/JdwpInternalErrorException"); if (JVMTI_ERROR_NONE != (*jvmtienv)->GetClassStatus(jvmtienv, par1, &status)) env->ThrowNew(env,ec,"jvmti error occoured");*/ return 0; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getFrame * Signature: (Ljava/lang/Thread;Ljava/nio/ByteBuffer;)Lgnu/classpath/jdwp/VMFrame; */ JNIEXPORT struct gnu_classpath_jdwp_VMFrame* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrame(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, struct java_nio_ByteBuffer* par2) { log_text ("VMVirtualMachine_getFrame - IMPLEMENT ME!!!"); return 0; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getFrameCount * Signature: (Ljava/lang/Thread;)I */ JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) { jint count; jvmtiError err; err = (*jvmtienv)->GetFrameCount(jvmtienv, (jthread)par1, &count); printjvmtierror("VMVirtualMachine_getFrameCount GetFrameCount", err); return count; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getThreadStatus * Signature: (Ljava/lang/Thread;)I */ JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) { jint status; jvmtiError err; if (JVMTI_ERROR_NONE != (err = (*jvmtienv)->GetThreadState(jvmtienv, (jthread)par1, &status))) { printjvmtierror("VMVirtualMachine_getThreadStatus GetThreadState", err); return 0; } if (status && JVMTI_THREAD_STATE_ALIVE) { if (status && JVMTI_THREAD_STATE_WAITING) { return 4; /* WAIT - see JdwpConstants */ } if (status && JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) { return 3; /* MONITOR - see JdwpConstants */ } if (status && JVMTI_THREAD_STATE_SLEEPING) { return 2; /* SLEEPING - see JdwpConstants */ } return 1; /* RUNNING - see JdwpConstants */ } else return 0; /* ZOMBIE - see JdwpConstants */ return -1; /* some error */ } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getLoadRequests * Signature: (Ljava/lang/ClassLoader;)Ljava/util/ArrayList; */ JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getLoadRequests(JNIEnv *env, jclass clazz, struct java_lang_ClassLoader* par1) { log_text ("VMVirtualMachine_getLoadRequests("); return 0; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: executeMethod * Signature: (Ljava/lang/Object;Ljava/lang/Thread;Ljava/lang/Class;Ljava/lang/reflect/Method;[Ljava/lang/Object;Z)Lgnu/classpath/jdwp/util/MethodResult; */ JNIEXPORT struct gnu_classpath_jdwp_util_MethodResult* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod(JNIEnv *env, jclass clazz, struct java_lang_Object* par1, struct java_lang_Thread* par2, struct java_lang_Class* par3, struct java_lang_reflect_Method* par4, java_objectarray* par5, int32_t par6) { log_text ("VMVirtualMachine_executeMethod"); return 0; } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: getSourceFile * Signature: (Ljava/lang/Class;)Ljava/lang/String; */ JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSourceFile(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) { char* srcname; jstring str; jvmtiError err; if (JVMTI_ERROR_NONE !=(err=(*jvmtienv)-> GetSourceFileName(jvmtienv, (jclass)par1, &srcname))) { printjvmtierror("VMVirtualMachine.getSourceFile GetSourceFileName", err); return NULL; } str = (*env)->NewString(env,(jchar*)srcname,(jsize)strlen(srcname)); return (struct java_lang_String*)str; } /* match JdwpConstants.EventKind to jvmtiEvent constants */ static jvmtiEvent EventKind2jvmtiEvent(jbyte kind){ switch (kind) { case /* SINGLE_STEP */ 1: return JVMTI_EVENT_SINGLE_STEP; case /* BREAKPOINT */ 2: return JVMTI_EVENT_BREAKPOINT; case /* FRAME_POP */ 3: return JVMTI_EVENT_FRAME_POP; case /* EXCEPTION */ 4: return JVMTI_EVENT_EXCEPTION; case /* USER_DEFINED */ 5: return -1; /* can this be matched ? */ case /* THREAD_START */ 6: return JVMTI_EVENT_THREAD_START; case /* THREAD_END */ 7: return JVMTI_EVENT_THREAD_END; case /* CLASS_PREPARE */ 8: return JVMTI_EVENT_CLASS_PREPARE; case /* CLASS_UNLOAD */ 9: return -1; /* can this be matched ? */ case /* CLASS_LOAD */ 10: return JVMTI_EVENT_CLASS_LOAD; case /* FIELD_ACCESS */ 20: return JVMTI_EVENT_FIELD_ACCESS; case /* FIELD_MODIFICATION */ 21: return JVMTI_EVENT_FIELD_MODIFICATION; case /* EXCEPTION_CATCH */ 30: return JVMTI_EVENT_EXCEPTION_CATCH; case /* METHOD_ENTRY */ 40: return JVMTI_EVENT_METHOD_ENTRY; case /* METHOD_EXIT */ 41: return JVMTI_EVENT_METHOD_EXIT; case /* VM_INIT */ 90: return JVMTI_EVENT_VM_INIT; case /* VM_DEATH */ 99: return JVMTI_EVENT_VM_DEATH; case /* VM_DISCONNECTED */ 100: return -1; /* can this be matched ? */ default: return -1; } } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: registerEvent * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V */ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) { jbyte kind; jfieldID kindid; jclass erc; jvmtiError err; erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest"); kindid = (*env)->GetFieldID(env, erc, "_kind", "B"); kind = (*env)->GetByteField(env, (jobject)par1, kindid); if (JVMTI_ERROR_NONE != (err= (*jvmtienv)-> SetEventNotificationMode(jvmtienv, JVMTI_ENABLE, EventKind2jvmtiEvent(kind), NULL))) printjvmtierror("VMVirtualMachine_registerEvent SetEventNotificationMode",err); } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: unregisterEvent * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V */ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) { jbyte kind; jfieldID kindid; jclass erc; jvmtiError err; erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest"); kindid = (*env)->GetFieldID(env, erc, "_kind", "B"); kind = (*env)->GetByteField(env, (jobject)par1, kindid); if (JVMTI_ERROR_NONE != (err= (*jvmtienv)-> SetEventNotificationMode(jvmtienv, JVMTI_DISABLE, EventKind2jvmtiEvent(kind), NULL))) printjvmtierror("VMVirtualMachine_registerEvent SetEventNotificationMode",err); } /* * Class: gnu/classpath/jdwp/VMVirtualMachine * Method: clearEvents * Signature: (B)V */ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents(JNIEnv *env, jclass clazz, int32_t par1) { /* jvmti events are not saved - there is nothing to clear */ } /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: * mode: c * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 * End: */