+- The Linux native version is still experimental. You should configure
+ your compiler with:
+
+ ../gcc/configure \
+ --prefix=$PREFIX \
+ --enable-languages=c,c++,java \
+ --disable-nls \
+ --enable-libgcj \
+ --enable-threads=posix \
+ --enable-hash-synchronization \
+ --enable-static \
+ --disable-interpreter
+
+
+______________________________________________________________________________
+GetFullPathName patch
+
+Index: natFileWin32.cc
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/io/natFileWin32.cc,v
+retrieving revision 1.9.2.1
+diff -u -r1.9.2.1 natFileWin32.cc
+--- natFileWin32.cc 16 Apr 2002 15:35:20 -0000 1.9.2.1
++++ natFileWin32.cc 14 May 2002 01:57:39 -0000
+@@ -106,7 +106,7 @@
+ LPTSTR unused;
+ char buf2[MAX_PATH];
+ if(!GetFullPathName(buf, MAX_PATH, buf2, &unused))
+- throw new IOException (JvNewStringLatin1 ("GetFullPathName failed"));
++ return NULL;
+
+ // FIXME: what encoding to assume for file names? This affects many
+ // calls.
+
+
+______________________________________________________________________________
+File Locking Patch
+
+Index: java/io/natFileDescriptorWin32.cc
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/io/natFileDescriptorWin32.cc,v
+retrieving revision 1.5.2.2
+diff -u -r1.5.2.2 natFileDescriptorWin32.cc
+--- java/io/natFileDescriptorWin32.cc 10 Mar 2002 03:34:59 -0000 1.5.2.2
++++ java/io/natFileDescriptorWin32.cc 27 Apr 2002 08:40:40 -0000
+@@ -112,7 +112,7 @@
+ create = CREATE_ALWAYS;
+ }
+
+- handle = CreateFile(buf, access, share, NULL, create, 0, NULL);
++ handle = CreateFile(buf, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create, 0, NULL);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+
+
+
+______________________________________________________________________________
+Throwable.printStackTrace() patch
+
+Index: Class.h
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
+retrieving revision 1.43
+diff -u -r1.43 Class.h
+--- Class.h 21 Dec 2001 19:47:50 -0000 1.43
++++ Class.h 24 Apr 2002 03:06:14 -0000
+@@ -308,6 +308,7 @@
+ friend void _Jv_LayoutVTableMethods (jclass klass);
+ friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *);
+ friend void _Jv_MakeVTable (jclass);
++ friend JArray<java::lang::reflect::Method*>* _Jv_GetAllMethods();
+
+ // Return array class corresponding to element type KLASS, creating it if
+ // necessary.
+Index: ClassLoader.java
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/lang/ClassLoader.java,v
+retrieving revision 1.16
+diff -u -r1.16 ClassLoader.java
+--- ClassLoader.java 7 Dec 2001 23:34:12 -0000 1.16
++++ ClassLoader.java 24 Apr 2002 03:06:14 -0000
+@@ -577,4 +577,8 @@
+ // Default to returning null. Derived classes implement this.
+ return null;
+ }
++
++ static native java.lang.reflect.Method[] getAllMethods();
++ static native long[] getAllMethodAddrs();
++
+ }
+Index: Throwable.java
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/lang/Throwable.java,v
+retrieving revision 1.10
+diff -u -r1.10 Throwable.java
+--- Throwable.java 24 Feb 2001 03:52:49 -0000 1.10
++++ Throwable.java 24 Apr 2002 03:06:14 -0000
+@@ -123,21 +123,64 @@
+ printStackTrace (writer);
+ }
+
++ private native static long longFromStackTraceBytes(byte[] stackTrace, int i);
++
+ public void printStackTrace (PrintWriter wr)
+ {
+- try
+- {
+- CPlusPlusDemangler cPlusPlusFilter = new CPlusPlusDemangler (wr);
+- PrintWriter writer = new PrintWriter (cPlusPlusFilter);
+- printRawStackTrace (writer);
+- writer.close ();
+- if (cPlusPlusFilter.written == 0) // The demangler has failed...
+- printRawStackTrace (wr);
++ try
++ {
++ CPlusPlusDemangler cPlusPlusFilter = new CPlusPlusDemangler (wr);
++ PrintWriter writer = new PrintWriter (cPlusPlusFilter);
++ printRawStackTrace (writer);
++ writer.close ();
++ if (cPlusPlusFilter.written > 0) return;
++ }
++ catch (Exception e1)
++ {
++ }
++
++ wr.println(toString());
++ if (stackTrace == null) {
++ wr.flush();
++ return;
+ }
+- catch (Exception e1)
+- {
+- printRawStackTrace (wr);
++
++ long[] allAddrs = ClassLoader.getAllMethodAddrs();
++ java.lang.reflect.Method[] meths = ClassLoader.getAllMethods();
++
++ // FIXME: assumes little endian
++ for(int i=0; i<stackTrace.length; i++) {
++ long addr = longFromStackTraceBytes(stackTrace, i);
++ if (addr == 0) break;
++
++ int whichMethod = -1;
++ for(int j=0; j<allAddrs.length; j++) {
++ if (allAddrs[j] <= addr &&
++ (whichMethod == -1 || allAddrs[whichMethod] < allAddrs[j])) {
++ whichMethod = j;
++ }
++ }
++
++ if (whichMethod == -1) {
++ wr.println("[" + Long.toString(addr, 16) + "] " + "??");
++ continue;
++ }
++
++ if (meths[whichMethod].getDeclaringClass().getName().equals("gnu.gcj.runtime.FirstThread") &&
++ meths[whichMethod].getName().equals("call_main"))
++ break;
++
++ wr.println(" [" + Long.toString(addr, 16) + "] " +
++ meths[whichMethod].getDeclaringClass().getName() + "." +
++ meths[whichMethod].getName() + "() " +
++ "+" + (addr - allAddrs[whichMethod])
++ );
++
++ if (java.lang.Thread.class.isAssignableFrom(meths[whichMethod].getDeclaringClass()) &&
++ meths[whichMethod].getName().equals("run"))
++ break;
+ }
++ wr.flush();
+ }
+
+ public Throwable ()
+Index: natClassLoader.cc
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
+retrieving revision 1.47.8.1
+diff -u -r1.47.8.1 natClassLoader.cc
+--- natClassLoader.cc 2 Apr 2002 22:19:55 -0000 1.47.8.1
++++ natClassLoader.cc 24 Apr 2002 03:06:14 -0000
+@@ -40,6 +40,10 @@
+ #include <java/lang/StringBuffer.h>
+ #include <java/io/Serializable.h>
+ #include <java/lang/Cloneable.h>
++#include <java/lang/reflect/Method.h>
++
++#include<java/lang/reflect/Constructor.h>
++#include<gcj/method.h>
+
+ // FIXME: remove these.
+ #define CloneableClass java::lang::Cloneable::class$
+@@ -347,6 +351,50 @@
+ static jclass loaded_classes[HASH_LEN];
+
+ // This is the root of a linked list of classes
++
++JArray<java::lang::reflect::Method*>*
++java::lang::ClassLoader::getAllMethods()
++{
++ return _Jv_GetAllMethods();
++}
++
++JArray<jlong>*
++java::lang::ClassLoader::getAllMethodAddrs()
++{
++ JArray<java::lang::reflect::Method*>* arr = _Jv_GetAllMethods();
++ java::lang::reflect::Method** el = (java::lang::reflect::Method**)elements(arr);
++ JArray<jlong>* ret = JvNewLongArray(arr->length);
++ jlong* retel = (jlong*)elements(ret);
++ for(int i=0; i<arr->length; i++)
++ retel[i] = (jlong)((unsigned int)(_Jv_FromReflectedMethod (el[i])->ncode));
++ return ret;
++}
++
++JArray<java::lang::reflect::Method*>*
++_Jv_GetAllMethods()
++{
++ int numMethods = 0;
++
++ for(int i=0; i<HASH_LEN; i++)
++ for(jclass c = loaded_classes[i]; c; c = c->next)
++ numMethods += c->getDeclaredMethods()->length;
++
++ JArray<java::lang::reflect::Method*>* ret =
++ (JArray<java::lang::reflect::Method*>*)
++ JvNewObjectArray(numMethods, &java::lang::reflect::Method::class$, NULL);
++
++ java::lang::reflect::Method** el = (java::lang::reflect::Method**)elements(ret);
++
++ for(int i=0; i<HASH_LEN; i++)
++ for(jclass c = loaded_classes[i]; c; c = c->next) {
++ JArray<java::lang::reflect::Method*>* methods = c->getDeclaredMethods();
++ jint len = methods->length;
++ java::lang::reflect::Method** meths = (java::lang::reflect::Method**)elements(methods);
++ for(int j=0; j<len; j++) el[--numMethods] = meths[j];
++ }
++
++ return ret;
++}
+
+ \f
+
+Index: natThrowable.cc
+===================================================================
+RCS file: /cvs/gcc/gcc/libjava/java/lang/natThrowable.cc,v
+retrieving revision 1.11
+diff -u -r1.11 natThrowable.cc
+--- natThrowable.cc 7 Feb 2002 19:26:06 -0000 1.11
++++ natThrowable.cc 24 Apr 2002 03:06:14 -0000
+@@ -32,6 +32,7 @@
+ #include <stdio.h>
+
+ #include <unistd.h>
++#include <platform.h>
+
+ #ifdef HAVE_EXECINFO_H
+ #include <execinfo.h>
+@@ -102,3 +103,18 @@
+ #endif /* HAVE_BACKTRACE */
+ wr->flush ();
+ }
++
++// Returns the i^th call address in the stackTrace member, or 0 if i
++// is beyond the end of the trace. This has to be done in C++ because
++// the addresses in stackTrace are the same width as the platform's
++// pointers (which is unknown to Java code), and stackTrace is a
++// byte[] using the platform's endianness (which is unknown to Java
++// code).
++jlong
++java::lang::Throwable::longFromStackTraceBytes(jbyteArray stackArr, jint i)
++{
++ if (i * sizeof(void*) > stackArr->length) return 0;
++ unsigned int* stack = (unsigned int*)elements(stackArr);
++ return (jlong)stack[i];
++}
++
+
+
+
+
+