aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-01-24 13:05:11 +0100
committerSven Gothel <[email protected]>2014-01-24 13:05:11 +0100
commit022c31eefaa0c11fbc069fd35cf5311a556c9ae5 (patch)
tree15468323ce0ad1d1e368c1aaaba1f594742aacaa /src/java
parent2868816971bb80eb226e6edffc527d909ced755b (diff)
Bug 856 - Android: Support dual ABI (x86 i686 *and* ARMv7arm), i.e. pick 'best' ABI
- Use 'os.arch' as a prelim CPUType for MachineDescription - Always attempt to load a binary and parse it's elf header - Linux: self-exe - Android: gluegen-rt library - Other: java lib - Always use details (ABI) if ARM - Android: Check CPU_TYPE and CPU_TYPE2 // FIXME / HACK: // We use sCPUType for MachineDescriptionRuntime.getStatic() // until we have determined the final CPU_TYPE, etc. // MachineDescriptionRuntime gets notified via MachineDescriptionRuntime.notifyPropsInitialized() below. // // We could use Elf Ehdr's machine value to determine the bit-size // used for it's offset table! // However, 'os.arch' should be a good guess for this task. Tested manually on - Linux x86, x86_64, armhf (raspi) - Android intel and arm - Windows x86_64 - OSX x86_64
Diffstat (limited to 'src/java')
-rw-r--r--src/java/com/jogamp/common/os/AndroidVersion.java83
-rw-r--r--src/java/com/jogamp/common/os/Platform.java8
-rw-r--r--src/java/jogamp/common/os/MachineDescriptionRuntime.java61
-rw-r--r--src/java/jogamp/common/os/PlatformPropsImpl.java322
-rw-r--r--src/java/jogamp/common/os/android/GluegenVersionActivity.java33
-rw-r--r--src/java/jogamp/common/os/elf/ElfHeader.java36
6 files changed, 391 insertions, 152 deletions
diff --git a/src/java/com/jogamp/common/os/AndroidVersion.java b/src/java/com/jogamp/common/os/AndroidVersion.java
index a710310..edf2229 100644
--- a/src/java/com/jogamp/common/os/AndroidVersion.java
+++ b/src/java/com/jogamp/common/os/AndroidVersion.java
@@ -29,12 +29,25 @@ package com.jogamp.common.os;
import java.lang.reflect.Field;
+import com.jogamp.common.os.Platform.ABIType;
+import com.jogamp.common.os.Platform.CPUFamily;
+import com.jogamp.common.os.Platform.CPUType;
import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.common.util.ReflectionUtil;
public class AndroidVersion {
public static final boolean isAvailable;
+ /** The name of the instruction set (CPU type + ABI convention) of native code. API-4. All lower case.*/
+ public static final String CPU_ABI;
+ public static final CPUType CPU_TYPE;
+ public static final ABIType ABI_TYPE;
+
+ /** The name of the second instruction set (CPU type + ABI convention) of native code. API-8. All lower case.*/
+ public static final String CPU_ABI2;
+ public static final CPUType CPU_TYPE2;
+ public static final ABIType ABI_TYPE2;
+
/** Development codename, or the string "REL" for official release */
public static final String CODENAME;
@@ -50,37 +63,90 @@ public class AndroidVersion {
/** SDK Version string */
public static final String SDK_NAME;
+ private static final String androidBuild = "android.os.Build";
private static final String androidBuildVersion = "android.os.Build$VERSION";
private static final String androidBuildVersionCodes = "android.os.Build$VERSION_CODES";
+ /**
+ * Returns {@link CPUType} for matching <code>cpuABI<code>,
+ * i.e. {@link #CPU_ABI} or {@link #CPU_ABI2},
+ * or <code>null</code> for no match.
+ * <p>
+ * FIXME: Where is a comprehensive list of known 'android.os.Build.CPU_ABI' and 'android.os.Build.CPU_ABI2' strings ?<br/>
+ * Fount this one: <code>http://www.kandroid.org/ndk/docs/CPU-ARCH-ABIS.html</code>
+ * <pre>
+ * lib/armeabi/libfoo.so
+ * lib/armeabi-v7a/libfoo.so
+ * lib/x86/libfoo.so
+ * lib/mips/libfoo.so
+ * </pre>
+ * </p>
+ */
+ private static final CPUType getCPUTypeImpl(String cpuABI) {
+ if( null == cpuABI ) {
+ return null;
+ } else if( cpuABI.equals("armeabi-v7a") ) {
+ return CPUType.ARMv7;
+ } else if( cpuABI.equals("armeabi") ||
+ cpuABI.startsWith("arm") ) { // last chance ..
+ return CPUType.ARM;
+ } else if( cpuABI.equals("x86") ) {
+ return CPUType.X86_32;
+ } else if( cpuABI.equals("mips") ) { // no 32bit vs 64bit identifier ?
+ return CPUType.MIPS_32;
+ } else {
+ return null;
+ }
+ }
+ private static final ABIType getABITypeImpl(final CPUType cpuType, String cpuABI) {
+ if( null == cpuType || null == cpuABI ) {
+ return null;
+ } else if( CPUFamily.ARM != cpuType.family ) {
+ return ABIType.GENERIC_ABI;
+ }
+ return ABIType.EABI_GNU_ARMEL; // FIXME: How will they name ABIType.EABI_GNU_ARMHF
+ }
+
static {
final ClassLoader cl = AndroidVersion.class.getClassLoader();
+ Class<?> abClass = null;
+ Object abObject= null;
Class<?> abvClass = null;
Object abvObject= null;
Class<?> abvcClass = null;
Object abvcObject= null;
try {
+ abClass = ReflectionUtil.getClass(androidBuild, true, cl);
+ abObject = abClass.newInstance();
abvClass = ReflectionUtil.getClass(androidBuildVersion, true, cl);
abvObject = abvClass.newInstance();
abvcClass = ReflectionUtil.getClass(androidBuildVersionCodes, true, cl);
abvcObject = abvcClass.newInstance();
} catch (Exception e) { /* n/a */ }
- isAvailable = null != abvObject;
+ isAvailable = null != abObject && null != abvObject && null != abvcObject;
if(isAvailable) {
- CODENAME = getString(abvClass, abvObject, "CODENAME");
- INCREMENTAL = getString(abvClass, abvObject, "INCREMENTAL");
- RELEASE = getString(abvClass, abvObject, "RELEASE");
+ CPU_ABI = getString(abClass, abObject, "CPU_ABI", true);
+ CPU_ABI2 = getString(abClass, abObject, "CPU_ABI2", true);
+ CODENAME = getString(abvClass, abvObject, "CODENAME", false);
+ INCREMENTAL = getString(abvClass, abvObject, "INCREMENTAL", false);
+ RELEASE = getString(abvClass, abvObject, "RELEASE", false);
SDK_INT = getInt(abvClass, abvObject, "SDK_INT");
final IntObjectHashMap version_codes = getVersionCodes(abvcClass, abvcObject);
final String sdk_name = (String) version_codes.get(SDK_INT);
SDK_NAME = ( null != sdk_name ) ? sdk_name : "SDK_"+SDK_INT ;
} else {
+ CPU_ABI = null;
+ CPU_ABI2 = null;
CODENAME = null;
INCREMENTAL = null;
RELEASE = null;
SDK_INT = -1;
SDK_NAME = null;
}
+ CPU_TYPE = getCPUTypeImpl(CPU_ABI);
+ ABI_TYPE = getABITypeImpl(CPU_TYPE, CPU_ABI);
+ CPU_TYPE2 = getCPUTypeImpl(CPU_ABI2);
+ ABI_TYPE2 = getABITypeImpl(CPU_TYPE2, CPU_ABI2);
}
private static final IntObjectHashMap getVersionCodes(Class<?> cls, Object obj) {
@@ -97,10 +163,15 @@ public class AndroidVersion {
return map;
}
- private static final String getString(Class<?> cls, Object obj, String name) {
+ private static final String getString(Class<?> cls, Object obj, String name, boolean lowerCase) {
try {
Field f = cls.getField(name);
- return (String) f.get(obj);
+ final String s = (String) f.get(obj);
+ if( lowerCase && null != s ) {
+ return s.toLowerCase();
+ } else {
+ return s;
+ }
} catch (Exception e) { e.printStackTrace(); /* n/a */ }
return null;
}
diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java
index ee57d6a..e410e81 100644
--- a/src/java/com/jogamp/common/os/Platform.java
+++ b/src/java/com/jogamp/common/os/Platform.java
@@ -76,6 +76,8 @@ public class Platform extends PlatformPropsImpl {
PPC( 0x00020000),
/** SPARC */
SPARC( 0x00030000),
+ /** Mips */
+ MIPS( 0x00040000),
/** PA RISC */
PA_RISC(0xFFFF0000),
/** Itanium */
@@ -107,6 +109,10 @@ public class Platform extends PlatformPropsImpl {
SPARC_32( CPUFamily.SPARC, 0x0001),
/** SPARC 64bit */
SPARCV9_64(CPUFamily.SPARC, 0x0002),
+ /** MIPS 32bit */
+ MIPS_32( CPUFamily.MIPS, 0x0001),
+ /** MIPS 64bit */
+ MIPS_64( CPUFamily.MIPS, 0x0002),
/** Itanium default */
IA64( CPUFamily.IA64, 0x0000),
/** PA_RISC2_0 */
@@ -308,7 +314,7 @@ public class Platform extends PlatformPropsImpl {
/**
* Returns the OS type.
- * <p>In case of {@link OSType#ANDROID} the OS name, see {@link #getOSName()}, is Linux</p>
+ * <p>In case of {@link OSType#ANDROID} the {@link #getOSName() OS name}, is Linux</p>
*/
public static OSType getOSType() {
return OS_TYPE;
diff --git a/src/java/jogamp/common/os/MachineDescriptionRuntime.java b/src/java/jogamp/common/os/MachineDescriptionRuntime.java
index 01559b9..254cda2 100644
--- a/src/java/jogamp/common/os/MachineDescriptionRuntime.java
+++ b/src/java/jogamp/common/os/MachineDescriptionRuntime.java
@@ -37,23 +37,42 @@ import com.jogamp.common.os.MachineDescription.StaticConfig;
*/
public class MachineDescriptionRuntime {
- static volatile boolean smdQueried = false;
- static MachineDescription.StaticConfig smd = null;
+ static volatile boolean smdHardQueried = false;
+ static MachineDescription.StaticConfig smdHard = null;
+
+ static volatile boolean smdSoftQueried = false;
+ static MachineDescription.StaticConfig smdSoft = null;
+
+ static volatile boolean smdHardEnabled = false;
+
+ /* pp */ static void notifyPropsInitialized() { smdHardEnabled = true; }
public static MachineDescription.StaticConfig getStatic() {
- if(!smdQueried) {
- synchronized(MachineDescription.class) { // volatile dbl-checked-locking OK
- if(!smdQueried) {
- smd = getStaticImpl();
- smdQueried=true;
- }
- }
- }
- return smd;
+ if(!smdHardEnabled) {
+ if(!smdSoftQueried) {
+ synchronized(MachineDescription.class) { // volatile dbl-checked-locking OK
+ if(!smdSoftQueried) {
+ smdSoft = get(PlatformPropsImpl.OS_TYPE, PlatformPropsImpl.sCpuType, PlatformPropsImpl.LITTLE_ENDIAN);
+ smdSoftQueried=true;
+ }
+ }
+ }
+ return smdSoft;
+ } else {
+ if(!smdHardQueried) {
+ synchronized(MachineDescription.class) { // volatile dbl-checked-locking OK
+ if(!smdHardQueried) {
+ smdHard = get(PlatformPropsImpl.OS_TYPE, PlatformPropsImpl.CPU_ARCH, PlatformPropsImpl.LITTLE_ENDIAN);
+ smdHardQueried=true;
+ }
+ }
+ }
+ return smdHard;
+ }
}
- private static boolean isCPUArch32Bit() throws RuntimeException {
- switch( PlatformPropsImpl.CPU_ARCH ) {
+ private static boolean isCPUArch32Bit(final Platform.CPUType cpuType) throws RuntimeException {
+ switch( cpuType ) {
case X86_32:
case ARM:
case ARMv5:
@@ -72,23 +91,23 @@ public class MachineDescriptionRuntime {
}
}
- private static MachineDescription.StaticConfig getStaticImpl() {
- if(isCPUArch32Bit()) {
- if(PlatformPropsImpl.CPU_ARCH.getFamily() == Platform.CPUFamily.ARM && PlatformPropsImpl.LITTLE_ENDIAN) {
+ private static MachineDescription.StaticConfig get(final Platform.OSType osType, final Platform.CPUType cpuType, final boolean littleEndian) {
+ if( isCPUArch32Bit(cpuType) ) {
+ if( cpuType.getFamily() == Platform.CPUFamily.ARM && littleEndian) {
return StaticConfig.ARMle_EABI;
- } else if(PlatformPropsImpl.OS_TYPE == Platform.OSType.WINDOWS) {
+ } else if( osType == Platform.OSType.WINDOWS ) {
return StaticConfig.X86_32_WINDOWS;
- } else if(PlatformPropsImpl.OS_TYPE == Platform.OSType.MACOS) {
+ } else if( osType == Platform.OSType.MACOS ) {
return StaticConfig.X86_32_MACOS;
- } else if (PlatformPropsImpl.OS_TYPE == Platform.OSType.SUNOS) {
- if (PlatformPropsImpl.CPU_ARCH == Platform.CPUType.SPARC_32) {
+ } else if ( osType == Platform.OSType.SUNOS ) {
+ if ( cpuType == Platform.CPUType.SPARC_32 ) {
return StaticConfig.SPARC_32_SUNOS;
}
// TODO SPARCv9 description is missing
}
return StaticConfig.X86_32_UNIX;
} else {
- if(PlatformPropsImpl.OS_TYPE == Platform.OSType.WINDOWS) {
+ if( osType == Platform.OSType.WINDOWS ) {
return StaticConfig.X86_64_WINDOWS;
}
return StaticConfig.X86_64_UNIX;
diff --git a/src/java/jogamp/common/os/PlatformPropsImpl.java b/src/java/jogamp/common/os/PlatformPropsImpl.java
index 66fb5f9..f3b7ace 100644
--- a/src/java/jogamp/common/os/PlatformPropsImpl.java
+++ b/src/java/jogamp/common/os/PlatformPropsImpl.java
@@ -78,6 +78,8 @@ public abstract class PlatformPropsImpl {
public static final String NEWLINE;
public static final boolean LITTLE_ENDIAN;
+ /* pp */ static final CPUType sCpuType;
+
public static final CPUType CPU_ARCH;
public static final ABIType ABI_TYPE;
public static final OSType OS_TYPE;
@@ -86,14 +88,10 @@ public abstract class PlatformPropsImpl {
static {
Version16 = new VersionNumber(1, 6, 0);
Version17 = new VersionNumber(1, 7, 0);
+
// We don't seem to need an AccessController.doPrivileged() block
// here as these system properties are visible even to unsigned Applets.
- OS = System.getProperty("os.name");
- OS_lower = OS.toLowerCase();
- OS_VERSION = System.getProperty("os.version");
- OS_VERSION_NUMBER = new VersionNumber(OS_VERSION);
- ARCH = System.getProperty("os.arch");
- ARCH_lower = ARCH.toLowerCase();
+ final boolean isAndroid = AndroidVersion.isAvailable; // also triggers it's static initialization
JAVA_VENDOR = System.getProperty("java.vendor");
JAVA_VENDOR_URL = System.getProperty("java.vendor.url");
JAVA_VERSION = System.getProperty("java.version");
@@ -111,14 +109,116 @@ public abstract class PlatformPropsImpl {
JAVA_VM_NAME = System.getProperty("java.vm.name");
JAVA_RUNTIME_NAME = getJavaRuntimeNameImpl();
JAVA_SE = initIsJavaSE();
- JAVA_6 = JAVA_SE && ( AndroidVersion.isAvailable || JAVA_VERSION_NUMBER.compareTo(Version16) >= 0 ) ;
+ JAVA_6 = JAVA_SE && ( isAndroid || JAVA_VERSION_NUMBER.compareTo(Version16) >= 0 ) ;
NEWLINE = System.getProperty("line.separator");
+
+ OS = System.getProperty("os.name");
+ OS_lower = OS.toLowerCase();
+ OS_VERSION = System.getProperty("os.version");
+ OS_VERSION_NUMBER = new VersionNumber(OS_VERSION);
+ OS_TYPE = getOSTypeImpl(OS_lower, isAndroid);
+
LITTLE_ENDIAN = queryIsLittleEndianImpl();
- CPU_ARCH = getCPUTypeImpl(ARCH_lower);
- OS_TYPE = getOSTypeImpl();
- ABI_TYPE = queryABITypeImpl(OS_TYPE, CPU_ARCH);
+ // Soft values, i.e. w/o probing binaries
+ final String sARCH = System.getProperty("os.arch");
+ final String sARCH_lower = sARCH.toLowerCase();
+ sCpuType = getCPUTypeImpl(sARCH_lower);
+ if( DEBUG ) {
+ System.err.println("Platform.Soft: str "+sARCH+", cpuType "+sCpuType);
+ }
+
+ // Hard values, i.e. w/ probing binaries
+ //
+ // FIXME / HACK:
+ // We use sCPUType for MachineDescriptionRuntime.getStatic()
+ // until we have determined the final CPU_TYPE, etc.
+ // MachineDescriptionRuntime gets notified via MachineDescriptionRuntime.notifyPropsInitialized() below.
+ //
+ // We could use Elf Ehdr's machine value to determine the bit-size
+ // used for it's offset table!
+ // However, 'os.arch' should be a good guess for this task.
+ final CPUType ehCpuType;
+ final ABIType ehAbiType;
+ final boolean ehValid;
+ {
+ final CPUType[] _ehCpuType = { null };
+ final ABIType[] _ehAbiType = { null };
+ final ElfHeader eh = queryABITypeImpl(OS_TYPE, _ehCpuType, _ehAbiType);
+ if( null != eh && null != _ehCpuType[0] && null != _ehAbiType[0] ) {
+ ehCpuType = _ehCpuType[0];
+ ehAbiType = _ehAbiType[0];
+ if( isAndroid ) {
+ if( DEBUG ) {
+ System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", cpu "+AndroidVersion.CPU_TYPE+", abi "+AndroidVersion.ABI_TYPE);
+ System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", cpu "+AndroidVersion.CPU_TYPE2+", abi "+AndroidVersion.ABI_TYPE2);
+ }
+ final CPUFamily aCpuFamily1 = null != AndroidVersion.CPU_TYPE ? AndroidVersion.CPU_TYPE.family : null;
+ final CPUFamily aCpuFamily2 = null != AndroidVersion.CPU_TYPE2 ? AndroidVersion.CPU_TYPE2.family : null;
+ if( ehCpuType.family != aCpuFamily1 && ehCpuType.family != aCpuFamily2 ) {
+ // Ooops !
+ ehValid = false;
+ } else {
+ ehValid = true;
+ }
+ } else {
+ if( ehCpuType.family != sCpuType.family ) {
+ // Ooops !
+ ehValid = false;
+ } else {
+ ehValid = true;
+ }
+ }
+ if( DEBUG ) {
+ System.err.println("Platform.Elf: cpuType "+ehCpuType+", abiType "+ehAbiType+", valid "+ehValid);
+ }
+ } else {
+ ehCpuType = null;
+ ehAbiType = null;
+ ehValid = false;
+ if( DEBUG ) {
+ System.err.println("Platform.Elf: n/a");
+ }
+ }
+ }
+ if( isAndroid ) {
+ if( ehValid ) {
+ if( ehCpuType.family == AndroidVersion.CPU_TYPE.family ) {
+ ARCH = AndroidVersion.CPU_ABI;
+ CPU_ARCH = AndroidVersion.CPU_TYPE;
+ } else {
+ ARCH = AndroidVersion.CPU_ABI2;
+ CPU_ARCH = AndroidVersion.CPU_TYPE2;
+ }
+ ABI_TYPE = ehAbiType;
+ } else {
+ // default
+ if( AndroidVersion.CPU_TYPE.family == CPUFamily.ARM || null == AndroidVersion.CPU_TYPE2 ) {
+ ARCH = AndroidVersion.CPU_ABI;
+ CPU_ARCH = AndroidVersion.CPU_TYPE;
+ ABI_TYPE = AndroidVersion.ABI_TYPE;
+ } else {
+ ARCH = AndroidVersion.CPU_ABI2;
+ CPU_ARCH = AndroidVersion.CPU_TYPE2;
+ ABI_TYPE = AndroidVersion.ABI_TYPE2;
+ }
+ }
+ ARCH_lower = ARCH;
+ } else {
+ ARCH = sARCH;
+ ARCH_lower = sARCH_lower;
+ if( ehValid && CPUFamily.ARM == ehCpuType.family ) {
+ // Use Elf for ARM
+ CPU_ARCH = ehCpuType;
+ ABI_TYPE = ehAbiType;
+ } else {
+ // Otherwise trust detailed os.arch (?)
+ CPU_ARCH = sCpuType;
+ ABI_TYPE = ABIType.GENERIC_ABI;
+ }
+ }
+ MachineDescriptionRuntime.notifyPropsInitialized();
os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE);
}
@@ -159,8 +259,8 @@ public abstract class PlatformPropsImpl {
return 0x0C0D == tst_s.get(0);
}
- private static final CPUType getCPUTypeImpl(String archLower) {
- if( archLower.equals("x86") ||
+ private static final CPUType getCPUTypeImpl(final String archLower) {
+ if( archLower.equals("x86") || // jvm + android
archLower.equals("i386") ||
archLower.equals("i486") ||
archLower.equals("i586") ||
@@ -177,7 +277,9 @@ public abstract class PlatformPropsImpl {
return CPUType.ARMv5;
} else if( archLower.equals("armv6l") ) {
return CPUType.ARMv6;
- } else if( archLower.equals("armv7l") ) {
+ } else if( archLower.equals("armv7l") ||
+ archLower.equals("armeabi") || // android
+ archLower.equals("armeabi-v7a") ) { // android
return CPUType.ARMv7;
} else if( archLower.equals("sparc") ) {
return CPUType.SPARC_32;
@@ -187,13 +289,15 @@ public abstract class PlatformPropsImpl {
return CPUType.PA_RISC2_0;
} else if( archLower.equals("ppc") ) {
return CPUType.PPC;
+ } else if( archLower.equals("mips") ) { // android
+ return CPUType.MIPS_32;
} else {
throw new RuntimeException("Please port CPU detection to your platform (" + OS_lower + "/" + archLower + ")");
}
}
@SuppressWarnings("unused")
- private static final boolean contains(String data, String[] search) {
+ private static final boolean contains(final String data, final String[] search) {
if(null != data && null != search) {
for(int i=0; i<search.length; i++) {
if(data.indexOf(search[i]) >= 0) {
@@ -208,114 +312,120 @@ public abstract class PlatformPropsImpl {
* Returns the {@link ABIType} of the current platform using given {@link CPUType cpuType}
* and {@link OSType osType} as a hint.
* <p>
- * Note the following queries are performed:
+ * For Elf parsing one of the following binaries is used:
* <ul>
- * <li> not {@link CPUFamily#ARM} -> {@link ABIType#GENERIC_ABI} </li>
- * <li> else
- * <ul>
- * <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> On Error -> {@link ABIType#EABI_GNU_ARMEL}</li>
- * </ul></li>
- * </ul></li>
+ * <li>Linux: Current executable</li>
+ * <li>Android: Found gluegen-rt library</li>
+ * <li>Other: A found java/jvm native library.</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 osType
- * @param cpuType
- *
- * @return
*/
- private static final ABIType queryABITypeImpl(final OSType osType, final CPUType cpuType) {
- if( CPUFamily.ARM != cpuType.family ) {
- return ABIType.GENERIC_ABI;
- }
- 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";
+ private static final ElfHeader queryABITypeImpl(final OSType osType, final CPUType[] cpuType, final ABIType[] abiType) {
+ return AccessController.doPrivileged(new PrivilegedAction<ElfHeader>() {
@Override
- public ABIType run() {
- boolean abiARM = false;
- boolean abiVFPArgsAcceptsVFPVariant = false;
- RandomAccessFile in = null;
+ public ElfHeader run() {
+ ElfHeader res = null;
try {
File file = null;
- if( OSType.LINUX == osType ) {
- file = new File(GNU_LINUX_SELF_EXE);
- if( !checkFileReadAccess(file) ) {
- file = null;
+ if( OSType.ANDROID == osType ) {
+ file = new File(NativeLibrary.findLibrary("gluegen-rt", PlatformPropsImpl.class.getClassLoader()));
+ } else {
+ if( OSType.LINUX == osType ) {
+ file = new File("/proc/self/exe");
+ if( !checkFileReadAccess(file) ) {
+ file = null;
+ }
}
- }
- 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 HDR "+GNU_LINUX_SELF_EXE+": "+eh);
+ if( null == file ) {
+ file = findSysLib("java");
}
- 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());
- }
- }
+ if( null == file ) {
+ file = findSysLib("jvm");
}
}
+ if( null != file ) {
+ res = queryABITypeImpl(file, cpuType, abiType);
+ }
} catch(Throwable t) {
if(DEBUG) {
t.printStackTrace();
}
- } finally {
- if(null != in) {
- try {
- in.close();
- } catch (IOException e) { }
- }
}
- final ABIType res;
- if( abiARM ) {
- res = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL;
- } else {
- res = ABIType.GENERIC_ABI;
+ return res;
+ } } );
+ }
+ private static final ElfHeader queryABITypeImpl(final File file, final CPUType[] cpuType, final ABIType[] abiType) {
+ ElfHeader res = null;
+ RandomAccessFile in = null;
+ try {
+ in = new RandomAccessFile(file, "r");
+ final ElfHeader eh = ElfHeader.read(in);
+ if(DEBUG) {
+ System.err.println("ELF: Got HDR "+file+": "+eh);
+ }
+ if( eh.isArm() ) {
+ boolean abiVFPArgsAcceptsVFPVariant = false;
+ 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());
+ }
}
+ cpuType[0] = CPUType.ARM; // lowest denominator, ok for us
+ abiType[0] = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL;
if(DEBUG) {
- System.err.println("ELF: abiARM "+abiARM+", abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant+" -> "+res);
+ System.err.println("ELF: abiARM, abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant);
}
- return res;
- } } );
+ } else if ( eh.isX86_64() ) {
+ cpuType[0] = CPUType.X86_64;
+ abiType[0] = ABIType.GENERIC_ABI;
+ } else if ( eh.isX86_32() ) {
+ cpuType[0] = CPUType.X86_32;
+ abiType[0] = ABIType.GENERIC_ABI;
+ } else if ( eh.isIA64() ) {
+ cpuType[0] = CPUType.IA64;
+ abiType[0] = ABIType.GENERIC_ABI;
+ } else if ( eh.isMips() ) {
+ cpuType[0] = CPUType.MIPS_32; // FIXME
+ abiType[0] = ABIType.GENERIC_ABI;
+ }
+ res = eh;
+ } catch(Throwable t) {
+ if(DEBUG) {
+ System.err.println("Catched: "+t.getMessage());
+ t.printStackTrace();
+ }
+ } finally {
+ if(null != in) {
+ try {
+ in.close();
+ } catch (IOException e) { }
+ }
+ }
+ if(DEBUG) {
+ System.err.println("ELF: res "+res+", cpuType "+cpuType[0]+", abiType "+abiType[0]);
+ }
+ return res;
}
- private static boolean checkFileReadAccess(File file) {
+ private static boolean checkFileReadAccess(final File file) {
try {
return file.isFile() && file.canRead();
} catch (Throwable t) { }
return false;
}
- private static File findSysLib(String libName) {
- ClassLoader cl = PlatformPropsImpl.class.getClassLoader();
+ private static File findSysLib(final String libName) {
+ final 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);
@@ -333,33 +443,33 @@ public abstract class PlatformPropsImpl {
return null;
}
- private static final OSType getOSTypeImpl() throws RuntimeException {
- if ( AndroidVersion.isAvailable ) {
+ private static final OSType getOSTypeImpl(final String osLower, final boolean isAndroid) throws RuntimeException {
+ if ( isAndroid ) {
return OSType.ANDROID;
}
- if ( OS_lower.startsWith("linux") ) {
+ if ( osLower.startsWith("linux") ) {
return OSType.LINUX;
}
- if ( OS_lower.startsWith("freebsd") ) {
+ if ( osLower.startsWith("freebsd") ) {
return OSType.FREEBSD;
}
- if ( OS_lower.startsWith("android") ) {
+ if ( osLower.startsWith("android") ) {
return OSType.ANDROID;
}
- if ( OS_lower.startsWith("mac os x") ||
- OS_lower.startsWith("darwin") ) {
+ if ( osLower.startsWith("mac os x") ||
+ osLower.startsWith("darwin") ) {
return OSType.MACOS;
}
- if ( OS_lower.startsWith("sunos") ) {
+ if ( osLower.startsWith("sunos") ) {
return OSType.SUNOS;
}
- if ( OS_lower.startsWith("hp-ux") ) {
+ if ( osLower.startsWith("hp-ux") ) {
return OSType.HPUX;
}
- if ( OS_lower.startsWith("windows") ) {
+ if ( osLower.startsWith("windows") ) {
return OSType.WINDOWS;
}
- if ( OS_lower.startsWith("kd") ) {
+ if ( osLower.startsWith("kd") ) {
return OSType.OPENKODE;
}
throw new RuntimeException("Please port OS detection to your platform (" + OS_lower + "/" + ARCH_lower + ")");
@@ -395,7 +505,7 @@ public abstract class PlatformPropsImpl {
* </ul>
* @return
*/
- public static final String getOSAndArch(OSType osType, CPUType cpuType, ABIType abiType) {
+ public static final String getOSAndArch(final OSType osType, final CPUType cpuType, final ABIType abiType) {
String _os_and_arch;
switch( cpuType ) {
diff --git a/src/java/jogamp/common/os/android/GluegenVersionActivity.java b/src/java/jogamp/common/os/android/GluegenVersionActivity.java
index 581776b..5db3213 100644
--- a/src/java/jogamp/common/os/android/GluegenVersionActivity.java
+++ b/src/java/jogamp/common/os/android/GluegenVersionActivity.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,7 +20,7 @@
* 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.
@@ -40,21 +40,24 @@ import android.util.Log;
public class GluegenVersionActivity extends Activity {
TextView tv = null;
-
+
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(MD.TAG, "onCreate - S");
super.onCreate(savedInstanceState);
StaticContext.init(this.getApplicationContext());
+
+ System.setProperty("jogamp.debug", "all");
+
tv = new TextView(this);
final ScrollView scroller = new ScrollView(this);
scroller.addView(tv);
setContentView(scroller);
-
- tv.setText(VersionUtil.getPlatformInfo()+Platform.NEWLINE+GlueGenVersion.getInstance()+Platform.NEWLINE+Platform.NEWLINE);
+
+ tv.setText(VersionUtil.getPlatformInfo()+Platform.NEWLINE+GlueGenVersion.getInstance()+Platform.NEWLINE+Platform.NEWLINE);
Log.d(MD.TAG, "onCreate - X");
}
-
+
@Override
public void onStart() {
Log.d(MD.TAG, "onStart - S");
@@ -64,14 +67,14 @@ public class GluegenVersionActivity extends Activity {
}
Log.d(MD.TAG, "onStart - X");
}
-
+
@Override
public void onRestart() {
Log.d(MD.TAG, "onRestart - S");
super.onRestart();
if(null != tv) {
tv.append("> restarted"+Platform.NEWLINE);
- }
+ }
Log.d(MD.TAG, "onRestart - X");
}
@@ -80,7 +83,7 @@ public class GluegenVersionActivity extends Activity {
Log.d(MD.TAG, "onResume - S");
if(null != tv) {
tv.append("> resumed"+Platform.NEWLINE);
- }
+ }
super.onResume();
Log.d(MD.TAG, "onResume - X");
}
@@ -90,7 +93,7 @@ public class GluegenVersionActivity extends Activity {
Log.d(MD.TAG, "onPause - S");
if(null != tv) {
tv.append("> paused"+Platform.NEWLINE);
- }
+ }
super.onPause();
// Log.d(MD.TAG, "onPause - x");
// finish(); // ensure destroy after pause() -> one shot activity
@@ -103,7 +106,7 @@ public class GluegenVersionActivity extends Activity {
if(null != tv) {
tv.append("> stopped"+Platform.NEWLINE);
}
- super.onStop();
+ super.onStop();
Log.d(MD.TAG, "onStop - X");
}
@@ -115,7 +118,7 @@ public class GluegenVersionActivity extends Activity {
}
Log.d(MD.TAG, "onDestroy - x");
StaticContext.clear();
- super.onDestroy();
+ super.onDestroy();
Log.d(MD.TAG, "onDestroy - X");
- }
+ }
}
diff --git a/src/java/jogamp/common/os/elf/ElfHeader.java b/src/java/jogamp/common/os/elf/ElfHeader.java
index e6645b6..f12ccad 100644
--- a/src/java/jogamp/common/os/elf/ElfHeader.java
+++ b/src/java/jogamp/common/os/elf/ElfHeader.java
@@ -461,13 +461,37 @@ public class ElfHeader {
/**
* Returns true if {@link #getMachine() machine} is a 32 or 64 bit Intel CPU
* of type {@link #EM_386}, {@link #EM_486} or {@link #EM_X86_64}. */
- public final boolean isIntel() {
+ public final boolean isX86_32() {
final short m = getMachine();
return EM_386 == m ||
EM_486 == m ||
EM_X86_64 == m;
}
+ /**
+ * Returns true if {@link #getMachine() machine} is a 64 bit AMD/Intel x86_64 CPU
+ * of type {@link #EM_X86_64}. */
+ public final boolean isX86_64() {
+ return getMachine() == EM_X86_64;
+ }
+
+ /**
+ * Returns true if {@link #getMachine() machine} is a 64 bit Intel Itanium CPU
+ * of type {@link #EM_IA_64}. */
+ public final boolean isIA64() {
+ return getMachine() == EM_IA_64;
+ }
+
+ /**
+ * Returns true if {@link #getMachine() machine} is a 32 or 64 bit MIPS CPU
+ * of type {@link #EM_MIPS}, {@link #EM_MIPS_X} or {@link #EM_MIPS_RS3_LE}. */
+ public final boolean isMips() {
+ final short m = getMachine();
+ return EM_MIPS == m ||
+ EM_MIPS_X == m ||
+ EM_MIPS_RS3_LE == m;
+ }
+
/** Returns the processor-specific flags associated with the file. */
public final int getFlags() {
return d.getE_flags();
@@ -536,8 +560,14 @@ public class ElfHeader {
final String machineS;
if( isArm() ) {
machineS=", arm";
- } else if( isIntel() ) {
- machineS=", intel";
+ } else if( isX86_64() ) {
+ machineS=", x86_64";
+ } else if( isX86_32() ) {
+ machineS=", x86_32";
+ } else if( isIA64() ) {
+ machineS=", itanium";
+ } else if( isMips() ) {
+ machineS=", mips";
} else {
machineS="";
}