From c7efca6d9b0db7305f5352ebf15d915ae5a1fa24 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 26 Nov 2023 09:49:12 +0100 Subject: Bug 1479: NativeLibrary: Add getNativeLibraryPath() returning queried used native library path, supported throughout DynamicLibraryBundle[Info] Motivation: It is helpful to retrieve the actually used native library pathname, since loading a library w/o absolute path but lookup through LD_LIBRARY_PATH may render it hard for the user to determine which library is used. +++ +++ Windows implementation simply can use GetModuleFileNameA() with the native library handle. POSIX implementation may utilize a symbol-name to retrieve its address within the loading native library used to retrieved the library information via dladdr(). To support this feature throughout DynamicLibraryBundle and DynamicLibraryBundleInfo, the custom DynamicLibraryBundleInfo specializations shall provide optional symbol-names per each tool-library-name for the POSIX implementation, see above. public interface DynamicLibraryBundleInfo { ... /** * Returns optional list of optional symbol names per {@link #getToolLibNames()} * in same order for an OS which requires the symbol's address to retrieve * the path of the containing library. */ public List getSymbolForToolLibPath(); ... } --- make/scripts/runtest.sh | 4 +- .../com/jogamp/common/os/DynamicLibraryBundle.java | 65 +++++++++---- .../jogamp/common/os/DynamicLibraryBundleInfo.java | 7 +- src/java/com/jogamp/common/os/DynamicLinker.java | 15 ++- src/java/com/jogamp/common/os/NativeLibrary.java | 106 +++++++++++++-------- src/java/jogamp/common/os/DynamicLinkerImpl.java | 13 +++ .../jogamp/common/os/UnixDynamicLinkerImpl.java | 14 +++ .../jogamp/common/os/WindowsDynamicLinkerImpl.java | 9 ++ .../generation/Test1p2DynamicLibraryBundle.java | 5 + .../junit/generation/Test1p2LoadJNIAndImplLib.java | 3 +- .../generation/Test1p2ProcAddressEmitter.java | 3 +- .../test/junit/generation/Test2p2FuncPtr.java | 3 +- .../test/junit/generation/Test3p2PtrStorage.java | 3 +- .../test/junit/generation/Test4p2JavaCallback.java | 3 +- src/native/unix/UnixDynamicLinkerImpl_JNI.c | 29 +++++- src/native/windows/WindowsDynamicLinkerImpl_JNI.c | 16 ++++ 16 files changed, 228 insertions(+), 70 deletions(-) diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh index 7792f08..ab80674 100755 --- a/make/scripts/runtest.sh +++ b/make/scripts/runtest.sh @@ -149,7 +149,7 @@ function onetest() { #onetest com.jogamp.common.nio.TestByteBufferOutputStream 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestByteBufferCopyStream 2>&1 | tee -a $LOG #onetest com.jogamp.common.os.TestElfReader01 $* 2>&1 | tee -a $LOG -onetest com.jogamp.common.os.TestClock01 $* 2>&1 | tee -a $LOG +#onetest com.jogamp.common.os.TestClock01 $* 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.internals.TestType 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.TestJCPP $* 2>&1 | tee -a $LOG @@ -171,7 +171,7 @@ onetest com.jogamp.common.os.TestClock01 $* 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG -#onetest com.jogamp.gluegen.test.junit.generation.Test1p2DynamicLibraryBundle 2>&1 | tee -a $LOG +onetest com.jogamp.gluegen.test.junit.generation.Test1p2DynamicLibraryBundle 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test2p1FuncPtr 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test2p2FuncPtr 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test3p1PtrStorage 2>&1 | tee -a $LOG diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java index fee3c01..a513ec4 100644 --- a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * Copyright 2010-2023 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: @@ -61,11 +61,12 @@ import com.jogamp.common.util.RunnableExecutor; public class DynamicLibraryBundle implements DynamicLookupHelper { private final DynamicLibraryBundleInfo info; - protected final List nativeLibraries; - private final DynamicLinker dynLinkGlobal; private final List> toolLibNames; + protected final List toolLibraries; + private final List toolLibSymbolNames; private final List glueLibNames; private final boolean[] toolLibLoaded; + private final DynamicLinker dynLinkGlobal; private int toolLibLoadedNumber; @@ -97,8 +98,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - DynamicLibraryBundle.init start with: "+info.getClass().getName()); } - nativeLibraries = new ArrayList(); toolLibNames = info.getToolLibNames(); + toolLibraries = new ArrayList(toolLibNames.size()); + toolLibSymbolNames = info.getSymbolForToolLibPath(); glueLibNames = info.getGlueLibNames(); toolLibLoaded = new boolean[toolLibNames.size()]; if(DEBUG) { @@ -143,7 +145,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { System.err.println("DynamicLibraryBundle.init Summary: "+info.getClass().getName()); System.err.println(" toolGetProcAddressFuncNameList: "+toolGetProcAddressFuncNameList+", complete: "+toolGetProcAddressComplete+", 0x"+Long.toHexString(toolGetProcAddressHandle)); System.err.println(" Tool Lib Names : "+toolLibNames); + System.err.println(" Tool Lib Symbol: "+toolLibSymbolNames); System.err.println(" Tool Lib Loaded: "+getToolLibLoadedNumber()+"/"+getToolLibNumber()+" "+Arrays.toString(toolLibLoaded)+", complete "+isToolLibComplete()); + System.err.println(" Tool Libraries : "+toolLibraries); System.err.println(" Glue Lib Names : "+glueLibNames); System.err.println(" Glue Lib Loaded: "+getGlueLibLoadedNumber()+"/"+getGlueLibNumber()+" "+Arrays.toString(glueLibLoaded)+", complete "+isGlueLibComplete()); System.err.println(" All Complete: "+isLibComplete()); @@ -159,10 +163,13 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { toolGetProcAddressFuncNameSet = null; toolGetProcAddressHandle = 0; toolGetProcAddressComplete = false; - for(int i = 0; i getToolLibraries() { return toolLibraries; } + public final int getGlueLibNumber() { return glueLibNames.size(); } @@ -252,9 +265,9 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { protected static final NativeLibrary loadFirstAvailable(final List libNames, final boolean searchSystemPath, final boolean searchSystemPathFirst, - final ClassLoader loader, final boolean global) throws SecurityException { + final ClassLoader loader, final boolean global, final String symbolName) throws SecurityException { for (int i=0; i < libNames.size(); i++) { - final NativeLibrary lib = NativeLibrary.open(libNames.get(i), searchSystemPath, searchSystemPathFirst, loader, global); + final NativeLibrary lib = NativeLibrary.open(libNames.get(i), searchSystemPath, searchSystemPathFirst, loader, global, symbolName); if (lib != null) { return lib; } @@ -271,11 +284,13 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { for (i=0; i < toolLibNames.size(); i++) { final List libNames = toolLibNames.get(i); + final String symbolName = toolLibSymbolNames.get(i); if( null != libNames && libNames.size() > 0 ) { lib = loadFirstAvailable(libNames, info.searchToolLibInSystemPath(), info.searchToolLibSystemPathFirst(), - cl, info.shallLinkGlobal()); + cl, info.shallLinkGlobal(), symbolName); + toolLibraries.add(lib); if ( null == lib ) { if(DEBUG) { System.err.println("Unable to load any Tool library of: "+libNames); @@ -284,13 +299,14 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { if( null == dynLinkGlobal ) { dynLinkGlobal = lib.dynamicLinker(); } - nativeLibraries.add(lib); - toolLibLoaded[i]=true; + toolLibLoaded[i] = true; toolLibLoadedNumber++; if(DEBUG) { System.err.println("Loaded Tool library: "+lib); } } + } else { + toolLibraries.add(null); // same size and order as toolLibNames! } } if( toolLibNames.size() > 0 && !isToolLibLoaded() ) { @@ -347,16 +363,19 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { addr = dynLinkGlobal.lookupSymbolGlobal(funcName); } // Look up this function name in all known libraries - for (int i=0; 0==addr && i < nativeLibraries.size(); i++) { - lib = nativeLibraries.get(i); - addr = lib.dynamicLookupFunction(funcName); + for (int i=0; 0==addr && i < toolLibraries.size(); i++) { + final NativeLibrary lib0 = toolLibraries.get(i); + if( null != lib0 ) { + lib = lib0; + addr = lib0.dynamicLookupFunction(funcName); + } } if(DEBUG_LOOKUP) { final String libName = ( null == lib ) ? "GLOBAL" : lib.toString(); if(0!=addr) { System.err.println("Lookup-Native: <" + funcName + "> 0x" + Long.toHexString(addr) + " in lib " + libName ); } else { - System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** in libs " + nativeLibraries); + System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** in libs " + toolLibraries); } } return addr; @@ -377,14 +396,20 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { @Override public final void claimAllLinkPermission() throws SecurityException { - for (int i=0; i < nativeLibraries.size(); i++) { - nativeLibraries.get(i).claimAllLinkPermission(); + for(int i = 0; i> getToolLibNames(); + /** + * Returns optional list of optional symbol names per {@link #getToolLibNames()} in same order for an OS which requires the symbol's address to retrieve the path of the containing library. + */ + public List getSymbolForToolLibPath(); + /** * If a {@link SecurityManager} is installed, user needs link permissions * for the named libraries. diff --git a/src/java/com/jogamp/common/os/DynamicLinker.java b/src/java/com/jogamp/common/os/DynamicLinker.java index 4019c77..7b12aee 100644 --- a/src/java/com/jogamp/common/os/DynamicLinker.java +++ b/src/java/com/jogamp/common/os/DynamicLinker.java @@ -1,5 +1,5 @@ /** - * Copyright 2013 JogAmp Community. All rights reserved. + * Copyright 2013-2023 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: @@ -71,6 +71,19 @@ public interface DynamicLinker { */ public long openLibraryLocal(String pathname, boolean debug) throws SecurityException; + /** + * Security checks are implicit by previous call of + * {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)} + * retrieving the librarHandle. + * + * @param libraryHandle a library handle previously retrieved via {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)}. + * @param symbolName optional symbol name for an OS which requires the symbol's address to retrieve the path of the containing library + * @return the library pathname if found and supported by OS or {@code null}. + * @throws IllegalArgumentException in case case libraryHandle is unknown. + * @throws SecurityException if user is not granted access for the given library handle + */ + public String lookupLibraryPathname(long libraryHandle, String symbolName) throws SecurityException; + /** * If a {@link SecurityManager} is installed, user needs link permissions * for all libraries, i.e. for new RuntimePermission("loadLibrary.*");! diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 53db784..e00599c 100644 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -1,41 +1,30 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2011 JogAmp Community. All rights reserved. +/** + * Copyright 2011-2023 JogAmp Community. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. * - * - Redistribution 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. + * 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. * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 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. * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. + * 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 com.jogamp.common.os; @@ -126,13 +115,17 @@ public final class NativeLibrary implements DynamicLookupHelper { // May as well keep around the path to the library we opened private final String libraryPath; + // Native library path of the opened native libraryHandle, maybe null + private final String nativeLibraryPath; + private final boolean global; // Private constructor to prevent arbitrary instances from floating around - private NativeLibrary(final DynamicLinker dynLink, final long libraryHandle, final String libraryPath, final boolean global) { + private NativeLibrary(final DynamicLinker dynLink, final long libraryHandle, final String libraryPath, final boolean global, final String symbolName) { this.dynLink = dynLink; this.libraryHandle = libraryHandle; this.libraryPath = libraryPath; + this.nativeLibraryPath = dynLink.lookupLibraryPathname(libraryHandle, symbolName); this.global = global; if (DEBUG) { System.err.println("NativeLibrary.open(): Successfully loaded: " + this); @@ -141,7 +134,9 @@ public final class NativeLibrary implements DynamicLookupHelper { @Override public final String toString() { - return "NativeLibrary[" + dynLink.getClass().getSimpleName() + ", " + libraryPath + ", 0x" + Long.toHexString(libraryHandle) + ", global " + global + "]"; + final String nlp_s = null != nativeLibraryPath ? ", native '"+nativeLibraryPath+"'" : ""; + return "NativeLibrary[" + dynLink.getClass().getSimpleName() + ", path[given '" + libraryPath + "'"+nlp_s+"], 0x" + + Long.toHexString(libraryHandle) + ", global " + global + "]"; } /** @@ -198,7 +193,36 @@ public final class NativeLibrary implements DynamicLookupHelper { final boolean searchSystemPath, final boolean searchSystemPathFirst, final ClassLoader loader, final boolean global) throws SecurityException { - return open(libName, libName, libName, searchSystemPath, searchSystemPathFirst, loader, global); + return open(libName, libName, libName, searchSystemPath, searchSystemPathFirst, loader, global, null); + } + + /** Opens the given native library, assuming it has the same base + name on all platforms. +

+ The {@code searchSystemPath} argument changes the behavior to + either use the default system path or not at all. +

+

+ Assuming {@code searchSystemPath} is {@code true}, + the {@code searchSystemPathFirst} argument changes the behavior to first + search the default system path rather than searching it last. +

+ * @param libName library name, with or without prefix and suffix + * @param searchSystemPath if {@code true} library shall be searched in the system path (default), otherwise {@code false}. + * @param searchSystemPathFirst if {@code true} system path shall be searched first (default), rather than searching it last. + * if {@code searchSystemPath} is {@code false} this argument is ignored. + * @param loader {@link ClassLoader} to locate the library + * @param global if {@code true} allows system wide access of the loaded library, otherwise access is restricted to the process. + * @param symbolName optional symbol name for an OS which requires the symbol's address to retrieve the path of the containing library + * @return {@link NativeLibrary} instance or {@code null} if library could not be loaded. + * @throws SecurityException if user is not granted access for the named library. + * @since 2.4.0 + */ + public static final NativeLibrary open(final String libName, + final boolean searchSystemPath, + final boolean searchSystemPathFirst, + final ClassLoader loader, final boolean global, final String symbolName) throws SecurityException { + return open(libName, libName, libName, searchSystemPath, searchSystemPathFirst, loader, global, symbolName); } /** Opens the given native library, assuming it has the given base @@ -230,6 +254,7 @@ public final class NativeLibrary implements DynamicLookupHelper { * if {@code searchSystemPath} is {@code false} this argument is ignored. * @param loader {@link ClassLoader} to locate the library * @param global if {@code true} allows system wide access of the loaded library, otherwise access is restricted to the process. + * @param symbolName optional symbol name for an OS which requires the symbol's address to retrieve the path of the containing library * @return {@link NativeLibrary} instance or {@code null} if library could not be loaded. * @throws SecurityException if user is not granted access for the named library. */ @@ -238,7 +263,7 @@ public final class NativeLibrary implements DynamicLookupHelper { final String macOSXLibName, final boolean searchSystemPath, final boolean searchSystemPathFirst, - final ClassLoader loader, final boolean global) throws SecurityException { + final ClassLoader loader, final boolean global, final String symbolName) throws SecurityException { final List possiblePaths = enumerateLibraryPaths(windowsLibName, unixLibName, macOSXLibName, @@ -267,7 +292,7 @@ public final class NativeLibrary implements DynamicLookupHelper { res = 0; } if ( 0 != res ) { - return new NativeLibrary(dynLink, res, path, global); + return new NativeLibrary(dynLink, res, path, global, symbolName); } else if( DEBUG ) { if( null != t ) { System.err.println("NativeLibrary.open: Caught "+t.getClass().getSimpleName()+": "+t.getMessage()); @@ -366,6 +391,11 @@ public final class NativeLibrary implements DynamicLookupHelper { return libraryPath; } + /** Returns the native library path of the opened native {@link #getLibraryHandle()}, maybe null if not supported by OS. */ + public final String getNativeLibraryPath() { + return nativeLibraryPath; + } + /** Closes this native library. Further lookup operations are not allowed after calling this method. * @throws SecurityException if user is not granted access for the named library. diff --git a/src/java/jogamp/common/os/DynamicLinkerImpl.java b/src/java/jogamp/common/os/DynamicLinkerImpl.java index 5ce94c1..13b08d7 100644 --- a/src/java/jogamp/common/os/DynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/DynamicLinkerImpl.java @@ -45,6 +45,7 @@ import com.jogamp.common.util.SecurityUtil; /** * @throws SecurityException if user is not granted global access */ + @Override public final void claimAllLinkPermission() throws SecurityException { synchronized( secSync ) { allLinkPermissionGranted = true; @@ -54,6 +55,7 @@ import com.jogamp.common.util.SecurityUtil; /** * @throws SecurityException if user is not granted global access */ + @Override public final void releaseAllLinkPermission() throws SecurityException { synchronized( secSync ) { allLinkPermissionGranted = false; @@ -119,6 +121,17 @@ import com.jogamp.common.util.SecurityUtil; } protected abstract long openLibraryLocalImpl(final String pathname) throws SecurityException; + @Override + public final String lookupLibraryPathname(final long libraryHandle, final String symbolName) throws SecurityException { + checkLinkPermission(libraryHandle); + final String fname = lookupLibraryPathnameImpl(libraryHandle, symbolName); + if(DEBUG_LOOKUP) { + System.err.println("DynamicLinkerImpl.lookupLibraryPathname(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> '"+fname+"'"); + } + return fname; + } + protected abstract String lookupLibraryPathnameImpl(final long libraryHandle, String symbolName) throws SecurityException; + @Override public final long lookupSymbolGlobal(final String symbolName) throws SecurityException { checkAllLinkPermission(); diff --git a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java index ddaeea2..4a0aeb4 100644 --- a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java @@ -47,6 +47,20 @@ package jogamp.common.os; /** Interface to C language function:
void * dlsym(void * , const char * ); */ protected static native long dlsym(long arg0, java.lang.String arg1); + /** Interface to C language function:
int dladdr(void * , Dl_info *); , returning the Dl_info.dli_fname */ + protected static native java.lang.String dladdr_fname(long arg0); + + @Override + protected final String lookupLibraryPathnameImpl(final long libraryHandle, final String symbolName) throws SecurityException { + if( 0 != libraryHandle && null != symbolName && symbolName.length() > 0 ) { + final long addr = dlsym(libraryHandle, symbolName); + if( 0 != addr ) { + return dladdr_fname(addr); + } + } + return null; + } + @Override protected final long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException { return 0 != libraryHandle ? dlsym(libraryHandle, symbolName) : 0; diff --git a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java index 04f13fb..a99cb35 100644 --- a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java @@ -41,6 +41,9 @@ public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl { /** Interface to C language function:
HANDLE LoadLibraryW(LPCWSTR lpLibFileName); */ private static native long LoadLibraryW(java.lang.String lpLibFileName); + /** Interface to C language function:
PROC GetModuleFileNameA(HANDLE hModule, LPSTR lpFilename, DWORD nSize); */ + private static native java.lang.String GetModuleFileNameA(long hModule); + @Override protected final long openLibraryLocalImpl(final String libraryName) throws SecurityException { // How does that work under Windows ? @@ -53,6 +56,12 @@ public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl { return LoadLibraryW(libraryName); } + @Override + protected final String lookupLibraryPathnameImpl(final long libraryHandle, final String symbolName) throws SecurityException { + // symbolName is not required + return 0 != libraryHandle ? GetModuleFileNameA(libraryHandle) : null; + } + @Override protected final long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException { if(DEBUG_LOOKUP) { diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java index e4adce1..fbf0ff0 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java @@ -37,6 +37,7 @@ import com.jogamp.common.util.RunnableExecutor; import com.jogamp.common.util.TestIOUtil01; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.junit.AfterClass; @@ -58,6 +59,7 @@ public class Test1p2DynamicLibraryBundle extends BaseClass { public static void chapter__TestLoadLibrary() throws Exception { dlb = new DynamicLibraryBundle(new Test1DynLibBundleInfo()); Assert.assertTrue("DynamicLibraryBundle failed", dlb.isLibComplete()); + System.err.println("Loaded: "+dlb.getToolLibraries()); Bindingtest1p2Impl.resetProcAddressTable(dlb); } @@ -261,6 +263,9 @@ public class Test1p2DynamicLibraryBundle extends BaseClass { return libNamesList; } + @Override + public List getSymbolForToolLibPath() { return Arrays.asList("testXID"); } + @Override public final List getToolGetProcAddressFuncNameList() { return null; diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java index e61c600..4791002 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2LoadJNIAndImplLib.java @@ -48,8 +48,9 @@ public class Test1p2LoadJNIAndImplLib extends BaseClass { @BeforeClass public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest1p2(); - dynamicLookupHelper = NativeLibrary.open("test1", true, true, Test1p2LoadJNIAndImplLib.class.getClassLoader(), true); + dynamicLookupHelper = NativeLibrary.open("test1", true, true, Test1p2LoadJNIAndImplLib.class.getClassLoader(), true, "testXID"); Assert.assertNotNull("NativeLibrary.open(test1) failed", dynamicLookupHelper); + System.err.println("Loaded: "+dynamicLookupHelper); Bindingtest1p2Impl.resetProcAddressTable(dynamicLookupHelper); } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java index 366d9eb..b2c1974 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java @@ -57,8 +57,9 @@ public class Test1p2ProcAddressEmitter extends BaseClass { @BeforeClass public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest1p2(); - dynamicLookupHelper = NativeLibrary.open("test1", false, false, Test1p2ProcAddressEmitter.class.getClassLoader(), true); + dynamicLookupHelper = NativeLibrary.open("test1", false, false, Test1p2ProcAddressEmitter.class.getClassLoader(), true, "testXID"); Assert.assertNotNull("NativeLibrary.open(test1) failed", dynamicLookupHelper); + System.err.println("Loaded: "+dynamicLookupHelper); Bindingtest1p2Impl.resetProcAddressTable(dynamicLookupHelper); } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2p2FuncPtr.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2p2FuncPtr.java index 05ae826..4e75fd0 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2p2FuncPtr.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2p2FuncPtr.java @@ -49,8 +49,9 @@ public class Test2p2FuncPtr extends BaseClass2FuncPtr { @BeforeClass public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest2p2(); - dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test2p2FuncPtr.class.getClassLoader(), true); + dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test2p2FuncPtr.class.getClassLoader(), true, "textXID"); Assert.assertNotNull("NativeLibrary.open(test2) failed", dynamicLookupHelper); + System.err.println("Loaded: "+dynamicLookupHelper); Bindingtest2p2Impl.resetProcAddressTable(dynamicLookupHelper); } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test3p2PtrStorage.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test3p2PtrStorage.java index 642e1bd..2c77c1b 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test3p2PtrStorage.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test3p2PtrStorage.java @@ -49,8 +49,9 @@ public class Test3p2PtrStorage extends BaseClass3PtrStorage { @BeforeClass public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest2p2(); - dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test3p2PtrStorage.class.getClassLoader(), true); + dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test3p2PtrStorage.class.getClassLoader(), true, "textXID"); Assert.assertNotNull("NativeLibrary.open(test2) failed", dynamicLookupHelper); + System.err.println("Loaded: "+dynamicLookupHelper); Bindingtest2p2Impl.resetProcAddressTable(dynamicLookupHelper); } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test4p2JavaCallback.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test4p2JavaCallback.java index 7dd9a79..0b0588d 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test4p2JavaCallback.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test4p2JavaCallback.java @@ -49,8 +49,9 @@ public class Test4p2JavaCallback extends BaseClass4JavaCallback { @BeforeClass public static void chapter__TestLoadLibrary() throws Exception { BindingJNILibLoader.loadBindingtest2p2(); - dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test4p2JavaCallback.class.getClassLoader(), true); + dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test4p2JavaCallback.class.getClassLoader(), true, "textXID"); Assert.assertNotNull("NativeLibrary.open(test2) failed", dynamicLookupHelper); + System.err.println("Loaded: "+dynamicLookupHelper); Bindingtest2p2Impl.resetProcAddressTable(dynamicLookupHelper); } diff --git a/src/native/unix/UnixDynamicLinkerImpl_JNI.c b/src/native/unix/UnixDynamicLinkerImpl_JNI.c index d818b3e..844002f 100644 --- a/src/native/unix/UnixDynamicLinkerImpl_JNI.c +++ b/src/native/unix/UnixDynamicLinkerImpl_JNI.c @@ -1,14 +1,22 @@ /* !---- DO NOT EDIT: This file autogenerated by com\sun\gluegen\JavaEmitter.java on Mon Jul 31 16:26:59 PDT 2006 ----! */ +#if defined(_WIN32) + // NOP +#elif defined(__linux__) + #define _GNU_SOURCE +#else + // NOP +#endif + +#include +#include + #include #include #include "jogamp_common_os_UnixDynamicLinkerImpl.h" - #include - #include - #ifndef RTLD_DEFAULT #define RTLD_DEFAULT ((void *) 0) #endif @@ -127,3 +135,18 @@ Java_jogamp_common_os_UnixDynamicLinkerImpl_dlsym(JNIEnv *env, jclass _unused, j return (jlong) (intptr_t) _res; } +/* + * Class: jogamp_common_os_UnixDynamicLinkerImpl + * Method: dladdr_fname + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_jogamp_common_os_UnixDynamicLinkerImpl_dladdr_1fname(JNIEnv *env, jclass _unused, jlong arg0) { + Dl_info info; + if( 0 != dladdr((void *) (intptr_t) arg0, &info) && NULL != info.dli_fname ) { + return (*env)->NewStringUTF(env, info.dli_fname); + } else { + return NULL; + } +} + diff --git a/src/native/windows/WindowsDynamicLinkerImpl_JNI.c b/src/native/windows/WindowsDynamicLinkerImpl_JNI.c index ef94bb0..1874b30 100644 --- a/src/native/windows/WindowsDynamicLinkerImpl_JNI.c +++ b/src/native/windows/WindowsDynamicLinkerImpl_JNI.c @@ -94,4 +94,20 @@ Java_jogamp_common_os_WindowsDynamicLinkerImpl_LoadLibraryW(JNIEnv *env, jclass return (jlong) (intptr_t) _res; } +/* + * Class: jogamp_common_os_WindowsDynamicLinkerImpl + * Method: GetModuleFileNameA + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_jogamp_common_os_WindowsDynamicLinkerImpl_GetModuleFileNameA(JNIEnv *env, jclass _unused, jlong hModule) { + TCHAR tpath[PATH_MAX+1]; + memset(tpath, 0, PATH_MAX+1); + DWORD size = GetModuleFileNameA((HANDLE) (intptr_t) hModule, (LPTSTR)&tpath, PATH_MAX); + if( 0 == size ) { + return NULL; + } + return (*env)->NewStringUTF(env, tpath); +} + -- cgit v1.2.3