diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/java/com/jogamp/common/os/NativeLibrary.java | 54 | ||||
-rw-r--r-- | src/java/jogamp/common/os/PlatformPropsImpl.java | 117 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/os/TestElfReader01.java | 56 |
3 files changed, 168 insertions, 59 deletions
diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 49ec860..130812c 100755 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -277,11 +277,11 @@ public class NativeLibrary implements DynamicLookupHelper { /** Given the base library names (no prefixes/suffixes) for the various platforms, enumerate the possible locations and names of the indicated native library on the system. */ - public static List<String> enumerateLibraryPaths(String windowsLibName, - String unixLibName, - String macOSXLibName, - boolean searchSystemPathFirst, - ClassLoader loader) { + public static List<String> enumerateLibraryPaths(final String windowsLibName, + final String unixLibName, + final String macOSXLibName, + final boolean searchSystemPathFirst, + final ClassLoader loader) { List<String> paths = new ArrayList<String>(); String libName = selectName(windowsLibName, unixLibName, macOSXLibName); if (libName == null) { @@ -312,17 +312,43 @@ public class NativeLibrary implements DynamicLookupHelper { } // Add entries from java.library.path - String javaLibraryPath = - AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return System.getProperty("java.library.path"); + final String[] javaLibraryPaths = + AccessController.doPrivileged(new PrivilegedAction<String[]>() { + public String[] run() { + int count = 0; + final String usrPath = System.getProperty("java.library.path"); + if(null != usrPath) { + count++; + } + final String sysPath = System.getProperty("sun.boot.library.path"); + if(null != sysPath) { + count++; + } + final String[] res = new String[count]; + int i=0; + if (searchSystemPathFirst) { + if(null != sysPath) { + res[i++] = sysPath; + } + } + if(null != usrPath) { + res[i++] = usrPath; + } + if (!searchSystemPathFirst) { + if(null != sysPath) { + res[i++] = sysPath; + } + } + return res; } }); - if (javaLibraryPath != null) { - StringTokenizer tokenizer = new StringTokenizer(javaLibraryPath, File.pathSeparator); - while (tokenizer.hasMoreTokens()) { - addPaths(tokenizer.nextToken(), baseNames, paths); - } + if ( null != javaLibraryPaths ) { + for( int i=0; i < javaLibraryPaths.length; i++ ) { + final StringTokenizer tokenizer = new StringTokenizer(javaLibraryPaths[i], File.pathSeparator); + while (tokenizer.hasMoreTokens()) { + addPaths(tokenizer.nextToken(), baseNames, paths); + } + } } // Add current working directory diff --git a/src/java/jogamp/common/os/PlatformPropsImpl.java b/src/java/jogamp/common/os/PlatformPropsImpl.java index 0c597cb..5b8bf0e 100644 --- a/src/java/jogamp/common/os/PlatformPropsImpl.java +++ b/src/java/jogamp/common/os/PlatformPropsImpl.java @@ -1,5 +1,6 @@ package jogamp.common.os; +import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; @@ -7,6 +8,7 @@ import java.nio.IntBuffer; import java.nio.ShortBuffer; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.List; import jogamp.common.Debug; import jogamp.common.os.elf.ElfHeader; @@ -15,6 +17,7 @@ import jogamp.common.os.elf.SectionHeader; import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.AndroidVersion; +import com.jogamp.common.os.NativeLibrary; import com.jogamp.common.os.Platform; import com.jogamp.common.os.Platform.ABIType; import com.jogamp.common.os.Platform.CPUFamily; @@ -91,7 +94,7 @@ public abstract class PlatformPropsImpl { CPU_ARCH = getCPUTypeImpl(ARCH_lower); OS_TYPE = getOSTypeImpl(); - ABI_TYPE = queryABITypeImpl(CPU_ARCH, OS_TYPE); + ABI_TYPE = queryABITypeImpl(OS_TYPE, CPU_ARCH); os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE); } @@ -185,59 +188,81 @@ public abstract class PlatformPropsImpl { * <li> not {@link CPUFamily#ARM} -> {@link ABIType#GENERIC_ABI} </li> * <li> else * <ul> - * <li> not {@link OSType#LINUX} -> {@link ABIType#EABI_GNU_ARMEL} </li> + * <li> {@link OSType#ANDROID} -> {@link ABIType#EABI_GNU_ARMEL} (due to EACCES, Permission denied)</li> * <li> else * <ul> - * <li> Elf ARM Tags -> {@link ABIType#EABI_GNU_ARMEL}, {@link ABIType#EABI_GNU_ARMHF} </li> + * <li> Elf ARM Tags -> {@link ABIType#EABI_GNU_ARMEL}, {@link ABIType#EABI_GNU_ARMHF}</li> + * <li> On Error -> {@link ABIType#EABI_GNU_ARMEL}</li> * </ul></li> * </ul></li> * </ul> * </p> * <p> + * For Elf parsing either the current executable is used (Linux) or a found java/jvm native library. + * </p> + * <p> * Elf ARM Tags are read using {@link ElfHeader}, .. and {@link SectionArmAttributes#abiVFPArgsAcceptsVFPVariant(byte)}. * </p> - * - * @param cpuType * @param osType + * @param cpuType + * * @return */ - private static final ABIType queryABITypeImpl(CPUType cpuType, OSType osType) { + private static final ABIType queryABITypeImpl(final OSType osType, final CPUType cpuType) { if( CPUFamily.ARM != cpuType.family ) { return ABIType.GENERIC_ABI; } - // TODO: GNU/Linux-Android and other OS - // Android: /proc/self/exe: open failed: EACCES (Permission denied) - // ( OSType.LINUX != osType && OSType.ANDROID != osType ) ) - if( OSType.LINUX != osType ) { + if( OSType.ANDROID == osType ) { // EACCES (Permission denied) - We assume a not rooted device! return ABIType.EABI_GNU_ARMEL; } return AccessController.doPrivileged(new PrivilegedAction<ABIType>() { private final String GNU_LINUX_SELF_EXE = "/proc/self/exe"; public ABIType run() { + boolean abiARM = false; boolean abiVFPArgsAcceptsVFPVariant = false; RandomAccessFile in = null; try { - in = new RandomAccessFile(GNU_LINUX_SELF_EXE, "r"); - final ElfHeader eh = ElfHeader.read(in); - if(DEBUG) { - System.err.println("ELF: Got HDR "+GNU_LINUX_SELF_EXE+": "+eh); - } - final SectionHeader sh = eh.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); - if( null != sh ) { - if(DEBUG) { - System.err.println("ELF: Got ARM Attribs Section Header: "+sh); + File file = null; + if( OSType.LINUX == osType ) { + file = new File(GNU_LINUX_SELF_EXE); + if( !checkFileReadAccess(file) ) { + file = null; } - final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); + } + if( null == file ) { + file = findSysLib("java"); + } + if( null == file ) { + file = findSysLib("jvm"); + } + if( null != file ) { + in = new RandomAccessFile(file, "r"); + final ElfHeader eh = ElfHeader.read(in); if(DEBUG) { - System.err.println("ELF: Got ARM Attribs Section Block : "+sArmAttrs); + System.err.println("ELF: Got HDR "+GNU_LINUX_SELF_EXE+": "+eh); } - final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args); - if( null != abiVFPArgsAttr ) { - abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); + abiARM = eh.isArm(); + if( abiARM ) { + final SectionHeader sh = eh.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); + if( null != sh ) { + if(DEBUG) { + System.err.println("ELF: Got ARM Attribs Section Header: "+sh); + } + final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); + if(DEBUG) { + System.err.println("ELF: Got ARM Attribs Section Block : "+sArmAttrs); + } + final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args); + if( null != abiVFPArgsAttr ) { + abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); + } + } } } } catch(Throwable t) { - t.printStackTrace(); + if(DEBUG) { + t.printStackTrace(); + } } finally { if(null != in) { try { @@ -245,13 +270,42 @@ public abstract class PlatformPropsImpl { } catch (IOException e) { } } } - final ABIType res = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; + final ABIType res; + if( abiARM ) { + res = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; + } else { + res = ABIType.GENERIC_ABI; + } if(DEBUG) { - System.err.println("ELF: abiVFPArgsAcceptsVFPVariant : "+abiVFPArgsAcceptsVFPVariant+" -> "+res); + System.err.println("ELF: abiARM "+abiARM+", abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant+" -> "+res); } return res; } } ); } + private static boolean checkFileReadAccess(File file) { + try { + return file.isFile() && file.canRead(); + } catch (Throwable t) { } + return false; + } + private static File findSysLib(String libName) { + ClassLoader cl = PlatformPropsImpl.class.getClassLoader(); + final List<String> possibleLibPaths = NativeLibrary.enumerateLibraryPaths(libName, libName, libName, true, cl); + for(int i=0; i<possibleLibPaths.size(); i++) { + final String libPath = possibleLibPaths.get(i); + final File lib = new File(libPath); + if(DEBUG) { + System.err.println("findSysLib #"+i+": test "+lib); + } + if( checkFileReadAccess(lib) ) { + return lib; + } + if(DEBUG) { + System.err.println("findSysLib #"+i+": "+lib+" not readable"); + } + } + return null; + } private static final OSType getOSTypeImpl() throws RuntimeException { if ( AndroidVersion.isAvailable ) { @@ -303,6 +357,7 @@ public abstract class PlatformPropsImpl { * <li>linux-ia64</li> * <li>linux-i586</li> * <li>linux-armv6</li> + * <li>linux-armv6hf</li> * <li>android-armv6</li> * <li>macosx-universal</li> * <li>solaris-sparc</li> @@ -322,16 +377,10 @@ public abstract class PlatformPropsImpl { _os_and_arch = "i586"; break; case ARM: - _os_and_arch = "armv6"; // TODO: sync with gluegen-cpptasks-base.xml - break; case ARMv5: - _os_and_arch = "armv6"; - break; case ARMv6: - _os_and_arch = "armv6"; - break; case ARMv7: - _os_and_arch = "armv6"; + _os_and_arch = "armv6"; // TODO: sync with gluegen-cpptasks-base.xml break; case SPARC_32: _os_and_arch = "sparc"; diff --git a/src/junit/com/jogamp/common/os/TestElfReader01.java b/src/junit/com/jogamp/common/os/TestElfReader01.java index 1f42067..3993fc4 100644 --- a/src/junit/com/jogamp/common/os/TestElfReader01.java +++ b/src/junit/com/jogamp/common/os/TestElfReader01.java @@ -6,6 +6,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; +import java.util.List; import jogamp.common.os.elf.ElfHeader; import jogamp.common.os.elf.Section; @@ -21,28 +22,61 @@ public class TestElfReader01 extends JunitTracer { public static String GNU_LINUX_SELF_EXE = "/proc/self/exe"; public static String ARM_HF_EXE = "tst-exe-armhf"; public static String ARM_SF_EXE = "tst-exe-arm"; + + private static boolean checkFileReadAccess(File file) { + try { + return file.isFile() && file.canRead(); + } catch (Throwable t) { } + return false; + } + static File findJVMLib(String libName) { + ClassLoader cl = TestElfReader01.class.getClassLoader(); + final List<String> possibleLibPaths = NativeLibrary.enumerateLibraryPaths(libName, libName, libName, true, cl); + for(int i=0; i<possibleLibPaths.size(); i++) { + final String libPath = possibleLibPaths.get(i); + final File lib = new File(libPath); + System.err.println("XXX2 #"+i+": test "+lib); + if( checkFileReadAccess(lib) ) { + return lib; + } + System.err.println("XXX2 #"+i+": "+lib+" not readable"); + } + return null; + } @Test public void testGNULinuxSelfExe () throws IOException { if( OSType.LINUX == Platform.getOSType() ) { - testElfHeaderImpl(GNU_LINUX_SELF_EXE, false); + File f = new File(GNU_LINUX_SELF_EXE); + if( checkFileReadAccess(f) ) { + testElfHeaderImpl(f, false); + } } } - // @Test - public void testArmHFExe () throws IOException { - testElfHeaderImpl(ARM_HF_EXE, false); - } - - // @Test - public void testArmSFExe () throws IOException { - testElfHeaderImpl(ARM_SF_EXE, false); + @Test + public void testJavaLib () throws IOException { + File jvmLib = findJVMLib("java"); + if( null == jvmLib ) { + jvmLib = findJVMLib("jvm"); + } + if( null != jvmLib ) { + testElfHeaderImpl(jvmLib, false); + } } - void testElfHeaderImpl(String file, boolean fileOutSections) throws IOException { + void testElfHeaderImpl(File file, boolean fileOutSections) throws IOException { + System.err.println("Test file "+file.getAbsolutePath()); RandomAccessFile in = new RandomAccessFile(file, "r"); try { - final ElfHeader eh = ElfHeader.read(in); + final ElfHeader eh; + try { + eh = ElfHeader.read(in); + } catch (Exception e) { + System.err.println("Probably not an ELF file - or not in current format: (catched) "+e.getMessage()); + e.printStackTrace(); + return; + } int i=0; System.err.println(eh); System.err.println("SH entsz "+eh.d.getE_shentsize()); |