diff options
author | Sven Gothel <[email protected]> | 2015-01-30 21:09:17 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-01-30 21:09:17 +0100 |
commit | 12feaa7d3b1544098f684d851e3caff1ec88cbc8 (patch) | |
tree | 2d979c57cca37220bc026a8ee08ee479ae0508bf /src/java/com | |
parent | 3caf446e29a3934900b9983dfd72cb8aa0d9e8d7 (diff) |
Refine Native Library Code: Bulk Permissions, Cleanup DynamicLinker impl. - and fix Android AArch64 BionicDynamicLinker (Bug 1122)
- Bulk Permissions
ProcAddressTable.reset(..) performs address lookup in one block.
Now claiming all permissions upfront once, and releasing them afterwards.
- Cleanup DynamicLinker impl.
Proper top-down impl. of DynamicLinkerImpl,
handling all security code and validations.
- Fix Android AArch64 BionicDynamicLinker (Bug 1122)
Dalvik uses diff RTLD_* defines for AArch64!
Diffstat (limited to 'src/java/com')
5 files changed, 142 insertions, 49 deletions
diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java index 0f5ea8f..06cef6f 100644 --- a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java @@ -62,6 +62,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { private final DynamicLibraryBundleInfo info; protected final List<NativeLibrary> nativeLibraries; + private final DynamicLinker dynLinkGlobal; private final List<List<String>> toolLibNames; private final List<String> glueLibNames; private final boolean[] toolLibLoaded; @@ -118,11 +119,15 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { glueLibLoaded[i] = false; } - info.getLibLoaderExecutor().invoke(true, new Runnable() { - @Override - public void run() { - loadLibraries(); - } } ) ; + { + final DynamicLinker[] _dynLinkGlobal = { null }; + info.getLibLoaderExecutor().invoke(true, new Runnable() { + @Override + public void run() { + _dynLinkGlobal[0] = loadLibraries(); + } } ) ; + dynLinkGlobal = _dynLinkGlobal[0]; + } toolGetProcAddressFuncNameList = info.getToolGetProcAddressFuncNameList(); if( null != toolGetProcAddressFuncNameList ) { @@ -184,7 +189,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { * @see DynamicLibraryBundleInfo#getToolLibNames() */ public final boolean isToolLibComplete() { - return toolGetProcAddressComplete && getToolLibNumber() == getToolLibLoadedNumber(); + return toolGetProcAddressComplete && null != dynLinkGlobal && getToolLibNumber() == getToolLibLoadedNumber(); } public final boolean isToolLibLoaded() { @@ -241,7 +246,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { return aptr; } - protected final NativeLibrary loadFirstAvailable(final List<String> libNames, final ClassLoader loader, final boolean global) { + protected static final NativeLibrary loadFirstAvailable(final List<String> libNames, final ClassLoader loader, final boolean global) { for (int i=0; i < libNames.size(); i++) { final NativeLibrary lib = NativeLibrary.open(libNames.get(i), loader, global); if (lib != null) { @@ -251,11 +256,12 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { return null; } - final void loadLibraries() { + final DynamicLinker loadLibraries() { int i; toolLibLoadedNumber = 0; final ClassLoader cl = info.getClass().getClassLoader(); NativeLibrary lib = null; + DynamicLinker dynLinkGlobal = null; for (i=0; i < toolLibNames.size(); i++) { final List<String> libNames = toolLibNames.get(i); @@ -266,6 +272,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { System.err.println("Unable to load any Tool library of: "+libNames); } } else { + if( null == dynLinkGlobal ) { + dynLinkGlobal = lib.getDynamicLinker(); + } nativeLibraries.add(lib); toolLibLoaded[i]=true; toolLibLoadedNumber++; @@ -279,7 +288,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { if(DEBUG) { System.err.println("No Tool libraries loaded"); } - return; + return dynLinkGlobal; } glueLibLoadedNumber = 0; @@ -304,6 +313,8 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { glueLibLoadedNumber++; } } + + return dynLinkGlobal; } private final long dynamicLookupFunctionOnLibs(final String funcName) { @@ -318,7 +329,8 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { if( info.shallLookupGlobal() ) { // Try a global symbol lookup first .. - addr = NativeLibrary.dynamicLookupFunctionGlobal(funcName); + // addr = NativeLibrary.dynamicLookupFunctionGlobal(funcName); + addr = dynLinkGlobal.lookupSymbolGlobal(funcName); } // Look up this function name in all known libraries for (int i=0; 0==addr && i < nativeLibraries.size(); i++) { @@ -350,6 +362,20 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { } @Override + public final void claimAllLinkPermission() throws SecurityException { + for (int i=0; i < nativeLibraries.size(); i++) { + final NativeLibrary lib = nativeLibraries.get(i); + nativeLibraries.get(i).claimAllLinkPermission(); + } + } + @Override + public final void releaseAllLinkPermission() throws SecurityException { + for (int i=0; i < nativeLibraries.size(); i++) { + nativeLibraries.get(i).releaseAllLinkPermission(); + } + } + + @Override public final long dynamicLookupFunction(final String funcName) { if(!isToolLibLoaded() || null==funcName) { if(DEBUG_LOOKUP && !isToolLibLoaded()) { diff --git a/src/java/com/jogamp/common/os/DynamicLinker.java b/src/java/com/jogamp/common/os/DynamicLinker.java index 3b1ec3f..4019c77 100644 --- a/src/java/com/jogamp/common/os/DynamicLinker.java +++ b/src/java/com/jogamp/common/os/DynamicLinker.java @@ -34,6 +34,16 @@ public interface DynamicLinker { public static final boolean DEBUG_LOOKUP = NativeLibrary.DEBUG_LOOKUP; /** + * @throws SecurityException if user is not granted global access + */ + public void claimAllLinkPermission() throws SecurityException; + + /** + * @throws SecurityException if user is not granted global access + */ + public void releaseAllLinkPermission() throws SecurityException; + + /** * If a {@link SecurityManager} is installed, user needs link permissions * for the named library. * <p> @@ -80,8 +90,9 @@ public interface DynamicLinker { * @param symbolName global symbol name to lookup up system wide. * @return the library handle, maybe 0 if not found. * @throws IllegalArgumentException in case case <code>libraryHandle</code> is unknown. + * @throws SecurityException if user is not granted access for the given library handle */ - public long lookupSymbol(long libraryHandle, String symbolName) throws IllegalArgumentException; + public long lookupSymbol(long libraryHandle, String symbolName) throws SecurityException, IllegalArgumentException; /** * Security checks are implicit by previous call of @@ -89,9 +100,11 @@ public interface DynamicLinker { * retrieving the <code>librarHandle</code>. * * @param libraryHandle a library handle previously retrieved via {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)}. + * @param debug set to true to enable debugging * @throws IllegalArgumentException in case case <code>libraryHandle</code> is unknown. + * @throws SecurityException if user is not granted access for the given library handle */ - public void closeLibrary(long libraryHandle) throws IllegalArgumentException; + public void closeLibrary(long libraryHandle, boolean debug) throws SecurityException, IllegalArgumentException; /** * Returns a string containing the last error. diff --git a/src/java/com/jogamp/common/os/DynamicLookupHelper.java b/src/java/com/jogamp/common/os/DynamicLookupHelper.java index 0f87351..7997d57 100644 --- a/src/java/com/jogamp/common/os/DynamicLookupHelper.java +++ b/src/java/com/jogamp/common/os/DynamicLookupHelper.java @@ -51,12 +51,23 @@ public interface DynamicLookupHelper { public static final boolean DEBUG_LOOKUP = Debug.debug("NativeLibrary.Lookup"); /** + * @throws SecurityException if user is not granted access for the library set. + */ + public void claimAllLinkPermission() throws SecurityException; + /** + * @throws SecurityException if user is not granted access for the library set. + */ + public void releaseAllLinkPermission() throws SecurityException; + + /** * Returns the function handle for function 'funcName'. + * @throws SecurityException if user is not granted access for the library set. */ - public long dynamicLookupFunction(String funcName); + public long dynamicLookupFunction(String funcName) throws SecurityException; /** * Queries whether function 'funcName' is available. + * @throws SecurityException if user is not granted access for the library set. */ - public boolean isFunctionAvailable(String funcName); + public boolean isFunctionAvailable(String funcName) throws SecurityException; } diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index c70bdbd..fc2c1d4 100644 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -50,7 +50,8 @@ import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; -import jogamp.common.os.BionicDynamicLinkerImpl; +import jogamp.common.os.BionicDynamicLinker32bitImpl; +import jogamp.common.os.BionicDynamicLinker64BitImpl; import jogamp.common.os.MacOSXDynamicLinkerImpl; import jogamp.common.os.PlatformPropsImpl; import jogamp.common.os.PosixDynamicLinkerImpl; @@ -74,7 +75,6 @@ import com.jogamp.common.util.cache.TempJarCache; supporting code needed in the generated library. */ public final class NativeLibrary implements DynamicLookupHelper { - private static final DynamicLinker dynLink; private static final String[] prefixes; private static final String[] suffixes; @@ -82,19 +82,16 @@ public final class NativeLibrary implements DynamicLookupHelper { // Instantiate dynamic linker implementation switch (PlatformPropsImpl.OS_TYPE) { case WINDOWS: - dynLink = new WindowsDynamicLinkerImpl(); prefixes = new String[] { "" }; suffixes = new String[] { ".dll" }; break; case MACOS: - dynLink = new MacOSXDynamicLinkerImpl(); prefixes = new String[] { "lib" }; suffixes = new String[] { ".dylib", ".jnilib" }; break; case ANDROID: - dynLink = new BionicDynamicLinkerImpl(); prefixes = new String[] { "lib" }; suffixes = new String[] { ".so" }; break; @@ -106,13 +103,14 @@ public final class NativeLibrary implements DynamicLookupHelper { case OPENKODE: case LINUX: */ default: - dynLink = new PosixDynamicLinkerImpl(); prefixes = new String[] { "lib" }; suffixes = new String[] { ".so" }; break; } } + private final DynamicLinker dynLink; + // Platform-specific representation for the handle to the open // library. This is an HMODULE on Windows and a void* (the result of // a dlopen() call) on Unix and Mac OS X platforms. @@ -124,7 +122,8 @@ public final class NativeLibrary implements DynamicLookupHelper { private final boolean global; // Private constructor to prevent arbitrary instances from floating around - private NativeLibrary(final long libraryHandle, final String libraryPath, final boolean global) { + private NativeLibrary(final DynamicLinker dynLink, final long libraryHandle, final String libraryPath, final boolean global) { + this.dynLink = dynLink; this.libraryHandle = libraryHandle; this.libraryPath = libraryPath; this.global = global; @@ -135,22 +134,26 @@ public final class NativeLibrary implements DynamicLookupHelper { @Override public final String toString() { - return "NativeLibrary[" + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + ", global " + global + "]"; + return "NativeLibrary[" + dynLink.getClass().getSimpleName() + ", " + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + ", global " + global + "]"; } /** Opens the given native library, assuming it has the same base name on all platforms, looking first in the system's search path, and in the context of the specified ClassLoader, which is - used to help find the library in the case of e.g. Java Web Start. */ - public static final NativeLibrary open(final String libName, final ClassLoader loader) { + used to help find the library in the case of e.g. Java Web Start. + * @throws SecurityException if user is not granted access for the named library. + */ + public static final NativeLibrary open(final String libName, final ClassLoader loader) throws SecurityException { return open(libName, libName, libName, true, loader, true); } /** Opens the given native library, assuming it has the same base name on all platforms, looking first in the system's search path, and in the context of the specified ClassLoader, which is - used to help find the library in the case of e.g. Java Web Start. */ - public static final NativeLibrary open(final String libName, final ClassLoader loader, final boolean global) { + used to help find the library in the case of e.g. Java Web Start. + * @throws SecurityException if user is not granted access for the named library. + */ + public static final NativeLibrary open(final String libName, final ClassLoader loader, final boolean global) throws SecurityException { return open(libName, libName, libName, true, loader, global); } @@ -168,26 +171,54 @@ public final class NativeLibrary implements DynamicLookupHelper { ending in .so, for example .so.0), and in general if this dynamic loading facility is used correctly the version number will be irrelevant. - */ + * @throws SecurityException if user is not granted access for the named library. + */ public static final NativeLibrary open(final String windowsLibName, final String unixLibName, final String macOSXLibName, final boolean searchSystemPathFirst, - final ClassLoader loader) { + final ClassLoader loader) throws SecurityException { return open(windowsLibName, unixLibName, macOSXLibName, searchSystemPathFirst, loader, true); } + /** + * @throws SecurityException if user is not granted access for the named library. + */ public static final NativeLibrary open(final String windowsLibName, final String unixLibName, final String macOSXLibName, final boolean searchSystemPathFirst, - final ClassLoader loader, final boolean global) { + final ClassLoader loader, final boolean global) throws SecurityException { final List<String> possiblePaths = enumerateLibraryPaths(windowsLibName, unixLibName, macOSXLibName, searchSystemPathFirst, loader); Platform.initSingleton(); // loads native gluegen-rt library + + final DynamicLinker dynLink; + switch (PlatformPropsImpl.OS_TYPE) { + case WINDOWS: + dynLink = new WindowsDynamicLinkerImpl(); + break; + + case MACOS: + dynLink = new MacOSXDynamicLinkerImpl(); + break; + + case ANDROID: + if( PlatformPropsImpl.CPU_ARCH.is32Bit ) { + dynLink = new BionicDynamicLinker32bitImpl(); + } else { + dynLink = new BionicDynamicLinker64BitImpl(); + } + break; + + default: + dynLink = new PosixDynamicLinkerImpl(); + break; + } + // Iterate down these and see which one if any we can actually find. for (final Iterator<String> iter = possiblePaths.iterator(); iter.hasNext(); ) { final String path = iter.next(); @@ -207,7 +238,7 @@ public final class NativeLibrary implements DynamicLookupHelper { res = 0; } if ( 0 != res ) { - return new NativeLibrary(res, path, global); + return new NativeLibrary(dynLink, res, path, global); } else if( DEBUG ) { if( null != t ) { System.err.println("NativeLibrary.open: Caught "+t.getClass().getSimpleName()+": "+t.getMessage()); @@ -234,7 +265,16 @@ public final class NativeLibrary implements DynamicLookupHelper { } @Override - public final long dynamicLookupFunction(final String funcName) { + public final void claimAllLinkPermission() throws SecurityException { + dynLink.claimAllLinkPermission(); + } + @Override + public final void releaseAllLinkPermission() throws SecurityException { + dynLink.releaseAllLinkPermission(); + } + + @Override + public final long dynamicLookupFunction(final String funcName) throws SecurityException { if ( 0 == libraryHandle ) { throw new RuntimeException("Library is not open"); } @@ -242,22 +282,21 @@ public final class NativeLibrary implements DynamicLookupHelper { } @Override - public final boolean isFunctionAvailable(final String funcName) { + public final boolean isFunctionAvailable(final String funcName) throws SecurityException { if ( 0 == libraryHandle ) { throw new RuntimeException("Library is not open"); } return 0 != dynLink.lookupSymbol(libraryHandle, funcName); } - /** Looks up the given function name in all loaded libraries. */ - public static final long dynamicLookupFunctionGlobal(final String funcName) { + /** Looks up the given function name in all loaded libraries. + * @throws SecurityException if user is not granted access for the named library. + */ + public final long dynamicLookupFunctionGlobal(final String funcName) throws SecurityException { return dynLink.lookupSymbolGlobal(funcName); } - /** Looks up the given function name in all loaded libraries. */ - public static final boolean isFunctionAvailableGlobal(final String funcName) { - return 0 != dynLink.lookupSymbolGlobal(funcName); - } + /* pp */ final DynamicLinker getDynamicLinker() { return dynLink; } /** Retrieves the low-level library handle from this NativeLibrary object. On the Windows platform this is an HMODULE, and on Unix @@ -272,8 +311,10 @@ public final class NativeLibrary implements DynamicLookupHelper { } /** Closes this native library. Further lookup operations are not - allowed after calling this method. */ - public final void close() { + allowed after calling this method. + * @throws SecurityException if user is not granted access for the named library. + */ + public final void close() throws SecurityException { if (DEBUG) { System.err.println("NativeLibrary.close(): closing " + this); } @@ -282,7 +323,7 @@ public final class NativeLibrary implements DynamicLookupHelper { } final long handle = libraryHandle; libraryHandle = 0; - dynLink.closeLibrary(handle); + dynLink.closeLibrary(handle, DEBUG); if (DEBUG) { System.err.println("NativeLibrary.close(): Successfully closed " + this); ExceptionUtils.dumpStack(System.err); diff --git a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java index a0988cd..d910f7b 100644 --- a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java +++ b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java @@ -119,8 +119,6 @@ public abstract class ProcAddressTable { * @throws SecurityException if user is not granted access for all libraries. */ public void reset(final DynamicLookupHelper lookup) throws SecurityException, RuntimeException { - SecurityUtil.checkAllLinkPermission(); - if(null==lookup) { throw new RuntimeException("Passed null DynamicLookupHelper"); } @@ -137,13 +135,17 @@ public abstract class ProcAddressTable { // All at once - performance. AccessibleObject.setAccessible(fields, true); - - for (int i = 0; i < fields.length; ++i) { - final String fieldName = fields[i].getName(); - if ( isAddressField(fieldName) ) { - final String funcName = fieldToFunctionName(fieldName); - setEntry(fields[i], funcName, lookup); + lookup.claimAllLinkPermission(); + try { + for (int i = 0; i < fields.length; ++i) { + final String fieldName = fields[i].getName(); + if ( isAddressField(fieldName) ) { + final String funcName = fieldToFunctionName(fieldName); + setEntry(fields[i], funcName, lookup); + } } + } finally { + lookup.releaseAllLinkPermission(); } if (DEBUG) { |