[kaffe] Using Kaffe with remote debugging via Eclipse
Derek Davies
ddavies at ddavies.net
Thu Aug 19 22:11:45 PDT 2004
Hi,
There's bad news and good news. The bad news is that my most recent
backup of kaffe JVMDI work (~2001) gets I/O errors when I try to read
it. It's shrimp toast. The good news is that at least I was able to
read the second most recent backup I have (~2000) and that has some
stuff done against 1.0.5 .
I don't think I have the 1.0.6 stuff I did anywhere. I do remember
that I had run into problems that made me redo a lot of stuff...
Best of luck and thanks for trying to revive this. It brings back
good memories!
Derek
diff -Nru kaffe-1.0.5/kaffe/kaffe/main.c kaffe-1.0.5-hacks/kaffe/kaffe/main.c
--- kaffe-1.0.5/kaffe/kaffe/main.c 1999-10-18 01:23:54.000000000 -0400
+++ kaffe-1.0.5-hacks/kaffe/kaffe/main.c 2000-01-02 17:47:57.000000000 -0500
@@ -9,6 +9,16 @@
* of this file.
*/
+/* +++ DLD Tue Oct 19 21:02:26 1999 */
+#include <jvmdi.h>
+#include <jvmdiEvents.h>
+/* --- DLD */
+
+/* +++ DLD Thu Oct 14 19:04:54 1999 */
+/* FIXME: I know this isn't right...use the accepted abstractions */
+#include <dlfcn.h>
+/* --- DLD */
+
#include "config.h"
#include "config-std.h"
#include "config-mem.h"
@@ -36,11 +46,19 @@
JNIEnv* env;
JavaVM* vm;
static int isJar = 0;
+/* +++ DLD Thu Oct 14 16:47:51 1999 */
+static void* dlHdl = NULL;
+static char* jvmdiClientLibraryName = NULL;
+static char* jvmdiClientLibraryOnLoadArgs = NULL;
+/* --- DLD */
static int options(char**);
static void usage(void);
static size_t parseSize(char*);
static void handleErrors(void);
+/* +++ DLD Thu Oct 14 16:22:01 1999 */
+static int registerJVMDIClient(void);
+/* --- DLD */
static int main2(JNIEnv* env, char *argv[], int farg, int argc);
#define KAFFEHOME "KAFFEHOME"
@@ -109,6 +127,19 @@
exit(1);
}
+ /* +++ DLD Thu Oct 14 16:17:18 1999 */
+
+ /* Load the JVMDI client library, if it was given.
+ */
+ if (jvmdiClientLibraryName)
+ {
+ if (registerJVMDIClient()) {
+ exit(2);
+ }
+ }
+
+ /* --- DLD */
+
/* Initialise */
JNI_CreateJavaVM(&vm, &env, &vmargs);
@@ -190,11 +221,34 @@
(*env)->SetObjectArrayElement(env, args, i, str);
handleErrors();
}
+
+ /* +++ DLD Thu Oct 21 19:01:56 1999 */
+ fireVMInitEvent();
+ handleErrors();
+ /* --- DLD */
/* Call method, check for errors and then exit */
(*env)->CallStaticVoidMethod(env, mcls, mmth, args);
handleErrors();
+ /* +++ DLD Sun Oct 17 13:57:22 1999 */
+ /* FIXME: Is this really the right time/place to fire this event? The
+ spec is, um, a little sparse regarding this detail. */
+ fireVMDeathEvent();
+ handleErrors();
+ /* --- DLD */
+
+ /* +++ DLD Thu Oct 14 16:49:38 1999 */
+ /* FIXME: make this portable */
+ if (dlHdl)
+ {
+ (void)dlclose(dlHdl);
+ dlHdl = NULL;
+
+ fprintf(stderr, "Unloaded JVMDI client library\n");
+ }
+ /* --- DLD */
+
(*vm)->DetachCurrentThread(vm);
return (0);
}
@@ -403,6 +457,28 @@
prop->key = &argv[i][2];
prop->value = &argv[i][sz];
}
+ /* +++ DLD Thu Oct 14 15:27:37 1999 */
+ /* eXtension? I don't know, Sun came up with this. */
+ else if (argv[i][1] == 'X') {
+ if (strcmp(&(argv[i][2]), "debug") == 0) {
+ /* FIXME */
+ }
+ else if (strcmp(&(argv[i][2]), "noagent") == 0) {
+ /* FIXME */
+ }
+ else if (strncmp(&(argv[i][2]), "run", 3) == 0) {
+ for (sz = 5; argv[i][sz] != 0; sz++) {
+ if (argv[i][sz] == ':') {
+ argv[i][sz] = 0;
+ sz++;
+ break;
+ }
+ }
+ jvmdiClientLibraryName = &argv[i][5];
+ jvmdiClientLibraryOnLoadArgs = &argv[i][sz];
+ }
+ }
+ /* --- DLD */
/* The following options are not supported and will be
* ignored for compatibility purposes.
*/
@@ -462,6 +538,11 @@
#ifdef KAFFE_STATS
fprintf(stderr, " -vmstats <flag{,flag}> Print VM statistics. Set flag=all for all\n");
#endif
+ /* +++ DLD Fri Oct 15 10:25:42 1999 */
+ fprintf(stderr, " -Xdebug * Turn on debugger mode\n");
+ fprintf(stderr, " -Xnoagent * Don't load default debug agent\n");
+ fprintf(stderr, " -Xrun<lib>:<args> JVMDI client library and args\n");
+ /* --- DLD */
fprintf(stderr, " * Option currently ignored.\n");
}
@@ -488,3 +569,44 @@
return (sz);
}
+
+/* +++ DLD Thu Oct 14 16:22:47 1999 */
+
+static jint registerJVMDIClient()
+{
+ /* FIXME: Make this portable */
+ /*JNIEXPORT*/ jint /*JNICALL*/ (*JVM_OnLoad)(JavaVM*, char*, void*);
+
+ if (!(dlHdl = dlopen(jvmdiClientLibraryName, RTLD_LAZY)))
+ {
+ fprintf(stderr,
+ "Error loading JVMDI client library:\n%s\n", dlerror());
+ return 1;
+ }
+
+ /* This is part of JVMDI protocol.
+ */
+ JVM_OnLoad = dlsym(dlHdl, "JVM_OnLoad");
+ {
+ char* e = dlerror();
+ if (e)
+ {
+ (void)dlclose(dlHdl);
+ dlHdl = NULL;
+ fprintf(
+ stderr,
+ "Can't find JVMDI client library JVM_OnLoad routine:\n%s\n",
+ e);
+ return 1;
+ }
+ }
+
+ /* FIXME: Do I have to increment the ref count on VM here or what?
+ What's the right way to hand this out? Is it under GC?
+ */
+ (*JVM_OnLoad)(vm, jvmdiClientLibraryOnLoadArgs, (void*)NULL);
+
+ return 0;
+}
+
+/* --- DLD */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/Makefile.am kaffe-1.0.5-hacks/kaffe/kaffevm/Makefile.am
--- kaffe-1.0.5/kaffe/kaffevm/Makefile.am 1999-10-18 01:23:57.000000000 -0400
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/Makefile.am 2000-01-11 18:57:40.000000000 -0500
@@ -61,6 +61,7 @@
itypes.c \
jar.c \
jni.c \
+ jvmdi.c \
locks.c \
lookup.c \
object.c \
@@ -99,6 +100,8 @@
itypes.h \
jar.h \
jnirefs.h \
+ jvmdiEvents.h \
+ jvmdiRawMonitor.h \
lerrno.h \
locks.h \
lookup.h \
diff -Nru kaffe-1.0.5/kaffe/kaffevm/Makefile.in kaffe-1.0.5-hacks/kaffe/kaffevm/Makefile.in
--- kaffe-1.0.5/kaffe/kaffevm/Makefile.in 1999-10-18 01:23:57.000000000 -0400
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/Makefile.in 2000-01-11 18:58:11.000000000 -0500
@@ -184,6 +184,7 @@
itypes.c \
jar.c \
jni.c \
+ jvmdi.c \
locks.c \
lookup.c \
object.c \
@@ -223,6 +224,8 @@
itypes.h \
jar.h \
jnirefs.h \
+ jvmdiEvents.h \
+ jvmdiRawMonitor.h \
lerrno.h \
locks.h \
lookup.h \
@@ -259,7 +262,7 @@
am_libkaffevm_la_OBJECTS = gc-mem.lo md.lo baseClasses.lo \
classMethod.lo classPool.lo methodCache.lo code-analyse.lo code.lo \
constants.lo debug.lo exception.lo external.lo findInJar.lo fp.lo gc.lo \
-hashtab.lo inflate.lo itypes.lo jar.lo jni.lo locks.lo lookup.lo \
+hashtab.lo inflate.lo itypes.lo jar.lo jni.lo jvmdi.lo locks.lo lookup.lo \
object.lo readClass.lo sha-1.lo soft.lo stackTrace.lo stats.lo \
string.lo support.lo thread.lo utf8const.lo gcFuncs.lo gcRefs.lo \
verify.lo
diff -Nru kaffe-1.0.5/kaffe/kaffevm/intrp/machine.c kaffe-1.0.5-hacks/kaffe/kaffevm/intrp/machine.c
--- kaffe-1.0.5/kaffe/kaffevm/intrp/machine.c 1999-10-18 01:24:00.000000000 -0400
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/intrp/machine.c 1999-12-07 20:52:45.000000000 -0500
@@ -44,6 +44,11 @@
#include "errors.h"
#include "md.h"
+/* +++ DLD Thu Oct 21 20:29:43 1999 */
+#include "jvmdi.h"
+#include "jvmdiEvents.h"
+/* --- DLD */
+
/*
* Define information about this engine.
*/
@@ -241,6 +246,28 @@
mjbuf->pc = pc;
npc = pc + insnLen[code[pc]];
+ /* +++ DLD Thu Oct 21 20:02:14 1999 */
+/*
+#ifdef JVMDI
+*/
+ if (strncmp(meth->class->name->data,
+ "HiChico",
+ sizeof("HiChico")) == 0)
+ {
+ printf("in HiChico.%s:{pc=%d, npc=%d, code=0x%x}\n",
+ meth->name->data, pc, npc, code[pc]);
+
+ fireSingleStepEvent(
+ *(jthread_current()),
+ (jclass)meth->class,
+ (jmethodID)meth->idx,
+ (jlocation)pc);
+ }
+/*
+#endif
+*/
+ /* --- DLD */
+
switch (code[pc]) {
default:
fprintf(stderr, "Unknown bytecode %d\n", code[pc]);
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/HiChico.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/HiChico.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/HiChico.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/HiChico.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/HiChico.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/HiChico.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,24 @@
+
+class HiChico
+{
+ public void sayHiAgain()
+ {
+ System.out.println("Mia! Mia!");
+ }
+
+ HiChico()
+ {
+ System.out.println("Anichka Maya!");
+ sayHiAgain();
+ System.out.println("Hi Chico!");
+ }
+
+ public static void main(String args[])
+ {
+ System.out.println("Bilky");
+ new HiChico();
+ System.out.println("smaltcoat");
+ }
+}
+
+// End of HiChico.java
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/Makefile kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/Makefile
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/Makefile 2000-01-02 18:43:39.000000000 -0500
@@ -0,0 +1,16 @@
+
+# FIXME: Do this the Right Way.
+
+CFLAGS=-I../../../include -I../../../config -I../systems/unix-jthreads -I../ -DKVER -I/usr/include/readline
+
+.PHONY: all
+all: jpdaBackend.so
+
+jpdaBackend.so: jpdaBackend.o
+ gcc -shared $^ -Wl,--whole-archive ../systems/unix-jthreads/.libs/libkthread.al -Wl,--no-whole-archive -ldl -lm -lc -lreadline -Wl,-soname -Wl,-llibkaffevm-1.0b4.so -o ./libjpdaBackend.so
+
+.PHONY: check
+check:
+ test.sh
+
+# End of Makefile
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/Makefile-cli-serv kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/Makefile-cli-serv
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/Makefile-cli-serv 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/Makefile-cli-serv 1999-12-27 13:38:41.000000000 -0500
@@ -0,0 +1,19 @@
+
+LOADLIBES=-lsocket -lnsl
+CFLAGS=-Wall
+CC=gcc
+
+.PHONY: all
+all: cmd-client cmd-server
+
+cmd-client: cmd-client.o sockhelp.o
+
+cmd-server: cmd-server.o sockhelp.o
+
+sockhelp.o: sockhelp.c
+
+.PHONY: clean
+clean:
+ rm -f *.o cmd-client cmd-server
+
+# End of Makefile
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/README.RUN kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/README.RUN
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/README.RUN 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/README.RUN 2000-01-02 18:46:43.000000000 -0500
@@ -0,0 +1,166 @@
+
+<READ Example run:>
+
+V.:/home/ddavies/src/kaffe-1.0.5>export LD_LIBRARY_PATH=.:/usr/local/lib:/usr/lib:/lib
+V.:/home/ddavies/src/kaffe-1.0.5>kaffe -XrunlibjpdaBackend.so:hi,chico HiChico
+Error loading JVMDI client library:
+libjpdaBackend.so: cannot open shared object file: No such file or directory
+V.:/home/ddavies/src/kaffe-1.0.5>cd kaffe/kaffevm/jpdaBackend/
+V.:/home/ddavies/src/kaffe-1.0.5/kaffe/kaffevm/jpdaBackend>kaffe -XrunlibjpdaBackend.so:hi,chico HiChico
+jvmdb: Kaffe JVMDI Debugger Client
+jvmdb: Hack! Hack!
+jvmdb: VM initialization event received.
+jvmdb> b
+Internal error: caught an unexpected exception.
+Please check your CLASSPATH and your installation.
+java/lang/NullPointerException
+Aborted (core dumped)
+V.:/home/ddavies/src/kaffe-1.0.5/kaffe/kaffevm/jpdaBackend>kaffe -XrunlibjpdaBackend.so:hi,chico HiChico
+jvmdb: Kaffe JVMDI Debugger Client
+jvmdb: Hack! Hack!
+jvmdb: VM initialization event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=0, npc=3, code=0xb2}
+SingleStepEvent!! pc is 0
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=3, npc=5, code=0x12}
+SingleStepEvent!! pc is 3
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=5, npc=8, code=0xb6}
+SingleStepEvent!! pc is 5
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+Bilky
+in HiChico.main:{pc=8, npc=11, code=0xbb}
+SingleStepEvent!! pc is 8
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=11, npc=12, code=0x59}
+SingleStepEvent!! pc is b
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=12, npc=15, code=0xb7}
+SingleStepEvent!! pc is c
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=0, npc=1, code=0x2a}
+SingleStepEvent!! pc is 0
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=1, npc=4, code=0xb7}
+SingleStepEvent!! pc is 1
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=4, npc=7, code=0xb2}
+SingleStepEvent!! pc is 4
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=7, npc=9, code=0x12}
+SingleStepEvent!! pc is 7
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=9, npc=12, code=0xb6}
+SingleStepEvent!! pc is 9
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+Anichka Maya!
+in HiChico.<init>:{pc=12, npc=13, code=0x2a}
+SingleStepEvent!! pc is c
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=13, npc=16, code=0xb6}
+SingleStepEvent!! pc is d
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.sayHiAgain:{pc=0, npc=3, code=0xb2}
+SingleStepEvent!! pc is 0
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.sayHiAgain:{pc=3, npc=5, code=0x12}
+SingleStepEvent!! pc is 3
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.sayHiAgain:{pc=5, npc=8, code=0xb6}
+SingleStepEvent!! pc is 5
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+Mia! Mia!
+in HiChico.sayHiAgain:{pc=8, npc=9, code=0xb1}
+SingleStepEvent!! pc is 8
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=16, npc=19, code=0xb2}
+SingleStepEvent!! pc is 10
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=19, npc=21, code=0x12}
+SingleStepEvent!! pc is 13
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.<init>:{pc=21, npc=24, code=0xb6}
+SingleStepEvent!! pc is 15
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+Hi Chico!
+in HiChico.<init>:{pc=24, npc=25, code=0xb1}
+SingleStepEvent!! pc is 18
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=15, npc=16, code=0x57}
+SingleStepEvent!! pc is f
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=16, npc=19, code=0xb2}
+SingleStepEvent!! pc is 10
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=19, npc=21, code=0x12}
+SingleStepEvent!! pc is 13
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+in HiChico.main:{pc=21, npc=24, code=0xb6}
+SingleStepEvent!! pc is 15
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+smaltcoat
+in HiChico.main:{pc=24, npc=25, code=0xb1}
+SingleStepEvent!! pc is 18
+jvmdb: Single step event received.
+jvmdb> c
+jvmdb: Continuing.
+jvmdb: VM death event received.
+jvmdb> c
+jvmdb: Error. Unrecognized command.
+jvmdb> q
+jvmdb: Quiting.
+
+
+</READ thats all for now, add to me! >
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/breakpoints.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/breakpoints.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/breakpoints.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/breakpoints.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,16 @@
+
+#include "jvmdi.h"
+
+jvmdiError SetBreakpoint(jclass clazz, jmethodID method, jlocation location)
+{
+}
+
+jvmdiError ClearBreakpoint(jclass class, jmethodID method, jlocalion location)
+{
+}
+
+jvmdierror ClearAllBreakpoints()
+{
+}
+
+/* End of breakpoints.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/class_info.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/class_info.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/class_info.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/class_info.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,47 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetClassSignature(jclass clazz, char** sigPtr)
+{
+}
+
+jvmdiError GetClassStatus(jclass clazz, char* statusPtr)
+{
+}
+
+jvmdiError GetSourceFileName(jclass clazz, char** sourceNamePtr)
+{
+}
+
+jvmdiError GetClassModifiers(jclass clazz, jint* modifiersPtr)
+{
+}
+
+jvmdiError GetClassMethods(jclass clazz, jint* methodCountPtr,
+ methodID** methodsPtr)
+{
+}
+
+jvmdiError GetClassFields(jclass clazz, jint* fieldCountPtr,
+ jfieldID** fieldsPtr)
+{
+}
+
+jvmdiError GetImplementedInterfaces(jclass clazz, jint* interfaceCountPtr,
+ jclass** interfacesPtr)
+{
+}
+
+jvmdiError IsInterface(jclass clazz, jboolean* isInterfacePtr)
+{
+}
+
+jvmdiError IsArrayclass(jclass clazz, jboolean* isArrayClassPyr)
+{
+}
+
+jvmdiError GetClassLoader(jclass clazz, jobject* classloaderPtr)
+{
+}
+
+/* End of class_info.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/cmd-client.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/cmd-client.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/cmd-client.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/cmd-client.c 1999-12-27 13:32:46.000000000 -0500
@@ -0,0 +1,67 @@
+/*
+ * This file is provided for use with the unix-socket-faq. It is public
+ * domain, and may be copied freely. There is no copyright on it. The
+ * original work was by Vic Metcalfe (vic at brutus.tlug.org), and any
+ * modifications made to that work were made with the understanding that
+ * the finished work would be in the public domain.
+ *
+ * If you have found a bug, please pass it on to me at the above address
+ * acknowledging that there will be no copyright on your work.
+ *
+ * The most recent version of this file, and the unix-socket-faq can be
+ * found at http://www.interlog.com/~vic/sock-faq/.
+ */
+
+#include "sockhelp.h"
+#include <stdio.h>
+#include <unistd.h>
+
+int read_line_from_server_and_print(int sock)
+{
+ static char buffer[1024];
+
+ if (sock_gets(sock, buffer, sizeof(buffer) - 1) < 0)
+ {
+ fprintf(stderr, "sock_gets() call failed, aborting\n");
+ return -1;
+ }
+ else
+ {
+ printf("%s\n", buffer);
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int sock;
+
+ if (argc != 3)
+ {
+ fprintf(stderr,"Usage: hostname-client host port\n");
+ fprintf(stderr,"where host is the machine which is running the\n");
+ fprintf(stderr,"hostname-server program, and port is the port\n");
+ fprintf(stderr,"on which it's listening.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ ignore_pipe();
+ sock = make_connection(argv[2], SOCK_STREAM, argv[1]);
+ if (sock == -1)
+ {
+ fprintf(stderr,"make_connection failed.\n");
+ return -1;
+ }
+
+ if (read_line_from_server_and_print(sock) >= 0)
+ {
+ (void)read_line_from_server_and_print(sock);
+ }
+
+ close(sock);
+
+ return 0;
+}
+
+/* End of hostname-client.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/cmd-server.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/cmd-server.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/cmd-server.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/cmd-server.c 1999-12-27 13:49:50.000000000 -0500
@@ -0,0 +1,79 @@
+
+/*
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <sys/utsname.h>
+#include <sys/resource.h>
+*/
+#include "sockhelp.h"
+
+/* Waits for all children so that they don't become zombies.
+*/
+void sig_chld(int signal_type)
+{
+ int pid;
+ int status;
+
+ while ((pid = wait3(&status, WNOHANG, NULL)) > 0);
+}
+
+int main(int argc, char* argv[])
+{
+ int sock;
+ int port = -1;
+ char buffer[1024];
+ struct sigaction act;
+ struct sigaction oldact;
+ struct utsname system_info;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: cmd-server <port>\n");
+ fprintf(stderr, "Where:\n");
+ fprintf(stderr, "\t<port> is a port number or service name.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ ignore_pipe();
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = sig_chld;
+ sigaction(SIGCHLD, &act, &oldact);
+
+ port = atoport(argv[1], "tcp");
+ if (port == -1)
+ {
+ fprintf(stderr, "Unable to find service: %s\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ sock = get_connection(SOCK_STREAM, port, NULL);
+
+ sock_puts(sock, "Welcome to the cmd-server!\n");
+
+ if (uname(&system_info) < 0)
+ {
+ sprintf(buffer,
+ "Couldn't get hostname [uname() call failed, errno is %d]\n",
+ errno);
+ sock_puts(sock, buffer);
+ }
+ else
+ {
+ sprintf(buffer,
+ "This server is running on host %s\n",
+ system_info.nodename);
+ sock_puts(sock, buffer);
+ }
+
+ close(sock);
+
+ return 0;
+}
+
+/* End of cmd-server.c */
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/cmd.tar and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/cmd.tar differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpClass.pl kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpClass.pl
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpClass.pl 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpClass.pl 1999-12-07 20:57:42.000000000 -0500
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+#
+# Dump a java .class file to stdout
+#
+
+#
+# Copyright (c) 1999 University of Utah CSL.
+#
+# This file 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.
+#
+# Written by Patrick Tullmann <tullmann at cs.utah.edu>
+#
+
+use JavaClass;
+
+# Control the verbosity of &printClass()
+$JavaClass::detailedFields = 0;
+$JavaClass::detailedMethods = 0;
+
+## Parse the command line
+my $classFile = shift || &usage();
+
+## Read/parse the class file
+my $class = &JavaClass::readClass($classFile);
+
+## Print the class filea
+&JavaClass::printClass($class);
+
+###
+###
+###
+
+sub usage() {
+ print STDOUT "Usage:\n";
+ print STDOUT " dumpClass.pl <ClassFile>\n\n";
+ print STDOUT " Note that '.class' will be appended if it is not specified in the file name.\n";
+
+ exit 11;
+}
+
+#eof
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/HiChico.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/HiChico.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.DPD kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.DPD
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.DPD 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.DPD 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,19 @@
+# Symantec IDDE generated .dpd file. V: 7200
+util\attributeinfo.class: \
+ util\attributeinfo.java \
+ util\ConstantPoolInfo.java
+util\constantpoolinfo.class: \
+ util\constantpoolinfo.java
+util\classfile.class: \
+ util\classfile.java \
+ util\FieldInfo.java
+util\fieldinfo.class: \
+ util\fieldinfo.java \
+ util\MethodInfo.java
+util\methodinfo.class: \
+ util\methodinfo.java \
+ util\ConstantPoolInfo.java \
+ util\AttributeInfo.java
+dumpclass.class: \
+ dumpclass.java \
+ util\ClassFile.java
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.MAK kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.MAK
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.MAK 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.MAK 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,90 @@
+ORIGIN = Symantec Café
+ORIGIN_VER = Version 7.22
+VERSION = DEBUG
+
+!IFDEF SUB_DEBUG
+DEBUG = $(SUB_DEBUG)
+NDEBUG = !$(SUB_DEBUG)
+!ELSE
+DEBUG = 1
+NDEBUG = 0
+!ENDIF
+
+PROJ = dumpclass
+APPTYPE = JAVA CONSOLE
+PROJTYPE = class
+
+JAVAC = sj
+MAKE = SMAKE
+LNK = LINK
+
+
+HEADERS =
+!IF $(DEBUG)
+OUTPUTDIR = .
+CREATEOUTPUTDIR =
+TARGETDIR = .
+CREATETARGETDIR =
+
+CFLAGS = -g
+DEFINES =
+!ELSE
+OUTPUTDIR = .
+CREATEOUTPUTDIR =
+TARGETDIR = .
+CREATETARGETDIR =
+
+CFLAGS = -O
+DEFINES =
+!ENDIF
+
+MFLAGS = MASTERPROJ=$(PROJ)
+DEBUGGERFLAGS =
+PAR = PROJS BATS OBJS
+
+INCLUDES = -classpath .;C:\Cafe\JAVA\LIB\CLASSES.ZIP;d:\temp
+
+
+
+OBJS = util\AttributeInfo.class util\ClassFile.class util\ConstantPoolInfo.class \
+ util\FieldInfo.class util\MethodInfo.class dumpclass.class
+
+BATS =
+
+.SUFFIXES: .JAVA .CLASS
+
+.JAVA.CLASS:
+ $(JAVAC) $(CFLAGS) $(INCLUDES) $*.java
+
+
+
+all: noteout createdir $(PRECOMPILE) $(OBJS) $(POSTCOMPILE) _done
+
+
+all2: createdir $(PRECOMPILE) $(OBJS) $(POSTCOMPILE) _done
+
+noteout:
+ REM Output to $(OUTPUTDIR)
+
+createdir:
+ $(CREATEOUTPUTDIR)
+ $(CREATETARGETDIR)
+
+_done:
+ REM Project is up to date
+
+buildall: clean all
+
+
+clean:
+ -del $(TARGETDIR)\$$SCW$$.$(PROJTYPE)
+ -del $(TARGETDIR)\$(PROJ).CLE
+ -del dumpclass.dpd
+ -del $(OBJS)
+
+
+
+!IF EXIST (dumpclass.dpd)
+!INCLUDE dumpclass.dpd
+!ENDIF
+
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.OPN and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.OPN differ
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,35 @@
+/*
+ * dumpclass.java
+ *
+ * Uses the class file decoders in util to dump out a
+ * class file.
+ * Written : 22 - May - 1996 by Chuck McManis
+ */
+
+import util.*;
+import java.io.*;
+
+public class dumpclass {
+ public static void main(String args[]) {
+ FileInputStream fis;
+ ClassFile cf = new ClassFile();
+ cf.debug = true;
+
+
+ /* Try to open arg[0] as the name of a .class file */
+ try { fis = new FileInputStream(args[0]); }
+ catch (IOException e) { fis = null; }
+
+ try {
+ /* Read in the .class file (can throw various things) */
+ if (! cf.read(fis)) {
+ System.out.println("Couldn't load "+args[0]+", press a key.");
+ int c = System.in.read(); /* this is for Symantec */
+ throw new Exception("File not parsed.");
+ }
+
+ cf.display(System.out);
+ int c = System.in.read(); /* Keep screen open */
+ } catch (Exception e) { }
+ }
+}
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.prj kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.prj
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.prj 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.prj 1999-12-07 20:57:42.000000000 -0500
@@ -0,0 +1,13 @@
+82570
+D:\TEMP\dumpclass.prj
+dumpclass.OPN
+novcs
+dumpclass.DEF
+24
+0
+0 0 0 0 0 "util\AttributeInfo.java" "util\AttributeInfo.class"
+0 0 0 0 0 "util\ClassFile.java" "util\ClassFile.class"
+0 0 0 0 0 "util\ConstantPoolInfo.java" "util\ConstantPoolInfo.class"
+0 0 0 0 0 "util\FieldInfo.java" "util\FieldInfo.class"
+0 0 0 0 0 "util\MethodInfo.java" "util\MethodInfo.class"
+0 0 0 0 0 "dumpclass.java" ""
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.tar and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/dumpclass.tar differ
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/AttributeInfo.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/AttributeInfo.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/AttributeInfo.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/AttributeInfo.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/AttributeInfo.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/AttributeInfo.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,100 @@
+/*
+ * @(#)AttributeInfo.java 1.4 95/08/16 Chuck McManis
+ *
+ * Copyright (c) 1996 Chuck McManis, All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies.
+ *
+ * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+package util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * This class defines the generic Attribute type for Java class files.
+ * It is a little bit smart in that for some Attributes it can display
+ * them intelligently if it also has access to the constant pool of the
+ * current class.
+ *
+ * @version 1.4, 16 Aug 1995
+ * @author Chuck McManis
+ * @see ClassFile
+ */
+public class AttributeInfo {
+ ConstantPoolInfo name; // attribute name
+ byte data[]; // attribute's contents
+
+ public AttributeInfo(ConstantPoolInfo newName, byte newData[]) {
+ name = name;
+ data = newData;
+ }
+
+ public AttributeInfo() {
+ }
+
+ public boolean read(DataInputStream di, ConstantPoolInfo pool[])
+ throws IOException {
+ int len;
+
+ name = pool[di.readShort()];
+ len = di.readInt();
+ data = new byte[len];
+ len = di.read(data);
+ if (len != data.length)
+ return (false);
+ return (true);
+ }
+
+ public void write(DataOutputStream dos, ConstantPoolInfo pool[])
+ throws IOException, Exception {
+ dos.writeShort(ConstantPoolInfo.indexOf(name, pool));
+ dos.writeInt(data.length);
+ dos.write(data, 0, data.length);
+ }
+
+ short indexFromBytes(byte a[]) {
+ return (short)(((a[0] << 8) & (0xff << 8)) |
+ ((a[1] << 0) & (0xff << 0)));
+ }
+
+ public String toString(ConstantPoolInfo pool[]) {
+ StringBuffer x = new StringBuffer();
+ String type = name.toString();
+ ConstantPoolInfo item;
+
+ if (type.compareTo("ConstantValue") == 0) {
+ item = pool[indexFromBytes(data)];
+ return (item.toString());
+ } else if (type.compareTo("SourceFile") == 0) {
+ item = pool[indexFromBytes(data)];
+ return (item.toString());
+ } else {
+ x.append(type+"<"+data.length+" bytes>");
+ }
+ return (x.toString());
+ }
+
+ public String toBoolean(ConstantPoolInfo pool[]) {
+ ConstantPoolInfo item = pool[indexFromBytes(data)];
+
+ if (item.intValue == 0)
+ return ("= false");
+ return ("= true");
+ }
+
+ public String toString() {
+ return (name.toString()+" <"+data.length+" bytes>");
+ }
+}
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/ClassFile.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/ClassFile.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/ClassFile.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/ClassFile.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/ClassFile.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/ClassFile.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,787 @@
+/*
+ * ClassFile.java Chuck McManis
+ *
+ * Copyright (c) 1996 Chuck McManis, All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies.
+ *
+ * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+package util;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * This class is used to manipulate Java class files in strange and
+ * mysterious ways.
+ *
+ * Usage it typically to feed it an array of bytes that are a class
+ * file, manipulate the class, then convert the class back into bytes,
+ * and feed the final result to <TT>defineClass()</TT>.
+ *
+ * @version 1.6, 19 Aug 1995
+ * @author Chuck McManis
+ * @see AttributeInfo
+ * @see ConstantPoolInfo
+ * @see MethodInfo
+ * @see FieldInfo
+ */
+
+public class ClassFile {
+ int magic;
+ short majorVersion;
+ short minorVersion;
+ ConstantPoolInfo constantPool[];
+ short accessFlags;
+ ConstantPoolInfo thisClass;
+ ConstantPoolInfo superClass;
+ ConstantPoolInfo interfaces[];
+ FieldInfo fields[];
+ MethodInfo methods[];
+ AttributeInfo attributes[];
+ boolean isValidClass = false;
+
+ public static final int ACC_PUBLIC = 0x1;
+ public static final int ACC_PRIVATE = 0x2;
+ public static final int ACC_PROTECTED = 0x4;
+ public static final int ACC_STATIC = 0x8;
+ public static final int ACC_FINAL = 0x10;
+ public static final int ACC_SYNCHRONIZED = 0x20;
+ public static final int ACC_THREADSAFE = 0x40;
+ public static final int ACC_TRANSIENT = 0x80;
+ public static final int ACC_NATIVE = 0x100;
+ public static final int ACC_INTERFACE = 0x200;
+ public static final int ACC_ABSTRACT = 0x400;
+
+ public boolean debug = false;
+ public boolean dumpConstants = false;
+ /**
+ * Read a class from InputStream <i>in</i>.
+ */
+ public boolean read(InputStream in)
+ throws IOException {
+ DataInputStream di = new DataInputStream(in);
+ int count;
+
+ magic = di.readInt();
+ if (magic != (int) 0xCAFEBABE) {
+ return (false);
+ }
+
+ majorVersion = di.readShort();
+ minorVersion = di.readShort();
+ count = di.readShort();
+ constantPool = new ConstantPoolInfo[count];
+ if (debug)
+ System.out.println("read(): Read header...");
+ constantPool[0] = new ConstantPoolInfo();
+ for (int i = 1; i < constantPool.length; i++) {
+ constantPool[i] = new ConstantPoolInfo();
+ if (! constantPool[i].read(di)) {
+ return (false);
+ }
+ // These two types take up "two" spots in the table
+ if ((constantPool[i].type == ConstantPoolInfo.LONG) ||
+ (constantPool[i].type == ConstantPoolInfo.DOUBLE))
+ i++;
+ }
+
+ /*
+ * Update pointers in the constant table. This turns the
+ * table into a real datastructure.
+ *
+ * TODO: Have it verify that the right arguments are present
+ */
+ for (int i = 1; i < constantPool.length; i++) {
+ if (constantPool[i] == null)
+ continue;
+ if (constantPool[i].index1 > 0)
+ constantPool[i].arg1 = constantPool[constantPool[i].index1];
+ if (constantPool[i].index2 > 0)
+ constantPool[i].arg2 = constantPool[constantPool[i].index2];
+ }
+
+ if (dumpConstants) {
+ for (int i = 1; i < constantPool.length; i++) {
+ System.out.println("C"+i+" - "+constantPool[i]);
+ }
+ }
+ accessFlags = di.readShort();
+
+ thisClass = constantPool[di.readShort()];
+ superClass = constantPool[di.readShort()];
+ if (debug)
+ System.out.println("read(): Read class info...");
+
+ /*
+ * Identify all of the interfaces implemented by this class
+ */
+ count = di.readShort();
+ if (count != 0) {
+ if (debug)
+ System.out.println("Class implements "+count+" interfaces.");
+ interfaces = new ConstantPoolInfo[count];
+ for (int i = 0; i < count; i++) {
+ int iindex = di.readShort();
+ if ((iindex < 1) || (iindex > constantPool.length - 1))
+ return (false);
+ interfaces[i] = constantPool[iindex];
+ if (debug)
+ System.out.println("I"+i+": "+interfaces[i]);
+ }
+ }
+ if (debug)
+ System.out.println("read(): Read interface info...");
+
+ /*
+ * Identify all fields in this class.
+ */
+ count = di.readShort();
+ if (debug)
+ System.out.println("This class has "+count+" fields.");
+ if (count != 0) {
+ fields = new FieldInfo[count];
+ for (int i = 0; i < count; i++) {
+ fields[i] = new FieldInfo();
+ if (! fields[i].read(di, constantPool)) {
+ return (false);
+ }
+ if (debug)
+ System.out.println("F"+i+": "+
+ fields[i].toString(constantPool));
+ }
+ }
+ if (debug)
+ System.out.println("read(): Read field info...");
+
+ /*
+ * Identify all the methods in this class.
+ */
+ count = di.readShort();
+ if (count != 0) {
+ methods = new MethodInfo[count];
+ for (int i = 0; i < count; i++) {
+ methods[i] = new MethodInfo();
+ if (! methods[i].read(di, constantPool)) {
+ return (false);
+ }
+ if (debug)
+ System.out.println("M"+i+": "+methods[i].toString());
+ }
+ }
+ if (debug)
+ System.out.println("read(): Read method info...");
+
+
+ /*
+ * Identify all of the attributes in this class
+ */
+ count = di.readShort();
+ if (count != 0) {
+ attributes = new AttributeInfo[count];
+ for (int i = 0; i < count; i++) {
+ attributes[i] = new AttributeInfo();
+ if (! attributes[i].read(di, constantPool)) {
+ return (false);
+ }
+ }
+ }
+ if (debug) {
+ System.out.println("read(): Read attribute info...");
+ System.out.println("done.");
+ }
+ isValidClass = true;
+ return(true);
+ }
+
+ /**
+ * Write the class out as a stream of bytes to the output
+ * stream.
+ *
+ * Generally you will read a class file, manipulate
+ * it in some way, and then write it out again before passing
+ * it to <TT>defineClass</TT> in some class loader.
+ */
+ public void write(OutputStream out)
+ throws IOException, Exception {
+ DataOutputStream dos = new DataOutputStream(out);
+
+ if (! isValidClass) {
+ throw new Exception("ClassFile::write() - Invalid Class");
+ }
+
+ dos.writeInt(magic);
+ dos.writeShort(majorVersion);
+ dos.writeShort(minorVersion);
+ dos.writeShort(constantPool.length);
+ for (int i = 1; i < constantPool.length; i++) {
+ if (constantPool[i] != null)
+ constantPool[i].write(dos, constantPool);
+ }
+ dos.writeShort(accessFlags);
+ dos.writeShort(ConstantPoolInfo.indexOf(thisClass, constantPool));
+ dos.writeShort(ConstantPoolInfo.indexOf(superClass, constantPool));
+
+ if (interfaces == null) {
+ dos.writeShort(0);
+ } else {
+ dos.writeShort(interfaces.length);
+ for (int i = 0; i < interfaces.length; i++) {
+ dos.writeShort(ConstantPoolInfo.indexOf(interfaces[i],
+ constantPool));
+ }
+ }
+
+ if (fields == null) {
+ dos.writeShort(0);
+ } else {
+ dos.writeShort(fields.length);
+ for (int i = 0; i < fields.length; i++) {
+ fields[i].write(dos, constantPool);
+ }
+ }
+
+ if (methods == null) {
+ dos.writeShort(0);
+ } else {
+ dos.writeShort(methods.length);
+ for (int i = 0; i < methods.length; i++) {
+ methods[i].write(dos, constantPool);
+ }
+ }
+
+ if (attributes == null) {
+ dos.writeShort(0);
+ } else {
+ dos.writeShort(attributes.length);
+ for (int i = 0; i < attributes.length; i++) {
+ attributes[i].write(dos, constantPool);
+ }
+ }
+ }
+
+ /**
+ * Returns a string that represents what the access flags
+ * are set for. So 0x14 returns "public final "
+ */
+ public static String accessString(short flags) {
+ StringBuffer x = new StringBuffer();
+
+ if ((flags & ACC_PUBLIC) != 0) {
+ x.append("public ");
+ }
+
+ if ((flags & ACC_PRIVATE) != 0) {
+ x.append("private ");
+ }
+
+ if ((flags & ACC_PROTECTED) != 0) {
+ x.append("protected ");
+ }
+
+ if ((flags & ACC_STATIC) != 0) {
+ x.append("static ");
+ }
+
+ if ((flags & ACC_FINAL) != 0) {
+ x.append("final ");
+ }
+
+ if ((flags & ACC_SYNCHRONIZED) != 0) {
+ x.append("synchronized ");
+ }
+
+ if ((flags & ACC_THREADSAFE) != 0) {
+ x.append("threadsafe ");
+ }
+
+ if ((flags & ACC_TRANSIENT) != 0) {
+ x.append("transient ");
+ }
+
+ if ((flags & ACC_NATIVE) != 0) {
+ x.append("native ");
+ }
+
+ if ((flags & ACC_INTERFACE) != 0) {
+ x.append("interface ");
+ }
+
+ if ((flags & ACC_ABSTRACT) != 0) {
+ x.append("abstract ");
+ }
+
+ return (x.toString());
+ }
+
+ /**
+ * Takes a type signature and a string representing a variable name
+ * and returns a declaration for that variable name.
+ *
+ * For example, passing this the strings "[B" and "myArray" will
+ * return the string "byte myArray[]"
+ */
+ public static String typeString(String typeString, String varName) {
+ int isArray = 0;
+ int ndx = 0;
+ StringBuffer x = new StringBuffer();
+
+ while (typeString.charAt(ndx) == '[') {
+ isArray++;
+ ndx++;
+ }
+
+ switch (typeString.charAt(ndx)) {
+ case 'B' :
+ x.append("byte ");
+ break;
+ case 'C' :
+ x.append("char ");
+ break;
+ case 'D' :
+ x.append("double ");
+ break;
+ case 'F' :
+ x.append("float ");
+ break;
+ case 'I' :
+ x.append("int ");
+ break;
+ case 'J' :
+ x.append("long ");
+ break;
+ case 'L' :
+ for (int i = ndx+1; i < typeString.indexOf(';'); i++) {
+ if (typeString.charAt(i) != '/')
+ x.append(typeString.charAt(i));
+ else
+ x.append('.');
+ }
+ x.append(" ");
+ break;
+ case 'V':
+ x.append("void ");
+ break;
+ case 'S' :
+ x.append("short ");
+ break;
+ case 'Z' :
+ x.append("boolean ");
+ break;
+ }
+ x.append(varName);
+ while (isArray > 0) {
+ x.append("[]");
+ isArray--;
+ }
+ return (x.toString());
+ }
+
+ /**
+ * Returns the next signature from a string of concatenated signatures.
+ * For example if the signature was "[BII", this method would return
+ * "II"
+ */
+ public static String nextSig(String sig) {
+ int ndx = 0;
+ String x;
+
+ while (sig.charAt(ndx) == '[')
+ ndx++;
+
+ if (sig.charAt(ndx) == 'L') {
+ while (sig.charAt(ndx) != ';')
+ ndx++;
+ }
+ ndx++;
+ x = (sig.substring(ndx));
+ return (x);
+ }
+
+ /**
+ * Print the name of a class in "canonical form"
+ */
+ private String printClassName(String s) {
+ StringBuffer x;
+
+ if (s.charAt(0) == '[') {
+ return(typeString(s, ""));
+ }
+
+ x = new StringBuffer();
+ for (int j = 0; j < s.length(); j++) {
+ if (s.charAt(j) == '/')
+ x.append('.');
+ else
+ x.append(s.charAt(j));
+ }
+ return (x.toString());
+
+ }
+
+ public String getClassName() {
+ return printClassName(thisClass.arg1.strValue);
+ }
+
+ /**
+ * The boring version of display().
+ */
+ public String toString() {
+ return("Class File (Version "+majorVersion+"."+minorVersion+
+ ") for class "+thisClass.arg1);
+ }
+
+ /**
+ * Write out a text version of this class.
+ */
+ public void display(PrintStream ps)
+ throws Exception {
+ int i;
+ String myClassName;
+ String mySuperClassName;
+ String packageName = null;
+
+ if (! isValidClass) {
+ ps.println("Not a valid class");
+ }
+
+ myClassName = printClassName(thisClass.arg1.strValue);
+ mySuperClassName = printClassName(superClass.arg1.strValue);
+ if (myClassName.indexOf('.') > 0) {
+ packageName =
+ myClassName.substring(0, myClassName.lastIndexOf('.'));
+ myClassName = myClassName.substring(myClassName.lastIndexOf('.')+1);
+ ps.println("package "+packageName+"\n");
+ }
+
+ for (i = 1; i < constantPool.length; i++) {
+ if (constantPool[i] == null)
+ continue;
+ if ((constantPool[i] == thisClass) ||
+ (constantPool[i] == superClass))
+ continue;
+ if (constantPool[i].type == ConstantPoolInfo.CLASS) {
+ String s = constantPool[i].arg1.strValue;
+ if (s.charAt(0) == '[')
+ continue;
+ s = printClassName(constantPool[i].arg1.strValue);
+ if ((packageName != null) && (s.startsWith(packageName)))
+ continue;
+ ps.println("import "+printClassName(s)+";");
+ }
+ }
+ ps.println();
+ ps.println("/*");
+ DataInputStream dis;
+ ConstantPoolInfo cpi;
+
+ if (attributes != null) {
+ ps.println(" * This class has "+attributes.length+
+ " optional class attributes.");
+ ps.println(" * These attributes are: ");
+ for (i = 0; i < attributes.length; i++) {
+ String attrName = attributes[i].name.strValue;
+ dis = new DataInputStream(new ByteArrayInputStream(attributes[i].data));
+
+ ps.println(" * Attribute "+(i+1)+" is of type "+attributes[i].name);
+ if (attrName.compareTo("SourceFile") == 0) {
+ cpi = null;
+ try {
+ cpi = constantPool[dis.readShort()];
+ } catch (IOException e) { }
+ ps.println(" * SourceFile : "+cpi);
+ } else {
+ ps.println(" * TYPE ("+attrName+")");
+ }
+ }
+ } else {
+ ps.println(" * This class has NO optional class attributes.");
+ }
+ ps.println(" */\n");
+ ps.print(accessString(accessFlags)+"class "+myClassName+" extends "+
+ mySuperClassName);
+ if (interfaces != null) {
+ ps.print(" implements ");
+ for (i = 0; i < interfaces.length - 1; i++) {
+ ps.print(interfaces[i].arg1.strValue+", ");
+ }
+ ps.print(interfaces[interfaces.length-1].arg1.strValue);
+ }
+ ps.println(" {\n");
+ if (fields != null) {
+ ps.println("/* Instance Variables */");
+ for (i = 0; i < fields.length; i++) {
+ ps.println(" "+fields[i].toString(constantPool)+";");
+ }
+ }
+
+ if (methods != null) {
+ ps.println("\n/* Methods */");
+ for (i = 0; i < methods.length; i++) {
+ ps.println(" "+methods[i].toString(myClassName));
+ }
+ }
+ ps.println("\n}");
+ }
+
+ public ConstantPoolInfo getConstantRef(short index) {
+ return (constantPool[index]);
+ }
+
+ /**
+ * Add a single constant pool item and return its index.
+ * If the item is already in the pool then the index of
+ * the <i>preexisting</i> item is returned. Thus you cannot
+ * assume that a pointer to your item will be useful.
+ */
+ public short addConstantPoolItem(ConstantPoolInfo item)
+ throws Exception {
+ ConstantPoolInfo newConstantPool[];
+ ConstantPoolInfo cp;
+
+ cp = item.inPool(constantPool);
+ if (cp != null)
+ return ConstantPoolInfo.indexOf(cp, constantPool);
+
+ newConstantPool = new ConstantPoolInfo[constantPool.length+1];
+ for (int i = 1; i < constantPool.length; i++) {
+ newConstantPool[i] = constantPool[i];
+ }
+ newConstantPool[constantPool.length] = item;
+ constantPool = newConstantPool;
+ return ConstantPoolInfo.indexOf(item, constantPool);
+ }
+
+ /**
+ * Add some items to the constant pool. This is used to add new
+ * items to the constant pool. The items references in arg1 and
+ * arg2 are expected to be valid pointers (if necessary). Pruning
+ * is done to prevent adding redundant items to the list and to
+ * preserve string space.
+ *
+ * The algorithm is simple, first identify pool items containing
+ * constants in the list of items to be added that are already
+ * in the constant pool. If any are found to already exist, change
+ * the pointers in the non-constant items to point to the ones in
+ * the pool rather than the ones in the list. Next check to see
+ * if any of the non-constant items are already in the pool and
+ * if so fix up the others in the list to point to the ones in
+ * the pool. Finally, add any items (there must be at least one)
+ * from the item list that aren't already in the pool, all of
+ * the pointers will already be fixed.
+ *
+ * NOTE: Since constants in the constant pool may be referenced
+ * <i>inside</i> the opaque portion of attributes the constant
+ * table cannot be re-ordered, only extended.
+ */
+ public void addConstantPoolItems(ConstantPoolInfo items[]) {
+ ConstantPoolInfo newArg;
+ ConstantPoolInfo newConstantPool[];
+ boolean delete[] = new boolean[items.length];
+
+ /* Step one, look for matching constants */
+ for (int j = 0; j < items.length; j++) {
+ if ( (items[j].type == ConstantPoolInfo.ASCIZ) ||
+ (items[j].type == ConstantPoolInfo.UNICODE) ||
+ (items[j].type == ConstantPoolInfo.INTEGER) ||
+ (items[j].type == ConstantPoolInfo.LONG) ||
+ (items[j].type == ConstantPoolInfo.FLOAT) ||
+ (items[j].type == ConstantPoolInfo.DOUBLE)) {
+
+ // Look for this item in the constant pool
+ delete[j] = false;
+ newArg = items[j].inPool(constantPool);
+ if (newArg != null) {
+ // replace the references in our list.
+ delete[j] = true; // mark it for deletion
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].arg1 == items[j])
+ items[i].arg1 = newArg;
+ if (items[i].arg2 == items[j])
+ items[i].arg2 = newArg;
+ }
+ }
+ }
+ }
+
+ /* Step two : now match everything else */
+ for (int j = 0; j < items.length; j++) {
+ if ( (items[j].type == ConstantPoolInfo.CLASS) ||
+ (items[j].type == ConstantPoolInfo.FIELDREF) ||
+ (items[j].type == ConstantPoolInfo.METHODREF) ||
+ (items[j].type == ConstantPoolInfo.STRING) ||
+ (items[j].type == ConstantPoolInfo.INTERFACE) ||
+ (items[j].type == ConstantPoolInfo.NAMEANDTYPE)) {
+
+ // Look for this item in the constant pool
+ delete[j] = false;
+ newArg = items[j].inPool(constantPool);
+ if (newArg != null) {
+ // replace the references in our list.
+ delete[j] = true; // mark it for deletion
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].arg1 == items[j])
+ items[i].arg1 = newArg;
+ if (items[i].arg2 == items[j])
+ items[i].arg2 = newArg;
+ }
+ }
+ }
+ }
+
+ /* Step three: Add the surviving items to the pool */
+ int count = 0;
+ for (int i = 0; i < items.length; i++) {
+ if (! delete[i])
+ count++;
+ }
+ // count == # of survivors
+ newConstantPool = new ConstantPoolInfo[constantPool.length + count];
+ for (int i = 1; i < constantPool.length; i++) {
+ newConstantPool[i] = constantPool[i];
+ }
+ // newConstantPool == existing constantPool
+
+ int ndx = 0;
+ for (int i = constantPool.length; i < newConstantPool.length; i++) {
+ while (delete[ndx])
+ ndx++;
+ newConstantPool[i] = items[ndx];
+ ndx++;
+ }
+ // newConstantPool == existing + new
+ constantPool = newConstantPool;
+ // all done.
+ }
+
+ /**
+ * Add a new optional class Attribute.
+ *
+ * Items is an array of constant pool items that are first added
+ * to the constant pool. At a minimum items[0] must be an ASCIZ
+ * item with the name of the attribute. If the body of the attribute
+ * references constant pool items these should be in the item list
+ * as well.
+ */
+ public void addAttribute(AttributeInfo newAttribute) {
+
+ if (attributes == null) {
+ attributes = new AttributeInfo[1];
+ attributes[0] = newAttribute;
+ } else {
+ AttributeInfo newAttrList[] = new AttributeInfo[1+attributes.length];
+ for (int i = 0; i < attributes.length; i++) {
+ newAttrList[i] = attributes[i];
+ }
+ newAttrList[attributes.length] = newAttribute;
+ attributes = newAttrList;
+ }
+ }
+
+ /**
+ * Return the attribute named 'name' from the class file.
+ */
+ public AttributeInfo getAttribute(String name) {
+ if (attributes == null)
+ return null;
+ for (int i = 0; i < attributes.length; i++) {
+ if (name.compareTo(attributes[i].name.toString()) == 0)
+ return attributes[i];
+ }
+ return (null);
+ }
+
+ /**
+ * Return a constant pool item from this class. (note does fixup
+ * of indexes to facilitate extracting nested or linked items.
+ */
+ public ConstantPoolInfo getConstantPoolItem(short index)
+ throws Exception {
+ ConstantPoolInfo cp;
+
+ if ((index <= 0) || (index > (constantPool.length - 1)))
+ return (null);
+ cp = constantPool[index];
+ if (cp.arg1 != null)
+ cp.index1 = ConstantPoolInfo.indexOf(cp.arg1, constantPool);
+ if (cp.arg2 != null)
+ cp.index2 = ConstantPoolInfo.indexOf(cp.arg2, constantPool);
+ return cp;
+ }
+
+ /* Examples of mysterious things you can do to a class file before
+ * writing it back out. These methods are not currently functional.
+ * (that would be too easy :-)
+ */
+
+ /**
+ * Map occurences of class <i>oldClass</i> to occurrences of
+ * class <i>newClass</i>. This method is used to retarget
+ * accesses to one class, seamlessly to another.
+ *
+ * The format for the class name is slash (/) separated so
+ * the class <tt>util.ClassFile</tt> would be represented as
+ * <tt>util/ClassFile</tt>
+ */
+ public void mapClass(String oldClass, String newClass) {
+ if (debug)
+ System.out.println("Mapping class name "+oldClass+" ==> "+
+ newClass+" for class "+thisClass.arg1);
+ for (int i = 0; i < constantPool.length; i++) {
+ if (constantPool[i].type == ConstantPoolInfo.CLASS) {
+ String cname = constantPool[i].arg1.strValue;
+ if (cname.compareTo(oldClass) == 0) {
+ if (debug) {
+ System.out.println("REPLACING "+cname+" with "+newClass);
+ }
+ constantPool[i].arg1.strValue = newClass;
+ }
+ }
+ }
+ }
+
+ /**
+ * Map occurences of package <i>oldPackage</i> to package
+ * <i>newPackage</i>.
+ *
+ * The format for the package name is slash (/) separated so
+ * the package <tt>java.util</tt> would be represented as
+ * <tt>java/util</tt>
+ */
+ public void mapPackage(String oldPackage, String newPackage) {
+ for (int i = 0; i < constantPool.length; i++) {
+ if (constantPool[i].type == ConstantPoolInfo.CLASS) {
+ String cname = constantPool[i].arg1.strValue;
+ if (cname.startsWith(oldPackage)) {
+ constantPool[i].arg1.strValue = newPackage +
+ cname.substring(cname.lastIndexOf('/'));
+ }
+ }
+ }
+ }
+
+ /**
+ * Delete a named method from this class. This method is used
+ * to excise specific methods from the loaded class. The actual
+ * method code remains, however the method signature is deleted
+ * from the constant pool. If this method is called by a class
+ * the exception IncompatibleClassChangeException is generated
+ * by the runtime.
+ */
+ public void deleteMethod(String name, String signature) {
+ for (int i = 0; i < constantPool.length; i++) {
+ if (constantPool[i].type == ConstantPoolInfo.CLASS) {
+ }
+ }
+ }
+}
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/ConstantPoolInfo.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/ConstantPoolInfo.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/ConstantPoolInfo.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/ConstantPoolInfo.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/ConstantPoolInfo.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/ConstantPoolInfo.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,344 @@
+/*
+ * @(#)ConstantPoolInfo.java 1.5 95/08/16 Chuck McManis
+ *
+ * Copyright (c) 1996 Chuck McManis, All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies.
+ *
+ * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+package util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * This class defines an entry in the constant pool for a Java class.
+ * The class file is primarily composed of ConstantPool entries and
+ * manipulation is done by modifying those entries.
+ *
+ * @version 1.5, 16 Aug 1995
+ * @author Chuck McManis
+ * @see ClassFile
+ */
+
+public class ConstantPoolInfo{
+ int type; // type of this item
+ String name; // String for the type
+ ConstantPoolInfo arg1; // index to first argument
+ ConstantPoolInfo arg2; // index to second argument
+ short index1, index2;
+ String strValue; // ASCIZ String value
+ int intValue;
+ long longValue;
+ float floatValue;
+ double doubleValue;
+
+ public static final int CLASS = 7;
+ public static final int FIELDREF = 9;
+ public static final int METHODREF = 10;
+ public static final int STRING = 8;
+ public static final int INTEGER = 3;
+ public static final int FLOAT = 4;
+ public static final int LONG = 5;
+ public static final int DOUBLE = 6;
+ public static final int INTERFACE = 11;
+ public static final int NAMEANDTYPE = 12;
+ public static final int ASCIZ = 1;
+ public static final int UNICODE = 2;
+
+
+ /**
+ * Construct a new ConstantPoolInfo object that is of type ASCIZ
+ */
+ public ConstantPoolInfo(String value) {
+ index1 = -1;
+ index2 = -1;
+ arg1 = null;
+ arg2 = null;
+ type = ASCIZ;
+ strValue = value;
+ }
+
+ /**
+ * Construct a new ConstantPoolInfo object that is of type INTEGER
+ */
+ public ConstantPoolInfo(int value) {
+ index1 = -1;
+ index2 = -1;
+ arg1 = null;
+ arg2 = null;
+ type = INTEGER;
+ intValue = value;
+ }
+
+ /**
+ * Construct a new ConstantPoolInfo object that is of type FLOAT
+ */
+ public ConstantPoolInfo(float value) {
+ index1 = -1;
+ index2 = -1;
+ arg1 = null;
+ arg2 = null;
+ type = FLOAT;
+ floatValue = value;
+ }
+
+ /**
+ * Construct a new ConstantPoolInfo object that is of type LONG
+ */
+ public ConstantPoolInfo(long value) {
+ index1 = -1;
+ index2 = -1;
+ arg1 = null;
+ arg2 = null;
+ type = LONG;
+ longValue = value;
+ }
+
+ /**
+ * Construct a new ConstantPoolInfo object that is of type DOUBLE
+ */
+ public ConstantPoolInfo(double value) {
+ index1 = -1;
+ index2 = -1;
+ arg1 = null;
+ arg2 = null;
+ type = DOUBLE;
+ doubleValue = value;
+ }
+
+ /**
+ * Generic constructor
+ */
+ public ConstantPoolInfo() {
+ index1 = -1;
+ index2 = -1;
+ arg1 = null;
+ arg2 = null;
+ type = -1;
+ }
+
+ /**
+ * return the type of this constant pool item.
+ */
+ public int isType() {
+ return (type);
+ }
+
+ public boolean read(DataInputStream dis)
+ throws IOException {
+ int len;
+ char c;
+
+ type = dis.readByte();
+ switch (type) {
+ case CLASS:
+ name = "Class";
+ index1 = dis.readShort();
+ index2 = -1;
+ break;
+ case FIELDREF:
+ name = "Field Reference";
+ index1 = dis.readShort();
+ index2 = dis.readShort();
+ break;
+ case METHODREF:
+ name = "Method Reference";
+ index1 = dis.readShort();
+ index2 = dis.readShort();
+ break;
+ case INTERFACE:
+ name = "Interface Method Reference";
+ index1 = dis.readShort();
+ index2 = dis.readShort();
+ break;
+ case NAMEANDTYPE:
+ name = "Name and Type";
+ index1 = dis.readShort();
+ index2 = dis.readShort();
+ break;
+ case STRING:
+ name = "String";
+ index1 = dis.readShort();
+ index2 = -1;
+ break;
+ case INTEGER:
+ name = "Integer";
+ intValue = dis.readInt();
+ break;
+ case FLOAT:
+ name = "Float";
+ floatValue = dis.readFloat();
+ break;
+ case LONG:
+ name = "Long";
+ longValue = dis.readLong();
+ break;
+ case DOUBLE:
+ name = "Double";
+ doubleValue = dis.readDouble();
+ break;
+ case ASCIZ:
+ case UNICODE:
+ if (type == ASCIZ)
+ name = "ASCIZ";
+ else
+ name = "UNICODE";
+
+ StringBuffer xxBuf = new StringBuffer();
+
+ len = dis.readShort();
+ while (len > 0) {
+ c = (char) (dis.readByte());
+ xxBuf.append(c);
+ len--;
+ }
+ strValue = xxBuf.toString();
+ break;
+ default:
+ System.out.println("Warning bad type.");
+ }
+ return (true);
+ }
+
+ public void write(DataOutputStream dos, ConstantPoolInfo pool[])
+ throws IOException, Exception {
+ dos.write(type);
+ switch (type) {
+ case CLASS:
+ case STRING:
+ dos.writeShort(indexOf(arg1, pool));
+ break;
+ case FIELDREF:
+ case METHODREF:
+ case INTERFACE:
+ case NAMEANDTYPE:
+ dos.writeShort(indexOf(arg1, pool));
+ dos.writeShort(indexOf(arg2, pool));
+ break;
+ case INTEGER:
+ dos.writeInt(intValue);
+ break;
+ case FLOAT:
+ dos.writeFloat(floatValue);
+ break;
+ case LONG:
+ dos.writeLong(longValue);
+ break;
+ case DOUBLE:
+ dos.writeDouble(doubleValue);
+ break;
+ case ASCIZ:
+ case UNICODE:
+ dos.writeShort(strValue.length());
+ dos.writeBytes(strValue);
+ break;
+ default:
+ throw new Exception("ConstantPoolInfo::write() - bad type.");
+ }
+ }
+
+ public String toString() {
+ StringBuffer s;
+
+ if (type == ASCIZ) {
+ return(strValue);
+ }
+
+ if (type == INTEGER) {
+ return("= "+intValue);
+ }
+
+ if (type == LONG) {
+ return("= "+longValue);
+ }
+
+ if (type == FLOAT) {
+ return("= "+floatValue);
+ }
+
+ if (type == DOUBLE) {
+ return("= "+doubleValue);
+ }
+
+ s = new StringBuffer();
+ s.append(name);
+ s.append(":");
+ if (arg1 != null)
+ s.append(arg1.toString());
+ else if (index1 != -1)
+ s.append("I1["+index1+"], ");
+ if (arg2 != null)
+ s.append(arg2.toString());
+ else if (index2 != -1)
+ s.append("I2["+index2+"], ");
+ return (s.toString());
+ }
+
+ public static short indexOf(ConstantPoolInfo item,
+ ConstantPoolInfo pool[])
+ throws Exception {
+ for (int i = 0; i < pool.length; i++) {
+ if (item == pool[i])
+ return (short) i;
+ }
+ throw new Exception("ConstantPoolInfo:: indexOf() - item not in pool.");
+ }
+
+ /**
+ * Returns true if these constant pool items are identical.
+ */
+ public boolean isEqual(ConstantPoolInfo cp) {
+ if (cp == null)
+ return false;
+
+ if (cp.type != type)
+ return (false);
+ switch (cp.type) {
+ case CLASS:
+ case STRING:
+ return (arg1 == cp.arg1);
+ case FIELDREF:
+ case METHODREF:
+ case INTERFACE:
+ case NAMEANDTYPE:
+ return ((arg1 == cp.arg1) && (arg2 == cp.arg2));
+ case INTEGER:
+ return (cp.intValue == intValue);
+ case FLOAT:
+ return (cp.floatValue == floatValue);
+ case LONG:
+ return (cp.longValue == longValue);
+ case DOUBLE:
+ return (cp.doubleValue == doubleValue);
+ case ASCIZ:
+ case UNICODE:
+ return (cp.strValue.compareTo(strValue) == 0);
+ }
+ return (false);
+ }
+
+ /**
+ * Returns the reference to the constant pool item that is
+ * already in pool, that matches this one.
+ */
+ public ConstantPoolInfo inPool(ConstantPoolInfo pool[]) {
+ for (int i = 1; i < pool.length; i++) {
+ if (isEqual(pool[i]))
+ return (pool[i]);
+ }
+ return null;
+ }
+
+}
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/FieldInfo.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/FieldInfo.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/FieldInfo.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/FieldInfo.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/FieldInfo.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/FieldInfo.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,104 @@
+/*
+ * @(#)FieldInfo.java 1.3 95/08/16 Chuck McManis
+ *
+ * Copyright (c) 1996 Chuck McManis, All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies.
+ *
+ * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+package util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * This class defines a FieldInfo in the class file. Fields are used to
+ * describe instance variables in a class. The toString() method is
+ * augmented by a version that takes an array of ConstantPoolInfo
+ * objects (a constant pool). When a constant pool is available the
+ * toString() method generates a declaration for the field as it would
+ * appear in Java source.
+ *
+ * @version 1.3, 16 Aug 1995
+ * @author Chuck McManis
+ * @see ClassFile
+ */
+
+public class FieldInfo {
+ short accessFlags;
+ ConstantPoolInfo name;
+ ConstantPoolInfo signature;
+ AttributeInfo attributes[];
+
+ public boolean read(DataInputStream di, ConstantPoolInfo pool[])
+ throws IOException {
+ int count;
+
+ accessFlags = di.readShort();
+ name = pool[di.readShort()];
+ signature = pool[di.readShort()];
+ count = di.readShort();
+ if (count != 0) {
+ attributes = new AttributeInfo[count];
+ for (int i = 0; i < count; i++) {
+ attributes[i] = new AttributeInfo();
+ if (! attributes[i].read(di, pool))
+ return (false);
+ }
+ }
+ return (true);
+ }
+
+ public void write(DataOutputStream dos, ConstantPoolInfo pool[])
+ throws IOException, Exception {
+ dos.writeShort(accessFlags);
+ dos.writeShort(ConstantPoolInfo.indexOf(name, pool));
+ dos.writeShort(ConstantPoolInfo.indexOf(signature, pool));
+ if (attributes == null) {
+ dos.writeShort(0);
+ } else {
+ dos.writeShort(attributes.length);
+ for (int i = 0; i < attributes.length; i++) {
+ attributes[i].write(dos, pool);
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuffer x = new StringBuffer();
+
+ x.append(ClassFile.accessString(accessFlags));
+ x.append(ClassFile.typeString(signature.toString(), name.toString()));
+ if (attributes != null) {
+ x.append(" = "+attributes[0].toString());
+ }
+ return (x.toString());
+ }
+
+ public String toString(ConstantPoolInfo pool[]) {
+ StringBuffer x = new StringBuffer();
+ String mytype;
+
+ x.append(ClassFile.accessString(accessFlags));
+ mytype = ClassFile.typeString(signature.toString(), name.toString());
+ x.append(mytype);
+ if (attributes != null) {
+ if (mytype.startsWith("boolean")) {
+ x.append(" "+attributes[0].toBoolean(pool));
+ } else
+ x.append(" "+attributes[0].toString(pool));
+ }
+ return (x.toString());
+ }
+}
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/MethodInfo.class and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/MethodInfo.class differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/MethodInfo.java kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/MethodInfo.java
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/dumpclass/util/MethodInfo.java 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/dumpclass/util/MethodInfo.java 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,137 @@
+/*
+ * @(#)MethodInfo.java 1.4 95/08/16 Chuck McManis
+ *
+ * Copyright (c) 1996 Chuck McManis, All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies.
+ *
+ * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+package util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * This class describes a Method as it is stored in the class file.
+ * The attribute associated with method is the code that actually implements
+ * the method. Since we don't need to manipulate the byte codes directly
+ * we leave them as an opaque chunk in the attributes[] array. References
+ * in the code are all references into the constant table so when we are
+ * modifing a class to use a different object we needn't get into the code
+ * level.
+ *
+ * @version 1.4, 16 Aug 1995
+ * @author Chuck McManis
+ * @see ClassFile
+ */
+
+public class MethodInfo {
+ short accessFlags;
+ ConstantPoolInfo name;
+ ConstantPoolInfo signature;
+ AttributeInfo attributes[];
+
+ /**
+ * Read a method_info from the data stream.
+ */
+ public boolean read(DataInputStream di, ConstantPoolInfo pool[])
+ throws IOException {
+ int count;
+
+ accessFlags = di.readShort();
+ name = pool[di.readShort()];
+ signature = pool[di.readShort()];
+ count = di.readShort();
+ if (count != 0) {
+ attributes = new AttributeInfo[count];
+ for (int i = 0; i < count; i++) {
+ attributes[i] = new AttributeInfo(); // "code"
+ if (! attributes[i].read(di, pool)) {
+ return (false);
+ }
+ }
+ }
+ return (true);
+ }
+
+ /**
+ * Write out a method_info, do constant table fixups on the write.
+ */
+ public void write(DataOutputStream dos, ConstantPoolInfo pool[])
+ throws IOException, Exception {
+ dos.writeShort(accessFlags);
+ dos.writeShort(ConstantPoolInfo.indexOf(name, pool));
+ dos.writeShort(ConstantPoolInfo.indexOf(signature, pool));
+ if (attributes == null) {
+ dos.writeShort(0);
+ } else {
+ dos.writeShort(attributes.length);
+ for (int i = 0; i < attributes.length; i++)
+ attributes[i].write(dos, pool);
+ }
+ }
+
+ /**
+ * print out the method, much as you would see it in the source
+ * file. The string ClassName is substituted for <init> when
+ * printing.
+ */
+ public String toString(String className) {
+ StringBuffer x = new StringBuffer();
+ boolean isArray = false;
+ String paramSig;
+ String returnSig;
+ int ndx = 0;
+ StringBuffer parameterList = new StringBuffer();
+ char initialParameter = 'a';
+ StringBuffer varName = new StringBuffer();
+
+
+ String s = signature.strValue;
+ paramSig = s.substring(s.indexOf('(')+1, s.indexOf(')'));
+ returnSig = s.substring(s.indexOf(')')+1);
+
+ x.append(ClassFile.accessString(accessFlags));
+ /* catch constructors */
+ if ((className != null) && (name.toString().startsWith("<init>")))
+ parameterList.append(className);
+ else
+ parameterList.append(name.toString());
+ parameterList.append("(");
+ if ((paramSig.length() > 0) && paramSig.charAt(0) != 'V') {
+ while (paramSig.length() > 0) {
+ varName.setLength(0);
+ varName.append(initialParameter);
+ initialParameter++;
+ parameterList.append(
+ ClassFile.typeString(paramSig, varName.toString()));
+ paramSig = ClassFile.nextSig(paramSig);
+ if (paramSig.length() > 0)
+ parameterList.append(", ");
+ }
+
+ }
+ parameterList.append(")");
+ x.append(ClassFile.typeString(returnSig, parameterList.toString()));
+ x.append(";");
+ return (x.toString());
+ }
+
+ /**
+ * Generic toString method, init method is unchanged.
+ */
+ public String toString() {
+ return (toString((String)null));
+ }
+}
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/fieldInfo.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/fieldInfo.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/fieldInfo.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/fieldInfo.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,23 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetFieldName(jclass clazz, jfieldID field, char** namePtr,
+ char** signaturePtr)
+{
+}
+
+jvmdiError GetFieldDeclaringClass(jclass clazz, jfieldID field,
+ jclass* declaringClassPtr)
+{
+}
+
+jvmdiError GetFieldModifiers(jclass clazz, jfieldID field, jint* modifiersPtr)
+{
+}
+
+jvmdiError IsFieldSynthetic(jclass clazz, jfieldID field,
+ jboolean* isSyntheticPtr)
+{
+}
+
+/* End of field_info.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/frameAccess.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/frameAccess.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/frameAccess.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/frameAccess.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,25 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetFrameCount(jthread thread, jint* countPtr)
+{
+}
+
+jvmdiError GetCurrentFrame(jthread thread, jframeID* framePtr)
+{
+}
+
+jvmdiError GetCallerFrame(jframeID called, jframeID* framePtr)
+{
+}
+
+jvmdiError GetFrameLocation(jframeID frame, jclass* classPtr,
+ jlocation* locationPtr)
+{
+}
+
+jvmdiError NotifyFramePop(jframeID frame)
+{
+}
+
+/* End of frame_access.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwp.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwp.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwp.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwp.c 1999-12-22 19:33:00.000000000 -0500
@@ -0,0 +1,2 @@
+
+/* End of jdwp.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwp.h kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwp.h
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwp.h 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwp.h 2000-01-02 18:36:13.000000000 -0500
@@ -0,0 +1,377 @@
+
+#ifndef JDWP_H
+
+#define JDWP_H
+
+/* Created: Sun Dec 19 18:23:30 1999 DLD
+
+ FYI: JDWP canonical form is big-endian (i.e. Java format).
+*/
+
+#define JDWP_SOCKET_TRANSPORT 1
+#define JDWP_SERIAL_LINE_TRANSPORT 2
+#define JDWP_SHARED_MEMORY_TRANSPORT 3
+
+/* +++
+
+ JDWP data types: Object IDs, referenct IDs, Field IDs, method IDs, and
+ frame IDs may be sized differently in different VM implementations. Max
+ size is 8 bytes. The "idSizes" Command in the "VirtualMachine" command set
+ relates the sizes.
+*/
+
+/* Here's a byte. This is definatly some kind of axiom, but what the hell:
+*/
+typedef char jdwpByte[1];
+
+/* Zero is false and non-zero is true.
+*/
+typedef jdwpByte jdwpBoolean[1];
+
+/* Signed unless explicitly unsigned.
+*/
+typedef jdwpByte jdwpInt[4];
+
+/* Signed unless explicitly unsigned.
+*/
+typedef jdwpByte jdwpLong[8];
+
+/* VM specific object ID over lifetime of VM object (The spec then
+ goes on to say that 0 is the null object, seemingly in violation of
+ this being VM specific). May be up to 8-bytes long.
+
+ This ID is valid until _explicitly_disposed_, regardless of whether the
+ object has been GC'd.
+
+ Existance of an object ID does not prevent object GC. Access to GC'd
+ objects results in INVALID_OBJECT error code. GC can be disabled with the
+ "DisableCollection" command (this usage is rare).
+*/
+typedef jdwpByte jdwpObjectID[8];
+
+/* Also known as a "Typed-Object", this is the jdwpObjectID preceeded by an
+ object's "Type". <<FIXME: JDWP.Tag (whatever that is) >> enumerates
+ values.
+*/
+typedef jdwpByte jdwpTaggedObjectID[sizeof(jdwpObjectID)+1];
+
+/* ID's a VM specific thread object. Up to 8 bytes long.
+*/
+typedef jdwpByte jdwpThreadID[sizeof(jdwpObjectID)];
+
+/* ID's a VM specific thread group object. Up to 8 bytes long.
+*/
+typedef jdwpByte jdwpThreadGroupID[sizeof(jdwpObjectID)];
+
+/* ID's a VM specific string object. Up to 8 bytes long.
+*/
+typedef jdwpByte jdwpStringID[sizeof(jdwpObjectID)];
+
+/* ID's a VM specific class loader object. Up to 8 bytes long.
+*/
+typedef jdwpByte jdwpClassLoaderID[sizeof(jdwpObjectID)];
+
+/* ID's a VM specific class object. Up to 8 bytes long.
+*/
+typedef jdwpByte jdwpClassObjectID[sizeof(jdwpObjectID)];
+
+/* ID's a VM unique, specific, reference object. Up to 8 bytes long. It's
+ noted that a class object may have a diffent class object ID from it's
+ reference type ID.
+
+ Reference types are unique for commands and replies throught the lifetime
+ of the debugging session, regardless of whether the referenced class has
+ been unloaded.
+*/
+typedef jdwpByte jdwpReferenceTypeID[sizeof(jdwpObjectID)];
+
+/* ID's a VM specific class object.
+*/
+typedef jdwpByte jdwpClassID[sizeof(jdwpReferenceTypeID)];
+
+/* ID's a VM specific interface object.
+*/
+typedef jdwpByte jdwpInterfaceID[sizeof(jdwpReferenceTypeID)];
+
+/* ID's a VM specific array object.
+*/
+typedef jdwpByte jdwpArrayID[sizeof(jdwpReferenceTypeID)];
+
+/* ID's a VM specific method within a VM specific class ID.
+ This uniquely identifies the method within it's class as well as
+ in all extenders and implementers.
+*/
+typedef jdwpByte jdwpMethodID[8];
+
+/* ID's a VM specific field within a VM specific class ID.
+ This uniquely identifies the field within it's class as well as
+ in all extenders and implementers.
+
+ The ID may be relative to the declaring type or the
+ extender's or implementer's type, so there's the potential of
+ some late binding.
+
+ This is VM specific, up to eight bytes long.
+*/
+typedef jdwpByte jdwpFieldID[8];
+
+/* ID's a VM specific frame.
+
+ A frame ID is unique to an entire VM rather than unique to a
+ specific thread.
+
+ A frame ID need only be valid during the time in which a thread is
+ suspended.
+*/
+typedef jdwpByte jdwpFrameID[8];
+
+/* This is the Program Counter. There are some exceedingly sensible
+ constraints [it does what you'd think] placed upon this value in the spec.
+
+ Here's the crazy part: the spec seems to say that each location is ID'd by
+ a type tag (1 byte), followed by a class ID, followed by a method ID,
+ followed by an unsigned 8 byte, within-method, location index.
+*/
+typedef jdwpByte jdwpLocation[8];
+
+/* These are counted stings. Four byte lenth, no termination, followed by
+ UTF-8 data.
+*/
+typedef jdwpByte jdwpString[0];
+
+/* First byte is a signature according to JDWP.TAG. VM specific value follows.
+ May be an object ID or a primitive value (1 to 8 bytes). See the commands
+ for more specific information.
+*/
+typedef jdwpByte jdwpValue[0];
+
+/* Same as a value except that the type can be deduced from context and is
+ omitted.
+*/
+typedef jdwpByte jdwpUntaggedValue[0];
+
+/* Sequence of values for some array operations. For primatives, elements
+ are of type jdwpUntaggedValue. For objects, elements are fo type
+ jdwpValues.
+*/
+typedef jdwpByte jdwpTypedSequence[8];
+
+/* --- */
+
+/* +++ +++
+
+ JDWP commands within their command sets.
+*/
+
+/* +++ Virtual machine command set.
+*/
+
+#define JDWP_VIRTUAL_MACHINE 1
+
+/* Returns JDWP version info.
+*/
+#define JDWP_VIRUTAL_MACHINE__VERSION 1
+struct jdwpVirtualMachine_Version_ReplyData
+{
+ /* VM dependant description of version.
+ */
+ jdwpString description;
+
+ /* Major version number.
+ */
+ jdwpInt jdwpMajor;
+
+ /* Minor version number.
+ */
+ jdwpInt jdwpMinor;
+
+ /* JRE version, as per java.version property.
+ */
+ jdwpString vmVersion;
+
+ /* VM name as per java.vm.name property.
+ */
+ jdwpString vmName;
+};
+
+/* Returns references to loaded classes that match a signature. Multiple
+ references will be returned if two or more class loaders have loaded a
+ class of the same name. The search is confined to loaded classes only;
+ no attmpt is made to load a class of the given signature.
+
+ Command argument:
+
+ jdwpString signature;
+
+ This is the JNI signature of the class to find (ie "Ljava/lang/String;").
+
+ The reply data consists of a jdwpInt value, count, followed by count
+ jdwpVirtualMachineClassesBySignatureReplyDataItem type data structures.
+*/
+#define JDWP_VIRTUAL_MACHINE__CLASSES_BY_SIGNATURE 2
+struct jdwpVirtualMachine_ClassesBySignature_ReplyDataItem
+{
+ /* This is the reference type's <i>kind</i>.
+ */
+ jdwpByte refTypeTag;
+
+ /* A reference to a class that matched the search.
+ */
+ jdwpReferenceTypeID typeID;
+
+ /* The class status (FIXME: whatever that is).
+ */
+ jdwpInt status;
+};
+
+/* Returns references to all currently loaded classes.
+*/
+#define JDWP_VIRTUAL_MACHINE__ALL_CLASSES 3
+struct jdwpVirtualMachine_AllClasses_ReplyDataItem
+{
+ /* This is the reference type's <i>kind</i>.
+ */
+ jdwpByte refTypeTag;
+
+ /* A reference to a currently loaded class.
+ */
+ jdwpReferenceTypeID typeID;
+
+ /* This reference's JNI signature.
+ */
+ jdwpString signature;
+
+ /* The class status (FIXME: whatever that is).
+ */
+ jdwpInt status;
+};
+
+#define JDWP_VIRTUAL_MACHINE__ALL_THREADS 4
+
+#define JDWP_VIRTUAL_MACHINE__TOP_LEVEL_THEAD_GROUPS 5
+
+#define JDWP_VIRTUAL_MACHINE__DISPOSE 6
+
+#define JDWP_VIRTUAL_MACHINE__ID_SIZES 7
+
+#define JDWP_VIRTUAL_MACHINE__SUSPEND 8
+
+#define JDWP_VIRTUAL_MACHINE__RESUME 9
+
+#define JDWP_VIRTUAL_MACHINE__EXIT 10
+
+#define JDWP_VIRTUAL_MACHINE__CREATE_STRING 11
+
+#define JDWP_VIRTUAL_MACHINE__CAPABILITIES 12
+
+#define JDWP_VIRTUAL_MACHINE__CLASS_PATHS 13
+
+#define JDWP_VIRTUAL_MACHINE__DISPOSE_OBJECTS 14
+
+#define JDWP_VIRTUAL_MACHINE__HOLD_EVENTS 15
+
+#define JDWP_VIRTUAL_MACHINE__RELEASE_EVENTS 16
+
+/* --- */
+
+/* +++ reference type command set.
+*/
+
+#define JDWP_REFERENCE_TYPE 2
+
+/* --- */
+
+#define JDWP_CLASS_TYPE 3
+
+#define JDWP_ARRAY_TYPE 4
+
+#define JDWP_INTERFACE_TYPE 5
+
+#define JDWP_METHOD 6
+
+/* FIXME: where's seven?? */
+
+#define JDWP_FIELD 8
+
+#define JDWP_OBJECT_REFERENCE 9
+
+#define JDWP_STRING_REFERENCE 10
+
+#define JDWP_THREAD_REFERENCE 11
+
+#define JDWP_THREAD_GROUP_REFERENCE 12
+
+#define JDWP_ARRAY_REFERENCE 13
+
+#define JDWP_CLASS_LOADER_REFERENCE 14
+
+#define JDWP_EVENT_REQUEST 15
+
+#define JDWP_STACK_FRAME 16
+
+#define JDWP_CLASS_OBJECT_REFERENCE 17
+
+#define JDWP_EVENT 64
+
+/* --- --- */
+
+/* JDWP command / reply shared header.
+*/
+struct commandReplySharedHeader
+{
+ /* This is the size of the header and the data. So the emtpy
+ message has length 11, the length of the shared header, 9, and the
+ fixed length of the private part, 2.
+ */
+ jdwpByte length[4];
+
+ /* Unique packet command/reply-pair ID. << A reply packet has the same
+ ID as the command packet to which it replies. [FIXME attrib to SUN
+ JDWP spec] >>
+ */
+ jdwpByte id[4];
+
+ /* There's only one flag bit currently defined, 0x80, which denotes a
+ replay, rather than a command, packet.
+ */
+ jdwpByte flags[1];
+};
+
+/* JDWP Command
+*/
+struct commandPacket
+{
+ struct commandReplySharedHeader sharedHeader;
+
+ /* These group commands. 0 to 63 are commands sent to the target VM,
+ while 64 to 127 are sent to the debugger. 128 to 256 are reserved for
+ vendors. These are [somehow] bound closely to the JDI spec.
+ */
+ jdwpByte commandSet[1];
+
+ /* This, and commandSet, is the way for the reciever to know what to do.
+ */
+ jdwpByte command[1];
+
+ /* This is unique to each command AND reply.
+ */
+ jdwpByte* data[0];
+};
+
+/* JDWP Reply
+*/
+struct replyPacket
+{
+ struct commandReplySharedHeader sharedHeader;
+
+ /* 0 is success otherwise it's an error. May be mapped to a JVMDI error
+ code or may be command/reply specific.
+ */
+ jdwpByte errorCode[2];
+
+ /* This is unique to each command AND reply.
+ */
+ jdwpByte* data[0];
+};
+
+#endif
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwpServer.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwpServer.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwpServer.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwpServer.c 2000-01-02 17:49:55.000000000 -0500
@@ -0,0 +1,462 @@
+
+/* The networking code comes from the unix-socket-faq. It is public
+ domain, and may be copied freely. There is no copyright on it. The
+ original work was by Vic Metcalfe (vic at brutus.tlug.org), and any
+ modifications made to that work were made with the understanding that
+ the finished work would be in the public domain.
+
+ If you have found a bug, please pass it on to me at the above address
+ acknowledging that there will be no copyright on your work.
+
+ The most recent version of this file, and the unix-socket-faq can be
+ found at http://www.interlog.com/~vic/sock-faq/.
+*/
+
+#include "jdwpSockHelp.h"
+
+static int startSocketServer(int);
+
+/* Take a service name, and a service type, and return a port number. If the
+ service name is not found, it tries it as a decimal number. The number
+ returned is byte ordered for the network.
+*/
+int atoport(char* service, char* proto)
+{
+ int port;
+ long int lport;
+ struct servent* serv;
+ char* errpos;
+
+ /* First try to read it from /etc/services
+ */
+ serv = getservbyname(service, proto);
+ if (serv != NULL)
+ {
+ port = serv->s_port;
+ }
+ else
+ {
+ /* Not in services, maybe a number?
+ */
+ lport = strtol(service,&errpos,0);
+ if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) )
+ {
+ /* Invalid port address
+ */
+ return -1;
+ }
+ port = htons(lport);
+ }
+ return port;
+}
+
+/* Converts ascii text to in_addr struct. NULL is returned if the address
+ can not be found.
+*/
+struct in_addr* atoaddr(char* address)
+{
+ struct hostent* host;
+ static struct in_addr saddr;
+
+ /* First try it as aaa.bbb.ccc.ddd.
+ */
+ saddr.s_addr = inet_addr(address);
+ if (saddr.s_addr != -1)
+ {
+ return &saddr;
+ }
+ host = gethostbyname(address);
+ if (host != NULL)
+ {
+ return (struct in_addr*)*host->h_addr_list;
+ }
+ return NULL;
+}
+
+/* This function listens on a port, and returns connections. It forks
+ returns off internally, so your main function doesn't have to worry
+ about that. This can be confusing if you don't know what is going on.
+ The function will create a new process for every incoming connection,
+ so in the listening process, it will never return. Only when a connection
+ comes in, and we create a new process for it will the function return.
+ This means that your code that calls it should _not_ loop.
+
+ The parameters are as follows:
+
+ socket_type: SOCK_STREAM or SOCK_DGRAM (TCP or UDP sockets)
+
+ port: The port to listen on. Remember that ports < 1024 are
+ reserved for the root user. Must be passed in network byte
+ order (see "man htons").
+
+ listener: This is a pointer to a variable for holding the file
+ descriptor of the socket which is being used to listen. It
+ is provided so that you can write a signal handler to close
+ it in the event of program termination. If you aren't interested,
+ just pass NULL. Note that all modern unixes will close file
+ descriptors for you on exit, so this is not required.
+*/
+int get_connection(int socket_type, u_short port, int* listener)
+{
+ struct sockaddr_in address;
+ int listening_socket;
+ int connected_socket = -1;
+ int new_process;
+ int reuse_addr = 1;
+
+ /* Setup internet address information.
+ This is used with the bind() call
+ */
+ memset((char*)&address, 0, sizeof(address));
+ address.sin_family = AF_INET;
+ address.sin_port = port;
+ address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ listening_socket = socket(AF_INET, socket_type, 0);
+ if (listening_socket < 0)
+ {
+ perror("socket");
+ exit(EXIT_FAILURE);
+ }
+
+ if (listener != NULL)
+ {
+ *listener = listening_socket;
+ }
+
+ setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
+ (char*)&reuse_addr, sizeof(reuse_addr));
+
+ if (bind(listening_socket,
+ (struct sockaddr*)&address,
+ sizeof(address)) < 0)
+ {
+ perror("bind");
+ close(listening_socket);
+ exit(EXIT_FAILURE);
+ }
+
+ if (socket_type == SOCK_STREAM)
+ {
+ /* Queue up to five connections before
+ having them automatically rejected.
+ */
+ listen(listening_socket, 5);
+
+ while(connected_socket < 0)
+ {
+ connected_socket = accept(listening_socket, NULL, NULL);
+ if (connected_socket < 0)
+ {
+ /* Either a real error occured, or blocking was interrupted for
+ some reason. Only abort execution if a real error occured.
+ */
+ if (errno != EINTR)
+ {
+ perror("accept");
+ close(listening_socket);
+ exit(EXIT_FAILURE);
+ }
+ else
+ {
+ /* don't fork - do the accept again
+ */
+ continue;
+ }
+ }
+
+ new_process = fork();
+ if (new_process < 0)
+ {
+ perror("fork");
+ close(connected_socket);
+ connected_socket = -1;
+ }
+ else
+ {
+ /* We have a new process...
+ */
+ if (new_process == 0)
+ {
+ /* This is the new process. Close our copy of this
+ socket.
+ */
+ close(listening_socket);
+ if (listener != NULL)
+ {
+ /* Closed in this process. We are not
+ responsible for it.
+ */
+ *listener = -1;
+ }
+ }
+ else
+ {
+ /* This is the main loop. Close copy of connected socket,
+ and continue loop.
+ */
+ close(connected_socket);
+ connected_socket = -1;
+ }
+ }
+ }
+
+ return connected_socket;
+ }
+ else
+ {
+ return listening_socket;
+ }
+}
+
+/* This is just like the read() system call, accept that it will make
+ sure that all your data goes through the socket.
+*/
+int sock_read(int sockfd, char* buf, size_t count)
+{
+ size_t bytes_read = 0;
+ int this_read;
+
+ while (bytes_read < count)
+ {
+ do
+ {
+ this_read = read(sockfd, buf, count - bytes_read);
+ }
+ while ( (this_read < 0) && (errno == EINTR) );
+
+ if (this_read < 0)
+ {
+ return this_read;
+ }
+ else if (this_read == 0)
+ {
+ return bytes_read;
+ }
+
+ bytes_read += this_read;
+ buf += this_read;
+ }
+ return count;
+}
+
+/* This is just like the write() system call, accept that it will
+ make sure that all data is transmitted.
+*/
+int sock_write(int sockfd, const char* buf, size_t count)
+{
+ size_t bytes_sent = 0;
+ int this_write;
+
+ while (bytes_sent < count)
+ {
+ do
+ {
+ this_write = write(sockfd, buf, count - bytes_sent);
+ }
+ while ( (this_write < 0) && (errno == EINTR) );
+
+ if (this_write <= 0)
+ {
+ return this_write;
+ }
+
+ bytes_sent += this_write;
+ buf += this_write;
+ }
+ return count;
+}
+
+/* This function reads from a socket, until it recieves a linefeed
+ character. It fills the buffer "str" up to the maximum size "count".
+
+ This function will return -1 if the socket is closed during the read
+ operation.
+
+ Note that if a single line exceeds the length of count, the extra data
+ will be read and discarded! You have been warned.
+*/
+int sock_gets(int sockfd, char* str, size_t count)
+{
+ int bytes_read;
+ int total_count = 0;
+ char* current_position;
+ char last_read = 0;
+
+ current_position = str;
+ while (last_read != 10)
+ {
+ bytes_read = read(sockfd, &last_read, 1);
+
+ if (bytes_read <= 0)
+ {
+ /* The other side may have closed unexpectedly. Is this
+ effective on other platforms than linux?
+ */
+ return -1;
+ }
+
+ if ( (total_count < count) && (last_read != 10) && (last_read !=13) )
+ {
+ current_position[0] = last_read;
+ current_position++;
+ total_count++;
+ }
+ }
+
+ if (count > 0)
+ {
+ current_position[0] = 0;
+ }
+
+ return total_count;
+}
+
+/* This function writes a character string out to a socket. It will
+ return -1 if the connection is closed while it is trying to write.
+*/
+int sock_puts(int sockfd, char* str)
+{
+ return sock_write(sockfd, str, strlen(str));
+}
+
+/* This ignores the SIGPIPE signal. This is usually a good idea, since
+ the default behaviour is to terminate the application. SIGPIPE is
+ sent when you try to write to an unconnected socket. You should
+ check your return codes to make sure you catch this error!
+*/
+void ignore_pipe(void)
+{
+ struct sigaction sig;
+
+ sig.sa_handler = SIG_IGN;
+ sig.sa_flags = 0;
+ sigemptyset(&sig.sa_mask);
+ sigaction(SIGPIPE,&sig,NULL);
+}
+
+int jdwpStartServer(int argc, char* argv[])
+{
+ int transport = JDWP_SOCKET_TRANSPORT;
+
+ /* FIXME: A better design can probably eliminate this switch statement.
+ */
+ switch (transport)
+ {
+ case JDWP_SOCKET_TRANSPORT:
+
+ /* Create socket transport.
+ */
+ (void)startSocketServer(6969);
+ break;
+
+ case JDWP_SERIAL_LINE_TRANSPORT:
+
+ /* Create serial line transport.
+ */
+ /*(void)startSerialLineServer();*/
+ break;
+
+ case JDWP_SHARED_MEMORY_TRANSPORT:
+
+ /* Create shared memory transport.
+ */
+ /*(void)startSharedMemoryServer();*/
+ break;
+ }
+
+ (void)serve();
+
+ return 0;
+}
+
+/* This is NOT high performance. There's no intention of doing multi-client
+ debugging (yet). The most basic single concurrent client use cases are
+ supported, but otherwise is intentionally ignored.
+*/
+static int startSocketServer(int port)
+{
+ struct servent *sp;
+ struct sockaddr_in sin, from;
+
+ if ((sp = getservbyname(service, "jdwp")) == NULL)
+ {
+ /* FIXME: Error...
+ */
+ return 9995;
+ }
+
+ /* sin.sin_family= <etc...> */
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ /* FIXME: Error ...
+ */
+ return 9996;
+ }
+
+ if (bind(s, &sin, sizeof(sin)) < 0)
+ {
+ /* FIXME: Error ...
+ */
+ return 9997;
+ }
+
+ if (listen(s, QUELEN) < 0)
+ {
+ /* FIXME: Error ...
+ */
+ return 9998;
+ }
+
+ return 0;
+}
+
+static int serve()
+{
+ /* Allow successive (non-simultaneous) debugging sessions ...
+ */
+ for (;;)
+ {
+ if ((g = accept(f, &from, &len)) < 0)
+ {
+ /* FIXME: Error ...
+ */
+ return 9999;
+ }
+
+ /* Do it!
+ */
+ (void)jdwpDebugSession();
+
+ /* Done
+ */
+ close(g);
+ }
+}
+
+static int jdwpDebugSession()
+{
+ for ( ; doJDWPCommand(); ) {}
+}
+
+static int doJDWPCommand(commandSet, command)
+{
+ switch (commandSet)
+ {
+ case VIRTUAL_MACHINE:
+
+ switch (command)
+ {
+ case ():
+ break;
+ case ():
+ break;
+ case ():
+ break;
+ }
+ break;
+ }
+}
+
+/* End of jdwpServer.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwpSockHelp.h kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwpSockHelp.h
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jdwpSockHelp.h 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jdwpSockHelp.h 1999-12-27 13:36:54.000000000 -0500
@@ -0,0 +1,43 @@
+/*
+ * This file is provided for use with the unix-socket-faq. It is public
+ * domain, and may be copied freely. There is no copyright on it. The
+ * original work was by Vic Metcalfe (vic at brutus.tlug.org), and any
+ * modifications made to that work were made with the understanding that
+ * the finished work would be in the public domain.
+ *
+ * If you have found a bug, please pass it on to me at the above address
+ * acknowledging that there will be no copyright on your work.
+ *
+ * The most recent version of this file, and the unix-socket-faq can be
+ * found at http://www.interlog.com/~vic/sock-faq/.
+ */
+
+#ifndef _SOCKHELP_H_
+#define _SOCKHELP_H_
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <limits.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+int atoport(char*, char*);
+struct in_addr* atoaddr(char*);
+
+int get_connection(int, u_short, int*);
+int make_connection(char*, int, char*);
+
+int sock_read(int, char*, size_t);
+int sock_write(int, const char*, size_t);
+int sock_gets(int, char*, size_t);
+int sock_puts(int, const char*);
+void ignore_pipe(void);
+
+#endif
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jpdaBackend.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jpdaBackend.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/jpdaBackend.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/jpdaBackend.c 2000-01-11 11:52:33.000000000 -0500
@@ -0,0 +1,653 @@
+
+#include <jni.h>
+#include <jvmdi.h>
+#include <string.h>
+#include <readline.h>
+#include "jdwp.h"
+
+static int handleVMInitEvent(void);
+static int handleSingleStepEvent(JNIEnv*, JVMDI_Event*);
+static int handleVMDeathEvent(void);
+
+static int setBreakpoint(char*);
+static int doContinue(char*);
+static int doQuit(char*);
+static int doStep(char*);
+
+static int readAndParseCommand(char**, char**);
+static int checkAndDispatchCommand(char*, char*, char*[], int,
+ int (*[])(char*));
+static int safelySkipWhitespace(char**, int);
+static int safelySkipNonWhitespace(char**, int);
+
+static const char* const prompt = "jvmdb> ";
+
+/* FIXME: What the return value supposed to be? The spec doesn't say!
+ What should happen with vm? Is it GC'd? Do I have to fuck with it's
+ reference count? Who free's it (me?) ?
+*/
+JNIEXPORT jint JNICALL JVM_OnLoad(JavaVM* vm, char* options, void* reserved)
+{
+ {
+ /* Wait for a JDWP client to connect.
+ */
+ int jdwpTransport = JDWP_SOCKET_TRANSPORT;
+ switch (jdwpTransport)
+ {
+ case JDWP_SOCKET_TRANSPORT:
+
+ (void)getSocketConnection(6969);
+ break;
+
+ case JDWP_SERIAL_LINE_TRANSPORT:
+
+ (void)getSerialLineConnection();
+ break;
+
+ case JDWP_SHARED_MEMORY_TRANSPORT:
+
+ (void)getSharedMemoryConnection();
+ break;
+ }
+ }
+
+ {
+ /* Set the event hook
+ */
+ JVMDI_Interface_1* jvmdiEnv;
+ jint r;
+ if ((r = (*vm)->GetEnv(vm, &jvmdiEnv, JVMDI_VERSION_1)) != JNI_OK)
+ {
+ if (r == JNI_EDETACHED)
+ {
+ /* Current thread is not attached to the VM given in vm .
+ */
+ return 1;
+ }
+ else if (r == JNI_EVERSION)
+ {
+ /* Interface version is not supported.
+ */
+ return 2;
+ }
+ else
+ {
+ /* Shouldn't happen...
+ */
+ return 3;
+ }
+ }
+
+ if ((*jvmdiEnv)->SetEventHook((JVMDI_EventHook)eventHook))
+ {
+ return 4;
+ }
+ }
+
+ return 0;
+}
+
+void eventHook(JNIEnv* env, JVMDI_Event* e)
+{
+ switch(e->kind)
+ {
+ case JVMDI_EVENT_VM_INIT:
+ if (!handleVMInitEvent())
+ {
+ /* FIXME: handle error */
+ }
+ break;
+
+ case JVMDI_EVENT_SINGLE_STEP:
+
+ if (!handleSingleStepEvent(env, e))
+ {
+ /* FIXME: handle error */
+ }
+ break;
+
+ case JVMDI_EVENT_BREAKPOINT:
+ break;
+
+ case JVMDI_EVENT_FRAME_POP:
+ break;
+
+ case JVMDI_EVENT_METHOD_ENTRY:
+ break;
+
+ case JVMDI_EVENT_METHOD_EXIT:
+ break;
+
+ case JVMDI_EVENT_FIELD_ACCESS:
+ break;
+
+ case JVMDI_EVENT_FIELD_MODIFICATION:
+ break;
+
+ case JVMDI_EVENT_EXCEPTION:
+ break;
+
+ case JVMDI_EVENT_EXCEPTION_CATCH:
+ break;
+
+ case JVMDI_EVENT_USER_DEFINED:
+ break;
+
+ case JVMDI_EVENT_THREAD_END:
+ break;
+
+ case JVMDI_EVENT_THREAD_START:
+ break;
+
+ case JVMDI_EVENT_CLASS_LOAD:
+ break;
+
+ case JVMDI_EVENT_CLASS_UNLOAD:
+ break;
+
+ case JVMDI_EVENT_CLASS_PREPARE:
+ break;
+
+ case JVMDI_EVENT_VM_DEATH:
+ if (!handleVMDeathEvent())
+ {
+ /* FIXME: handle error */
+ }
+ break;
+ }
+}
+
+/* FIXME: This will go away when we speak JDWP.
+*/
+static void displayBanner()
+{
+ printf("jvmdb: Kaffe JVMDI Debugger Client\n");
+ printf("jvmdb: Hack! Hack!\n");
+ return;
+}
+
+static int handleVMInitEvent()
+{
+ char* cmd;
+ char* args;
+ int i;
+
+ /* These are sorted by length, ties are not significant. The elements
+ correspond to the cmdHandlers array.
+ */
+ char* validCmds[] =
+ {
+ "breakpoint",
+ "continue",
+ "quit",
+ "step"
+ };
+ int (*cmdHandlers[])(char*) =
+ {
+ setBreakpoint,
+ doContinue,
+ doQuit,
+ doStep
+ };
+
+ displayBanner();
+
+ fprintf(stdout, "jvmdb: VM initialization event received.\n");
+
+ do
+ {
+ if (!readAndParseCommand(&cmd, &args))
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ continue;
+ }
+
+ if (!(i = checkAndDispatchCommand(cmd,
+ args,
+ validCmds,
+ sizeof(validCmds) / sizeof(char*),
+ cmdHandlers)))
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ continue;
+ }
+ else
+ {
+ if (i == 1)
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ break;
+ }
+ }
+
+ /* FIXME: This memory is leaked if it's a quit command since the
+ quit command handler calls exit(). No big deal, but may as
+ well fix it.
+ */
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ }
+ while (1);
+
+ return 0;
+}
+
+static int handleSingleStepEvent(JNIEnv* env, JVMDI_Event* e)
+{
+ char* cmd;
+ char* args;
+ int i;
+
+ /* These are sorted by length, ties are not significant. The elements
+ correspond to the cmdHandlers array.
+ */
+ char* validCmds[] =
+ {
+ "continue",
+ "quit",
+ "step"
+ };
+ int (*cmdHandlers[])(char*) =
+ {
+ doContinue,
+ doQuit,
+ doStep
+ };
+
+ fprintf(stdout, "jvmdb: Single step event received.\n");
+
+ do
+ {
+ if (!readAndParseCommand(&cmd, &args))
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ continue;
+ }
+
+ if (!(i = checkAndDispatchCommand(cmd,
+ args,
+ validCmds,
+ sizeof(validCmds) / sizeof(char*),
+ cmdHandlers)))
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ continue;
+ }
+ else
+ {
+ if (i == 1)
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ break;
+ }
+ }
+
+ /* FIXME: This memory is leaked if it's a quit command since the
+ quit command handler calls exit(). No big deal, but may as
+ well fix it.
+ */
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ }
+ while (1);
+
+ return 0;
+}
+
+static int handleVMDeathEvent()
+{
+ char* cmd;
+ char* args;
+ int i;
+
+ char* validCmds[] =
+ {
+ "quit"
+ };
+ int (*cmdHandlers[])(char*) =
+ {
+ doQuit
+ };
+
+ fprintf(stdout, "jvmdb: VM death event received.\n");
+
+ do
+ {
+ if (!readAndParseCommand(&cmd, &args))
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ continue;
+ }
+
+ if (!(i = checkAndDispatchCommand(cmd,
+ args,
+ validCmds,
+ sizeof(validCmds) / sizeof(char*),
+ cmdHandlers)))
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ continue;
+ }
+ else
+ {
+ if (i == 1)
+ {
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ break;
+ }
+ }
+
+ /* FIXME: This memory is leaked if it's a quit command since the
+ quit command handler calls exit(). No big deal, but may as
+ well fix it.
+ */
+ if (cmd != NULL) free(cmd);
+ if (args != NULL) free(args);
+ }
+ while (1);
+
+ return 0;
+}
+
+static int doContinue(char* args)
+{
+ fprintf(stdout, "jvmdb: Continuing.\n");
+
+ return 1;
+}
+
+static int doStep(char* args)
+{
+ fprintf(stdout, "jvmdb: Steping.\n");
+
+ return 1;
+}
+
+static int doQuit(char* args)
+{
+ fprintf(stdout, "jvmdb: Quiting.\n");
+
+ exit(0);
+
+ return 1;
+}
+
+static int setBreakpoint(char* args)
+{
+ char* p = args;
+ char* class = args;
+ char* meth;
+ char* loc;
+
+ if (!args)
+ {
+ fprintf(stderr, "jvmdb: Error. Must give at least class and method, separated by \".\", as breakpoint command args\n");
+ return 0;
+ }
+
+ /* We work from right to left while parseing this command's args.
+ */
+ p = args + strlen(args) - 1;
+
+ /* Get the optional location.
+ */
+ while (*p != ':' && *p != '.' && p > args)
+ {
+ p--;
+ }
+
+ /* Location?
+ */
+ if (*p == ':')
+ {
+ loc = p + 1;
+ }
+ /* No location means "on function entry" breakpoint.
+ */
+ else if (*p == '.')
+ {
+ loc = NULL;
+ }
+ else
+ {
+ fprintf(stderr, "jvmdb: Error. Must give at least class and method, separated by \".\", as breakpoint command args\n");
+ return 0;
+ }
+
+ /* Get the method name.
+ */
+ if (*p == ':')
+ {
+ *p = '\0';
+
+ while (*p != '.' && p > args)
+ {
+ p--;
+ }
+
+ if (*p == '.')
+ {
+ meth = p + 1;
+ *p = '\0';
+ }
+ else
+ {
+ fprintf(stderr, "jvmdb: Error. Must give at least class and method, separated by \".\", as breakpoint command args\n");
+ return 0;
+ }
+ }
+ else
+ {
+ meth = p + 1;
+ *p = '\0';
+ }
+
+
+ if (loc != NULL)
+ {
+ fprintf(stdout, "jvmdb: Breakpoint set at %s.%s:%s\n",
+ class, meth, loc);
+ }
+ else
+ {
+ fprintf(stdout, "jvmdb: Breakpoint set at %s.%s\n",
+ class, meth);
+ }
+
+ return 0;
+}
+
+/* Caller must free cmd and args.
+*/
+static int readAndParseCommand(char** cmd, char** args)
+{
+ const int maxLineLen = 512;
+ char* buf;
+ char* p;
+ char* q;
+
+ buf = readline(prompt);
+ p = buf;
+
+ /* Get the command part of the string. First, trim whitespace from
+ the beginning.
+ */
+ if (!safelySkipWhitespace(&p, maxLineLen))
+ {
+ fprintf(stderr,
+ "jvmdb: Error. Input line exceeded %d characters.\n",
+ maxLineLen);
+ free(buf);
+ return 0;
+ }
+
+ /* Null command?
+ */
+ if (*p == '\0')
+ {
+ free(buf);
+ return 0;
+ }
+
+ /* Skip over the command part.
+ */
+ q = p;
+ if (!safelySkipNonWhitespace(&q, maxLineLen - (q - buf)))
+ {
+ fprintf(stderr,
+ "jvmdb: Error. Input line exceeded %d characters.\n",
+ maxLineLen);
+ free(buf);
+ return 0;
+ }
+
+ /* Get the argument part of the command.
+ */
+ if (*q == '\0')
+ {
+ /* No argument part - just pass NULL as args to the command
+ handler.
+ */
+ q = NULL;
+ }
+ else
+ {
+ *q = '\0';
+ q++;
+
+ /* Trim whitespace from the beginning of the argument part.
+ */
+ if (!safelySkipWhitespace(&q, maxLineLen - (q - buf)))
+ {
+ fprintf(stderr,
+ "jvmdb: Error. Input line exceeded %d characters.\n",
+ maxLineLen);
+ free(buf);
+ return 0;
+ }
+
+ if (*q == '\0')
+ {
+ /* Aha! No argument part, but the shameful user tried to fool us!
+ */
+ q = NULL;
+ }
+ }
+
+ if (p != NULL)
+ {
+ *cmd = strdup(p);
+ }
+ else
+ {
+ *cmd = (char*)malloc(sizeof(char*));
+ *cmd = NULL;
+ }
+
+ if (q != NULL)
+ {
+ *args = strdup(q);
+ }
+ else
+ {
+ *args = (char*)malloc(sizeof(char*));
+ *args = NULL;
+ }
+
+ free(buf);
+
+ return 1;
+}
+
+static int checkAndDispatchCommand(char* cmd,
+ char* args,
+ char* validCmds[],
+ int nCmds,
+ int (*cmdHandlers[])(char*))
+{
+ int i;
+
+ if (strlen(cmd) > strlen(validCmds[0]))
+ {
+ fprintf(stderr, "jvmdb: Error. Unrecognized command.\n");
+ return 0;
+ }
+
+ for (i = 0; i < nCmds; i++)
+ {
+ if (strstr(validCmds[i], cmd) == validCmds[i])
+ {
+ break;
+ }
+ }
+
+ if (i == nCmds)
+ {
+ fprintf(stderr, "jvmdb: Error. Unrecognized command.\n");
+ return 0;
+ }
+ else
+ {
+ if (cmdHandlers[i](args))
+ {
+ return 1;
+ }
+ else
+ {
+ return 2;
+ }
+ }
+}
+
+static int safelySkipWhitespace(char** s, int maxLen)
+{
+ int i;
+
+ for (i = 0; i < maxLen; i++)
+ {
+ if (**s != ' ' && **s != '\t')
+ {
+ return 1;
+ }
+ else
+ {
+ (*s)++;
+ }
+ }
+
+ /* Line too long.
+ */
+ return 0;
+}
+
+static int safelySkipNonWhitespace(char** s, int maxLen)
+{
+ int i;
+
+ for (i = 0; i < maxLen; i++)
+ {
+ if (**s == ' ' || **s == '\t' || **s == '\0')
+ {
+ return 1;
+ }
+ else
+ {
+ (*s)++;
+ }
+ }
+
+ /* Line too long.
+ */
+ return 0;
+}
+
+/* End of jpdaBackend.c */
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/libjpdaBackend.so and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/libjpdaBackend.so differ
Binary files kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/libjvmdiClient.so and kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/libjvmdiClient.so differ
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/localVars.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/localVars.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/localVars.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/localVars.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,44 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetLocalObject(jframeID frame, jint slot, jobject* valuePtr)
+{
+}
+
+jvmdiError GetLocalInt(jframeID frame, jint slot, jint* valuePtr)
+{
+}
+
+jvmdiError GetLocalLong(jframeID frame, jint slot, jlong* valuePtr)
+{
+}
+
+jvmdiError GetLocalFloat(jframeID frame, jint slot, jfloat* valuePtr)
+{
+}
+
+jvmdiError GetLocalDouble(jframeID frame, jint slot, jdouble* valuePtr)
+{
+}
+
+jvmdiError Set LocalObject(jframeID frame, jint slot, jobject value)
+{
+}
+
+jvmdiError Set LocalInt(jframeID frame, jint slot, jint value)
+{
+}
+
+jvmdiError Set LocalLong(jframeID frame, jint slot, jlong value)
+{
+}
+
+jvmdiError Set LocalFloat(jframeID frame, jint slot, jfloat value)
+{
+}
+
+jvmdiError Set LocalDouble(jframeID frame, jint slot, jdouble value)
+{
+}
+
+/* End of local_vars.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/methodInfo.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/methodInfo.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/methodInfo.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/methodInfo.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,76 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetMethodName(jclass clazz, jmethodID method,
+ char** namePtr, char** signaturePtr)
+{
+}
+
+jvmdiError GetMethodDeclaringClass(jclass clazz, jmethodID method,
+ jclass* declaringClassPtr)
+{
+}
+
+jvmdiError GetMethodModifiers(jclass clazz, jmethodID method,
+ jint* modifiersPtr)
+{
+}
+
+jvmdiError GetMaxStack(jclass clazz, jmethodID method, jint* maxPtr)
+{
+}
+
+jvmdiError GetMaxLocals(jclass clazz, jmethodID method, jint* maxPtr)
+{
+}
+
+jvmdiError GetArgumentsSize(jclass clazz, jmethodID method, jint* sizePtr)
+{
+}
+
+jvmdiError GetLineNumberTable(jclass clazz, jmethodID method,
+ jint* entryCountPtr,
+ JVMDI_line_number_entry** tablePtr)
+{
+}
+
+jvmdiError GetMethodLocation(jclass clazz, jmethodID method,
+ jlocation* startLocationPtr,
+ jlocation* endLocationptr)
+{
+}
+
+jvmdiError GetLocalVariableTable(jclass clazz, jmethodID method,
+ jint* entryCountPtr,
+ JVMDI_local_variable_entry** tablePtr)
+{
+}
+
+jvmdiError GetExceptionhandlerTable(jclass clazz, jmethodID method,
+ jint* entryCountPtr,
+ JVMDI_exception_handler_entry** tablePtr)
+{
+}
+
+jvmdiError GetThrownExceptions(jclass clazz, jmethodID method,
+ jint* exceptioncountPtr,
+ jclass** exceptionsPtr)
+{
+}
+
+jvmdiError GetByteCodes(jclass clazz, jmethodID method, jint* bytecodeCountPtr,
+ jbyte** bytecodesPtr)
+{
+}
+
+jvmdiError IsMethodNative(jclass clazz, jmethodID method,
+ jboolean* isNativePtr)
+{
+}
+
+jvmdiError IsMethodSynthetic(jclass clazz, jmethodID method,
+ jboolean* isSyntheticPtr)
+{
+}
+
+/* End of method_info.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/misc.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/misc.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/misc.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/misc.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,21 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetLoadedClasses(jint* classCountPtr, jclass** classesPtr)
+{
+}
+
+jvmdiError GetClassLoaderClasses(jobject initiatingLoader,
+ jint* classCountPtr, jclass** classesPtr)
+{
+}
+
+jvmdiError GetVersionNumber(jint* versionPtr)
+{
+}
+
+jvmdiError GetCapabilities(JVMDI_capabilities* capabilitiesPtr)
+{
+}
+
+/* End of misc.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/mm.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/mm.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/mm.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/mm.c 1999-12-07 20:57:42.000000000 -0500
@@ -0,0 +1,19 @@
+
+/* Memory Managment
+*/
+
+#include "jvmdi.h"
+
+jvmdiError SetAllocationHooks(JVMDI_AllocHook, JVMDI_DeallocHook)
+{
+}
+
+jvmdiError Allocate(jlong size, jbyte** memPtr)
+{
+}
+
+jvmdiError Deallocate(jbyte* mem /* FIXME: sic, they used "memPtr" before */)
+{
+}
+
+/* End of mm.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/noJVMDIClientLibError.test-case kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/noJVMDIClientLibError.test-case
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/noJVMDIClientLibError.test-case 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/noJVMDIClientLibError.test-case 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,2 @@
+Error loading JVMDI client library.
+NotASharedLibrary: cannot open shared object file: No such file or directory
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/object_info.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/object_info.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/object_info.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/object_info.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,12 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetObjectHashCode(jobject object, jint* hashCodePtr)
+{
+}
+
+jvmdiError GetMonitorInfo(jobject, JVMDI_monitor_info* infoPtr)
+{
+}
+
+/* End of object_info.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/sockhelp.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/sockhelp.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/sockhelp.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/sockhelp.c 1999-12-27 13:32:46.000000000 -0500
@@ -0,0 +1,323 @@
+/*
+ * This file is provided for use with the unix-socket-faq. It is public
+ * domain, and may be copied freely. There is no copyright on it. The
+ * original work was by Vic Metcalfe (vic at brutus.tlug.org), and any
+ * modifications made to that work were made with the understanding that
+ * the finished work would be in the public domain.
+ *
+ * If you have found a bug, please pass it on to me at the above address
+ * acknowledging that there will be no copyright on your work.
+ *
+ * The most recent version of this file, and the unix-socket-faq can be
+ * found at http://www.interlog.com/~vic/sock-faq/.
+ */
+
+#include "sockhelp.h"
+
+/* Take a service name, and a service type, and return a port number. If the
+ service name is not found, it tries it as a decimal number. The number
+ returned is byte ordered for the network. */
+int atoport(service, proto)
+char *service;
+char *proto;
+{
+ int port;
+ long int lport;
+ struct servent *serv;
+ char *errpos;
+
+ /* First try to read it from /etc/services */
+ serv = getservbyname(service, proto);
+ if (serv != NULL)
+ port = serv->s_port;
+ else { /* Not in services, maybe a number? */
+ lport = strtol(service,&errpos,0);
+ if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) )
+ return -1; /* Invalid port address */
+ port = htons(lport);
+ }
+ return port;
+}
+
+/* Converts ascii text to in_addr struct. NULL is returned if the address
+ can not be found. */
+struct in_addr *atoaddr(address)
+char *address;
+{
+ struct hostent *host;
+ static struct in_addr saddr;
+
+ /* First try it as aaa.bbb.ccc.ddd. */
+ saddr.s_addr = inet_addr(address);
+ if (saddr.s_addr != -1) {
+ return &saddr;
+ }
+ host = gethostbyname(address);
+ if (host != NULL) {
+ return (struct in_addr *) *host->h_addr_list;
+ }
+ return NULL;
+}
+
+/* This function listens on a port, and returns connections. It forks
+ returns off internally, so your main function doesn't have to worry
+ about that. This can be confusing if you don't know what is going on.
+ The function will create a new process for every incoming connection,
+ so in the listening process, it will never return. Only when a connection
+ comes in, and we create a new process for it will the function return.
+ This means that your code that calls it should _not_ loop.
+
+ The parameters are as follows:
+ socket_type: SOCK_STREAM or SOCK_DGRAM (TCP or UDP sockets)
+ port: The port to listen on. Remember that ports < 1024 are
+ reserved for the root user. Must be passed in network byte
+ order (see "man htons").
+ listener: This is a pointer to a variable for holding the file
+ descriptor of the socket which is being used to listen. It
+ is provided so that you can write a signal handler to close
+ it in the event of program termination. If you aren't interested,
+ just pass NULL. Note that all modern unixes will close file
+ descriptors for you on exit, so this is not required. */
+int get_connection(socket_type, port, listener)
+int socket_type;
+u_short port;
+int *listener;
+{
+ struct sockaddr_in address;
+ int listening_socket;
+ int connected_socket = -1;
+ int new_process;
+ int reuse_addr = 1;
+
+ /* Setup internet address information.
+ This is used with the bind() call */
+ memset((char *) &address, 0, sizeof(address));
+ address.sin_family = AF_INET;
+ address.sin_port = port;
+ address.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ listening_socket = socket(AF_INET, socket_type, 0);
+ if (listening_socket < 0) {
+ perror("socket");
+ exit(EXIT_FAILURE);
+ }
+
+ if (listener != NULL)
+ *listener = listening_socket;
+
+ setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr,
+ sizeof(reuse_addr));
+
+ if (bind(listening_socket, (struct sockaddr *) &address,
+ sizeof(address)) < 0) {
+ perror("bind");
+ close(listening_socket);
+ exit(EXIT_FAILURE);
+ }
+
+ if (socket_type == SOCK_STREAM) {
+ listen(listening_socket, 5); /* Queue up to five connections before
+ having them automatically rejected. */
+
+ while(connected_socket < 0) {
+ connected_socket = accept(listening_socket, NULL, NULL);
+ if (connected_socket < 0) {
+ /* Either a real error occured, or blocking was interrupted for
+ some reason. Only abort execution if a real error occured. */
+ if (errno != EINTR) {
+ perror("accept");
+ close(listening_socket);
+ exit(EXIT_FAILURE);
+ } else {
+ continue; /* don't fork - do the accept again */
+ }
+ }
+
+ new_process = fork();
+ if (new_process < 0) {
+ perror("fork");
+ close(connected_socket);
+ connected_socket = -1;
+ }
+ else { /* We have a new process... */
+ if (new_process == 0) {
+ /* This is the new process. */
+ close(listening_socket); /* Close our copy of this socket */
+ if (listener != NULL)
+ *listener = -1; /* Closed in this process. We are not
+ responsible for it. */
+ }
+ else {
+ /* This is the main loop. Close copy of connected socket, and
+ continue loop. */
+ close(connected_socket);
+ connected_socket = -1;
+ }
+ }
+ }
+ return connected_socket;
+ }
+ else
+ return listening_socket;
+}
+
+/* This is a generic function to make a connection to a given server/port.
+ service is the port name/number,
+ type is either SOCK_STREAM or SOCK_DGRAM, and
+ netaddress is the host name to connect to.
+ The function returns the socket, ready for action.*/
+int make_connection(service, type, netaddress)
+char *service;
+int type;
+char *netaddress;
+{
+ /* First convert service from a string, to a number... */
+ int port = -1;
+ struct in_addr *addr;
+ int sock, connected;
+ struct sockaddr_in address;
+
+ if (type == SOCK_STREAM)
+ port = atoport(service, "tcp");
+ if (type == SOCK_DGRAM)
+ port = atoport(service, "udp");
+ if (port == -1) {
+ fprintf(stderr,"make_connection: Invalid socket type.\n");
+ return -1;
+ }
+ addr = atoaddr(netaddress);
+ if (addr == NULL) {
+ fprintf(stderr,"make_connection: Invalid network address.\n");
+ return -1;
+ }
+
+ memset((char *) &address, 0, sizeof(address));
+ address.sin_family = AF_INET;
+ address.sin_port = (port);
+ address.sin_addr.s_addr = addr->s_addr;
+
+ sock = socket(AF_INET, type, 0);
+
+ printf("Connecting to %s on port %d.\n",inet_ntoa(*addr),htons(port));
+
+ if (type == SOCK_STREAM) {
+ connected = connect(sock, (struct sockaddr *) &address,
+ sizeof(address));
+ if (connected < 0) {
+ perror("connect");
+ return -1;
+ }
+ return sock;
+ }
+ /* Otherwise, must be for udp, so bind to address. */
+ if (bind(sock, (struct sockaddr *) &address, sizeof(address)) < 0) {
+ perror("bind");
+ return -1;
+ }
+ return sock;
+}
+
+/* This is just like the read() system call, accept that it will make
+ sure that all your data goes through the socket. */
+int sock_read(sockfd, buf, count)
+int sockfd;
+char *buf;
+size_t count;
+{
+ size_t bytes_read = 0;
+ int this_read;
+
+ while (bytes_read < count) {
+ do
+ this_read = read(sockfd, buf, count - bytes_read);
+ while ( (this_read < 0) && (errno == EINTR) );
+ if (this_read < 0)
+ return this_read;
+ else if (this_read == 0)
+ return bytes_read;
+ bytes_read += this_read;
+ buf += this_read;
+ }
+ return count;
+}
+
+/* This is just like the write() system call, accept that it will
+ make sure that all data is transmitted. */
+int sock_write(sockfd, buf, count)
+int sockfd;
+char *buf;
+size_t count;
+{
+ size_t bytes_sent = 0;
+ int this_write;
+
+ while (bytes_sent < count) {
+ do
+ this_write = write(sockfd, buf, count - bytes_sent);
+ while ( (this_write < 0) && (errno == EINTR) );
+ if (this_write <= 0)
+ return this_write;
+ bytes_sent += this_write;
+ buf += this_write;
+ }
+ return count;
+}
+
+/* This function reads from a socket, until it recieves a linefeed
+ character. It fills the buffer "str" up to the maximum size "count".
+
+ This function will return -1 if the socket is closed during the read
+ operation.
+
+ Note that if a single line exceeds the length of count, the extra data
+ will be read and discarded! You have been warned. */
+int sock_gets(sockfd, str, count)
+int sockfd;
+char *str;
+size_t count;
+{
+ int bytes_read;
+ int total_count = 0;
+ char *current_position;
+ char last_read = 0;
+
+ current_position = str;
+ while (last_read != 10) {
+ bytes_read = read(sockfd, &last_read, 1);
+ if (bytes_read <= 0) {
+ /* The other side may have closed unexpectedly */
+ return -1; /* Is this effective on other platforms than linux? */
+ }
+ if ( (total_count < count) && (last_read != 10) && (last_read !=13) ) {
+ current_position[0] = last_read;
+ current_position++;
+ total_count++;
+ }
+ }
+ if (count > 0)
+ current_position[0] = 0;
+ return total_count;
+}
+
+/* This function writes a character string out to a socket. It will
+ return -1 if the connection is closed while it is trying to write. */
+int sock_puts(sockfd, str)
+int sockfd;
+char *str;
+{
+ return sock_write(sockfd, str, strlen(str));
+}
+
+/* This ignores the SIGPIPE signal. This is usually a good idea, since
+ the default behaviour is to terminate the application. SIGPIPE is
+ sent when you try to write to an unconnected socket. You should
+ check your return codes to make sure you catch this error! */
+void ignore_pipe(void)
+{
+ struct sigaction sig;
+
+ sig.sa_handler = SIG_IGN;
+ sig.sa_flags = 0;
+ sigemptyset(&sig.sa_mask);
+ sigaction(SIGPIPE,&sig,NULL);
+}
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/test.sh kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/test.sh
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/test.sh 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/test.sh 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,9 @@
+
+rm -f test.stdout test.stderr
+kaffe -XrunNotASharedLibrary:hi,chico HiChico 1>test.stdout 2>test.stderr && echo "Error: kaffe did not return failure status"
+diff test.stderr noJVMDIClientLibError.test-case || echo "Error: diff failed"
+[ "`ls -s test.stdout`" != " 0 test.stdout" ] && echo "Error: stdout test failed"
+
+kaffe Hello && echo "Error: kaffe returned failure status"
+
+# End of test.sh
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/test.stderr kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/test.stderr
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/test.stderr 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/test.stderr 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,2 @@
+Error loading JVMDI client library.
+NotASharedLibrary: cannot open shared object file: No such file or directory
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/threadExec.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/threadExec.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/threadExec.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/threadExec.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,49 @@
+/* Thread Execution Functions
+*/
+
+#include "jvmdi.h"
+
+jvmdiError GetThreadStatus(jthread thread, jint* threadStatusPtr,
+ jint* suspendStatusPtr)
+{
+}
+
+jvmdiError GetAllThreads(jint* threadsCountPtr, jthread** threadsPtr)
+{
+}
+
+jvmdiError SuspendThread(jthread thread)
+{
+}
+
+jvmdiError ResumeThread(jthread thread)
+{
+}
+
+jvmdiError StopThread(jthread thread, jobject exception)
+{
+}
+
+jvmdiError InterruptThread(jthread thread)
+{
+}
+
+jvmdiError GetThreadInfo(jthread thread, JVMDI_thread_info* infoPtr)
+{
+}
+
+jvmdiError GetOwnedMonitorInfo(jthread thread,
+ JVMDI_owned_monitor_info* infoPtr)
+{
+}
+
+jvmdierror GetCurrentContendedMonitor(jthread thread, jobject* monitorPtr)
+{
+}
+
+jvmdiError RunDebugThread(jthread thread, JVMDIR_StartFunction proc,
+ void* arg, int priority)
+{
+}
+
+/* End of thread_exec.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/threadGroups.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/threadGroups.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/threadGroups.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/threadGroups.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,15 @@
+
+#include "jvmdi.h"
+
+jvmdiError GetThreadGroupInfo(jthreadGroup goup,
+ JVMDIR_thread_group_info* infoPtr)
+{
+}
+
+jvmdiError GetThreadGroupChildren(jthreadGroup group, jint* threadCountPtr,
+ jthread** threadsPtr, jint* groupCountPtr,
+ jthreadGroup** groupsPtr)
+{
+}
+
+/* End of thread_groups.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/watches.c kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/watches.c
--- kaffe-1.0.5/kaffe/kaffevm/jpdaBackend/watches.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jpdaBackend/watches.c 1999-12-07 20:57:43.000000000 -0500
@@ -0,0 +1,20 @@
+
+#include "jvmdi.h"
+
+jvmdiError SetFieldAccessWatch(jclass clazz, jfieldID field)
+{
+}
+
+jvmdiError ClearFieldAccessWatch(jclass clazz, jfieldID field)
+{
+}
+
+jvmdiError SetFieldModificationWatch(jclass clazz, jfieldID field)
+{
+}
+
+jvmdiError ClearFieldModificationWatch(jclass clazz, jfieldID field)
+{
+}
+
+/* End of watches.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jvmdi.c kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdi.c
--- kaffe-1.0.5/kaffe/kaffevm/jvmdi.c 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdi.c 2000-01-11 19:05:35.000000000 -0500
@@ -0,0 +1,526 @@
+
+/* Outside Interface API */
+#include "jvmdi.h"
+
+/* Inside Event Interface API */
+#include "jvmdiEvents.h"
+#include "jvmdiRawMonitor.h"
+
+/* FIXME: Duh! This can't stay global, static */
+JVMDI_EventHook theHook;
+
+jvmdiError SetEventHook(JVMDI_EventHook hook)
+{
+ JVMDI_RawMonitor m;
+ jvmdiError err;
+
+ /* Lock
+ */
+ if ((err = CreateAndEnterRawMonitor("__JVMDI_Lock", &m)) !=
+ JVMDI_ERROR_NONE)
+ {
+ return err;
+ }
+
+ /* Set thread-specific hook
+ */
+ theHook = hook;
+
+ /* Unlock
+ */
+ if ((err = ExitAndDestroyRawMonitor(m)) != JVMDI_ERROR_NONE)
+ {
+ /* Unset thread-specific hook
+ */
+ theHook = NULL;
+
+ return err;
+ }
+
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError SetEventNotificationMode(jint mode, jint eventType,
+ jthread thead, ...)
+{
+ JVMDI_RawMonitor m;
+ jvmdiError err;
+
+ /* Lock
+ */
+ if ((err = CreateAndEnterRawMonitor("__JVMDI_Lock", &m)) !=
+ JVMDI_ERROR_NONE)
+ {
+ return err;
+ }
+
+ /* Set thread-specific event notify mask */
+
+ /* Unlock
+ */
+ if ((err = ExitAndDestroyRawMonitor(m)) != JVMDI_ERROR_NONE)
+ {
+ /* Unset thread-specific event notify mask */
+
+ return err;
+ }
+
+ return JVMDI_ERROR_NONE;
+}
+
+static void fireEvent(JVMDI_Event e)
+{
+ JNIEnv* env;
+
+ /* Get a JNIEnv
+ */
+ env = (JNIEnv*)malloc(sizeof(*env));
+
+ /* Call the hook
+ */
+ if (theHook)
+ {
+ (void)theHook(env, &e);
+ }
+
+ /* dealloc JNIEnv
+ */
+ free(env);
+}
+
+void fireSingleStepEvent(jthread thread,
+ jclass clazz,
+ jmethodID method,
+ jlocation location)
+{
+ JVMDI_Event* e;
+ JVMDI_single_step_event_data* ss;
+
+ /* +++ FIXME */
+ printf("SingleStepEvent!! pc is %x\n", (int)location);
+ /* --- FIXME */
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_SINGLE_STEP;
+ ss = (JVMDI_single_step_event_data*)(&(e->u));
+ ss->thread = thread;
+ ss->clazz = clazz;
+ ss->method = method;
+ ss->location = location;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireBreakpointEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location)
+{
+ JVMDI_Event* e;
+ JVMDI_breakpoint_event_data* b;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_BREAKPOINT;
+ b = (JVMDI_breakpoint_event_data*)(&(e->u));
+ b->thread = thread;
+ b->clazz = clazz;
+ b->method = method;
+ b->location = location;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+static void frameEvent(jint kind,
+ jthread thread,
+ jclass clazz,
+ jmethodID method,
+ jframeID frame)
+{
+ JVMDI_Event* e;
+ JVMDI_frame_event_data* fe;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = kind;
+ fe = (JVMDI_frame_event_data*)(&(e->u));
+ fe->thread = thread;
+ fe->clazz = clazz;
+ fe->method = method;
+ fe->frame = frame;
+
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireFramePopEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame)
+{
+ frameEvent(JVMDI_EVENT_FRAME_POP, thread, clazz, method, frame);
+}
+
+void fireMethodEntryEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame)
+{
+ frameEvent(JVMDI_EVENT_METHOD_ENTRY, thread, clazz, method, frame);
+}
+
+void fireMethodExitEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame)
+{
+ frameEvent(JVMDI_EVENT_METHOD_EXIT, thread, clazz, method, frame);
+}
+
+void fireFieldAccessEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jclass field_clazz, jobject object,
+ jfieldID field)
+{
+ JVMDI_Event* e;
+ JVMDI_field_access_event_data* fa;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_FIELD_ACCESS;
+ fa = (JVMDI_field_access_event_data*)(&(e->u));
+ fa->thread = thread;
+ fa->clazz = clazz;
+ fa->method = method;
+ fa->location = location;
+ fa->field_clazz = field_clazz;
+ fa->object = object;
+ fa->field = field;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireFieldModificationEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jclass field_clazz, jobject object,
+ jfieldID field, char signature_type,
+ jvalue new_value)
+{
+ JVMDI_Event* e;
+ JVMDI_field_modification_event_data* fm;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_FIELD_MODIFICATION;
+ fm = (JVMDI_field_modification_event_data*)(&(e->u));
+ fm->thread = thread;
+ fm->clazz = clazz;
+ fm->method = method;
+ fm->location = location;
+ fm->field_clazz = field_clazz;
+ fm->object = object;
+ fm->field = field;
+ fm->signature_type = signature_type;
+ fm->new_value = new_value;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireExceptionEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jobject exception, jclass catch_clazz,
+ jmethodID catch_method, jlocation catch_location)
+{
+ JVMDI_Event* e;
+ JVMDI_exception_event_data* ex;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_EXCEPTION;
+ ex = (JVMDI_exception_event_data*)(&(e->u));
+ ex->thread = thread;
+ ex->clazz = clazz;
+ ex->method = method;
+ ex->location = location;
+ ex->exception = exception;
+ ex->catch_clazz = catch_clazz;
+ ex->catch_method = catch_method;
+ ex->catch_location = catch_location;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireExceptionCatchEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jobject exception)
+{
+ JVMDI_Event* e;
+ JVMDI_exception_catch_event_data* ec;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_EXCEPTION_CATCH;
+ ec = (JVMDI_exception_catch_event_data*)(&(e->u));
+ ec->thread = thread;
+ ec->clazz = clazz;
+ ec->method = method;
+ ec->location = location;
+ ec->exception = exception;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireUserDefinedEvent(jobject object, jint key)
+{
+ JVMDI_Event* e;
+ JVMDI_user_event_data* ud;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_USER_DEFINED;
+ ud = (JVMDI_user_event_data*)(&(e->u));
+ ud->object = object;
+ ud->key = key;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+static void threadChangeEvent(jint kind, jthread thread)
+{
+ JVMDI_Event* e;
+ JVMDI_thread_change_event_data* tc;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = kind;
+ tc = (JVMDI_thread_change_event_data*)(&(e->u));
+ tc->thread = thread;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireThreadStartEvent(jthread thread)
+{
+ threadChangeEvent(JVMDI_EVENT_THREAD_START, thread);
+}
+
+void fireThreadEndEvent(jthread thread)
+{
+ threadChangeEvent(JVMDI_EVENT_THREAD_END, thread);
+}
+
+static void classEvent(jint kind, jthread thread, jclass clazz)
+{
+ JVMDI_Event* e;
+ JVMDI_class_event_data* c;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = kind;
+ c = (JVMDI_class_event_data*)(&(e->u));
+ c->thread = thread;
+ c->clazz = clazz;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireClassLoadEvent(jthread thread, jclass clazz)
+{
+ classEvent(JVMDI_EVENT_CLASS_LOAD, thread, clazz);
+}
+
+void fireClassUnloadEvent(jthread thread, jclass clazz)
+{
+ classEvent(JVMDI_EVENT_CLASS_UNLOAD, thread, clazz);
+}
+
+void fireClassPrepareEvent(jthread thread, jclass clazz)
+{
+ classEvent(JVMDI_EVENT_CLASS_PREPARE, thread, clazz);
+}
+
+void fireVMInitEvent(void)
+{
+ JVMDI_Event* e;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+
+ e->kind = JVMDI_EVENT_VM_INIT;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireVMDeathEvent(void)
+{
+ JVMDI_Event* e;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_VM_DEATH;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+jvmdiError CreateRawMonitor(char* name, JVMDI_RawMonitor* monitorPtr)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError DestroyRawMonitor(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorEnter(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorExit(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorWait(JVMDI_RawMonitor monitor, jlong millis)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorNotify(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorNotifyAll(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError CreateAndEnterRawMonitor(char* name, JVMDI_RawMonitor* monitorPtr)
+{
+ jvmdiError err;
+
+ if ((err = CreateRawMonitor(name, monitorPtr) != JVMDI_ERROR_NONE))
+ {
+ return err;
+ }
+ else
+ {
+ if ((err = RawMonitorEnter(*monitorPtr) != JVMDI_ERROR_NONE))
+ {
+ (void)DestroyRawMonitor(*monitorPtr);
+ return err;
+ }
+ }
+
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError ExitAndDestroyRawMonitor(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+/* End of jvmdi.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jvmdi.h kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdi.h
--- kaffe-1.0.5/kaffe/kaffevm/jvmdi.h 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdi.h 1999-12-07 20:56:44.000000000 -0500
@@ -0,0 +1,491 @@
+
+#ifndef __jvmdi_h
+#define __jvmdi_h
+
+/*
+ FIXME. QUESTION: Can I lift this file from Sun? If so, lets use theirs for
+ compatibility sake. We can also leverage some of their testing effort
+ for free. Just in case I've derived this myself from the spec.
+*/
+
+/* NOTES
+
+ All the "name" parameters are commented with "Name in UTF-8". I've omited
+ those in favor of mentioning it once here.
+
+*/
+
+#include <jtypes.h>
+#include <jthread.h>
+
+/* FIXME: No way these are right...
+*/
+typedef jlong jthreadGroup;
+typedef jlong jframeID;
+typedef jlong jlocation;
+
+typedef struct {
+ jlong q;
+} JVMDI_local_variable_entry;
+
+typedef struct {
+ jlong q;
+} JVMDI_exception_handler_entry;
+
+typedef struct {
+ jlong q;
+} JVMDI_RawMonitor;
+
+/* FIXME: what should this really be?
+*/
+typedef jint jvmdiError;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jlocation location;
+} JVMDI_single_step_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jlocation location;
+} JVMDI_breakpoint_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jlocation location;
+ jclass field_clazz;
+ jobject object;
+ jfieldID field;
+} JVMDI_field_access_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jlocation location;
+ jclass field_clazz;
+ jobject object;
+ jfieldID field;
+ char signature_type;
+ jvalue new_value;
+} JVMDI_field_modification_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jframeID frame;
+} JVMDI_frame_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jlocation location;
+ jobject exception;
+ jclass catch_clazz;
+ jmethodID catch_method;
+ jlocation catch_location;
+} JVMDI_exception_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+ jmethodID method;
+ jlocation location;
+ jobject exception;
+} JVMDI_exception_catch_event_data;
+
+typedef struct
+{
+ jobject object;
+ jint key;
+} JVMDI_user_event_data;
+
+typedef struct
+{
+ jthread thread;
+} JVMDI_thread_change_event_data;
+
+typedef struct
+{
+ jthread thread;
+ jclass clazz;
+} JVMDI_class_event_data;
+
+typedef struct
+{
+ jint kind;
+
+ union
+ {
+ #define JVMDI_EVENT_SINGLE_STEP 1
+ JVMDI_single_step_event_data single_step;
+
+ #define JVMDI_EVENT_BREAKPOINT 2
+ JVMDI_breakpoint_event_data breakpoint;
+
+ #define JVMDI_EVENT_FRAME_POP 3
+ #define JVMDI_EVENT_METHOD_ENTRY 4
+ #define JVMDI_EVENT_METHOD_EXIT 5
+ JVMDI_frame_event_data frame;
+
+ #define JVMDI_EVENT_FIELD_ACCESS 6
+ JVMDI_field_access_event_data field_access;
+
+ #define JVMDI_EVENT_FIELD_MODIFICATION 7
+ JVMDI_field_modification_event_data field_modification;
+
+ #define JVMDI_EVENT_EXCEPTION 8
+ JVMDI_exception_event_data exception;
+
+ #define JVMDI_EVENT_EXCEPTION_CATCH 9
+ JVMDI_exception_catch_event_data execption_catch;
+
+ #define JVMDI_EVENT_USER_DEFINED 10
+ JVMDI_user_event_data user;
+
+ #define JVMDI_EVENT_THREAD_END 11
+ #define JVMDI_EVENT_THREAD_START 12
+ JVMDI_thread_change_event_data thread_change;
+
+ #define JVMDI_EVENT_CLASS_LOAD 13
+ #define JVMDI_EVENT_CLASS_UNLOAD 14
+ #define JVMDI_EVENT_CLASS_PREPARE 15
+ JVMDI_class_event_data class_event;
+
+ #define JVMDI_EVENT_VM_DEATH 16
+ #define JVMDI_EVENT_VM_INIT 17
+ } u;
+} JVMDI_Event;
+
+/* Memory Managment
+*/
+typedef jvmdiError (*JVMDI_AllocHook)(jlong size, jbyte** memPtr);
+
+typedef jvmdiError (*JVMDI_DeallocHook)(jbyte* buffer);
+
+jvmdiError SetAllocationHooks(JVMDI_AllocHook, JVMDI_DeallocHook);
+
+jvmdiError Allocate(jlong size, jbyte** memPtr);
+
+jvmdiError Deallocate(jbyte* mem /* FIXME: sic, they used "memPtr" before */);
+
+/* Thread Execution Functions
+*/
+jvmdiError GetThreadStatus(jthread thread, jint* threadStatusPtr,
+ jint* suspendStatusPtr);
+
+jvmdiError GetAllThreads(jint* threadsCountPtr, jthread** threadsPtr);
+
+jvmdiError SuspendThread(jthread thread);
+
+jvmdiError ResumeThread(jthread thread);
+
+jvmdiError StopThread(jthread thread, jobject exception);
+
+jvmdiError InterruptThread(jthread thread);
+
+typedef struct
+{
+ char* name;
+ jint priority;
+ jboolean is_daemon;
+ jthreadGroup thread_group;
+ jobject context_class_loader;
+} JVMDI_thread_info;
+
+jvmdiError GetThreadInfo(jthread thread, JVMDI_thread_info* infoPtr);
+
+typedef struct
+{
+ jint owned_monitor_count;
+ jobject* owned_monitors;
+} JVMDI_owned_monitor_info;
+
+jvmdiError GetOwnedMonitorInfo(jthread thread,
+ JVMDI_owned_monitor_info* infoPtr);
+
+jvmdiError GetCurrentContendedMonitor(jthread thread, jobject* monitorPtr);
+
+typedef void (*JVMDIR_StartFunction)(void*);
+
+jvmdiError RunDebugThread(jthread thread, JVMDIR_StartFunction proc,
+ void* arg, int priority);
+
+/* Thread Groups
+*/
+jvmdiError GetTopThreadGroups(jint* groupCountPtr, jthreadGroup** groupsPtr);
+
+typedef struct
+{
+ jthreadGroup parent;
+ char* name;
+ jint max_priority;
+ jboolean is_daemon;
+} JVMDIR_thread_group_info;
+
+jvmdiError GetThreadGroupInfo(jthreadGroup goup,
+ JVMDIR_thread_group_info* infoPtr);
+jvmdiError GetThreadGroupChildren(jthreadGroup group, jint* threadCountPtr,
+ jthread** threadsPtr, jint* groupCountPtr,
+ jthreadGroup** groupsPtr);
+
+/* Stack Frame Access
+*/
+jvmdiError GetFrameCount(jthread thread, jint* countPtr);
+
+jvmdiError GetCurrentFrame(jthread thread, jframeID* framePtr);
+
+jvmdiError GetCallerFrame(jframeID called, jframeID* framePtr);
+
+jvmdiError GetFrameLocation(jframeID frame, jclass* classPtr, jlocation* locationPtr);
+
+jvmdiError NotifyFramePop(jframeID frame);
+
+/* Local Variable Access
+*/
+jvmdiError GetLocalObject(jframeID frame, jint slot, jobject* valuePtr);
+
+jvmdiError GetLocalInt(jframeID frame, jint slot, jint* valuePtr);
+
+jvmdiError GetLocalLong(jframeID frame, jint slot, jlong* valuePtr);
+
+jvmdiError GetLocalFloat(jframeID frame, jint slot, jfloat* valuePtr);
+
+jvmdiError GetLocalDouble(jframeID frame, jint slot, jdouble* valuePtr);
+
+jvmdiError SetLocalObject(jframeID frame, jint slot, jobject value);
+
+jvmdiError SetLocalInt(jframeID frame, jint slot, jint value);
+
+jvmdiError SetLocalLong(jframeID frame, jint slot, jlong value);
+
+jvmdiError SetLocalFloat(jframeID frame, jint slot, jfloat value);
+
+jvmdiError SetLocalDouble(jframeID frame, jint slot, jdouble value);
+
+/* Breakpoints
+*/
+jvmdiError SetBreakpoint(jclass clazz, jmethodID method, jlocation location);
+
+jvmdiError ClearBreakpoint(jclass class, jmethodID method, jlocation location);
+
+jvmdiError ClearAllBreakpoints(void);
+
+/* Watched Fields
+*/
+jvmdiError SetFieldAccessWatch(jclass clazz, jfieldID field);
+
+jvmdiError ClearFieldAccessWatch(jclass clazz, jfieldID field);
+
+jvmdiError SetFieldModificationWatch(jclass clazz, jfieldID field);
+
+jvmdiError ClearFieldModificationWatch(jclass clazz, jfieldID field);
+
+/* Class Information
+*/
+jvmdiError GetClassSignature(jclass clazz, char** sigPtr);
+
+jvmdiError GetClassStatus(jclass clazz, char* statusPtr);
+
+jvmdiError GetSourceFileName(jclass clazz, char** sourceNamePtr);
+
+jvmdiError GetClassModifiers(jclass clazz, jint* modifiersPtr);
+
+jvmdiError GetClassMethods(jclass clazz, jint* methodCountPtr,
+ jmethodID** methodsPtr);
+
+jvmdiError GetClassFields(jclass clazz, jint* fieldCountPtr,
+ jfieldID** fieldsPtr);
+
+jvmdiError GetImplementedInterfaces(jclass clazz, jint* interfaceCountPtr,
+ jclass** interfacesPtr);
+
+jvmdiError IsInterface(jclass clazz, jboolean* isInterfacePtr);
+
+jvmdiError IsArrayclass(jclass clazz, jboolean* isArrayClassPyr);
+
+jvmdiError GetClassLoader(jclass clazz, jobject* classloaderPtr);
+
+/* Object Information
+*/
+jvmdiError GetObjectHashCode(jobject object, jint* hashCodePtr);
+
+typedef struct
+{
+ jthread owner;
+ jint entry_count;
+ jint waiter_count;
+ jthread* waiters;
+} JVMDI_monitor_info;
+
+jvmdiError GetMonitorInfo(jobject, JVMDI_monitor_info* infoPtr);
+
+/* Field Information
+*/
+jvmdiError GetFieldName(jclass clazz, jfieldID field, char** namePtr,
+ char** signaturePtr);
+
+jvmdiError GetFieldDeclaringClass(jclass clazz, jfieldID field,
+ jclass* declaringClassPtr);
+
+jvmdiError GetFieldModifiers(jclass clazz, jfieldID field, jint* modifiersPtr);
+
+jvmdiError IsFieldSynthetic(jclass clazz, jfieldID field,
+ jboolean* isSyntheticPtr);
+
+/* MethodInformation
+*/
+jvmdiError GetMethodName(jclass clazz, jmethodID method,
+ char** namePtr, char** signaturePtr);
+
+jvmdiError GetMethodDeclaringClass(jclass clazz, jmethodID method,
+ jclass* declaringClassPtr);
+
+jvmdiError GetMethodModifiers(jclass clazz, jmethodID method,
+ jint* modifiersPtr);
+
+
+jvmdiError GetMaxStack(jclass clazz, jmethodID method, jint* maxPtr);
+
+jvmdiError GetMaxLocals(jclass clazz, jmethodID method, jint* maxPtr);
+
+jvmdiError GetArgumentsSize(jclass clazz, jmethodID method, jint* sizePtr);
+
+typedef struct
+{
+ jlocation start_location;
+ jint line_number;
+} JVMDI_line_number_entry;
+
+jvmdiError GetLineNumberTable(jclass clazz, jmethodID method,
+ jint* entryCountPtr,
+ JVMDI_line_number_entry** tablePtr);
+
+jvmdiError GetMethodLocation(jclass clazz, jmethodID method,
+ jlocation* startLocationPtr,
+ jlocation* endLocationptr);
+
+jvmdiError GetLocalVariableTable(jclass clazz, jmethodID method,
+ jint* entryCountPtr,
+ JVMDI_local_variable_entry** tablePtr);
+
+jvmdiError GetExceptionhandlerTable(jclass clazz, jmethodID method,
+ jint* entryCountPtr,
+ JVMDI_exception_handler_entry** tablePtr);
+
+jvmdiError GetThrownExceptions(jclass clazz, jmethodID method,
+ jint* exceptioncountPtr,
+ jclass** exceptionsPtr);
+
+jvmdiError GetByteCodes(jclass clazz, jmethodID method, jint* bytecodeCountPtr,
+ jbyte** bytecodesPtr);
+
+jvmdiError IsMethodNative(jclass clazz, jmethodID method,
+ jboolean* isNativePtr);
+
+jvmdiError IsMethodSynthetic(jclass clazz, jmethodID method,
+ jboolean* isSyntheticPtr);
+
+/* Raw Monitor Support
+*/
+jvmdiError CreateRawMonitor(char* name, JVMDI_RawMonitor* monitorPtr);
+
+jvmdiError DestroyRawMontor(JVMDI_RawMonitor monitor);
+
+jvmdiError RawMonitorEnter(JVMDI_RawMonitor monitor);
+
+jvmdiError RawMonitorExit(JVMDI_RawMonitor monitor);
+
+jvmdiError RawMonitorwait(JVMDI_RawMonitor monitor, jlong millis);
+
+jvmdiError RawMonitorNotify(JVMDI_RawMonitor monitor);
+
+jvmdiError RawMonitorNotifyAll(JVMDI_RawMonitor monitor);
+
+/* Events
+*/
+typedef void (*JVMDI_EventHook)(JNIEnv* env, JVMDI_Event* event);
+
+jvmdiError SetEventHook(JVMDI_EventHook hook);
+
+jvmdiError SetEventNotificationMode(jint mode, jint eventType,
+ jthread thead, ...);
+
+/* Miscellaneous Functions
+*/
+jvmdiError GetLoadedClasses(jint* classCountPtr, jclass** classesPtr);
+
+jvmdiError GetClassLoaderClasses(jobject initiatingLoader,
+ jint* classCountPtr, jclass** classesPtr);
+
+jvmdiError GetVersionNumber(jint* versionPtr);
+
+typedef struct
+{
+ unsigned int can_watch_field_modification;
+ unsigned int can_watch_field_access;
+ unsigned int can_get_bytecodes;
+ unsigned int can_get_synthetic_attribute;
+ unsigned int can_get_owned_monitor_info;
+ unsigned int can_get_current_contended_monitor;
+ unsigned int can_get_monitor_info;
+} JVMDI_capabilities;
+
+jvmdiError GetCapabilities(JVMDI_capabilities* capabilitiesPtr);
+
+/* Universal Errors
+*/
+#define JVMDI_ERROR_NONE 0
+#define JVMDI_ERROR_OUT_OF_MEMORY 1
+#define JVMDI_ERROR_ACCESS_DENIED 2
+#define JVMDI_ERROR_UNATTACHED_THREAD 3
+#define JVMDI_ERROR_VM_DEAD 4
+#define JVMDI_ERROR_INTERNAL 5
+
+/* Function Specific Errors
+*/
+#define JVMDI_ERROR_INVALID_THREAD 6
+#define JVMDI_ERROR_INVALID_FIELDID 7
+#define JVMDI_ERROR_INVALID_METHODID 8
+#define JVMDI_ERROR_INVALID_LOCATION 9
+#define JVMDI_ERROR_INVALID_FRAMEID 10
+#define JVMDI_ERROR_NO_MORE_FRAMES 11
+#define JVMDI_ERROR_OPAQUE_FRAME 12
+#define JVMDI_ERROR_NOT_CURRENT_FRAME 13
+#define JVMDI_ERROR_TYPE_MISMATCH 14
+#define JVMDI_ERROR_INVALID_SLOT 15
+#define JVMDI_ERROR_DUPLICATE 16
+#define JVMDI_ERROR_THREAD_NOT_SUSPENDED 17
+#define JVMDI_ERROR_THREAD_SUSPENDED 18
+#define JVMDI_ERROR_INVALID_OBJECT 19
+#define JVMDI_ERROR_INVLAID_CLASS 20
+#define JVMDI_ERROR_CLASS_NOT_PREPARED 21
+#define JVMDI_ERROR_NULL_POINTER 22
+#define JVMDI_ERROR_ABSENT_INFORMATION 23
+#define JVMDI_ERROR_INVALID_EVENT_TYPE 24
+#define JVMDI_ERROR_NOT_IMPLEMENTED 25
+#define JVMDI_ERROR_INVALID_THREAD_GROUP 26
+#define JVMDI_ERROR_INVALID_PRIORITY 27
+#define JVMDI_ERROR_NOT_FOUND 28
+#define JVMDI_ERROR_INAVLID_MONITOR 29
+#define JVMDI_ERROR_ILLEGAL_ARGUMENT 30
+#define JVMDI_ERROR_NOT_MONITOR_OWNER 31
+#define JVMDI_ERROR_INTERRUPT 32
+#define JVMDI_ERROR_INVALID_TYPESTATE 33
+
+#endif
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jvmdiEvents.c-save kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiEvents.c-save
--- kaffe-1.0.5/kaffe/kaffevm/jvmdiEvents.c-save 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiEvents.c-save 1999-12-07 20:56:44.000000000 -0500
@@ -0,0 +1,467 @@
+
+/* Outside Interface API */
+#include "jvmdi.h"
+
+/* Inside Event Interface API */
+#include "jvmdiEvents.h"
+#include "jvmdiRawMonitor.h"
+
+/* FIXME: Duh! This can't stay global, static */
+JVMDI_EventHook theHook;
+
+jvmdiError SetEventHook(JVMDI_EventHook hook)
+{
+ JVMDI_RawMonitor m;
+ jvmdiError err;
+
+ /* Lock
+ */
+ if ((err = CreateAndEnterRawMonitor("__JVMDI_Lock", &m)) !=
+ JVMDI_ERROR_NONE)
+ {
+ return err;
+ }
+
+ /* Set thread-specific hook
+ */
+ theHook = hook;
+
+ /* Unlock
+ */
+ if ((err = ExitAndDestroyRawMonitor(m)) != JVMDI_ERROR_NONE)
+ {
+ /* Unset thread-specific hook
+ */
+ theHook = NULL;
+
+ return err;
+ }
+
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError SetEventNotificationMode(jint mode, jint eventType,
+ jthread thead, ...)
+{
+ JVMDI_RawMonitor m;
+ jvmdiError err;
+
+ /* Lock
+ */
+ if ((err = CreateAndEnterRawMonitor("__JVMDI_Lock", &m)) !=
+ JVMDI_ERROR_NONE)
+ {
+ return err;
+ }
+
+ /* Set thread-specific event notify mask */
+
+ /* Unlock
+ */
+ if ((err = ExitAndDestroyRawMonitor(m)) != JVMDI_ERROR_NONE)
+ {
+ /* Unset thread-specific event notify mask */
+
+ return err;
+ }
+
+ return JVMDI_ERROR_NONE;
+}
+
+static void fireEvent(JVMDI_Event e)
+{
+ JNIEnv* env;
+
+ /* Get a JNIEnv
+ */
+ env = (JNIEnv*)malloc(sizeof(*env));
+
+ /* Call the hook
+ */
+ if (theHook)
+ {
+ (void)theHook(env, &e);
+ }
+
+ /* dealloc JNIEnv
+ */
+ free(env);
+}
+
+void fireSingleStepEvent(jthread thread,
+ jclass clazz,
+ jmethodID method,
+ jlocation location)
+{
+ JVMDI_Event* e;
+ JVMDI_single_step_event_data* ss;
+
+ /* +++ FIXME */
+ printf("SingleStepEvent!! pc is %x\n", location);
+ /* --- FIXME */
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_SINGLE_STEP;
+ ss = (JVMDI_single_step_event_data*)(&(e->u));
+ ss->thread = thread;
+ ss->clazz = clazz;
+ ss->method = method;
+ ss->location = location;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireBreakpointEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location)
+{
+ JVMDI_Event* e;
+ JVMDI_breakpoint_event_data* b;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_BREAKPOINT;
+ b = (JVMDI_breakpoint_event_data*)(&(e->u));
+ b->thread = thread;
+ b->clazz = clazz;
+ b->method = method;
+ b->location = location;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+static void frameEvent(jint kind,
+ jthread thread,
+ jclass clazz,
+ jmethodID method,
+ jframeID frame)
+{
+ JVMDI_Event* e;
+ JVMDI_frame_event_data* fe;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = kind;
+ fe = (JVMDI_frame_event_data*)(&(e->u));
+ fe->thread = thread;
+ fe->clazz = clazz;
+ fe->method = method;
+ fe->frame = frame;
+
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireFramePopEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame)
+{
+ frameEvent(JVMDI_EVENT_FRAME_POP, thread, clazz, method, frame);
+}
+
+void fireMethodEntryEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame)
+{
+ frameEvent(JVMDI_EVENT_METHOD_ENTRY, thread, clazz, method, frame);
+}
+
+void fireMethodExitEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame)
+{
+ frameEvent(JVMDI_EVENT_METHOD_EXIT, thread, clazz, method, frame);
+}
+
+void fireFieldAccessEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jclass field_clazz, jobject object,
+ jfieldID field)
+{
+ JVMDI_Event* e;
+ JVMDI_field_access_event_data* fa;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_FIELD_ACCESS;
+ fa = (JVMDI_field_access_event_data*)(&(e->u));
+ fa->thread = thread;
+ fa->clazz = clazz;
+ fa->method = method;
+ fa->location = location;
+ fa->field_clazz = field_clazz;
+ fa->object = object;
+ fa->field = field;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireFieldModificationEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jclass field_clazz, jobject object,
+ jfieldID field, char signature_type,
+ jvalue new_value)
+{
+ JVMDI_Event* e;
+ JVMDI_field_modification_event_data* fm;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_FIELD_MODIFICATION;
+ fm = (JVMDI_field_modification_event_data*)(&(e->u));
+ fm->thread = thread;
+ fm->clazz = clazz;
+ fm->method = method;
+ fm->location = location;
+ fm->field_clazz = field_clazz;
+ fm->object = object;
+ fm->field = field;
+ fm->signature_type = signature_type;
+ fm->new_value = new_value;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireExceptionEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jobject exception, jclass catch_clazz,
+ jmethodID catch_method, jlocation catch_location)
+{
+ JVMDI_Event* e;
+ JVMDI_exception_event_data* ex;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_EXCEPTION;
+ ex = (JVMDI_exception_event_data*)(&(e->u));
+ ex->thread = thread;
+ ex->clazz = clazz;
+ ex->method = method;
+ ex->location = location;
+ ex->exception = exception;
+ ex->catch_clazz = catch_clazz;
+ ex->catch_method = catch_method;
+ ex->catch_location = catch_location;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireExceptionCatchEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jobject exception)
+{
+ JVMDI_Event* e;
+ JVMDI_exception_catch_event_data* ec;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_EXCEPTION_CATCH;
+ ec = (JVMDI_exception_catch_event_data*)(&(e->u));
+ ec->thread = thread;
+ ec->clazz = clazz;
+ ec->method = method;
+ ec->location = location;
+ ec->exception = exception;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireUserDefinedEvent(jobject object, jint key)
+{
+ JVMDI_Event* e;
+ JVMDI_user_event_data* ud;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_USER_DEFINED;
+ ud = (JVMDI_user_event_data*)(&(e->u));
+ ud->object = object;
+ ud->key = key;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+static void threadChangeEvent(jint kind, jthread thread)
+{
+ JVMDI_Event* e;
+ JVMDI_thread_change_event_data* tc;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = kind;
+ tc = (JVMDI_thread_change_event_data*)(&(e->u));
+ tc->thread = thread;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireThreadStartEvent(jthread thread)
+{
+ threadChangeEvent(JVMDI_EVENT_THREAD_START, thread);
+}
+
+void fireThreadEndEvent(jthread thread)
+{
+ threadChangeEvent(JVMDI_EVENT_THREAD_END, thread);
+}
+
+static void classEvent(jint kind, jthread thread, jclass clazz)
+{
+ JVMDI_Event* e;
+ JVMDI_class_event_data* c;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = kind;
+ c = (JVMDI_class_event_data*)(&(e->u));
+ c->thread = thread;
+ c->clazz = clazz;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireClassLoadEvent(jthread thread, jclass clazz)
+{
+ classEvent(JVMDI_EVENT_CLASS_LOAD, thread, clazz);
+}
+
+void fireClassUnloadEvent(jthread thread, jclass clazz)
+{
+ classEvent(JVMDI_EVENT_CLASS_UNLOAD, thread, clazz);
+}
+
+void fireClassPrepareEvent(jthread thread, jclass clazz)
+{
+ classEvent(JVMDI_EVENT_CLASS_PREPARE, thread, clazz);
+}
+
+void fireVMInitEvent(void)
+{
+ JVMDI_Event* e;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+
+ e->kind = JVMDI_EVENT_VM_INIT;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+void fireVMDeathEvent(void)
+{
+ JVMDI_Event* e;
+
+ /* obtain raw monitor */
+
+ /* alloc specific JVMDI_Event (FIXME as a "JNI local ref")
+ */
+ e = (JVMDI_Event*)malloc(sizeof(*e));
+ e->kind = JVMDI_EVENT_VM_DEATH;
+
+ fireEvent(*e);
+
+ /* dealloc JVMDI_Event
+ */
+ free(e);
+
+ /* release raw monitor */
+}
+
+/* End of jvmdiEvents.c */
+
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jvmdiEvents.h kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiEvents.h
--- kaffe-1.0.5/kaffe/kaffevm/jvmdiEvents.h 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiEvents.h 1999-12-07 20:56:44.000000000 -0500
@@ -0,0 +1,58 @@
+
+#ifndef __jvmdi_events_h
+#define __jvmdi_events_h
+
+#include <jthread.h>
+
+void fireSingleStepEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location);
+
+void fireBreakpointEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location);
+
+void fireFramePopEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame);
+
+void fireMethodEntryEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame);
+
+void fireMethodExitEvent(jthread thread, jclass clazz,
+ jmethodID method, jframeID frame);
+
+void fireFieldAccessEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jclass field_clazz, jobject object,
+ jfieldID field);
+
+void fireFieldModificationEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jclass field_clazz, jobject object,
+ jfieldID field, char signature_type,
+ jvalue new_value);
+
+void fireExceptionEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jobject exception, jclass catch_clazz,
+ jmethodID catch_method, jlocation catch_location);
+
+void fireExceptionCatchEvent(jthread thread, jclass clazz,
+ jmethodID method, jlocation location,
+ jobject exception);
+
+void fireUserDefinedEvent(jobject object, jint key);
+
+void fireThreadStartEvent(jthread thread);
+
+void fireThreadEndEvent(jthread thread);
+
+void fireClassLoadEvent(jthread thread, jclass clazz);
+
+void fireClassUnloadEvent(jthread thread, jclass clazz);
+
+void fireClassPrepareEvent(jthread thread, jclass clazz);
+
+void fireVMInitEvent(void);
+
+void fireVMDeathEvent(void);
+
+#endif
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jvmdiRawMonitor.c-save kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiRawMonitor.c-save
--- kaffe-1.0.5/kaffe/kaffevm/jvmdiRawMonitor.c-save 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiRawMonitor.c-save 1999-12-07 20:56:44.000000000 -0500
@@ -0,0 +1,66 @@
+
+#include "jvmdi.h"
+
+#include "jvmdiRawMonitor.h"
+
+jvmdiError CreateRawMonitor(char* name, JVMDI_RawMonitor* monitorPtr)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError DestroyRawMonitor(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorEnter(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorExit(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorWait(JVMDI_RawMonitor monitor, jlong millis)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorNotify(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError RawMonitorNotifyAll(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError CreateAndEnterRawMonitor(char* name, JVMDI_RawMonitor* monitorPtr)
+{
+ jvmdiError err;
+
+ if ((err = CreateRawMonitor(name, monitorPtr) != JVMDI_ERROR_NONE))
+ {
+ return err;
+ }
+ else
+ {
+ if ((err = RawMonitorEnter(*monitorPtr) != JVMDI_ERROR_NONE))
+ {
+ (void)DestroyRawMonitor(*monitorPtr);
+ return err;
+ }
+ }
+
+ return JVMDI_ERROR_NONE;
+}
+
+jvmdiError ExitAndDestroyRawMonitor(JVMDI_RawMonitor monitor)
+{
+ return JVMDI_ERROR_NONE;
+}
+
+/* End of jvmdiRawMonitor.c */
diff -Nru kaffe-1.0.5/kaffe/kaffevm/jvmdiRawMonitor.h kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiRawMonitor.h
--- kaffe-1.0.5/kaffe/kaffevm/jvmdiRawMonitor.h 1969-12-31 19:00:00.000000000 -0500
+++ kaffe-1.0.5-hacks/kaffe/kaffevm/jvmdiRawMonitor.h 1999-12-07 20:56:44.000000000 -0500
@@ -0,0 +1,9 @@
+
+#ifndef __jvmdi_raw_monitor_h
+
+#define __jvmdi_raw_monitor_h
+
+jvmdiError CreateAndEnterRawMonitor(char* name, JVMDI_RawMonitor* monitorPtr);
+jvmdiError ExitAndDestroyRawMonitor(JVMDI_RawMonitor monitor);
+
+#endif
More information about the kaffe
mailing list