diff options
-rw-r--r-- | make/scripts/crosstest-java-linux-armv6-rel.sh | 8 | ||||
-rw-r--r-- | make/scripts/crosstest-java-linux-armv6hf-rel.sh | 8 | ||||
-rwxr-xr-x | make/scripts/runtest.sh | 5 | ||||
-rw-r--r-- | src/java/jogamp/common/os/PlatformPropsImpl.java | 91 | ||||
-rw-r--r-- | src/java/jogamp/common/os/elf/ElfHeader.java | 64 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/os/TestElfReader01.java | 22 |
6 files changed, 146 insertions, 52 deletions
diff --git a/make/scripts/crosstest-java-linux-armv6-rel.sh b/make/scripts/crosstest-java-linux-armv6-rel.sh index deee01e..92cd2d2 100644 --- a/make/scripts/crosstest-java-linux-armv6-rel.sh +++ b/make/scripts/crosstest-java-linux-armv6-rel.sh @@ -10,8 +10,8 @@ export ANT_PATH=/usr/share/ant export BUILD_DIR=../build-linux-armv6 #TSTCLASS=com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter -#TSTCLASS=com.jogamp.common.GlueGenVersion -TSTCLASS=com.jogamp.common.os.TestElfReader01 +TSTCLASS=com.jogamp.common.GlueGenVersion +#TSTCLASS=com.jogamp.common.os.TestElfReader01 LOGFILE=`basename $0 .sh`.log @@ -25,12 +25,12 @@ cd $TARGET_ROOT/gluegen/make ; LD_LIBRARY_PATH=$BUILD_DIR/obj:$BUILD_DIR/test/build/natives \ java \ -Djava.library.path=$BUILD_DIR/obj:$BUILD_DIR/test/build/natives \ - -Djava.class.path=lib/junit.jar:$ANT_PATH/lib/ant.jar:$ANT_PATH/lib/ant-junit.jar:$BUILD_DIR/gluegen.jar:$BUILD_DIR/test/build/gluegen-test.jar \ + -cp lib/junit.jar:$ANT_PATH/lib/ant.jar:$ANT_PATH/lib/ant-junit.jar:$BUILD_DIR/gluegen-rt.jar:$BUILD_DIR/gluegen.jar:$BUILD_DIR/test/build/gluegen-test.jar \ -Djogamp.debug.JNILibLoader=true \ -Djogamp.debug.NativeLibrary=true \ -Djogamp.debug.NativeLibrary.Lookup=true \ -Djogamp.debug.ProcAddressHelper=true \ - $TSTCLASS \ + $* $TSTCLASS \ 2>&1 | tee $LOGFILE \ " diff --git a/make/scripts/crosstest-java-linux-armv6hf-rel.sh b/make/scripts/crosstest-java-linux-armv6hf-rel.sh index 24dec99..9c40ede 100644 --- a/make/scripts/crosstest-java-linux-armv6hf-rel.sh +++ b/make/scripts/crosstest-java-linux-armv6hf-rel.sh @@ -10,8 +10,8 @@ export ANT_PATH=/usr/share/ant export BUILD_DIR=../build-linux-armv6hf #TSTCLASS=com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter -#TSTCLASS=com.jogamp.common.GlueGenVersion -TSTCLASS=com.jogamp.common.os.TestElfReader01 +TSTCLASS=com.jogamp.common.GlueGenVersion +#TSTCLASS=com.jogamp.common.os.TestElfReader01 LOGFILE=`basename $0 .sh`.log @@ -25,12 +25,12 @@ cd $TARGET_ROOT/gluegen/make ; LD_LIBRARY_PATH=$BUILD_DIR/obj:$BUILD_DIR/test/build/natives \ java \ -Djava.library.path=$BUILD_DIR/obj:$BUILD_DIR/test/build/natives \ - -Djava.class.path=lib/junit.jar:$ANT_PATH/lib/ant.jar:$ANT_PATH/lib/ant-junit.jar:$BUILD_DIR/gluegen.jar:$BUILD_DIR/test/build/gluegen-test.jar \ + -cp lib/junit.jar:$ANT_PATH/lib/ant.jar:$ANT_PATH/lib/ant-junit.jar:$BUILD_DIR/gluegen-rt.jar:$BUILD_DIR/gluegen.jar:$BUILD_DIR/test/build/gluegen-test.jar \ -Djogamp.debug.JNILibLoader=true \ -Djogamp.debug.NativeLibrary=true \ -Djogamp.debug.NativeLibrary.Lookup=true \ -Djogamp.debug.ProcAddressHelper=true \ - $TSTCLASS \ + $* $TSTCLASS \ 2>&1 | tee $LOGFILE \ " diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh index b8af676..9f9a769 100755 --- a/make/scripts/runtest.sh +++ b/make/scripts/runtest.sh @@ -41,6 +41,7 @@ rm -f $LOG #D_ARGS="-Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true" #D_ARGS="-Djogamp.debug.TraceLock" +D_ARGS="-Djogamp.debug.Platform" #D_ARGS="-Djogamp.debug.JarUtil" #D_ARGS="-Djogamp.debug.TempJarCache" #D_ARGS="-Djogamp.debug.TempFileCache" @@ -69,8 +70,8 @@ function onetest() { java -cp $CLASSPATH $D_ARGS -Djava.library.path=$libspath $* echo } - -#onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG +# +onetest com.jogamp.common.GlueGenVersion 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestSystemPropsAndEnvs 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestVersionInfo 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestVersionNumber 2>&1 | tee -a $LOG diff --git a/src/java/jogamp/common/os/PlatformPropsImpl.java b/src/java/jogamp/common/os/PlatformPropsImpl.java index 8a4f2b2..0c597cb 100644 --- a/src/java/jogamp/common/os/PlatformPropsImpl.java +++ b/src/java/jogamp/common/os/PlatformPropsImpl.java @@ -1,11 +1,18 @@ package jogamp.common.os; +import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import java.security.AccessController; import java.security.PrivilegedAction; +import jogamp.common.Debug; +import jogamp.common.os.elf.ElfHeader; +import jogamp.common.os.elf.SectionArmAttributes; +import jogamp.common.os.elf.SectionHeader; + import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.AndroidVersion; import com.jogamp.common.os.Platform; @@ -26,6 +33,8 @@ import com.jogamp.common.util.VersionNumber; * </p> */ public abstract class PlatformPropsImpl { + static final boolean DEBUG = Debug.debug("Platform"); + // // static initialization order: // @@ -81,8 +90,8 @@ public abstract class PlatformPropsImpl { LITTLE_ENDIAN = queryIsLittleEndianImpl(); CPU_ARCH = getCPUTypeImpl(ARCH_lower); - ABI_TYPE = guessABITypeImpl(CPU_ARCH); OS_TYPE = getOSTypeImpl(); + ABI_TYPE = queryABITypeImpl(CPU_ARCH, OS_TYPE); os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE); } @@ -155,6 +164,7 @@ public abstract class PlatformPropsImpl { } } + @SuppressWarnings("unused") private static final boolean contains(String data, String[] search) { if(null != data && null != search) { for(int i=0; i<search.length; i++) { @@ -166,19 +176,80 @@ public abstract class PlatformPropsImpl { return false; } - private static final ABIType guessABITypeImpl(CPUType cpuType) { - if(CPUFamily.ARM != cpuType.family) { + /** + * 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: + * <ul> + * <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> else + * <ul> + * <li> Elf ARM Tags -> {@link ABIType#EABI_GNU_ARMEL}, {@link ABIType#EABI_GNU_ARMHF} </li> + * </ul></li> + * </ul></li> + * </ul> + * </p> + * <p> + * Elf ARM Tags are read using {@link ElfHeader}, .. and {@link SectionArmAttributes#abiVFPArgsAcceptsVFPVariant(byte)}. + * </p> + * + * @param cpuType + * @param osType + * @return + */ + private static final ABIType queryABITypeImpl(CPUType cpuType, OSType osType) { + 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 ) { + return ABIType.EABI_GNU_ARMEL; + } return AccessController.doPrivileged(new PrivilegedAction<ABIType>() { - private final String[] gnueabihf = new String[] { "gnueabihf", "armhf" }; - public ABIType run() { - if ( contains(System.getProperty("sun.boot.library.path"), gnueabihf) || - contains(System.getProperty("java.library.path"), gnueabihf) || - contains(System.getProperty("java.home"), gnueabihf) ) { - return ABIType.EABI_GNU_ARMHF; + private final String GNU_LINUX_SELF_EXE = "/proc/self/exe"; + public ABIType run() { + 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); + } + 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(); + } finally { + if(null != in) { + try { + in.close(); + } catch (IOException e) { } + } + } + final ABIType res = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; + if(DEBUG) { + System.err.println("ELF: abiVFPArgsAcceptsVFPVariant : "+abiVFPArgsAcceptsVFPVariant+" -> "+res); } - return ABIType.EABI_GNU_ARMEL; + return res; } } ); } diff --git a/src/java/jogamp/common/os/elf/ElfHeader.java b/src/java/jogamp/common/os/elf/ElfHeader.java index 85bdcf0..3b82a69 100644 --- a/src/java/jogamp/common/os/elf/ElfHeader.java +++ b/src/java/jogamp/common/os/elf/ElfHeader.java @@ -34,6 +34,7 @@ import java.nio.ByteBuffer; import static jogamp.common.os.elf.IOUtils.readBytes; import static jogamp.common.os.elf.IOUtils.seek; import static jogamp.common.os.elf.IOUtils.shortToInt; +import static jogamp.common.os.elf.IOUtils.toHexString; /** * ELF ABI Header @@ -370,6 +371,8 @@ public class ElfHeader { /** Public access to the {@link SectionHeader} */ public final SectionHeader[] sht; + private final String string; + /** * Note: The input stream shall stay untouch to be able to read sections! * @@ -397,6 +400,7 @@ public class ElfHeader { throw new IllegalArgumentException("Buffer is not an ELF Header"); } sht = readSectionHeaderTable(in); + string = toStringImpl(); } public final short getSize() { return d.getE_ehsize(); } @@ -415,29 +419,34 @@ public class ElfHeader { } /** - * Returns the processor's data encoding, - * 1 for {@link #ELFDATA2LSB}, 2 for for {@link #ELFDATA2MSB} - * and 0 for for {@link #ELFDATANONE} + * Returns the processor's data encoding, i.e. + * {@link #ELFDATA2LSB}, {@link #ELFDATA2MSB} or {@link #ELFDATANONE}; */ - public final int getDataEncodingMode() { - switch( d.getE_ident()[EI_DATA] ) { - case ELFDATA2LSB: return 1; - case ELFDATA2MSB: return 2; - default: return 0; - } + public final byte getDataEncodingMode() { + return d.getE_ident()[EI_DATA]; + } + + /** Returns the ELF file version, should be {@link #EV_CURRENT}. */ + public final byte getVersion() { + return d.getE_ident()[EI_VERSION]; } - /** 3 == Linux */ + /** Returns the operating system and ABI for this file, 3 == Linux. Note: Often not used. */ public final byte getOSABI() { return d.getE_ident()[EI_OSABI]; } + + /** Returns the version of the {@link #getOSABI() OSABI} for this file. */ + public final byte getOSABIVersion() { + return d.getE_ident()[EI_ABIVERSION]; + } - /** Returns the object file type */ + /** Returns the object file type, e.g. {@link #ET_EXEC}, .. */ public final short getType() { return d.getE_type(); } - /** Returns the required architecture for the file */ + /** Returns the required architecture for the file, e.g. {@link #EM_386}, .. */ public final short getMachine() { return d.getE_machine(); } @@ -518,6 +527,37 @@ public class ElfHeader { return null; } + public final String toString() { + return string; + } + + private final String toStringImpl() { + final String machineS; + if( isArm() ) { + machineS=", arm"; + } else if( isIntel() ) { + machineS=", intel"; + } else { + machineS=""; + } + final int enc = getDataEncodingMode(); + final String encS; + switch(enc) { + case 1: encS = "LSB"; break; + case 2: encS = "MSB"; break; + default: encS = "NON"; break; + } + final int armABI = getArmABI(); + final String armFlagsS; + if( 0 != armABI ) { + armFlagsS=", arm[abi "+armABI+", lGCC "+getArmLegacyGCCFlags()+", float "+getArmFloatMode()+"]"; + } else { + armFlagsS=""; + } + return "ElfHeader[vers "+getVersion()+", machine["+getMachine()+machineS+"], bits "+getArchClassBits()+", enc "+encS+ + ", abi[os "+getOSABI()+", vers "+getOSABIVersion()+"], flags["+toHexString(getFlags())+armFlagsS+"], type "+getType()+", sh-num "+sht.length+"]"; + } + final SectionHeader[] readSectionHeaderTable(RandomAccessFile in) throws IOException, IllegalArgumentException { // positioning { diff --git a/src/junit/com/jogamp/common/os/TestElfReader01.java b/src/junit/com/jogamp/common/os/TestElfReader01.java index fe6adc2..c04f2ac 100644 --- a/src/junit/com/jogamp/common/os/TestElfReader01.java +++ b/src/junit/com/jogamp/common/os/TestElfReader01.java @@ -39,27 +39,9 @@ public class TestElfReader01 extends JunitTracer { void testElfHeaderImpl(String file, boolean fileOutSections) throws IOException { RandomAccessFile in = new RandomAccessFile(file, "r"); try { - ElfHeader eh = ElfHeader.read(in); - byte[] e_ident = eh.d.getE_ident(); + final ElfHeader eh = ElfHeader.read(in); int i=0; - System.err.print("[0..4]: 0x"+toHexString(e_ident[i++])); - System.err.print(", 0x"+toHexString(e_ident[i++])); - System.err.print(", 0x"+toHexString(e_ident[i++])); - System.err.println(", 0x"+toHexString(e_ident[i++])); - System.err.println("e_class "+e_ident[ElfHeader.EI_CLASS]+", "+eh.getArchClassBits()+" bits"); - System.err.println("e_data "+e_ident[ElfHeader.EI_DATA]+", "+eh.getDataEncodingMode()); - System.err.println("e_flags "+toHexString(eh.getFlags())); - System.err.println(" ARM ABI "+eh.getArmABI()); - System.err.println(" ARM lGCC "+eh.getArmLegacyGCCFlags()); - System.err.println(" ARM FLOAT "+eh.getArmFloatMode()+", is hard-float "+(2 == eh.getArmFloatMode())); - System.err.println("e_version "+e_ident[ElfHeader.EI_VERSION]); - System.err.println("e_osabi "+eh.getOSABI()+", Linux "+ElfHeader.ELFOSABI_LINUX); - System.err.println("e_abiversion "+e_ident[ElfHeader.EI_ABIVERSION]); - System.err.println("e_machine "+eh.getMachine()+", isARM "+eh.isArm()+", isIntel "+eh.isIntel()); - System.err.println("e_version "+eh.d.getE_version()); - System.err.println("e_type "+eh.getType()); - System.err.println("EH Size "+eh.d.getE_ehsize()); - System.err.println("SH num "+eh.d.getE_shnum()); + System.err.println(eh); System.err.println("SH entsz "+eh.d.getE_shentsize()); System.err.println("SH off "+toHexString(eh.d.getE_shoff())); System.err.println("SH strndx "+eh.d.getE_shstrndx()); |