summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/com/jogamp/common/os/DynamicLibraryBundle.java46
-rw-r--r--src/java/com/jogamp/common/os/DynamicLinker.java17
-rw-r--r--src/java/com/jogamp/common/os/DynamicLookupHelper.java15
-rw-r--r--src/java/com/jogamp/common/os/NativeLibrary.java95
-rw-r--r--src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java18
-rw-r--r--src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java (renamed from src/java/jogamp/common/os/BionicDynamicLinkerImpl.java)26
-rw-r--r--src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java63
-rw-r--r--src/java/jogamp/common/os/DynamicLinkerImpl.java182
-rw-r--r--src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java12
-rw-r--r--src/java/jogamp/common/os/PosixDynamicLinkerImpl.java12
-rw-r--r--src/java/jogamp/common/os/UnixDynamicLinkerImpl.java41
-rw-r--r--src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java47
12 files changed, 402 insertions, 172 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) {
diff --git a/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java b/src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java
index b293776..e51ae69 100644
--- a/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/BionicDynamicLinker32bitImpl.java
@@ -28,34 +28,36 @@
package jogamp.common.os;
/**
- * Bionic specialization of {@link UnixDynamicLinkerImpl}
+ * Bionic 32bit specialization of {@link UnixDynamicLinkerImpl}
* utilizing Bionic's non POSIX flags and mode values.
* <p>
* Bionic is used on Android.
* </p>
*/
-public final class BionicDynamicLinkerImpl extends UnixDynamicLinkerImpl {
- private static final long RTLD_DEFAULT = 0xffffffffL;
- // static final long RTLD_NEXT = 0xfffffffeL;
+public final class BionicDynamicLinker32bitImpl extends UnixDynamicLinkerImpl {
- private static final int RTLD_LAZY = 0x00001;
// static final int RTLD_NOW = 0x00000;
+ private static final int RTLD_LAZY = 0x00001;
+
private static final int RTLD_LOCAL = 0x00000;
private static final int RTLD_GLOBAL = 0x00002;
+ // static final int RTLD_NOLOAD = 0x00004;
+
+ private static final long RTLD_DEFAULT = 0xffffffffL;
+ // static final long RTLD_NEXT = 0xfffffffeL;
@Override
- public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException {
- return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_LOCAL, debug);
+ protected final long openLibraryLocalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
}
@Override
- public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException {
- return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_GLOBAL, debug);
+ protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
@Override
- public final long lookupSymbolGlobal(final String symbolName) throws SecurityException {
- return this.lookupSymbolGlobalImpl(RTLD_DEFAULT, symbolName);
+ protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException {
+ return dlsym(RTLD_DEFAULT, symbolName);
}
-
}
diff --git a/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java b/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java
new file mode 100644
index 0000000..d8d3134
--- /dev/null
+++ b/src/java/jogamp/common/os/BionicDynamicLinker64BitImpl.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.common.os;
+
+/**
+ * Bionic 64bit specialization of {@link UnixDynamicLinkerImpl}
+ * utilizing Bionic's non POSIX flags and mode values.
+ * <p>
+ * Bionic is used on Android.
+ * </p>
+ */
+public final class BionicDynamicLinker64BitImpl extends UnixDynamicLinkerImpl {
+ // static final int RTLD_NOW = 0x00002;
+ private static final int RTLD_LAZY = 0x00001;
+
+ private static final int RTLD_LOCAL = 0x00000;
+ private static final int RTLD_GLOBAL = 0x00100;
+ // static final int RTLD_NOLOAD = 0x00004;
+
+ private static final long RTLD_DEFAULT = 0x00000000L;
+ // static final long RTLD_NEXT = -1L;
+
+ @Override
+ protected final long openLibraryLocalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
+ }
+
+ @Override
+ protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
+ }
+
+ @Override
+ protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException {
+ return dlsym(RTLD_DEFAULT, symbolName);
+ }
+
+}
diff --git a/src/java/jogamp/common/os/DynamicLinkerImpl.java b/src/java/jogamp/common/os/DynamicLinkerImpl.java
index 392d906..56a909e 100644
--- a/src/java/jogamp/common/os/DynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/DynamicLinkerImpl.java
@@ -29,6 +29,7 @@ package jogamp.common.os;
import com.jogamp.common.os.DynamicLinker;
import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.common.util.SecurityUtil;
/* pp */ abstract class DynamicLinkerImpl implements DynamicLinker {
@@ -38,18 +39,134 @@ import com.jogamp.common.util.LongObjectHashMap;
// ensuring no abuse via subclassing.
//
- private final LongObjectHashMap libHandle2Name = new LongObjectHashMap( 16 /* initialCapacity */ );
+ private final Object secSync = new Object();
+ private boolean allLinkPermissionGranted = false;
- protected static final class LibRef {
- public LibRef(final String name) {
+ /**
+ * @throws SecurityException if user is not granted global access
+ */
+ public final void claimAllLinkPermission() throws SecurityException {
+ synchronized( secSync ) {
+ allLinkPermissionGranted = true;
+ }
+ }
+
+ /**
+ * @throws SecurityException if user is not granted global access
+ */
+ public final void releaseAllLinkPermission() throws SecurityException {
+ synchronized( secSync ) {
+ allLinkPermissionGranted = false;
+ }
+ }
+
+ private final void checkLinkPermission(final String pathname) throws SecurityException {
+ synchronized( secSync ) {
+ if( !allLinkPermissionGranted ) {
+ SecurityUtil.checkLinkPermission(pathname);
+ }
+ }
+ }
+ private final void checkLinkPermission(final long libraryHandle) throws SecurityException {
+ synchronized( secSync ) {
+ if( !allLinkPermissionGranted ) {
+ final LibRef libRef = getLibRef( libraryHandle );
+ if( null == libRef ) {
+ throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
+ }
+ SecurityUtil.checkLinkPermission(libRef.getName());
+ }
+ }
+ }
+
+ private final void checkAllLinkPermission() throws SecurityException {
+ synchronized( secSync ) {
+ if( !allLinkPermissionGranted ) {
+ SecurityUtil.checkAllLinkPermission();
+ }
+ }
+ }
+
+ @Override
+ public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException {
+ checkLinkPermission(pathname);
+ final long handle = openLibraryGlobalImpl(pathname);
+ if( 0 != handle ) {
+ final LibRef libRef = incrLibRefCount(handle, pathname);
+ if( DEBUG || debug ) {
+ System.err.println("DynamicLinkerImpl.openLibraryGlobal \""+pathname+"\": 0x"+Long.toHexString(handle)+" -> "+libRef+")");
+ }
+ } else if ( DEBUG || debug ) {
+ System.err.println("DynamicLinkerImpl.openLibraryGlobal \""+pathname+"\" failed, error: "+getLastError());
+ }
+ return handle;
+ }
+ protected abstract long openLibraryGlobalImpl(final String pathname) throws SecurityException;
+
+ @Override
+ public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException {
+ checkLinkPermission(pathname);
+ final long handle = openLibraryLocalImpl(pathname);
+ if( 0 != handle ) {
+ final LibRef libRef = incrLibRefCount(handle, pathname);
+ if( DEBUG || debug ) {
+ System.err.println("DynamicLinkerImpl.openLibraryLocal \""+pathname+"\": 0x"+Long.toHexString(handle)+" -> "+libRef+")");
+ }
+ } else if ( DEBUG || debug ) {
+ System.err.println("DynamicLinkerImpl.openLibraryLocal \""+pathname+"\" failed, error: "+getLastError());
+ }
+ return handle;
+ }
+ protected abstract long openLibraryLocalImpl(final String pathname) throws SecurityException;
+
+ @Override
+ public final long lookupSymbolGlobal(final String symbolName) throws SecurityException {
+ checkAllLinkPermission();
+ final long addr = lookupSymbolGlobalImpl(symbolName);
+ if(DEBUG_LOOKUP) {
+ System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr));
+ }
+ return addr;
+ }
+ protected abstract long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException;
+
+ @Override
+ public final long lookupSymbol(final long libraryHandle, final String symbolName) throws SecurityException, IllegalArgumentException {
+ checkLinkPermission(libraryHandle);
+ final long addr = lookupSymbolLocalImpl(libraryHandle, symbolName);
+ if(DEBUG_LOOKUP) {
+ System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> 0x"+Long.toHexString(addr));
+ }
+ return addr;
+ }
+ protected abstract long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException;
+
+ @Override
+ public final void closeLibrary(final long libraryHandle, final boolean debug) throws SecurityException, IllegalArgumentException {
+ final LibRef libRef = decrLibRefCount( libraryHandle );
+ if( null == libRef ) {
+ throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
+ }
+ checkLinkPermission(libRef.getName());
+ if( DEBUG || debug ) {
+ System.err.println("DynamicLinkerImpl.closeLibrary(0x"+Long.toHexString(libraryHandle)+" -> "+libRef+")");
+ }
+ closeLibraryImpl(libraryHandle);
+ }
+ protected abstract void closeLibraryImpl(final long libraryHandle) throws SecurityException;
+
+ private static final LongObjectHashMap libHandle2Name = new LongObjectHashMap( 16 /* initialCapacity */ );
+
+ static final class LibRef {
+ LibRef(final String name) {
this.name = name;
this.refCount = 1;
}
- public final int incrRefCount() { return ++refCount; }
- public final int decrRefCount() { return --refCount; }
- public final int getRefCount() { return refCount; }
+ final int incrRefCount() { return ++refCount; }
+ final int decrRefCount() { return --refCount; }
+ final int getRefCount() { return refCount; }
- public final String getName() { return name; }
+ final String getName() { return name; }
@Override
public final String toString() { return "LibRef["+name+", refCount "+refCount+"]"; }
@@ -57,35 +174,40 @@ import com.jogamp.common.util.LongObjectHashMap;
private int refCount;
}
- protected final synchronized LibRef getLibRef(final long handle) {
- return (LibRef) libHandle2Name.get(handle);
+ private final LibRef getLibRef(final long handle) {
+ synchronized( libHandle2Name ) {
+ return (LibRef) libHandle2Name.get(handle);
+ }
}
- protected final synchronized LibRef incrLibRefCount(final long handle, final String libName) {
- LibRef libRef = getLibRef(handle);
- if( null == libRef ) {
- libRef = new LibRef(libName);
- libHandle2Name.put(handle, libRef);
- } else {
- libRef.incrRefCount();
- }
- if(DEBUG) {
- System.err.println("DynamicLinkerImpl.incrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size());
+ private final LibRef incrLibRefCount(final long handle, final String libName) {
+ synchronized( libHandle2Name ) {
+ LibRef libRef = getLibRef(handle);
+ if( null == libRef ) {
+ libRef = new LibRef(libName);
+ libHandle2Name.put(handle, libRef);
+ } else {
+ libRef.incrRefCount();
+ }
+ if(DEBUG) {
+ System.err.println("DynamicLinkerImpl.incrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size());
+ }
+ return libRef;
}
- return libRef;
}
- protected final synchronized LibRef decrLibRefCount(final long handle) {
- final LibRef libRef = getLibRef(handle);
- if( null != libRef ) {
- if( 0 == libRef.decrRefCount() ) {
- libHandle2Name.remove(handle);
+ private final LibRef decrLibRefCount(final long handle) {
+ synchronized( libHandle2Name ) {
+ final LibRef libRef = getLibRef(handle);
+ if( null != libRef ) {
+ if( 0 == libRef.decrRefCount() ) {
+ libHandle2Name.remove(handle);
+ }
}
+ if(DEBUG) {
+ System.err.println("DynamicLinkerImpl.decrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size());
+ }
+ return libRef;
}
- if(DEBUG) {
- System.err.println("DynamicLinkerImpl.decrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size());
- }
- return libRef;
}
-
}
diff --git a/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java b/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java
index 0fdfc8b..d724f9a 100644
--- a/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java
@@ -42,18 +42,18 @@ public final class MacOSXDynamicLinkerImpl extends UnixDynamicLinkerImpl {
private static final int RTLD_GLOBAL = 0x00008;
@Override
- public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException {
- return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_LOCAL, debug);
+ protected final long openLibraryLocalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
}
@Override
- public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException {
- return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_GLOBAL, debug);
+ protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
@Override
- public final long lookupSymbolGlobal(final String symbolName) throws SecurityException {
- return this.lookupSymbolGlobalImpl(RTLD_DEFAULT, symbolName);
+ protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException {
+ return dlsym(RTLD_DEFAULT, symbolName);
}
}
diff --git a/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java b/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java
index f929e03..a022f01 100644
--- a/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/PosixDynamicLinkerImpl.java
@@ -38,17 +38,17 @@ public final class PosixDynamicLinkerImpl extends UnixDynamicLinkerImpl {
private static final int RTLD_GLOBAL = 0x00100;
@Override
- public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException {
- return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_LOCAL, debug);
+ protected final long openLibraryLocalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
}
@Override
- public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException {
- return this.openLibraryImpl(pathname, RTLD_LAZY | RTLD_GLOBAL, debug);
+ protected final long openLibraryGlobalImpl(final String pathname) throws SecurityException {
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
@Override
- public final long lookupSymbolGlobal(final String symbolName) throws SecurityException {
- return this.lookupSymbolGlobalImpl(RTLD_DEFAULT, symbolName);
+ protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException {
+ return dlsym(RTLD_DEFAULT, symbolName);
}
}
diff --git a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java
index 59be76c..5e8ba9d 100644
--- a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java
@@ -27,8 +27,6 @@
*/
package jogamp.common.os;
-import com.jogamp.common.util.SecurityUtil;
-
/* pp */ abstract class UnixDynamicLinkerImpl extends DynamicLinkerImpl {
//
@@ -49,46 +47,17 @@ import com.jogamp.common.util.SecurityUtil;
/** Interface to C language function: <br> <code> void * dlsym(void * , const char * ); </code> */
protected static native long dlsym(long arg0, java.lang.String arg1);
- protected final long openLibraryImpl(final String pathname, final int dlSymFlags, final boolean debug) throws SecurityException {
- SecurityUtil.checkLinkPermission(pathname);
- final long handle = dlopen(pathname, dlSymFlags);
- if( 0 != handle ) {
- incrLibRefCount(handle, pathname);
- } else if ( DEBUG || debug ) {
- System.err.println("dlopen \""+pathname+"\" failed, error: "+dlerror());
- }
- return handle;
- }
-
- protected final long lookupSymbolGlobalImpl(final long dlSymGlobalFlag, final String symbolName) throws SecurityException {
- SecurityUtil.checkAllLinkPermission();
- final long addr = dlsym(dlSymGlobalFlag, symbolName);
- if(DEBUG_LOOKUP) {
- System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr));
- }
- return addr;
- }
-
@Override
- public final long lookupSymbol(final long libraryHandle, final String symbolName) throws IllegalArgumentException {
- if( null == getLibRef( libraryHandle ) ) {
- throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
- }
- final long addr = dlsym(libraryHandle, symbolName);
- if(DEBUG_LOOKUP) {
- System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> 0x"+Long.toHexString(addr));
- }
- return addr;
+ protected final long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException {
+ return dlsym(libraryHandle, symbolName);
}
@Override
- public final void closeLibrary(final long libraryHandle) throws IllegalArgumentException {
- if( null == decrLibRefCount( libraryHandle ) ) {
- throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
- }
- dlclose(libraryHandle);
+ protected final void closeLibraryImpl(final long libraryHandle) throws SecurityException {
+ dlclose(libraryHandle);
}
+
@Override
public final String getLastError() {
return dlerror();
diff --git a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java
index de69d0c..04f13fb 100644
--- a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java
+++ b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java
@@ -27,8 +27,6 @@
*/
package jogamp.common.os;
-import com.jogamp.common.util.SecurityUtil;
-
public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl {
/** Interface to C language function: <br> <code> BOOL FreeLibrary(HANDLE hLibModule); </code> */
@@ -44,28 +42,19 @@ public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl {
private static native long LoadLibraryW(java.lang.String lpLibFileName);
@Override
- public final long openLibraryLocal(final String libraryName, final boolean debug) throws SecurityException {
+ protected final long openLibraryLocalImpl(final String libraryName) throws SecurityException {
// How does that work under Windows ?
- // Don't know .. so it's an alias for the time being
- return openLibraryGlobal(libraryName, debug);
+ // Don't know .. so it's an alias to global, for the time being
+ return LoadLibraryW(libraryName);
}
@Override
- public final long openLibraryGlobal(final String libraryName, final boolean debug) throws SecurityException {
- SecurityUtil.checkLinkPermission(libraryName);
- final long handle = LoadLibraryW(libraryName);
- if( 0 != handle ) {
- incrLibRefCount(handle, libraryName);
- } else if ( DEBUG || debug ) {
- final int err = GetLastError();
- System.err.println("LoadLibraryW \""+libraryName+"\" failed, error code: 0x"+Integer.toHexString(err)+", "+err);
- }
- return handle;
+ protected final long openLibraryGlobalImpl(final String libraryName) throws SecurityException {
+ return LoadLibraryW(libraryName);
}
@Override
- public final long lookupSymbolGlobal(final String symbolName) throws SecurityException {
- SecurityUtil.checkAllLinkPermission();
+ protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException {
if(DEBUG_LOOKUP) {
System.err.println("lookupSymbolGlobal: Not supported on Windows");
}
@@ -73,34 +62,26 @@ public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl {
return 0;
}
+ private static final int symbolArgAlignment=4; // 4 byte alignment of each argument
+ private static final int symbolMaxArguments=12; // experience ..
+
@Override
- public final long lookupSymbol(final long libraryHandle, final String symbolName) throws IllegalArgumentException {
- if( null == getLibRef( libraryHandle ) ) {
- throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
- }
+ protected final long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws IllegalArgumentException {
String _symbolName = symbolName;
long addr = GetProcAddressA(libraryHandle, _symbolName);
- if(0==addr) {
+ if( 0 == addr ) {
// __stdcall hack: try some @nn decorations,
// the leading '_' must not be added (same with cdecl)
- final int argAlignment=4; // 4 byte alignment of each argument
- final int maxArguments=12; // experience ..
- for(int arg=0; 0==addr && arg<=maxArguments; arg++) {
- _symbolName = symbolName+"@"+(arg*argAlignment);
+ for(int arg=0; 0==addr && arg<=symbolMaxArguments; arg++) {
+ _symbolName = symbolName+"@"+(arg*symbolArgAlignment);
addr = GetProcAddressA(libraryHandle, _symbolName);
}
}
- if(DEBUG_LOOKUP) {
- System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> "+_symbolName+", 0x"+Long.toHexString(addr));
- }
return addr;
}
@Override
- public final void closeLibrary(final long libraryHandle) throws IllegalArgumentException {
- if( null == decrLibRefCount( libraryHandle ) ) {
- throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
- }
+ protected final void closeLibraryImpl(final long libraryHandle) throws IllegalArgumentException {
FreeLibrary(libraryHandle);
}