This was checked in to gcc.gnu.org on August 28.

Index: libjava/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* Makefile.in: Rebuilt.
	* Makefile.am (ordinary_java_source_files): Added new files.
	* java/lang/Class.h (_Jv_sharedlib_register_hook): Declare as
	friend.
	* java/net/URLClassLoader.java (findClass): Don't use
	findURLResource.  Use loader's getClass method.
	(URLLoader.getClass): New method.
	(addURL): Handle `solib' URLs.
	(SoURLLoader): New class.
	(SoResource): Likewise.
	* gnu/gcj/protocol/solib/Connection.java: New file.
	* gnu/gcj/protocol/solib/Handler.java: New file.
	* include/jvm.h (struct _Jv_core_chain): Moved from natCore.cc.
	(_Jv_RegisterCoreHook): Declare.
	(_Jv_FindCore): Declare.
	* gnu/gcj/runtime/SharedLibHelper.java: New file.
	* gnu/gcj/runtime/natSharedLibLoader.cc (CoreHookFunc): New
	typedef.
	(core_hook): New function.
	(struct SharedLibDummy) [saved_core]: New field.
	(init): Set _Jv_RegisterCoreHook.  Throw exception on failure.
	(register_hook): Set protection domain and class loader on new
	class.
	(finalize): Free core chain.
	* gnu/gcj/Core.java (Core): New constructor.
	* gnu/gcj/runtime/SharedLibLoader.java: Rewrote to use
	SharedLibHelper.
	* gnu/gcj/natCore.cc (_Jv_RegisterResource): Indentation fixlet.
	(_Jv_create_core): New function.
	(create): Use it.
	(default_register_resource): New function.
	(_Jv_RegisterCoreHook): New global.
	(_Jv_RegisterResource): Use it.
	(core_chain_struct): Removed.
	(_Jv_FindCore): New function.
	(_Jv_FreeCoreChain): New function.

Index: libjava/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.274
diff -u -r1.274 Makefile.am
--- libjava/Makefile.am 2 Feb 2003 23:06:39 -0000 1.274
+++ libjava/Makefile.am 6 Feb 2003 19:04:36 -0000
@@ -1880,12 +1880,15 @@
 gnu/gcj/protocol/http/Handler.java \
 gnu/gcj/protocol/jar/Connection.java \
 gnu/gcj/protocol/jar/Handler.java \
+gnu/gcj/protocol/solib/Connection.java \
+gnu/gcj/protocol/solib/Handler.java \
 gnu/gcj/runtime/FileDeleter.java \
 gnu/gcj/runtime/FinalizerThread.java \
 gnu/gcj/runtime/FirstThread.java \
 gnu/gcj/runtime/JNIWeakRef.java \
 gnu/gcj/runtime/MethodRef.java \
 gnu/gcj/runtime/NameFinder.java \
+gnu/gcj/runtime/SharedLibHelper.java \
 gnu/gcj/runtime/SharedLibLoader.java \
 gnu/gcj/runtime/StackTrace.java \
 gnu/gcj/runtime/StringBuffer.java \
Index: libjava/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.in,v
retrieving revision 1.294
diff -u -r1.294 Makefile.in
--- libjava/Makefile.in 2 Feb 2003 23:06:39 -0000 1.294
+++ libjava/Makefile.in 6 Feb 2003 19:04:39 -0000
@@ -1640,12 +1640,15 @@
 gnu/gcj/protocol/http/Handler.java \
 gnu/gcj/protocol/jar/Connection.java \
 gnu/gcj/protocol/jar/Handler.java \
+gnu/gcj/protocol/solib/Connection.java \
+gnu/gcj/protocol/solib/Handler.java \
 gnu/gcj/runtime/FileDeleter.java \
 gnu/gcj/runtime/FinalizerThread.java \
 gnu/gcj/runtime/FirstThread.java \
 gnu/gcj/runtime/JNIWeakRef.java \
 gnu/gcj/runtime/MethodRef.java \
 gnu/gcj/runtime/NameFinder.java \
+gnu/gcj/runtime/SharedLibHelper.java \
 gnu/gcj/runtime/SharedLibLoader.java \
 gnu/gcj/runtime/StackTrace.java \
 gnu/gcj/runtime/StringBuffer.java \
@@ -2583,10 +2586,13 @@
 .deps/gnu/gcj/protocol/http/Handler.P \
 .deps/gnu/gcj/protocol/jar/Connection.P \
 .deps/gnu/gcj/protocol/jar/Handler.P \
+.deps/gnu/gcj/protocol/solib/Connection.P \
+.deps/gnu/gcj/protocol/solib/Handler.P \
 .deps/gnu/gcj/runtime/FileDeleter.P \
 .deps/gnu/gcj/runtime/FinalizerThread.P \
 .deps/gnu/gcj/runtime/FirstThread.P .deps/gnu/gcj/runtime/JNIWeakRef.P \
 .deps/gnu/gcj/runtime/MethodRef.P .deps/gnu/gcj/runtime/NameFinder.P \
+.deps/gnu/gcj/runtime/SharedLibHelper.P \
 .deps/gnu/gcj/runtime/SharedLibLoader.P \
 .deps/gnu/gcj/runtime/StackTrace.P .deps/gnu/gcj/runtime/StringBuffer.P \
 .deps/gnu/gcj/runtime/VMClassLoader.P \
Index: libjava/gnu/gcj/Core.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/Core.java,v
retrieving revision 1.1
diff -u -r1.1 Core.java
--- libjava/gnu/gcj/Core.java 6 Sep 2001 22:32:53 -0000 1.1
+++ libjava/gnu/gcj/Core.java 6 Feb 2003 19:04:41 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001  Free Software Foundation
+/* Copyright (C) 2001, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -14,5 +14,8 @@
 
   public RawData ptr;
   public int length;
-}
 
+  Core ()
+  {
+  }
+}
Index: libjava/gnu/gcj/natCore.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/natCore.cc,v
retrieving revision 1.2
diff -u -r1.2 natCore.cc
--- libjava/gnu/gcj/natCore.cc 24 Apr 2002 23:05:17 -0000 1.2
+++ libjava/gnu/gcj/natCore.cc 6 Feb 2003 19:04:42 -0000
@@ -1,6 +1,6 @@
 // natCore -- C++ side of Core
 
-/* Copyright (C) 2001, 2002  Free Software Foundation
+/* Copyright (C) 2001, 2002, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -21,40 +21,49 @@
 #include <java/io/IOException.h>
 #include <gnu/gcj/Core.h>
 
-typedef struct core_chain_struct
+// List of global core values.
+static _Jv_core_chain *root;
+
+static void
+default_register_resource (_Jv_core_chain *node)
 {
-  int name_length;
-  const char *name;
-  int data_length;
-  const void *data;
-  
-  struct core_chain_struct *next;
-} core_chain;
-
-static core_chain *root;
-
-void _Jv_RegisterResource (void *vptr)
-{
-  char *rptr = (char *)vptr;
-
-  // These are permanent data structures for now.  This routine is
-  // called from a static constructor, so we shouldn't depend on too
-  // much existing infrastructure.
-  core_chain *cc = (core_chain *) _Jv_Malloc (sizeof (core_chain));
+  node->next = root;
+  root = node;
+}
+
+// This is set only when a lock is held on java.lang.Class.
+// This function is called to handle a new core node.
+void (*_Jv_RegisterCoreHook) (_Jv_core_chain *) = default_register_resource;
+
+void
+_Jv_RegisterResource (void *vptr)
+{
+  char *rptr = (char *) vptr;
+
+  _Jv_core_chain *cc = (_Jv_core_chain *) _Jv_Malloc (sizeof (_Jv_core_chain));
 
   cc->name_length = ((int *)rptr)[0];
   cc->data_length = ((int *)rptr)[1];
-  cc->name = rptr + 2*sizeof(int);
+  cc->name = rptr + 2 * sizeof (int);
   cc->data = cc->name + cc->name_length;
+  cc->next = NULL;
 
-  // Add this new item to the chain...
-  core_chain *old_root = root;
-  cc->next = old_root;
-  root = cc;
+  (*_Jv_RegisterCoreHook) (cc);
 }
 
-gnu::gcj::Core *
-gnu::gcj::Core::create (jstring name)
+void
+_Jv_FreeCoreChain (_Jv_core_chain *chain)
+{
+  while (chain != NULL)
+    {
+      _Jv_core_chain *next = chain->next;
+      _Jv_Free (chain);
+      chain = next;
+    }
+}
+
+_Jv_core_chain *
+_Jv_FindCore (_Jv_core_chain *node, jstring name)
 {
   char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (name) + 1);
   jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
@@ -68,23 +77,38 @@
       --total;
     }
 
-  core_chain *node = root;
-
   while (node)
     {
       if (total == node->name_length
 	  && strncmp (buf, node->name, total) == 0)
-	{
-	  gnu::gcj::Core *core = 
-	    (gnu::gcj::Core *) _Jv_AllocObject(&gnu::gcj::Core::class$,
-					       sizeof (gnu::gcj::Core));
-	  core->ptr = (gnu::gcj::RawData *) node->data;
-	  core->length = node->data_length;
-	  return core;
-	}
-      else
-	node = node->next;
+	return node;
+      node = node->next;
     }
 
-  throw new java::io::IOException (JvNewStringLatin1 ("can't open core"));
+  return NULL;
+}
+
+gnu::gcj::Core *
+_Jv_create_core (_Jv_core_chain *node, jstring name)
+{
+  node = _Jv_FindCore (node, name);
+
+  gnu::gcj::Core *core = NULL;
+  if (node)
+    {
+      core = (gnu::gcj::Core *) _Jv_AllocObject(&gnu::gcj::Core::class$,
+						sizeof (gnu::gcj::Core));
+      core->ptr = (gnu::gcj::RawData *) node->data;
+      core->length = node->data_length;
+    }
+  return core;
+}
+
+gnu::gcj::Core *
+gnu::gcj::Core::create (jstring name)
+{
+  gnu::gcj::Core *core = _Jv_create_core (root, name);
+  if (core == NULL)
+    throw new java::io::IOException (JvNewStringLatin1 ("can't open core"));
+  return core;
 }
Index: libjava/gnu/gcj/protocol/core/Connection.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/protocol/core/Connection.java,v
retrieving revision 1.2
diff -u -r1.2 Connection.java
--- libjava/gnu/gcj/protocol/core/Connection.java 23 Aug 2002 04:54:02 -0000 1.2
+++ libjava/gnu/gcj/protocol/core/Connection.java 6 Feb 2003 19:04:42 -0000
@@ -1,6 +1,6 @@
 // Connection.java - Implementation of URLConnection for core protocol.
 
-/* Copyright (C) 2001  Free Software Foundation
+/* Copyright (C) 2001, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -55,7 +55,7 @@
 
     if (! doInput)
       throw new ProtocolException("Can't open InputStream if doInput is false");
-    return new BufferedInputStream(new CoreInputStream (core));
+    return new CoreInputStream (core);
   }
 
   // Override default method in URLConnection.
Index: libjava/gnu/gcj/runtime/SharedLibHelper.java
===================================================================
RCS file: libjava/gnu/gcj/runtime/SharedLibHelper.java
diff -N libjava/gnu/gcj/runtime/SharedLibHelper.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libjava/gnu/gcj/runtime/SharedLibHelper.java 6 Feb 2003 19:04:42 -0000
@@ -0,0 +1,144 @@
+/* Copyright (C) 2001, 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.runtime;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.security.*;
+import gnu.gcj.Core;
+
+public class SharedLibHelper
+{
+  /** Load a shared library, and associate a ClassLoader with it.
+   * @param libname named of shared library (passed to dlopen)
+   * @param parent the parent ClassLoader
+   * @parem flags passed to dlopen
+   */
+  SharedLibHelper(String libname, ClassLoader parent, CodeSource source,
+		  int flags)
+  {
+    // FIXME: ask security manager first.
+    loader = parent;
+    baseName = libname;
+    domain = new ProtectionDomain(source,
+				  Policy.getPolicy().getPermissions(source));
+    this.flags = flags;
+  }
+
+  public static SharedLibHelper findHelper (String libname)
+  {
+    synchronized (map)
+      {
+	WeakReference ref = (WeakReference) map.get(libname);
+	if (ref != null)
+	  return (SharedLibHelper) ref.get();
+	return null;
+      }
+  }
+
+  public static SharedLibHelper findHelper (ClassLoader loader, String libname,
+					    CodeSource source)
+  {
+    synchronized (map)
+      {
+	SharedLibHelper result;
+	WeakReference ref = (WeakReference) map.get(libname);
+	if (ref != null)
+	  {
+	    result = (SharedLibHelper) ref.get();
+	    if (result != null)
+	      {
+		if (result.loader != loader)
+		  // FIXME
+		  throw new UnknownError();
+		return result;
+	      }
+	  }
+
+	result = new SharedLibHelper(libname, loader, source, 0);
+	map.put(libname, new WeakReference(result));
+	return result;
+      }
+  }
+
+  public native void finalize ();
+
+  public Class findClass(String name)
+  {
+    ensureInit();
+    return (Class) classMap.get(name);
+  }
+
+  public URL findResource (String name)
+  {
+    ensureInit();
+    if (! hasResource(name))
+      return null;
+    try
+      {
+	return new URL("solib", "", -1, baseName + "!/" + name);
+      }
+    catch (MalformedURLException _)
+      {
+      }
+    return null;
+  }
+
+  public native Core findCore (String name);
+
+  void ensureInit()
+  {
+    synchronized (classMap)
+      {
+	if (initialized)
+	  return;
+	init();
+	initialized = true;
+      }
+  }
+
+  native boolean hasResource(String name);
+  native void init();
+
+  /** Called during dlopen's processing of the init section. */
+  void registerClass(String name, Class cls)
+  {
+    classMap.put(name, cls);
+  }
+
+  /** The handle returned by dlopen. */
+  gnu.gcj.RawData handler;
+
+  /** Holds a _Jv_core_chain for the loader.  */
+  gnu.gcj.RawData core_chain;
+
+  /** Map classnames to Classes. */
+  HashMap classMap = new HashMap(20);
+
+  /** Class loader we're helping.  */
+  ClassLoader loader;
+
+  /** Name of base file.  */
+  String baseName;
+
+  /** Protection domain for loaded classes.  */
+  ProtectionDomain domain;
+
+  /** Flags to pass to dlopen.  FIXME: platform dependent.
+      0 is always "sensible" (defined by us).  */
+  int flags;
+
+  /** True if we've been initialized.  */
+  boolean initialized = false;
+
+  /** Map shared library names to a helper object.  This uses weak
+      references in the values so we don't prevent collection.  */
+  static HashMap map = new HashMap ();
+}
Index: libjava/gnu/gcj/runtime/SharedLibLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/SharedLibLoader.java,v
retrieving revision 1.1
diff -u -r1.1 SharedLibLoader.java
--- libjava/gnu/gcj/runtime/SharedLibLoader.java 29 Sep 2001 19:16:26 -0000 1.1
+++ libjava/gnu/gcj/runtime/SharedLibLoader.java 6 Feb 2003 19:04:42 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001  Free Software Foundation
+/* Copyright (C) 2001, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -7,7 +7,12 @@
 details.  */
 
 package gnu.gcj.runtime;
-import java.util.Hashtable;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.util.Enumeration;
+import java.util.Vector;
 
 /**
  * A ClassLoader backed by a gcj-compiled shared library.
@@ -16,14 +21,6 @@
 
 public class SharedLibLoader extends ClassLoader
 {
-  public native void finalize ();
-
-  /** Called during dlopen's processing of the init section. */
-  void registerClass(String name, Class cls)
-  {
-    classMap.put(name, cls);
-  }
-
   /** Load a shared library, and associate a ClassLoader with it.
    * @param libname named of shared library (passed to dlopen)
    * @param parent the parent ClassLoader
@@ -32,44 +29,51 @@
   public SharedLibLoader(String libname, ClassLoader parent, int flags)
   {
     super(parent);
-    init(libname, flags);
+    URL url;
+    try
+      {
+	url = new URL("file", "", libname);
+      }
+    catch (MalformedURLException _)
+      {
+	url = null;
+      }
+    helper = SharedLibHelper.findHelper(this, libname,
+					new CodeSource(url, null));
   }
 
-
   /** Load a shared library, and asociate a ClassLoader with it.
    * @param libname named of shared library (passed to dlopen)
    */
   public SharedLibLoader(String libname)
   {
-    super(getSystemClassLoader());
-    init(libname, 0);
+    this(libname, getSystemClassLoader(), 0);
   }
 
-  void init(String libname, int flags)
+  public Class findClass(String name)
+    throws ClassNotFoundException
   {
-    init(libname.getBytes(), flags);
+    Class cls = helper.findClass(name);
+    if (cls == null)
+      throw new ClassNotFoundException(name);
+    return cls;
   }
 
-  native void init(byte[] libname, int flags);
-
-  public Class loadClass(String name)
-    throws ClassNotFoundException
+  public URL findResource (String name)
   {
-    return super.loadClass(name);
+    return helper.findResource(name);
   }
 
-  public Class findClass(String name)
-    throws ClassNotFoundException
+  public Enumeration findResources (String name) throws IOException
   {
-    Object cls = classMap.get(name);
-    if (cls == null)
-      throw new ClassNotFoundException(name);
-    return (Class) cls;
+    URL url = findResource(name);
+    if (url == null)
+      return null;
+    Vector v = new Vector(1);
+    v.add(url);
+    return v.elements();
   }
 
-  /** The handle returned by dlopen. */
-  gnu.gcj.RawData handler;
-
-  /** Map classnames to Classes. */
-  Hashtable classMap = new Hashtable(20);
+  /** The helper that does the work for us.  */
+  SharedLibHelper helper;
 }
Index: libjava/gnu/gcj/runtime/natSharedLibLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/natSharedLibLoader.cc,v
retrieving revision 1.2
diff -u -r1.2 natSharedLibLoader.cc
--- libjava/gnu/gcj/runtime/natSharedLibLoader.cc 24 Oct 2001 07:00:19 -0000 1.2
+++ libjava/gnu/gcj/runtime/natSharedLibLoader.cc 6 Feb 2003 19:04:42 -0000
@@ -1,6 +1,6 @@
-// natSharedLibLoader.cc - Implementation of FirstThread native methods.
+// natSharedLibLoader.cc - Implementation of SharedLibHelper native methods.
 
-/* Copyright (C) 2001  Free Software Foundation
+/* Copyright (C) 2001, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -11,65 +11,113 @@
 #include <config.h>
 
 #include <gcj/cni.h>
-#include <gnu/gcj/runtime/SharedLibLoader.h>
+#include <jvm.h>
+#include <gnu/gcj/runtime/SharedLibHelper.h>
 #include <java/io/IOException.h>
 #include <java/lang/UnsupportedOperationException.h>
+#include <java/lang/UnknownError.h>
 
 #ifdef HAVE_DLOPEN
 #include <dlfcn.h>
 
 /* Only used during dlopen, while having a lock on Class.class. */
-static gnu::gcj::runtime::SharedLibLoader* curLoader;
+static java::lang::ClassLoader *curLoader;
+static gnu::gcj::runtime::SharedLibHelper *curHelper;
 
 typedef void (*ClassHookFunc) (jclass);
+typedef void (*CoreHookFunc) (_Jv_core_chain *);
+
+void
+_Jv_sharedlib_register_hook (jclass cls)
+{
+  curHelper->registerClass(cls->getName(), cls);
+  cls->protectionDomain = curHelper->domain;
+  cls->loader = curLoader;
+}
 
 static void
-::register_hook(jclass cls)
+core_hook (_Jv_core_chain *chain)
 {
-  curLoader->registerClass(cls->getName(), cls);
+  chain->next = (_Jv_core_chain *) curHelper->core_chain;
+  curHelper->core_chain = (gnu::gcj::RawData *) chain;
 }
 
 struct SharedLibDummy
 {
   ClassHookFunc saved;
+  CoreHookFunc saved_core;
   SharedLibDummy()
   {
     saved = _Jv_RegisterClassHook;
+    saved_core = _Jv_RegisterCoreHook;
   }
   ~SharedLibDummy()
   {
     _Jv_RegisterClassHook = saved;
+    _Jv_RegisterCoreHook = saved_core;
     curLoader = NULL;
   }
 };
 #endif
 
 void
-gnu::gcj::runtime::SharedLibLoader::init(jbyteArray libname, jint flags)
+gnu::gcj::runtime::SharedLibHelper::init(void)
 {
 #ifdef HAVE_DLOPEN
-  char *lname = (char*) elements(libname);
+  char *lname = (char *) __builtin_alloca (JvGetStringUTFLength (baseName)
+					   + 1);
+  jsize total = JvGetStringUTFRegion (baseName, 0, baseName->length(), lname);
+  lname[total] = '\0';
+
   if (flags==0)
-    flags = RTLD_LAZY;
+    flags = RTLD_GLOBAL | RTLD_LAZY;
   JvSynchronize dummy1(&java::lang::Class::class$);
   SharedLibDummy dummy2;
-  curLoader = this;
-  _Jv_RegisterClassHook = ::register_hook;
+  curLoader = loader;
+  curHelper = this;
+  _Jv_RegisterClassHook = _Jv_sharedlib_register_hook;
+  _Jv_RegisterCoreHook = core_hook;
   void *h = dlopen(lname, flags);
   if (h == NULL)
     {
       const char *msg = dlerror();
+      throw new java::lang::UnknownError(JvNewStringLatin1(msg));
     }
   handler = (gnu::gcj::RawData*) h;
 #else
-  const char *msg = "ShareedLibLoader is not supported on this platform";
+  const char *msg
+    = "shared library class loading is not supported on this platform";
   throw new java::lang::UnsupportedOperationException(JvNewStringLatin1(msg));
 #endif
 }
 
+jboolean
+gnu::gcj::runtime::SharedLibHelper::hasResource (jstring name)
+{
+#ifdef HAVE_DLOPEN
+  _Jv_core_chain *node = _Jv_FindCore ((_Jv_core_chain *) core_chain, name);
+  return node != NULL;
+#else
+  return false;
+#endif
+}
+
+gnu::gcj::Core *
+gnu::gcj::runtime::SharedLibHelper::findCore (jstring name)
+{
+#ifdef HAVE_DLOPEN
+  extern gnu::gcj::Core *_Jv_create_core (_Jv_core_chain *node, jstring name);
+  ensureInit();
+  return _Jv_create_core ((_Jv_core_chain *) core_chain, name);
+#else
+  return NULL;
+#endif
+}
+
 void
-gnu::gcj::runtime::SharedLibLoader::finalize()
+gnu::gcj::runtime::SharedLibHelper::finalize()
 {
+  _Jv_FreeCoreChain ((_Jv_core_chain *) core_chain);
 #ifdef HAVE_DLOPEN
   dlclose (handler);
 #endif
Index: libjava/include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.53
diff -u -r1.53 jvm.h
--- libjava/include/jvm.h 28 Dec 2002 06:38:52 -0000 1.53
+++ libjava/include/jvm.h 6 Feb 2003 19:04:43 -0000
@@ -1,6 +1,6 @@
 // jvm.h - Header file for private implementation information. -*- c++ -*-
 
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -376,6 +376,22 @@
 bool _Jv_VerifyClassName (_Jv_Utf8Const *name);
 bool _Jv_VerifyIdentifier (_Jv_Utf8Const *);
 bool _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2);
+
+struct _Jv_core_chain
+{
+  int name_length;
+  const char *name;
+  int data_length;
+  const void *data;
+
+  struct _Jv_core_chain *next;
+};
+
+// This is called when new core data is loaded.
+extern void (*_Jv_RegisterCoreHook) (_Jv_core_chain *);
+
+_Jv_core_chain *_Jv_FindCore (_Jv_core_chain *node, jstring name);
+void _Jv_FreeCoreChain (_Jv_core_chain *chain);
 
 #ifdef ENABLE_JVMPI
 
Index: libjava/java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.55
diff -u -r1.55 Class.h
--- libjava/java/lang/Class.h 20 Jan 2003 06:46:28 -0000 1.55
+++ libjava/java/lang/Class.h 6 Feb 2003 19:04:44 -0000
@@ -366,6 +366,8 @@
   friend class gnu::gcj::runtime::StackTrace;
   friend class java::io::VMObjectStreamClass;
 
+  friend void _Jv_sharedlib_register_hook (jclass klass);
+
   // Chain for class pool.
   jclass next;
   // Name of class.
Index: libjava/java/net/URLClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/URLClassLoader.java,v
retrieving revision 1.13
diff -u -r1.13 URLClassLoader.java
--- libjava/java/net/URLClassLoader.java 2 Jan 2003 09:34:34 -0000 1.13
+++ libjava/java/net/URLClassLoader.java 6 Feb 2003 19:04:45 -0000
@@ -1,5 +1,5 @@
 /* URLClassLoader.java --  ClassLoader that loads classes from one or more URLs
-   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -61,6 +61,7 @@
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 import java.util.zip.ZipException;
+import gnu.gcj.runtime.SharedLibHelper;
 
 /**
  * A secure class loader that can load classes and resources from
@@ -196,6 +197,17 @@
     }
 
     /**
+     * Returns a <code>Class</code> loaded by this
+     * <code>URLLoader</code>, or <code>null</code> when this loader
+     * either can't load the class or doesn't know how to load classes
+     * at all.
+     */
+    Class getClass(String className)
+    {
+      return null;
+    }
+
+    /**
      * Returns a <code>Resource</code> loaded by this
      * <code>URLLoader</code>, or <code>null</code> when no
      * <code>Resource</code> with the given name exists.
@@ -284,7 +296,7 @@
     {
       super(classloader, baseURL);
 
-      // cache url prefix for all resources in this jar url
+      // Cache url prefix for all resources in this jar url.
       String external = baseURL.toExternalForm();
       StringBuffer sb = new StringBuffer(external.length() + 6);
       sb.append("jar:");
@@ -447,12 +459,12 @@
     {
       return stream;
     }
-                        
+
     public int getLength()
     {
       return length;
     }
-                
+
     public URL getURL()
     {
       return url;
@@ -460,6 +472,63 @@
   }
 
   /**
+   * A <code>SoURLLoader</code> is a type of <code>URLLoader</code>
+   * that loads classes and resources from a shared library.
+   */
+  final static class SoURLLoader extends URLLoader
+  {
+    SharedLibHelper helper;
+
+    SoURLLoader(URLClassLoader classloader, URL url)
+    {
+      super(classloader, url);
+      helper = SharedLibHelper.findHelper(classloader, url.getFile(),
+					  noCertCodeSource);
+    }
+
+    Class getClass(String className)
+    {
+      return helper.findClass(className);
+    }
+
+    Resource getResource(String name)
+    {
+      URL url = helper.findResource(name);
+      if (url == null)
+	return null;
+      return new SoResource(this, name, url);
+    }
+  }
+
+  final static class SoResource extends Resource
+  {
+    SoResource(SoURLLoader loader, String name, URL url)
+    {
+      super(loader, name);
+      this.url = url;
+    }
+
+    InputStream getInputStream() throws IOException
+    {
+      URLConnection conn = url.openConnection();
+      return conn.getInputStream();
+    }
+
+    public int getLength()
+    {
+      // FIXME we could find this by asking the core object.
+      return -1;
+    }
+
+    public URL getURL ()
+    {
+      return url;
+    }
+
+    final URL url;
+  }
+
+  /**
    * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
    * only loading from file url.
    */
@@ -643,7 +712,7 @@
     //   for cache initial size
     synchronized(factoryCache)
       {
-	if(factory != null && factoryCache.get(factory) == null)
+	if (factory != null && factoryCache.get(factory) == null)
 	  factoryCache.put(factory, new HashMap(5));
       }
   }
@@ -661,21 +730,24 @@
 	if (newUrl == null)
 	  return; // Silently ignore...
         
-	// check global cache to see if there're already url loader
-	// for this url
+	// Check global cache to see if there're already url loader
+	// for this url.
 	URLLoader loader = (URLLoader)urlloaders.get(newUrl);
 	if (loader == null)
 	  {
 	    String file = newUrl.getFile();
+	    String protocol = newUrl.getProtocol();
 	    // Check that it is not a directory
-	    if (! (file.endsWith("/") || file.endsWith(File.separator)))
+	    if ("solib".equals(protocol))
+	      loader = new SoURLLoader(this, newUrl);
+	    else if (! (file.endsWith("/") || file.endsWith(File.separator)))
 	      loader = new JarURLLoader(this, newUrl);
-	    else if ("file".equals(newUrl.getProtocol()))
+	    else if ("file".equals(protocol))
 	      loader = new FileURLLoader(this, newUrl);
 	    else
 	      loader = new RemoteURLLoader(this, newUrl);
 
-	    // cache it
+	    // Cache it.
 	    urlloaders.put(newUrl, loader);
 	  }
 
@@ -691,15 +763,15 @@
   private void addURLs(URL[] newUrls)
   {
     for (int i = 0; i < newUrls.length; i++)
-    {
-      addURL(newUrls[i]);
-    }
+      {
+	addURL(newUrls[i]);
+      }
   }
 
   /** 
    * Defines a Package based on the given name and the supplied manifest
    * information. The manifest indicates the tile, version and
-   * vendor information of the specification and implementation and wheter the
+   * vendor information of the specification and implementation and whether the
    * package is sealed. If the Manifest indicates that the package is sealed
    * then the Package will be sealed with respect to the supplied URL.
    *
@@ -758,7 +830,20 @@
   {
     // Just try to find the resource by the (almost) same name
     String resourceName = className.replace('.', '/') + ".class";
-    Resource resource = findURLResource(resourceName);
+    int max = urls.size();
+    Resource resource = null;
+    for (int i = 0; i < max && resource == null; i++)
+      {
+	URLLoader loader = (URLLoader)urlinfos.elementAt(i);
+	if (loader == null)
+	  continue;
+
+	Class k = loader.getClass(className);
+	if (k != null)
+	  return k;
+
+	resource = loader.getResource(resourceName);
+      }
     if (resource == null)
       throw new ClassNotFoundException(className + " not found in " + urls);
 
@@ -901,12 +986,12 @@
     URLStreamHandler handler;
     synchronized (factoryCache)
       {
-	// check if there're handler for the same protocol in cache
+	// Check if there're handler for the same protocol in cache.
 	HashMap cache = (HashMap)factoryCache.get(factory);
 	handler = (URLStreamHandler)cache.get(protocol);
 	if(handler == null)
 	  {
-	    // add it to cache
+	    // Add it to cache.
 	    handler = factory.createURLStreamHandler(protocol);
 	    cache.put(protocol, handler);
 	  }
@@ -965,23 +1050,23 @@
     // First get the permissions that would normally be granted
     PermissionCollection permissions = super.getPermissions(source);
         
-    // Now add the any extra permissions depending on the URL location
+    // Now add any extra permissions depending on the URL location.
     URL url = source.getLocation();
     String protocol = url.getProtocol();
     if (protocol.equals("file"))
       {
 	String file = url.getFile();
-	// If the file end in / it must be an directory
+	// If the file end in / it must be an directory.
 	if (file.endsWith("/") || file.endsWith(File.separator))
 	  {
 	    // Grant permission to read everything in that directory and
-	    // all subdirectories
+	    // all subdirectories.
 	    permissions.add(new FilePermission(file + "-", "read"));
 	  }
 	else
 	  {
-	    // It is a 'normal' file
-	    // Grant permission to access that file
+	    // It is a 'normal' file.
+	    // Grant permission to access that file.
 	    permissions.add(new FilePermission(file, "read"));
 	  }
       }
