1 /* Copyright (C) 2001, 2003  Free Software Foundation
2 
3    This file is part of libgcj.
4 
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8 
9 package gnu.gcj.runtime;
10 import java.lang.ref.WeakReference;
11 import java.net.URL;
12 import java.net.MalformedURLException;
13 import java.util.HashMap;
14 import java.security.*;
15 import gnu.gcj.Core;
16 
17 public class SharedLibHelper
18 {
19   /** Load a shared library, and associate a ClassLoader with it.
20    * @param libname named of shared library (passed to dlopen)
21    * @param parent the parent ClassLoader
22    * @parem flags passed to dlopen
23    */
SharedLibHelper(String libname, ClassLoader parent, CodeSource source, int flags)24   SharedLibHelper(String libname, ClassLoader parent, CodeSource source,
25 		  int flags)
26   {
27     // FIXME: ask security manager first.
28     loader = parent;
29     baseName = libname;
30     domain = new ProtectionDomain(source,
31 				  Policy.getPolicy().getPermissions(source));
32     this.flags = flags;
33   }
34 
findHelper(String libname)35   public static SharedLibHelper findHelper (String libname)
36   {
37     synchronized (map)
38       {
39 	WeakReference ref = (WeakReference) map.get(libname);
40 	if (ref != null)
41 	  return (SharedLibHelper) ref.get();
42 	return null;
43       }
44   }
45 
findHelper(ClassLoader loader, String libname, CodeSource source)46   public static SharedLibHelper findHelper (ClassLoader loader, String libname,
47 					    CodeSource source)
48   {
49     synchronized (map)
50       {
51 	SharedLibHelper result;
52 	WeakReference ref = (WeakReference) map.get(libname);
53 	if (ref != null)
54 	  {
55 	    result = (SharedLibHelper) ref.get();
56 	    if (result != null)
57 	      {
58 		if (result.loader != loader)
59 		  // FIXME
60 		  throw new UnknownError();
61 		return result;
62 	      }
63 	  }
64 
65 	result = new SharedLibHelper(libname, loader, source, 0);
66 	map.put(libname, new WeakReference(result));
67 	return result;
68       }
69   }
70 
finalize()71   public native void finalize ();
72 
findClass(String name)73   public Class findClass(String name)
74   {
75     ensureInit();
76     return (Class) classMap.get(name);
77   }
78 
findResource(String name)79   public URL findResource (String name)
80   {
81     ensureInit();
82     if (! hasResource(name))
83       return null;
84     try
85       {
86 	return new URL("gcjlib", "", -1, baseName + "!/" + name);
87       }
88     catch (MalformedURLException _)
89       {
90       }
91     return null;
92   }
93 
findCore(String name)94   public native Core findCore (String name);
95 
ensureInit()96   void ensureInit()
97   {
98     synchronized (classMap)
99       {
100 	if (initialized)
101 	  return;
102 	init();
103 	initialized = true;
104       }
105   }
106 
hasResource(String name)107   native boolean hasResource(String name);
init()108   native void init();
109 
110   /** Called during dlopen's processing of the init section. */
registerClass(String name, Class cls)111   void registerClass(String name, Class cls)
112   {
113     classMap.put(name, cls);
114   }
115 
116   /** The handle returned by dlopen. */
117   gnu.gcj.RawData handler;
118 
119   /** Holds a _Jv_core_chain for the loader.  */
120   gnu.gcj.RawData core_chain;
121 
122   /** Map classnames to Classes. */
123   HashMap classMap = new HashMap(20);
124 
125   /** Class loader we're helping.  */
126   ClassLoader loader;
127 
128   /** Name of base file.  */
129   String baseName;
130 
131   /** Protection domain for loaded classes.  */
132   ProtectionDomain domain;
133 
134   /** Flags to pass to dlopen.  FIXME: platform dependent.
135       0 is always "sensible" (defined by us).  */
136   int flags;
137 
138   /** True if we've been initialized.  */
139   boolean initialized = false;
140 
141   /** Map shared library names to a helper object.  This uses weak
142       references in the values so we don't prevent collection.  */
143   static HashMap map = new HashMap ();
144 }
145