diff options
author | Sven Gothel <[email protected]> | 2015-02-01 05:21:39 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-02-01 05:21:39 +0100 |
commit | a3f2d08801c5a54048faca52f422bcededf81b2a (patch) | |
tree | 96e83956b62ae3e25043ccc67f4cb1c2c1f232a1 /src | |
parent | 0deceee37d943faa7c34971388863a27f395d6a5 (diff) |
Bug 1125 - Make ELF Reader 'jogamp.common.os.elf' Stateless
ELF Reader 'jogamp.common.os.elf' currently uses
Platform's pre-determined OS_TYPE and CPUType.
It also uses the host platforms MachineDescription,
hence can not read ELF files from other machines.
This also forbids Platform to determine CPUType etc
w/o having a valid 'os.arch' property.
+++
ElfHeader should be split in
- ElfHeaderPart1 (CPUType independent)
- ElfHeaderPart2 (CPUType dependent)
Fix shall make the ELF Reader self containing
by only using ELF CPUType data, etc.
This requires customization of struct parsing,
where MachineDescription.Static index shall be
- defined in ElfHeaderPart1 using e_Ident's CPUType.
- used in ElfHeaderPart2 and all its struct types.
Diffstat (limited to 'src')
20 files changed, 1425 insertions, 1007 deletions
diff --git a/src/java/com/jogamp/common/os/AndroidVersion.java b/src/java/com/jogamp/common/os/AndroidVersion.java index f727a47..840933f 100644 --- a/src/java/com/jogamp/common/os/AndroidVersion.java +++ b/src/java/com/jogamp/common/os/AndroidVersion.java @@ -30,7 +30,6 @@ 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; @@ -67,61 +66,6 @@ public class AndroidVersion { 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(final String cpuABI) { - if( null == cpuABI ) { - return null; - } else if( cpuABI.equals("armv8-a") || - cpuABI.equals("arm64-v8a") ) { - return CPUType.ARMv8_A; - } else if( cpuABI.equals("aarch64") || - cpuABI.startsWith("arm64") ) { - return CPUType.ARM64; - } else if( cpuABI.equals("armeabi-v7a") || - cpuABI.equals("armeabi-v7a-hard") ) { - return CPUType.ARMv7; - } else if( cpuABI.equals("armeabi") || - cpuABI.startsWith("arm") ) { // last 32bit 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, final String cpuABI) { - if( null == cpuType || null == cpuABI ) { - return null; - } else if( CPUFamily.ARM == cpuType.family ) { - if( CPUType.ARM64 == cpuType || - CPUType.ARMv8_A == cpuType ) { - return ABIType.EABI_AARCH64; - } else if( cpuABI.equals("armeabi-v7a-hard") ) { - return ABIType.EABI_GNU_ARMHF; - } else { - return ABIType.EABI_GNU_ARMEL; - } - } else { - return ABIType.GENERIC_ABI; - } - } - static { final ClassLoader cl = AndroidVersion.class.getClassLoader(); Class<?> abClass = null; @@ -138,7 +82,7 @@ public class AndroidVersion { abvcClass = ReflectionUtil.getClass(androidBuildVersionCodes, true, cl); abvcObject = abvcClass.newInstance(); } catch (final Exception e) { /* n/a */ } - isAvailable = null != abObject && null != abvObject && null != abvcObject; + isAvailable = null != abObject && null != abvObject; if(isAvailable) { CPU_ABI = getString(abClass, abObject, "CPU_ABI", true); CPU_ABI2 = getString(abClass, abObject, "CPU_ABI2", true); @@ -146,9 +90,36 @@ public class AndroidVersion { 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); + final String sdk_name; + if( null != abvcObject ) { + final IntObjectHashMap version_codes = getVersionCodes(abvcClass, abvcObject); + sdk_name = (String) version_codes.get(SDK_INT); + } else { + sdk_name = null; + } SDK_NAME = ( null != sdk_name ) ? sdk_name : "SDK_"+SDK_INT ; + + /** + * <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> + */ + CPU_TYPE = Platform.CPUType.query(CPU_ABI); + ABI_TYPE = Platform.ABIType.query(CPU_TYPE, CPU_ABI); + if( null != CPU_ABI2 && CPU_ABI2.length() > 0 ) { + CPU_TYPE2 = Platform.CPUType.query(CPU_ABI2); + ABI_TYPE2 = Platform.ABIType.query(CPU_TYPE2, CPU_ABI2); + } else { + CPU_TYPE2 = null; + ABI_TYPE2 = null; + } } else { CPU_ABI = null; CPU_ABI2 = null; @@ -157,11 +128,11 @@ public class AndroidVersion { RELEASE = null; SDK_INT = -1; SDK_NAME = null; + CPU_TYPE = null; + ABI_TYPE = null; + CPU_TYPE2 = null; + ABI_TYPE2 = 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(final Class<?> cls, final Object obj) { diff --git a/src/java/com/jogamp/common/os/MachineDescription.java b/src/java/com/jogamp/common/os/MachineDescription.java index 98093d0..2a4627e 100644 --- a/src/java/com/jogamp/common/os/MachineDescription.java +++ b/src/java/com/jogamp/common/os/MachineDescription.java @@ -104,7 +104,7 @@ public class MachineDescription { alignments[j++]); } - public StringBuilder toString(StringBuilder sb) { + public final StringBuilder toString(StringBuilder sb) { if(null==sb) { sb = new StringBuilder(); } @@ -112,7 +112,9 @@ public class MachineDescription { md.toString(sb); return sb; } - + public final String toShortString() { + return this.name()+"("+this.ordinal()+")"; + } @Override public String toString() { return toString(null).toString(); diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java index 0d00a9a..6f6c99d 100644 --- a/src/java/com/jogamp/common/os/Platform.java +++ b/src/java/com/jogamp/common/os/Platform.java @@ -58,97 +58,186 @@ import jogamp.common.os.PlatformPropsImpl; public class Platform extends PlatformPropsImpl { public enum OSType { - LINUX(0), FREEBSD(1), ANDROID(2), MACOS(3), SUNOS(4), HPUX(5), WINDOWS(6), OPENKODE(7); - - public final int id; - - OSType(final int id){ - this.id = id; - } + LINUX, FREEBSD, ANDROID, MACOS, SUNOS, HPUX, WINDOWS, OPENKODE; } public enum CPUFamily { /** AMD/Intel */ - X86( 0x00000000), + X86, /** ARM */ - ARM( 0x00010000), + ARM, /** Power PC */ - PPC( 0x00020000), + PPC, /** SPARC */ - SPARC( 0x00030000), + SPARC, /** Mips */ - MIPS( 0x00040000), + MIPS, /** PA RISC */ - PA_RISC(0xFFFF0000), + PA_RISC, /** Itanium */ - IA64( 0xFFFF1000); - - public final int id; - - CPUFamily(final int id){ - this.id = id; - } + IA64; } public enum CPUType { /** X86 32bit */ - X86_32( CPUFamily.X86, 0x0001, true), + X86_32( CPUFamily.X86, true), /** X86 64bit */ - X86_64( CPUFamily.X86, 0x0002, false), + X86_64( CPUFamily.X86, false), /** ARM 32bit default */ - ARM( CPUFamily.ARM, 0x0000, true), + ARM( CPUFamily.ARM, true), /** ARM7EJ, ARM9E, ARM10E, XScale */ - ARMv5( CPUFamily.ARM, 0x0001, true), + ARMv5( CPUFamily.ARM, true), /** ARM11 */ - ARMv6( CPUFamily.ARM, 0x0002, true), + ARMv6( CPUFamily.ARM, true), /** ARM Cortex */ - ARMv7( CPUFamily.ARM, 0x0004, true), + ARMv7( CPUFamily.ARM, true), /** ARM64 default (64bit) */ - ARM64( CPUFamily.ARM, 0x0008, false), + ARM64( CPUFamily.ARM, false), /** ARM AArch64 (64bit) */ - ARMv8_A( CPUFamily.ARM, 0x0010, false), + ARMv8_A( CPUFamily.ARM, false), /** PPC 32bit default */ - PPC( CPUFamily.PPC, 0x0000, true), + PPC( CPUFamily.PPC, true), + /** PPC 64bit default */ + PPC64( CPUFamily.PPC, false), /** SPARC 32bit */ - SPARC_32( CPUFamily.SPARC, 0x0001, true), + SPARC_32( CPUFamily.SPARC, true), /** SPARC 64bit */ - SPARCV9_64(CPUFamily.SPARC, 0x0002, false), + SPARCV9_64(CPUFamily.SPARC, false), /** MIPS 32bit */ - MIPS_32( CPUFamily.MIPS, 0x0001, true), + MIPS_32( CPUFamily.MIPS, true), /** MIPS 64bit */ - MIPS_64( CPUFamily.MIPS, 0x0002, false), + MIPS_64( CPUFamily.MIPS, false), /** Itanium 64bit default */ - IA64( CPUFamily.IA64, 0x0000, false), + IA64( CPUFamily.IA64, false), /** PA_RISC2_0 64bit */ - PA_RISC2_0(CPUFamily.PA_RISC, 0x0001, false); + PA_RISC2_0(CPUFamily.PA_RISC, false); - public final int id; public final CPUFamily family; public final boolean is32Bit; - CPUType(final CPUFamily type, final int id, final boolean is32Bit){ + CPUType(final CPUFamily type, final boolean is32Bit){ this.family = type; - this.id = id; this.is32Bit = is32Bit; } - public CPUFamily getFamily() { return family; } + /** + * Returns {@code true} if the given {@link CPUType} is compatible + * w/ this one, i.e. at least {@link #family} and {@link #is32Bit} is equal. + */ + public final boolean isCompatible(final CPUType other) { + if( null == other ) { + return false; + } else if( other == this ) { + return true; + } else { + return this.family == other.family && + this.is32Bit == other.is32Bit; + } + } + + public static final CPUType query(final String cpuABILower) { + if( null == cpuABILower ) { + throw new IllegalArgumentException("Null cpuABILower arg"); + } + if( cpuABILower.equals("x86") || + cpuABILower.equals("i386") || + cpuABILower.equals("i486") || + cpuABILower.equals("i586") || + cpuABILower.equals("i686") ) { + return X86_32; + } else if( cpuABILower.equals("x86_64") || + cpuABILower.equals("amd64") ) { + return X86_64; + } else if( cpuABILower.equals("ia64") ) { + return IA64; + } else if( cpuABILower.equals("aarch64") ) { + return ARM64; + } else if( cpuABILower.startsWith("arm") ) { + if( cpuABILower.equals("armv8-a") || + cpuABILower.equals("arm-v8-a") || + cpuABILower.equals("arm-8-a") || + cpuABILower.equals("arm64-v8a") ) { + return ARMv8_A; + } else if( cpuABILower.startsWith("arm64") ) { + return ARM64; + } else if( cpuABILower.startsWith("armv7") || + cpuABILower.startsWith("arm-v7") || + cpuABILower.startsWith("arm-7") || + cpuABILower.startsWith("armeabi-v7") ) { + return ARMv7; + } else if( cpuABILower.startsWith("armv5") || + cpuABILower.startsWith("arm-v5") || + cpuABILower.startsWith("arm-5") ) { + return ARMv5; + } else if( cpuABILower.startsWith("armv6") || + cpuABILower.startsWith("arm-v6") || + cpuABILower.startsWith("arm-6") ) { + return ARMv6; + } else { + return ARM; + } + } else if( cpuABILower.equals("sparcv9") ) { + return SPARCV9_64; + } else if( cpuABILower.equals("sparc") ) { + return SPARC_32; + } else if( cpuABILower.equals("pa_risc2.0") ) { + return PA_RISC2_0; + } else if( cpuABILower.startsWith("ppc64") ) { + return PPC64; + } else if( cpuABILower.startsWith("ppc") ) { + return PPC; + } else if( cpuABILower.startsWith("mips") ) { + return MIPS_32; + } else { + throw new RuntimeException("Please port CPUType detection to your platform (CPU_ABI string '" + cpuABILower + "')"); + } + } } public enum ABIType { - GENERIC_ABI ( 0x0000 ), + GENERIC_ABI ( 0x00 ), /** ARM GNU-EABI ARMEL -mfloat-abi=softfp */ - EABI_GNU_ARMEL ( 0x0001 ), + EABI_GNU_ARMEL ( 0x01 ), /** ARM GNU-EABI ARMHF -mfloat-abi=hard */ - EABI_GNU_ARMHF ( 0x0002 ), + EABI_GNU_ARMHF ( 0x02 ), /** ARM EABI AARCH64 (64bit) */ - EABI_AARCH64 ( 0x0003 ); + EABI_AARCH64 ( 0x03 ); public final int id; ABIType(final int id){ this.id = id; } + + /** + * Returns {@code true} if the given {@link ABIType} is compatible + * w/ this one, i.e. they are equal. + */ + public final boolean isCompatible(final ABIType other) { + if( null == other ) { + return false; + } else { + return other == this; + } + } + + public static final ABIType query(final CPUType cpuType, final String cpuABILower) { + if( null == cpuType ) { + throw new IllegalArgumentException("Null cpuType"); + } else if( null == cpuABILower ) { + throw new IllegalArgumentException("Null cpuABILower"); + } else if( CPUFamily.ARM == cpuType.family ) { + if( !cpuType.is32Bit ) { + return EABI_AARCH64; + } else if( cpuABILower.equals("armeabi-v7a-hard") ) { + return EABI_GNU_ARMHF; + } else { + return EABI_GNU_ARMEL; + } + } else { + return GENERIC_ABI; + } + } } private static final String useTempJarCachePropName = "jogamp.gluegen.UseTempJarCache"; @@ -261,26 +350,6 @@ public class Platform extends PlatformPropsImpl { public static void initSingleton() { } /** - * Returns true only if having {@link java.nio.LongBuffer} and {@link java.nio.DoubleBuffer} available. - */ - public static boolean isJavaSE() { - return JAVA_SE; - } - - /** - * Returns true only if being compatible w/ language level 6, e.g. JRE 1.6. - * <p> - * Implies {@link #isJavaSE()}. - * </p> - * <p> - * <i>Note</i>: We claim Android is compatible. - * </p> - */ - public static boolean isJava6() { - return JAVA_6; - } - - /** * Returns true if this machine is little endian, otherwise false. */ public static boolean isLittleEndian() { @@ -328,7 +397,7 @@ public class Platform extends PlatformPropsImpl { * Returns the CPU family. */ public static CPUFamily getCPUFamily() { - return CPU_ARCH.getFamily(); + return CPU_ARCH.family; } /** diff --git a/src/java/com/jogamp/common/util/VersionUtil.java b/src/java/com/jogamp/common/util/VersionUtil.java index 6949d62..aef3fc2 100644 --- a/src/java/com/jogamp/common/util/VersionUtil.java +++ b/src/java/com/jogamp/common/util/VersionUtil.java @@ -58,10 +58,10 @@ public class VersionUtil { // environment sb.append("Platform: ").append(Platform.getOSType()).append(" / ").append(Platform.getOSName()).append(' ').append(Platform.getOSVersion()).append(" (").append(Platform.getOSVersionNumber()).append("), "); - sb.append(Platform.getArchName()).append(" (arch), ").append(Platform.getABIType()).append(", "); + sb.append(Platform.getArchName()).append(" (").append(Platform.getCPUType()).append(", ").append(Platform.getABIType()).append("), "); sb.append(Runtime.getRuntime().availableProcessors()).append(" cores"); sb.append(Platform.getNewline()); - if( AndroidVersion.isAvailable) { + if( Platform.OSType.ANDROID == PlatformPropsImpl.OS_TYPE ) { sb.append("Platform: Android Version: ").append(AndroidVersion.CODENAME).append(", "); sb.append(AndroidVersion.RELEASE).append(" [").append(AndroidVersion.RELEASE).append("], SDK: ").append(AndroidVersion.SDK_INT).append(", ").append(AndroidVersion.SDK_NAME); sb.append(Platform.getNewline()); @@ -73,8 +73,8 @@ public class VersionUtil { sb.append("Platform: Java Version: ").append(Platform.getJavaVersion()).append(" (").append(Platform.getJavaVersionNumber()).append("u").append(PlatformPropsImpl.JAVA_VERSION_UPDATE).append("), VM: ").append(Platform.getJavaVMName()); sb.append(", Runtime: ").append(Platform.getJavaRuntimeName()).append(Platform.getNewline()); sb.append("Platform: Java Vendor: ").append(Platform.getJavaVendor()).append(", ").append(Platform.getJavaVendorURL()); - sb.append(", JavaSE: ").append(Platform.isJavaSE()); - sb.append(", Java6: ").append(Platform.isJava6()); + sb.append(", JavaSE: ").append(PlatformPropsImpl.JAVA_SE); + sb.append(", Java6: ").append(PlatformPropsImpl.JAVA_6); sb.append(", AWT enabled: ").append(Platform.AWT_AVAILABLE); sb.append(Platform.getNewline()).append(SEPERATOR); diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java index b64c041..3924ec2 100644 --- a/src/java/com/jogamp/gluegen/JavaConfiguration.java +++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java @@ -42,6 +42,7 @@ package com.jogamp.gluegen; import com.jogamp.gluegen.JavaEmitter.EmissionStyle; import com.jogamp.gluegen.JavaEmitter.MethodAccess; + import java.io.*; import java.lang.reflect.Array; import java.util.*; @@ -53,6 +54,7 @@ import com.jogamp.gluegen.cgram.types.*; import java.util.logging.Logger; +import jogamp.common.os.MachineDescriptionRuntime; import static java.util.logging.Level.*; import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*; import static com.jogamp.gluegen.JavaEmitter.EmissionStyle.*; @@ -164,6 +166,7 @@ public class JavaConfiguration { private final Map<String, String> structPackages = new HashMap<String, String>(); private final List<String> customCCode = new ArrayList<String>(); private final List<String> forcedStructs = new ArrayList<String>(); + private final Map<String, String> structMachineDescriptorIndex = new HashMap<String, String>(); private final Map<String, String> returnValueCapacities = new HashMap<String, String>(); private final Map<String, String> returnValueLengths = new HashMap<String, String>(); private final Map<String, List<String>> temporaryCVariableDeclarations = new HashMap<String, List<String>>(); @@ -547,7 +550,12 @@ public class JavaConfiguration { } /** Returns true if the glue code for the given function will be - manually implemented by the end user. */ + manually implemented by the end user. + * <p> + * If symbol references a struct field or method, see {@link #canonicalStructFieldSymbol(String, String)}, + * it describes field's array-length or element-count referenced by a pointer. + * </p> + */ public boolean manuallyImplement(final String functionName) { return manuallyImplement.contains(functionName); } @@ -637,6 +645,20 @@ public class JavaConfiguration { } /** + * Returns a MessageFormat string of the Java code defining {@code mdIdx}, + * i.e. the index of the static MachineDescriptor index for structs. + * <p> + * If undefined, code generation uses the default expression: + * <pre> + * private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal(); + * </pre> + * </p> + */ + public String returnStructMachineDescriptorIndex(final String structName) { + return structMachineDescriptorIndex.get(structName); + } + + /** * Returns a MessageFormat string of the C expression calculating * the capacity of the java.nio.ByteBuffer being returned from a * native method, or null if no expression has been specified. @@ -1101,6 +1123,10 @@ public class JavaConfiguration { readTemporaryCVariableAssignment(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop // because TemporaryCVariableAssignment changes them. + } else if (cmd.equalsIgnoreCase("StructMachineDescriptorIndex")) { + readStructMachineDescriptorIndex(tok, filename, lineNo); + // Warning: make sure delimiters are reset at the top of this loop + // because StructMachineDescriptorIndex changes them. } else if (cmd.equalsIgnoreCase("ReturnValueCapacity")) { readReturnValueCapacity(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop @@ -1499,6 +1525,18 @@ public class JavaConfiguration { } } + protected void readStructMachineDescriptorIndex(final StringTokenizer tok, final String filename, final int lineNo) { + try { + final String structName = tok.nextToken(); + String restOfLine = tok.nextToken("\n\r\f"); + restOfLine = restOfLine.trim(); + structMachineDescriptorIndex.put(structName, restOfLine); + } catch (final NoSuchElementException e) { + throw new RuntimeException("Error parsing \"StructMachineDescriptorIndex\" command at line " + lineNo + + " in file \"" + filename + "\"", e); + } + } + protected void readReturnValueCapacity(final StringTokenizer tok, final String filename, final int lineNo) { try { final String functionName = tok.nextToken(); diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index 7e5ce51..48c7047 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -963,7 +963,10 @@ public class JavaEmitter implements GlueEmitter { javaWriter.println(); javaWriter.println(" StructAccessor accessor;"); javaWriter.println(); - javaWriter.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();"); + final String cfgMachDescrIdxCode = cfg.returnStructMachineDescriptorIndex(containingJTypeName); + final String machDescrIdxCode = null != cfgMachDescrIdxCode ? cfgMachDescrIdxCode : "private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();"; + javaWriter.println(" "+machDescrIdxCode); + javaWriter.println(" private final MachineDescription md;"); javaWriter.println(); // generate all offset and size arrays generateOffsetAndSizeArrays(javaWriter, " ", containingJTypeName, structCType, null, null); /* w/o offset */ @@ -1037,22 +1040,29 @@ public class JavaEmitter implements GlueEmitter { } } javaWriter.println(); - javaWriter.println(" public static int size() {"); - javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];"); - javaWriter.println(" }"); - javaWriter.println(); - javaWriter.println(" public static " + containingJTypeName + " create() {"); - javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));"); - javaWriter.println(" }"); - javaWriter.println(); - javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {"); - javaWriter.println(" return new " + containingJTypeName + "(buf);"); - javaWriter.println(" }"); - javaWriter.println(); - javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {"); - javaWriter.println(" accessor = new StructAccessor(buf);"); - javaWriter.println(" }"); - javaWriter.println(); + if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, "size")) ) { + javaWriter.println(" public static int size() {"); + javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];"); + javaWriter.println(" }"); + javaWriter.println(); + } + if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, "create")) ) { + javaWriter.println(" public static " + containingJTypeName + " create() {"); + javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));"); + javaWriter.println(" }"); + javaWriter.println(); + javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {"); + javaWriter.println(" return new " + containingJTypeName + "(buf);"); + javaWriter.println(" }"); + javaWriter.println(); + } + if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, containingJTypeName)) ) { + javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {"); + javaWriter.println(" md = MachineDescription.StaticConfig.values()[mdIdx].md;"); + javaWriter.println(" accessor = new StructAccessor(buf);"); + javaWriter.println(" }"); + javaWriter.println(); + } javaWriter.println(" public java.nio.ByteBuffer getBuffer() {"); javaWriter.println(" return accessor.getBuffer();"); javaWriter.println(" }"); @@ -1129,7 +1139,7 @@ public class JavaEmitter implements GlueEmitter { if( fieldTypeNativeSizeFixed ) { javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);"); } else { - javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());"); + javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, md."+sizeDenominator+"SizeInBytes());"); } javaWriter.println(" return this;"); javaWriter.println(" }"); @@ -1143,7 +1153,7 @@ public class JavaEmitter implements GlueEmitter { if( fieldTypeNativeSizeFixed ) { javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);"); } else { - javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());"); + javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], md."+sizeDenominator+"SizeInBytes());"); } javaWriter.println(" }"); } else { @@ -1240,7 +1250,9 @@ public class JavaEmitter implements GlueEmitter { writer.print(")"); } - private void generateOffsetAndSizeArrays(final PrintWriter writer, final String prefix, final String fieldName, final Type fieldType, final Field field, final String postfix) { + private void generateOffsetAndSizeArrays(final PrintWriter writer, final String prefix, + final String fieldName, final Type fieldType, + final Field field, final String postfix) { if(null != field) { writer.print(prefix+"private static final int[] "+fieldName+"_offset = new int[] { "); for( int i=0; i < machDescTargetConfigs.length; i++ ) { @@ -1668,7 +1680,7 @@ public class JavaEmitter implements GlueEmitter { if( baseCElemNativeSizeFixed ) { javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val);"); } else { - javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+baseCElemSizeDenominator+"SizeInBytes());"); + javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val, md."+baseCElemSizeDenominator+"SizeInBytes());"); } javaWriter.println(" return this;"); javaWriter.println(" }"); @@ -1831,7 +1843,7 @@ public class JavaEmitter implements GlueEmitter { if( baseCElemNativeSizeFixed ) { javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx]);"); } else { - javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+baseCElemSizeDenominator+"SizeInBytes());"); + javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], md."+baseCElemSizeDenominator+"SizeInBytes());"); } javaWriter.println(" }"); javaWriter.println(); diff --git a/src/java/jogamp/common/os/MachineDescriptionRuntime.java b/src/java/jogamp/common/os/MachineDescriptionRuntime.java index 8df29f6..9becd21 100644 --- a/src/java/jogamp/common/os/MachineDescriptionRuntime.java +++ b/src/java/jogamp/common/os/MachineDescriptionRuntime.java @@ -43,37 +43,24 @@ public class MachineDescriptionRuntime { 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(!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; + 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; + if( PlatformPropsImpl.DEBUG ) { + System.err.println("MachineDescription.StaticConfig.getStatic_Hard(os "+PlatformPropsImpl.OS_TYPE+", CpuType "+PlatformPropsImpl.CPU_ARCH+", little "+PlatformPropsImpl.LITTLE_ENDIAN+"): "+smdHard.toShortString()); } } } - return smdHard; } + return smdHard; } - private static MachineDescription.StaticConfig get(final Platform.OSType osType, final Platform.CPUType cpuType, final boolean littleEndian) { + public static MachineDescription.StaticConfig get(final Platform.OSType osType, final Platform.CPUType cpuType, final boolean littleEndian) { if( cpuType.is32Bit ) { - if( cpuType.getFamily() == Platform.CPUFamily.ARM && littleEndian) { + if( cpuType.family == Platform.CPUFamily.ARM && littleEndian) { return StaticConfig.ARMle_EABI; } else if( osType == Platform.OSType.WINDOWS ) { return StaticConfig.X86_32_WINDOWS; diff --git a/src/java/jogamp/common/os/PlatformPropsImpl.java b/src/java/jogamp/common/os/PlatformPropsImpl.java index b12ab6f..b35533f 100644 --- a/src/java/jogamp/common/os/PlatformPropsImpl.java +++ b/src/java/jogamp/common/os/PlatformPropsImpl.java @@ -11,9 +11,9 @@ import java.security.PrivilegedAction; import java.util.List; import jogamp.common.Debug; -import jogamp.common.os.elf.ElfHeader; +import jogamp.common.os.elf.ElfHeaderPart1; +import jogamp.common.os.elf.ElfHeaderPart2; import jogamp.common.os.elf.SectionArmAttributes; -import jogamp.common.os.elf.SectionHeader; import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.AndroidVersion; @@ -48,6 +48,13 @@ public abstract class PlatformPropsImpl { public static final VersionNumber Mavericks = new VersionNumber(10,9,0); } + /** + * Returns {@code true} if the given {@link CPUType}s and {@link ABIType}s are compatible. + */ + public static final boolean isCompatible(final CPUType cpu1, final ABIType abi1, final CPUType cpu2, final ABIType abi2) { + return cpu1.isCompatible(cpu2) && abi1.isCompatible(abi2); + } + // // static initialization order: // @@ -72,14 +79,20 @@ public abstract class PlatformPropsImpl { public static final String JAVA_RUNTIME_NAME; /** True if having {@link java.nio.LongBuffer} and {@link java.nio.DoubleBuffer} available. */ public static final boolean JAVA_SE; - /** True if being compatible w/ language level 6, e.g. JRE 1.6. Implies {@link #JAVA_SE}. <i>Note</i>: We claim Android is compatible. */ + /** + * True only if being compatible w/ language level 6, e.g. JRE 1.6. + * <p> + * Implies {@link #isJavaSE()}. + * </p> + * <p> + * <i>Note</i>: We claim Android is compatible. + * </p> + */ public static final boolean JAVA_6; 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; @@ -126,111 +139,191 @@ public abstract class PlatformPropsImpl { OS_VERSION_NUMBER = new VersionNumber(OS_VERSION); OS_TYPE = getOSTypeImpl(OS_lower, isAndroid); - LITTLE_ENDIAN = queryIsLittleEndianImpl(); - - // 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: sARCH "+sARCH+", sCpuType "+sCpuType); - if( isAndroid ) { - System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", CPU_TYPE "+AndroidVersion.CPU_TYPE+", ABI_TYPE "+AndroidVersion.ABI_TYPE); - System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", CPU_TYPE2 "+AndroidVersion.CPU_TYPE2+", ABI_TYPE2 "+AndroidVersion.ABI_TYPE2); - } - } - // Hard values, i.e. w/ probing binaries // // FIXME / HACK: - // We use sCPUType for MachineDescriptionRuntime.getStatic() + // We use preCpuType 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 String elfCpuName; final CPUType elfCpuType; - final ABIType elfAbiType; + final ABIType elfABIType; + final int elfLittleEndian; final boolean elfValid; { - 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] ) { - elfCpuType = _ehCpuType[0]; - elfAbiType = _ehAbiType[0]; - if( isAndroid ) { - 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( elfCpuType.family != aCpuFamily1 && elfCpuType.family != aCpuFamily2 ) { - // Ooops ! - elfValid = false; - } else { - elfValid = true; - } - } else { - if( elfCpuType.family != sCpuType.family ) { - // Ooops ! - elfValid = false; - } else { - elfValid = true; + final String[] _elfCpuName = { null }; + final CPUType[] _elfCpuType = { null }; + final ABIType[] _elfAbiType = { null }; + final int[] _elfLittleEndian = { 0 }; // 1 - little, 2 - big + final boolean[] _elfValid = { false }; + AccessController.doPrivileged(new PrivilegedAction<Object>() { + @Override + public Object run() { + RandomAccessFile in = null; + try { + final File file = queryElfFile(OS_TYPE); + if(DEBUG) { + System.err.println("ELF-1: Using "+file); + } + in = new RandomAccessFile(file, "r"); + final ElfHeaderPart1 eh1 = readElfHeaderPart1(OS_TYPE, in); + if(DEBUG) { + System.err.println("ELF-1: Got "+eh1); + } + if( null != eh1 ) { + final ElfHeaderPart2 eh2 = readElfHeaderPart2(eh1, in); + if(DEBUG) { + System.err.println("ELF-2: Got "+eh2); + } + if( null != eh2 ) { + _elfCpuName[0] = eh2.cpuName; + _elfCpuType[0] = eh2.cpuType; + _elfAbiType[0] = eh2.abiType; + if( eh1.isLittleEndian() ) { + _elfLittleEndian[0] = 1; + } else if( eh1.isBigEndian() ) { + _elfLittleEndian[0] = 2; + } + _elfValid[0] = true; + } + } + } catch (final Throwable t) { + if(DEBUG) { + t.printStackTrace(); + } + } finally { + if(null != in) { + try { + in.close(); + } catch (final IOException e) { } + } } - } - if( DEBUG ) { - System.err.println("Platform.Elf: cpuType "+elfCpuType+", abiType "+elfAbiType+", valid "+elfValid); - } - } else { - elfCpuType = null; - elfAbiType = null; - elfValid = false; - if( DEBUG ) { - System.err.println("Platform.Elf: n/a"); - } + return null; + } }); + elfCpuName = _elfCpuName[0]; + elfCpuType = _elfCpuType[0]; + elfABIType = _elfAbiType[0]; + elfLittleEndian = _elfLittleEndian[0]; + elfValid = _elfValid[0]; + if( DEBUG ) { + System.err.println("Platform.Elf: valid "+elfValid+", elfCpuName "+elfCpuName+", cpuType "+elfCpuType+", abiType "+elfABIType+", elfLittleEndian "+elfLittleEndian); + } + } + + // Determine endianess, favor ELF value + final boolean littleEndian = queryIsLittleEndianImpl(); + if( elfValid ) { + switch( elfLittleEndian ) { + case 1: + LITTLE_ENDIAN = true; + break; + case 2: + LITTLE_ENDIAN = false; + break; + default: + LITTLE_ENDIAN = littleEndian; + break; } + } else { + LITTLE_ENDIAN = littleEndian; + } + if( DEBUG ) { + System.err.println("Platform.Endian: test-little "+littleEndian+", elf[valid "+elfValid+", val "+elfLittleEndian+"] -> LITTLE_ENDIAN "+LITTLE_ENDIAN); } + + // Property values for comparison + // We might take the property values even if ELF values are available, + // since the latter only reflect the CPU/ABI version of the binary files! + final String propARCH = System.getProperty("os.arch"); + final String propARCH_lower = propARCH.toLowerCase(); + final CPUType propCpuType = CPUType.query(propARCH_lower); + final ABIType propABIType = ABIType.query(propCpuType, propARCH_lower); + if( DEBUG ) { + System.err.println("Platform.Property: ARCH "+propARCH+", CpuType "+propCpuType+", ABIType "+propABIType); + } + + final int strategy; if( isAndroid ) { + if( DEBUG ) { + System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", CPU_TYPE "+AndroidVersion.CPU_TYPE+", ABI_TYPE "+AndroidVersion.ABI_TYPE); + System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", CPU_TYPE2 "+AndroidVersion.CPU_TYPE2+", ABI_TYPE2 "+AndroidVersion.ABI_TYPE2); + } if( elfValid ) { - if( elfCpuType.family == AndroidVersion.CPU_TYPE.family && - elfAbiType == AndroidVersion.ABI_TYPE ) + if( null != AndroidVersion.CPU_TYPE && + isCompatible(elfCpuType, elfABIType, AndroidVersion.CPU_TYPE, AndroidVersion.ABI_TYPE) ) { + // ELF matches Android-1 ARCH = AndroidVersion.CPU_ABI; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE; - } else { + strategy = 110; + } else if( null != AndroidVersion.CPU_TYPE2 && + isCompatible(elfCpuType, elfABIType, AndroidVersion.CPU_TYPE2, AndroidVersion.ABI_TYPE2) ) + { + // ELF matches Android-2 ARCH = AndroidVersion.CPU_ABI2; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE2; + strategy = 111; + } else { + // We assume our ELF data beats AndroidVersion info (correctness) + ARCH = elfCpuType.toString(); + ARCH_lower = ARCH.toLowerCase(); + CPU_ARCH = elfCpuType; + strategy = 112; } - ABI_TYPE = elfAbiType; + ABI_TYPE = elfABIType; } else { - // default - if( AndroidVersion.CPU_TYPE.family == CPUFamily.ARM || null == AndroidVersion.CPU_TYPE2 ) { + if( AndroidVersion.CPU_TYPE.family == CPUFamily.ARM || + null == AndroidVersion.CPU_TYPE2 ) { + // Favor Android-1: Either b/c ARM Family, or no Android-2 ARCH = AndroidVersion.CPU_ABI; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE; ABI_TYPE = AndroidVersion.ABI_TYPE; + strategy = 120; } else { + // Last resort Android-2 ARCH = AndroidVersion.CPU_ABI2; + ARCH_lower = ARCH; CPU_ARCH = AndroidVersion.CPU_TYPE2; ABI_TYPE = AndroidVersion.ABI_TYPE2; + strategy = 121; } } - ARCH_lower = ARCH; } else { - ARCH = sARCH; - ARCH_lower = sARCH_lower; - if( elfValid && CPUFamily.ARM == elfCpuType.family ) { - // Use Elf for ARM - CPU_ARCH = elfCpuType; - ABI_TYPE = elfAbiType; + if( elfValid ) { + if( isCompatible(elfCpuType, elfABIType, propCpuType, propABIType) ) { + // Use property ARCH, compatible w/ ELF + ARCH = propARCH; + ARCH_lower = propARCH_lower; + CPU_ARCH = propCpuType; + ABI_TYPE = propABIType; + strategy = 210; + } else { + // use ELF ARCH + ARCH = elfCpuName; + ARCH_lower = elfCpuName; + CPU_ARCH = elfCpuType; + ABI_TYPE = elfABIType; + strategy = 211; + } } else { - // Otherwise trust detailed os.arch (?) - CPU_ARCH = sCpuType; - ABI_TYPE = ABIType.GENERIC_ABI; + // Last resort: properties + ARCH = propARCH; + ARCH_lower = propARCH_lower; + CPU_ARCH = propCpuType; + ABI_TYPE = propABIType; + strategy = 220; } } if( DEBUG ) { - System.err.println("Platform.Hard: ARCH "+ARCH+", CPU_ARCH "+CPU_ARCH+", ABI_TYPE "+ABI_TYPE+" - isAndroid "+isAndroid+", elfValid "+elfValid); + System.err.println("Platform.Hard: ARCH "+ARCH+", CPU_ARCH "+CPU_ARCH+", ABI_TYPE "+ABI_TYPE+" - strategy "+strategy+"(isAndroid "+isAndroid+", elfValid "+elfValid+")"); } - MachineDescriptionRuntime.notifyPropsInitialized(); os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE); } @@ -271,49 +364,6 @@ public abstract class PlatformPropsImpl { return 0x0C0D == tst_s.get(0); } - private static final CPUType getCPUTypeImpl(final String archLower) { - if( archLower.equals("x86") || // jvm + android - archLower.equals("i386") || - archLower.equals("i486") || - archLower.equals("i586") || - archLower.equals("i686") ) { - return CPUType.X86_32; - } else if( archLower.equals("x86_64") || - archLower.equals("amd64") ) { - return CPUType.X86_64; - } else if( archLower.equals("ia64") ) { - return CPUType.IA64; - } else if( archLower.equals("arm") ) { - return CPUType.ARM; - } else if( archLower.equals("armv5l") ) { - return CPUType.ARMv5; - } else if( archLower.equals("armv6l") ) { - return CPUType.ARMv6; - } else if( archLower.equals("armv7l") || - archLower.equals("armeabi") || // android - archLower.equals("armeabi-v7a") ) { // android - return CPUType.ARMv7; - } else if( archLower.equals("aarch64") || - archLower.equals("arm64") ) { - return CPUType.ARM64; - } else if( archLower.equals("armv8-a") || - archLower.equals("arm64-v8a") ) { - return CPUType.ARMv8_A; - } else if( archLower.equals("sparc") ) { - return CPUType.SPARC_32; - } else if( archLower.equals("sparcv9") ) { - return CPUType.SPARCV9_64; - } else if( archLower.equals("pa_risc2.0") ) { - 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(final String data, final String[] search) { if(null != data && null != search) { @@ -341,101 +391,53 @@ public abstract class PlatformPropsImpl { * Elf ARM Tags are read using {@link ElfHeader}, .. and {@link SectionArmAttributes#abiVFPArgsAcceptsVFPVariant(byte)}. * </p> */ - private static final ElfHeader queryABITypeImpl(final OSType osType, final CPUType[] cpuType, final ABIType[] abiType) { - return AccessController.doPrivileged(new PrivilegedAction<ElfHeader>() { - @Override - public ElfHeader run() { - ElfHeader res = null; - try { - 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 ) { - res = queryABITypeImpl(file, cpuType, abiType); - } - } catch(final Throwable t) { - if(DEBUG) { - t.printStackTrace(); - } - } - return res; - } } ); - } - private static final ElfHeader queryABITypeImpl(final File file, final CPUType[] cpuType, final ABIType[] abiType) { - ElfHeader res = null; - RandomAccessFile in = null; + private static final File queryElfFile(final OSType osType) { + File file = 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()); + 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; } } - cpuType[0] = CPUType.ARM; // lowest 32bit denominator, ok for us - abiType[0] = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; - if(DEBUG) { - System.err.println("ELF: abiARM, abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); + if( null == file ) { + file = findSysLib("java"); + } + if( null == file ) { + file = findSysLib("jvm"); } - } else if ( eh.isAARCH64() ) { - cpuType[0] = CPUType.ARM64; - abiType[0] = ABIType.EABI_AARCH64; - } 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(final Throwable t) { if(DEBUG) { - System.err.println("Caught: "+t.getMessage()); t.printStackTrace(); } - } finally { - if(null != in) { - try { - in.close(); - } catch (final IOException e) { } + } + return file; + } + private static final ElfHeaderPart1 readElfHeaderPart1(final OSType osType, final RandomAccessFile in) { + ElfHeaderPart1 res = null; + try { + res = ElfHeaderPart1.read(osType, in); + } catch(final Throwable t) { + if(DEBUG) { + System.err.println("Caught: "+t.getMessage()); + t.printStackTrace(); } } - if(DEBUG) { - System.err.println("ELF: res "+res+", cpuType "+cpuType[0]+", abiType "+abiType[0]); + return res; + } + private static final ElfHeaderPart2 readElfHeaderPart2(final ElfHeaderPart1 eh1, final RandomAccessFile in) { + ElfHeaderPart2 res = null; + try { + res = ElfHeaderPart2.read(eh1, in); + } catch(final Throwable t) { + if(DEBUG) { + System.err.println("Caught: "+t.getMessage()); + t.printStackTrace(); + } } return res; } @@ -551,6 +553,9 @@ public abstract class PlatformPropsImpl { case SPARC_32: _and_arch_tmp = "sparc"; break; + case PPC64: + _and_arch_tmp = "ppc64"; // TODO: sync with gluegen-cpptasks-base.xml + break; case PPC: _and_arch_tmp = "ppc"; // TODO: sync with gluegen-cpptasks-base.xml break; @@ -567,7 +572,7 @@ public abstract class PlatformPropsImpl { _and_arch_tmp = "risc2.0"; // TODO: sync with gluegen-cpptasks-base.xml break; default: - throw new InternalError("Complete case block"); + throw new InternalError("Unhandled CPUType: "+cpuType); } switch( osType ) { @@ -604,7 +609,7 @@ public abstract class PlatformPropsImpl { _and_arch_final = "hppa"; // TODO: really only hppa ? break; default: - throw new InternalError("Complete case block"); + throw new InternalError("Unhandled OSType: "+osType); } return os_ + "-" + _and_arch_final; } diff --git a/src/java/jogamp/common/os/elf/Ehdr.java b/src/java/jogamp/common/os/elf/Ehdr.java deleted file mode 100644 index 1aac1c1..0000000 --- a/src/java/jogamp/common/os/elf/Ehdr.java +++ /dev/null @@ -1,246 +0,0 @@ -/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Fri Jan 30 06:44:16 CET 2015 ----! */ - - -package jogamp.common.os.elf; - -import java.nio.*; - -import com.jogamp.gluegen.runtime.*; -import com.jogamp.common.os.*; -import com.jogamp.common.nio.*; -import jogamp.common.os.MachineDescriptionRuntime; - - -public class Ehdr { - - StructAccessor accessor; - - private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal(); - - private static final int[] Ehdr_size = new int[] { 52 /* ARMle_EABI */, 52 /* X86_32_UNIX */, 64 /* X86_64_UNIX */, 52 /* X86_32_MACOS */, 52 /* X86_32_WINDOWS */, 64 /* X86_64_WINDOWS */, 52 /* SPARC_32_SUNOS */ }; - private static final int[] e_ident_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* X86_64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */, 0 /* SPARC_32_SUNOS */ }; - private static final int[] e_ident_size = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 16 /* X86_64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; - private static final int[] e_type_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 16 /* X86_64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; -//private static final int[] e_type_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_machine_offset = new int[] { 18 /* ARMle_EABI */, 18 /* X86_32_UNIX */, 18 /* X86_64_UNIX */, 18 /* X86_32_MACOS */, 18 /* X86_32_WINDOWS */, 18 /* X86_64_WINDOWS */, 18 /* SPARC_32_SUNOS */ }; -//private static final int[] e_machine_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_version_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 20 /* X86_64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 20 /* X86_64_WINDOWS */, 20 /* SPARC_32_SUNOS */ }; -//private static final int[] e_version_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] e_entry_offset = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 24 /* X86_64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */, 24 /* SPARC_32_SUNOS */ }; -//private static final int[] e_entry_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] e_phoff_offset = new int[] { 28 /* ARMle_EABI */, 28 /* X86_32_UNIX */, 32 /* X86_64_UNIX */, 28 /* X86_32_MACOS */, 28 /* X86_32_WINDOWS */, 32 /* X86_64_WINDOWS */, 28 /* SPARC_32_SUNOS */ }; -//private static final int[] e_phoff_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] e_shoff_offset = new int[] { 32 /* ARMle_EABI */, 32 /* X86_32_UNIX */, 40 /* X86_64_UNIX */, 32 /* X86_32_MACOS */, 32 /* X86_32_WINDOWS */, 40 /* X86_64_WINDOWS */, 32 /* SPARC_32_SUNOS */ }; -//private static final int[] e_shoff_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] e_flags_offset = new int[] { 36 /* ARMle_EABI */, 36 /* X86_32_UNIX */, 48 /* X86_64_UNIX */, 36 /* X86_32_MACOS */, 36 /* X86_32_WINDOWS */, 48 /* X86_64_WINDOWS */, 36 /* SPARC_32_SUNOS */ }; -//private static final int[] e_flags_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] e_ehsize_offset = new int[] { 40 /* ARMle_EABI */, 40 /* X86_32_UNIX */, 52 /* X86_64_UNIX */, 40 /* X86_32_MACOS */, 40 /* X86_32_WINDOWS */, 52 /* X86_64_WINDOWS */, 40 /* SPARC_32_SUNOS */ }; -//private static final int[] e_ehsize_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_phentsize_offset = new int[] { 42 /* ARMle_EABI */, 42 /* X86_32_UNIX */, 54 /* X86_64_UNIX */, 42 /* X86_32_MACOS */, 42 /* X86_32_WINDOWS */, 54 /* X86_64_WINDOWS */, 42 /* SPARC_32_SUNOS */ }; -//private static final int[] e_phentsize_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_phnum_offset = new int[] { 44 /* ARMle_EABI */, 44 /* X86_32_UNIX */, 56 /* X86_64_UNIX */, 44 /* X86_32_MACOS */, 44 /* X86_32_WINDOWS */, 56 /* X86_64_WINDOWS */, 44 /* SPARC_32_SUNOS */ }; -//private static final int[] e_phnum_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_shentsize_offset = new int[] { 46 /* ARMle_EABI */, 46 /* X86_32_UNIX */, 58 /* X86_64_UNIX */, 46 /* X86_32_MACOS */, 46 /* X86_32_WINDOWS */, 58 /* X86_64_WINDOWS */, 46 /* SPARC_32_SUNOS */ }; -//private static final int[] e_shentsize_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_shnum_offset = new int[] { 48 /* ARMle_EABI */, 48 /* X86_32_UNIX */, 60 /* X86_64_UNIX */, 48 /* X86_32_MACOS */, 48 /* X86_32_WINDOWS */, 60 /* X86_64_WINDOWS */, 48 /* SPARC_32_SUNOS */ }; -//private static final int[] e_shnum_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - private static final int[] e_shstrndx_offset = new int[] { 50 /* ARMle_EABI */, 50 /* X86_32_UNIX */, 62 /* X86_64_UNIX */, 50 /* X86_32_MACOS */, 50 /* X86_32_WINDOWS */, 62 /* X86_64_WINDOWS */, 50 /* SPARC_32_SUNOS */ }; -//private static final int[] e_shstrndx_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* X86_64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; - - public static int size() { - return Ehdr_size[mdIdx]; - } - - public static Ehdr create() { - return create(Buffers.newDirectByteBuffer(size())); - } - - public static Ehdr create(java.nio.ByteBuffer buf) { - return new Ehdr(buf); - } - - Ehdr(java.nio.ByteBuffer buf) { - accessor = new StructAccessor(buf); - } - - public java.nio.ByteBuffer getBuffer() { - return accessor.getBuffer(); - } - - /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ - public static final int getE_identArrayLength() { - return 16; - } - - /** Setter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ - public Ehdr setE_ident(final int offset, byte[] val) { - final int arrayLength = 16; - if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException("offset "+offset+" + val.length "+val.length+" > array-length "+arrayLength); }; - final int elemSize = Buffers.SIZEOF_BYTE; - final ByteBuffer destB = getBuffer(); - final int bTotal = arrayLength * elemSize; - if( bTotal > e_ident_size[mdIdx] ) { throw new IndexOutOfBoundsException("bTotal "+bTotal+" > size "+e_ident_size[mdIdx]+", elemSize "+elemSize+" * "+arrayLength); }; - int bOffset = e_ident_offset[mdIdx]; - final int bLimes = bOffset + bTotal; - if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException("bLimes "+bLimes+" > buffer.limit "+destB.limit()+", elemOff "+bOffset+", elemSize "+elemSize+" * "+arrayLength); }; - bOffset += elemSize * offset; - accessor.setBytesAt(bOffset, val); - return this; - } - - /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ - public ByteBuffer getE_ident() { - return accessor.slice(e_ident_offset[mdIdx], Buffers.SIZEOF_BYTE * 16); - } - - /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ - public byte[] getE_ident(final int offset, byte result[]) { - final int arrayLength = 16; - if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException("offset "+offset+" + result.length "+result.length+" > array-length "+arrayLength); }; - return accessor.getBytesAt(e_ident_offset[mdIdx] + (Buffers.SIZEOF_BYTE * offset), result); - } - - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_type(short val) { - accessor.setShortAt(e_type_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_type() { - return accessor.getShortAt(e_type_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_machine(short val) { - accessor.setShortAt(e_machine_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_machine() { - return accessor.getShortAt(e_machine_offset[mdIdx]); - } - - /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ - public Ehdr setE_version(int val) { - accessor.setIntAt(e_version_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ - public int getE_version() { - return accessor.getIntAt(e_version_offset[mdIdx]); - } - - /** Setter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ - public Ehdr setE_entry(long val) { - accessor.setLongAt(e_entry_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - return this; - } - - /** Getter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ - public long getE_entry() { - return accessor.getLongAt(e_entry_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - } - - /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ - public Ehdr setE_phoff(long val) { - accessor.setLongAt(e_phoff_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - return this; - } - - /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ - public long getE_phoff() { - return accessor.getLongAt(e_phoff_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - } - - /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ - public Ehdr setE_shoff(long val) { - accessor.setLongAt(e_shoff_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - return this; - } - - /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ - public long getE_shoff() { - return accessor.getLongAt(e_shoff_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); - } - - /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ - public Ehdr setE_flags(int val) { - accessor.setIntAt(e_flags_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ - public int getE_flags() { - return accessor.getIntAt(e_flags_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_ehsize(short val) { - accessor.setShortAt(e_ehsize_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_ehsize() { - return accessor.getShortAt(e_ehsize_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_phentsize(short val) { - accessor.setShortAt(e_phentsize_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_phentsize() { - return accessor.getShortAt(e_phentsize_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_phnum(short val) { - accessor.setShortAt(e_phnum_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_phnum() { - return accessor.getShortAt(e_phnum_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_shentsize(short val) { - accessor.setShortAt(e_shentsize_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_shentsize() { - return accessor.getShortAt(e_shentsize_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_shnum(short val) { - accessor.setShortAt(e_shnum_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_shnum() { - return accessor.getShortAt(e_shnum_offset[mdIdx]); - } - - /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public Ehdr setE_shstrndx(short val) { - accessor.setShortAt(e_shstrndx_offset[mdIdx], val); - return this; - } - - /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ - public short getE_shstrndx() { - return accessor.getShortAt(e_shstrndx_offset[mdIdx]); - } -} diff --git a/src/java/jogamp/common/os/elf/Ehdr_p1.java b/src/java/jogamp/common/os/elf/Ehdr_p1.java new file mode 100644 index 0000000..0d23a0a --- /dev/null +++ b/src/java/jogamp/common/os/elf/Ehdr_p1.java @@ -0,0 +1,118 @@ +/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Sun Feb 01 03:27:25 CET 2015 ----! */ + + +package jogamp.common.os.elf; + +import java.nio.*; + +import com.jogamp.gluegen.runtime.*; +import com.jogamp.common.os.*; +import com.jogamp.common.nio.*; +import jogamp.common.os.MachineDescriptionRuntime; + + +public class Ehdr_p1 { + + StructAccessor accessor; + + private static final int mdIdx = 0; + private final MachineDescription md; + + private static final int[] Ehdr_p1_size = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 24 /* LP64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */, 24 /* SPARC_32_SUNOS */ }; + private static final int[] e_ident_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* LP64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */, 0 /* SPARC_32_SUNOS */ }; + private static final int[] e_ident_size = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 16 /* LP64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; + private static final int[] e_type_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 16 /* LP64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; +//private static final int[] e_type_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_machine_offset = new int[] { 18 /* ARMle_EABI */, 18 /* X86_32_UNIX */, 18 /* LP64_UNIX */, 18 /* X86_32_MACOS */, 18 /* X86_32_WINDOWS */, 18 /* X86_64_WINDOWS */, 18 /* SPARC_32_SUNOS */ }; +//private static final int[] e_machine_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_version_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 20 /* LP64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 20 /* X86_64_WINDOWS */, 20 /* SPARC_32_SUNOS */ }; +//private static final int[] e_version_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + + public static int size() { + return Ehdr_p1_size[mdIdx]; + } + + public static Ehdr_p1 create() { + return create(Buffers.newDirectByteBuffer(size())); + } + + public static Ehdr_p1 create(java.nio.ByteBuffer buf) { + return new Ehdr_p1(buf); + } + + Ehdr_p1(java.nio.ByteBuffer buf) { + md = MachineDescription.StaticConfig.values()[mdIdx].md; + accessor = new StructAccessor(buf); + } + + public java.nio.ByteBuffer getBuffer() { + return accessor.getBuffer(); + } + + /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ + public static final int getE_identArrayLength() { + return 16; + } + + /** Setter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ + public Ehdr_p1 setE_ident(final int offset, byte[] val) { + final int arrayLength = 16; + if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException("offset "+offset+" + val.length "+val.length+" > array-length "+arrayLength); }; + final int elemSize = Buffers.SIZEOF_BYTE; + final ByteBuffer destB = getBuffer(); + final int bTotal = arrayLength * elemSize; + if( bTotal > e_ident_size[mdIdx] ) { throw new IndexOutOfBoundsException("bTotal "+bTotal+" > size "+e_ident_size[mdIdx]+", elemSize "+elemSize+" * "+arrayLength); }; + int bOffset = e_ident_offset[mdIdx]; + final int bLimes = bOffset + bTotal; + if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException("bLimes "+bLimes+" > buffer.limit "+destB.limit()+", elemOff "+bOffset+", elemSize "+elemSize+" * "+arrayLength); }; + bOffset += elemSize * offset; + accessor.setBytesAt(bOffset, val); + return this; + } + + /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ + public ByteBuffer getE_ident() { + return accessor.slice(e_ident_offset[mdIdx], Buffers.SIZEOF_BYTE * 16); + } + + /** Getter for native field: CType['char *', size [fixed false, lnx64 16], [array*1]], with array length of <code>16</code> */ + public byte[] getE_ident(final int offset, byte result[]) { + final int arrayLength = 16; + if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException("offset "+offset+" + result.length "+result.length+" > array-length "+arrayLength); }; + return accessor.getBytesAt(e_ident_offset[mdIdx] + (Buffers.SIZEOF_BYTE * offset), result); + } + + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p1 setE_type(short val) { + accessor.setShortAt(e_type_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_type() { + return accessor.getShortAt(e_type_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p1 setE_machine(short val) { + accessor.setShortAt(e_machine_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_machine() { + return accessor.getShortAt(e_machine_offset[mdIdx]); + } + + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Ehdr_p1 setE_version(int val) { + accessor.setIntAt(e_version_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public int getE_version() { + return accessor.getIntAt(e_version_offset[mdIdx]); + } +} diff --git a/src/java/jogamp/common/os/elf/Ehdr_p2.java b/src/java/jogamp/common/os/elf/Ehdr_p2.java new file mode 100644 index 0000000..9dc561a --- /dev/null +++ b/src/java/jogamp/common/os/elf/Ehdr_p2.java @@ -0,0 +1,176 @@ +/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Sun Feb 01 03:27:25 CET 2015 ----! */ + + +package jogamp.common.os.elf; + +import java.nio.*; + +import com.jogamp.gluegen.runtime.*; +import com.jogamp.common.os.*; +import com.jogamp.common.nio.*; +import jogamp.common.os.MachineDescriptionRuntime; + + +public class Ehdr_p2 { + + StructAccessor accessor; + + private final int mdIdx; + private final MachineDescription md; + + private static final int[] Ehdr_p2_size = new int[] { 28 /* ARMle_EABI */, 28 /* X86_32_UNIX */, 40 /* LP64_UNIX */, 28 /* X86_32_MACOS */, 28 /* X86_32_WINDOWS */, 40 /* X86_64_WINDOWS */, 28 /* SPARC_32_SUNOS */ }; + private static final int[] e_entry_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* LP64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */, 0 /* SPARC_32_SUNOS */ }; +//private static final int[] e_entry_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] e_phoff_offset = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; +//private static final int[] e_phoff_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] e_shoff_offset = new int[] { 8 /* ARMle_EABI */, 8 /* X86_32_UNIX */, 16 /* LP64_UNIX */, 8 /* X86_32_MACOS */, 8 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 8 /* SPARC_32_SUNOS */ }; +//private static final int[] e_shoff_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] e_flags_offset = new int[] { 12 /* ARMle_EABI */, 12 /* X86_32_UNIX */, 24 /* LP64_UNIX */, 12 /* X86_32_MACOS */, 12 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */, 12 /* SPARC_32_SUNOS */ }; +//private static final int[] e_flags_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] e_ehsize_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 28 /* LP64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 28 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; +//private static final int[] e_ehsize_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_phentsize_offset = new int[] { 18 /* ARMle_EABI */, 18 /* X86_32_UNIX */, 30 /* LP64_UNIX */, 18 /* X86_32_MACOS */, 18 /* X86_32_WINDOWS */, 30 /* X86_64_WINDOWS */, 18 /* SPARC_32_SUNOS */ }; +//private static final int[] e_phentsize_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_phnum_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 32 /* LP64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 32 /* X86_64_WINDOWS */, 20 /* SPARC_32_SUNOS */ }; +//private static final int[] e_phnum_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_shentsize_offset = new int[] { 22 /* ARMle_EABI */, 22 /* X86_32_UNIX */, 34 /* LP64_UNIX */, 22 /* X86_32_MACOS */, 22 /* X86_32_WINDOWS */, 34 /* X86_64_WINDOWS */, 22 /* SPARC_32_SUNOS */ }; +//private static final int[] e_shentsize_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_shnum_offset = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 36 /* LP64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 36 /* X86_64_WINDOWS */, 24 /* SPARC_32_SUNOS */ }; +//private static final int[] e_shnum_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + private static final int[] e_shstrndx_offset = new int[] { 26 /* ARMle_EABI */, 26 /* X86_32_UNIX */, 38 /* LP64_UNIX */, 26 /* X86_32_MACOS */, 26 /* X86_32_WINDOWS */, 38 /* X86_64_WINDOWS */, 26 /* SPARC_32_SUNOS */ }; +//private static final int[] e_shstrndx_size = new int[] { 2 /* ARMle_EABI */, 2 /* X86_32_UNIX */, 2 /* LP64_UNIX */, 2 /* X86_32_MACOS */, 2 /* X86_32_WINDOWS */, 2 /* X86_64_WINDOWS */, 2 /* SPARC_32_SUNOS */ }; + + public java.nio.ByteBuffer getBuffer() { + return accessor.getBuffer(); + } + + /** Setter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ + public Ehdr_p2 setE_entry(long val) { + accessor.setLongAt(e_entry_offset[mdIdx], val, md.longSizeInBytes()); + return this; + } + + /** Getter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ + public long getE_entry() { + return accessor.getLongAt(e_entry_offset[mdIdx], md.longSizeInBytes()); + } + + /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public Ehdr_p2 setE_phoff(long val) { + accessor.setLongAt(e_phoff_offset[mdIdx], val, md.longSizeInBytes()); + return this; + } + + /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public long getE_phoff() { + return accessor.getLongAt(e_phoff_offset[mdIdx], md.longSizeInBytes()); + } + + /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public Ehdr_p2 setE_shoff(long val) { + accessor.setLongAt(e_shoff_offset[mdIdx], val, md.longSizeInBytes()); + return this; + } + + /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ + public long getE_shoff() { + return accessor.getLongAt(e_shoff_offset[mdIdx], md.longSizeInBytes()); + } + + /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public Ehdr_p2 setE_flags(int val) { + accessor.setIntAt(e_flags_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ + public int getE_flags() { + return accessor.getIntAt(e_flags_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_ehsize(short val) { + accessor.setShortAt(e_ehsize_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_ehsize() { + return accessor.getShortAt(e_ehsize_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_phentsize(short val) { + accessor.setShortAt(e_phentsize_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_phentsize() { + return accessor.getShortAt(e_phentsize_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_phnum(short val) { + accessor.setShortAt(e_phnum_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_phnum() { + return accessor.getShortAt(e_phnum_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_shentsize(short val) { + accessor.setShortAt(e_shentsize_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_shentsize() { + return accessor.getShortAt(e_shentsize_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_shnum(short val) { + accessor.setShortAt(e_shnum_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_shnum() { + return accessor.getShortAt(e_shnum_offset[mdIdx]); + } + + /** Setter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public Ehdr_p2 setE_shstrndx(short val) { + accessor.setShortAt(e_shstrndx_offset[mdIdx], val); + return this; + } + + /** Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]] */ + public short getE_shstrndx() { + return accessor.getShortAt(e_shstrndx_offset[mdIdx]); + } + + // --- Begin CustomJavaCode .cfg declarations + public static int size(final int mdIdx) { + return Ehdr_p2_size[mdIdx]; + } + + public static Ehdr_p2 create(final int mdIdx) { + return create(mdIdx, Buffers.newDirectByteBuffer(size(mdIdx))); + } + + public static Ehdr_p2 create(final int mdIdx, final java.nio.ByteBuffer buf) { + return new Ehdr_p2(mdIdx, buf); + } + + Ehdr_p2(final int mdIdx, final java.nio.ByteBuffer buf) { + this.mdIdx = mdIdx; + this.md = MachineDescription.StaticConfig.values()[mdIdx].md; + this.accessor = new StructAccessor(buf); + } + // ---- End CustomJavaCode .cfg declarations +} diff --git a/src/java/jogamp/common/os/elf/ElfHeader.java b/src/java/jogamp/common/os/elf/ElfHeaderPart1.java index 60b6d50..ec926e9 100644 --- a/src/java/jogamp/common/os/elf/ElfHeader.java +++ b/src/java/jogamp/common/os/elf/ElfHeaderPart1.java @@ -31,13 +31,21 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; +import jogamp.common.Debug; +import jogamp.common.os.MachineDescriptionRuntime; + +import com.jogamp.common.os.MachineDescription; +import com.jogamp.common.os.Platform.ABIType; +import com.jogamp.common.os.Platform.CPUType; +import com.jogamp.common.os.Platform.OSType; + 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 + * ELF ABI Header Part-1 + * <p> + * Part-1 can be read w/o knowledge of CPUType! + * </p> * <p> * References: * <ul> @@ -46,11 +54,14 @@ import static jogamp.common.os.elf.IOUtils.toHexString; * <li>http://infocenter.arm.com/ * <ul> * <li>ARM IHI 0044E, current through ABI release 2.09</li> + * <li>ARM IHI 0056B: Elf for ARM 64-bit Architecture</li> * </ul></li> * </ul> * </p> */ -public class ElfHeader { +public class ElfHeaderPart1 { + static final boolean DEBUG = Debug.debug("Platform"); + /** Size of e_ident array - {@value} */ public static int EI_NIDENT = 16; @@ -137,64 +148,6 @@ public class ElfHeader { */ public static final int EI_PAD = 9; - /** - * This masks an 8-bit version number, the version of the ABI to which this - * ELF file conforms. This ABI is version 5. A value of 0 denotes unknown conformance. - * {@value} - */ - public static final int EF_ARM_ABIMASK = 0xFF000000; - public static final int EF_ARM_ABISHIFT = 24; - - /** - * ARM ABI version 5. - * {@value} - */ - public static final int EF_ARM_ABI5 = 0x05000000; - - /** - * The ELF file contains BE-8 code, suitable for execution on an ARM - * Architecture v6 processor. This flag must only be set on an executable file. - * {@value} - */ - public static final int EF_ARM_BE8 = 0x00800000; - - /** - * Legacy code (ABI version 4 and earlier) generated by gcc-arm-xxx might - * use these bits. - * {@value} - */ - public static final int EF_ARM_GCCMASK = 0x00400FFF; - - /** - * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note that - * the executable file was built to conform to the hardware floating-point - * procedure-call standard. - * <p> - * Compatible with legacy (pre version 5) gcc use as EF_ARM_VFP_FLOAT. - * </p> - * <p> - * Note: This is not used (anymore) - * </p> - * {@value} - */ - public static final int EF_ARM_ABI_FLOAT_HARD = 0x00000400; - - /** - * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note - * explicitly that the executable file was built to conform to the software - * floating-point procedure-call standard (the base standard). If both - * {@link #EF_ARM_ABI_FLOAT_HARD} and {@link #EF_ARM_ABI_FLOAT_SOFT} are clear, - * conformance to the base procedure-call standard is implied. - * <p> - * Compatible with legacy (pre version 5) gcc use as EF_ARM_SOFT_FLOAT. - * </p> - * <p> - * Note: This is not used (anymore) - * </p> - * {@value} - */ - public static final int EF_ARM_ABI_FLOAT_SOFT = 0x00000200; - /** An unknown type - {@value} */ public static final short ET_NONE = 0; /** A relocatable file - {@value} */ @@ -365,47 +318,104 @@ public class ElfHeader { ELFMAG3 == ident[3] ; } - /** Public access to the raw elf header */ - public final Ehdr d; + /** Public access to the raw elf header part-1 (CPU/ABI independent read) */ + public final Ehdr_p1 raw; + private final byte[] E_ident; - /** Public access to the {@link SectionHeader} */ - public final SectionHeader[] sht; + /** Lower case CPUType name */ + public final String cpuName; + public final CPUType cpuType; + public final ABIType abiType; - private final String string; - private final byte[] E_ident; + public final MachineDescription.StaticConfig machDesc; /** * Note: The input stream shall stay untouch to be able to read sections! - * + * @param osType TODO * @param in input stream of a binary file at position zero + * * @return * @throws IOException if reading from the given input stream fails or less then ELF Header size bytes * @throws IllegalArgumentException if the given input stream does not represent an ELF Header */ - public static ElfHeader read(final RandomAccessFile in) throws IOException, IllegalArgumentException { - final int eh_sz = Ehdr.size(); - final byte[] buf = new byte[eh_sz]; - readBytes (in, buf, 0, eh_sz); - final ElfHeader eh = new ElfHeader(ByteBuffer.wrap(buf, 0, buf.length), in); - return eh; + public static ElfHeaderPart1 read(final OSType osType, final RandomAccessFile in) throws IOException, IllegalArgumentException { + return new ElfHeaderPart1(osType, in); } /** + * @param osType TODO * @param buf ELF Header bytes * @throws IllegalArgumentException if the given buffer does not represent an ELF Header * @throws IOException */ - ElfHeader(final java.nio.ByteBuffer buf, final RandomAccessFile in) throws IllegalArgumentException, IOException { - d = Ehdr.create(buf); - E_ident = d.getE_ident(0, new byte[Ehdr.getE_identArrayLength()]); + ElfHeaderPart1(final OSType osType, final RandomAccessFile in) throws IllegalArgumentException, IOException { + { + final byte[] buf = new byte[Ehdr_p1.size()]; + readBytes (in, buf, 0, buf.length); + final ByteBuffer eh1Bytes = ByteBuffer.wrap(buf, 0, buf.length); + raw = Ehdr_p1.create(eh1Bytes); + } + E_ident = raw.getE_ident(0, new byte[Ehdr_p1.getE_identArrayLength()]); if( !isIdentityValid(E_ident) ) { throw new IllegalArgumentException("Buffer is not an ELF Header"); } - sht = readSectionHeaderTable(in); - string = toStringImpl(); - } - public final short getSize() { return d.getE_ehsize(); } + final short machine = getMachine(); + switch ( machine ) { + case EM_ARM: + cpuName = "arm"; // lowest 32bit denominator, ok for now + abiType = ABIType.GENERIC_ABI; + break; + case EM_AARCH64: + cpuName = "aarch64"; + abiType = ABIType.EABI_AARCH64; + break; + case EM_X86_64: + cpuName = "x86_64"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_386: + cpuName = "i386"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_486: + cpuName = "i486"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_IA_64: + cpuName = "ia64"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_MIPS: + cpuName = "mips"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_MIPS_X: + cpuName = "mips-x"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_MIPS_RS3_LE: + cpuName = "mips-rs3-le"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_PPC: + cpuName = "ppc"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_PPC64: + cpuName = "ppc64"; + abiType = ABIType.GENERIC_ABI; + break; + case EM_SH: // Hitachi SuperH ? + default: + throw new IllegalArgumentException("CPUType and ABIType could not be determined"); + } + cpuType = CPUType.query(cpuName.toLowerCase()); + machDesc = MachineDescriptionRuntime.get(osType, cpuType, isLittleEndian()); + if(DEBUG) { + System.err.println("ELF-1: cpuName "+cpuName+" -> "+cpuType+", "+abiType+", machDesc "+machDesc.toShortString()); + } + } /** * Returns the architecture class in bits, @@ -428,6 +438,19 @@ public class ElfHeader { return E_ident[EI_DATA]; } + /** + * Returns whether the processor's {@link #getDataEncodingMode() data encoding} is {@link #ELFDATA2LSB}. + */ + public final boolean isLittleEndian() { return ELFDATA2LSB == E_ident[EI_DATA]; } + /** + * Returns whether the processor's {@link #getDataEncodingMode() data encoding} is {@link #ELFDATA2MSB}. + */ + public final boolean isBigEndian() { return ELFDATA2MSB == E_ident[EI_DATA]; } + /** + * Returns whether the processor's {@link #getDataEncodingMode() data encoding} is {@link #ELFDATANONE}. + */ + public final boolean isNoneEndian() { return ELFDATANONE == E_ident[EI_DATA]; } + /** Returns the ELF file version, should be {@link #EV_CURRENT}. */ public final byte getVersion() { return E_ident[EI_VERSION]; @@ -445,210 +468,33 @@ public class ElfHeader { /** Returns the object file type, e.g. {@link #ET_EXEC}, .. */ public final short getType() { - return d.getE_type(); + return raw.getE_type(); } /** Returns the required architecture for the file, e.g. {@link #EM_386}, .. */ public final short getMachine() { - return d.getE_machine(); - } - - /** - * Returns true if {@link #getMachine() machine} is a 32 bit ARM CPU - * of type {@link #EM_ARM}. */ - public final boolean isArm() { - return getMachine() == EM_ARM; - } - - /** - * Returns true if {@link #getMachine() machine} is a 64 bit AARCH64 ARM CPU - * of type {@link #EM_AARCH64}. */ - public final boolean isAARCH64() { - return getMachine() == EM_AARCH64; - } - - /** - * 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 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(); - } - - /** Returns the ARM EABI version from {@link #getFlags() flags}, maybe 0 if not an ARM EABI. */ - public byte getArmABI() { - return (byte) ( ( ( EF_ARM_ABIMASK & d.getE_flags() ) >> EF_ARM_ABISHIFT ) & 0xff ); - } - - /** Returns the ARM EABI legacy GCC {@link #getFlags() flags}, maybe 0 if not an ARM EABI or not having legacy GCC flags. */ - public int getArmLegacyGCCFlags() { - final int f = d.getE_flags(); - return 0 != ( EF_ARM_ABIMASK & f ) ? ( EF_ARM_GCCMASK & f ) : 0; - } - - /** - * Returns the ARM EABI float mode from {@link #getFlags() flags}, - * i.e. 1 for {@link #EF_ARM_ABI_FLOAT_SOFT}, 2 for {@link #EF_ARM_ABI_FLOAT_HARD} - * or 0 for none. - * <p> - * Note: This is not used (anymore) - * </p> - */ - public byte getArmFloatMode() { - final int f = d.getE_flags(); - if( 0 != ( EF_ARM_ABIMASK & f ) ) { - if( ( EF_ARM_ABI_FLOAT_HARD & f ) != 0 ) { - return 2; - } - if( ( EF_ARM_ABI_FLOAT_SOFT & f ) != 0 ) { - return 1; - } - } - return 0; - } - - /** Returns the 1st occurence of matching SectionHeader {@link SectionHeader#getType() type}, or null if not exists. */ - public final SectionHeader getSectionHeader(final int type) { - for(int i=0; i<sht.length; i++) { - final SectionHeader sh = sht[i]; - if( sh.getType() == type ) { - return sh; - } - } - return null; - } - - /** Returns the 1st occurence of matching SectionHeader {@link SectionHeader#getName() name}, or null if not exists. */ - public final SectionHeader getSectionHeader(final String name) { - for(int i=0; i<sht.length; i++) { - final SectionHeader sh = sht[i]; - if( sh.getName().equals(name) ) { - return sh; - } - } - return null; + return raw.getE_machine(); } @Override public final String toString() { - return string; - } - - private final String toStringImpl() { - final String machineS; - if( isArm() ) { - machineS=", arm"; - } 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=""; - } 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(final RandomAccessFile in) throws IOException, IllegalArgumentException { - // positioning - { - final long off = d.getE_shoff(); // absolute offset - if( 0 == off ) { - return new SectionHeader[0]; - } - seek(in, off); + case ELFDATA2LSB: encS = "LSB"; break; + case ELFDATA2MSB: encS = "MSB"; break; + default: encS = "NON"; break; /* ELFDATANONE */ } - final SectionHeader[] sht; - final int strndx = d.getE_shstrndx(); - final int size = d.getE_shentsize(); - final int num; - int i; - if( 0 == d.getE_shnum() ) { - // Read 1st table 1st and use it's sh_size - final byte[] buf0 = new byte[size]; - readBytes(in, buf0, 0, size); - final SectionHeader sh0 = new SectionHeader(buf0, 0, size, 0); - num = (int) sh0.d.getSh_size(); - if( 0 >= num ) { - throw new IllegalArgumentException("EHdr sh_num == 0 and 1st SHdr size == 0"); - } - sht = new SectionHeader[num]; - sht[0] = sh0; - i=1; - } else { - num = d.getE_shnum(); - sht = new SectionHeader[num]; - i=0; + final int type = getType(); + final String typeS; + switch(type) { + case ET_REL: typeS = "reloc"; break; + case ET_EXEC: typeS = "exec"; break; + case ET_DYN: typeS = "shared"; break; + case ET_CORE: typeS = "core"; break; + default: typeS = "none"; break; /* ET_NONE */ } - for(; i<num; i++) { - final byte[] buf = new byte[size]; - readBytes(in, buf, 0, size); - sht[i] = new SectionHeader(buf, 0, size, i); - } - if( SectionHeader.SHN_UNDEF != strndx ) { - // has section name string table - if( shortToInt(SectionHeader.SHN_LORESERVE) <= strndx ) { - throw new InternalError("TODO strndx: "+SectionHeader.SHN_LORESERVE+" < "+strndx); - } - final SectionHeader strShdr = sht[strndx]; - if( SectionHeader.SHT_STRTAB != strShdr.getType() ) { - throw new IllegalArgumentException("Ref. string Shdr["+strndx+"] is of type "+strShdr.d.getSh_type()); - } - final Section strS = strShdr.readSection(in); - for(i=0; i<num; i++) { - sht[i].initName(strS, sht[i].d.getSh_name()); - } - } - - return sht; + return "ELF-1[vers "+getVersion()+", machine["+getMachine()+", "+cpuType+", "+abiType+", machDesc "+machDesc.toShortString()+"], bits "+getArchClassBits()+", enc "+encS+ + ", abi[os "+getOSABI()+", vers "+getOSABIVersion()+"], type "+typeS+"]"; } } diff --git a/src/java/jogamp/common/os/elf/ElfHeaderPart2.java b/src/java/jogamp/common/os/elf/ElfHeaderPart2.java new file mode 100644 index 0000000..320b8b4 --- /dev/null +++ b/src/java/jogamp/common/os/elf/ElfHeaderPart2.java @@ -0,0 +1,374 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.common.os.elf; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +import com.jogamp.common.os.Platform.ABIType; +import com.jogamp.common.os.Platform.CPUFamily; +import com.jogamp.common.os.Platform.CPUType; + +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 Part-2 + * <p> + * Part-2 can only be read w/ knowledge of CPUType! + * </p> + * <p> + * References: + * <ul> + * <li>http://linux.die.net/man/5/elf</li> + * <li>http://www.sco.com/developers/gabi/latest/contents.html</li> + * <li>http://infocenter.arm.com/ + * <ul> + * <li>ARM IHI 0044E, current through ABI release 2.09</li> + * <li>ARM IHI 0056B: Elf for ARM 64-bit Architecture</li> + * </ul></li> + * </ul> + * </p> + */ +public class ElfHeaderPart2 { + /** + * This masks an 8-bit version number, the version of the ABI to which this + * ELF file conforms. This ABI is version 5. A value of 0 denotes unknown conformance. + * {@value} + */ + public static final int EF_ARM_ABIMASK = 0xFF000000; + public static final int EF_ARM_ABISHIFT = 24; + + /** + * ARM ABI version 5. + * {@value} + */ + public static final int EF_ARM_ABI5 = 0x05000000; + + /** + * The ELF file contains BE-8 code, suitable for execution on an ARM + * Architecture v6 processor. This flag must only be set on an executable file. + * {@value} + */ + public static final int EF_ARM_BE8 = 0x00800000; + + /** + * Legacy code (ABI version 4 and earlier) generated by gcc-arm-xxx might + * use these bits. + * {@value} + */ + public static final int EF_ARM_GCCMASK = 0x00400FFF; + + /** + * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note that + * the executable file was built to conform to the hardware floating-point + * procedure-call standard. + * <p> + * Compatible with legacy (pre version 5) gcc use as EF_ARM_VFP_FLOAT. + * </p> + * <p> + * Note: This is not used (anymore) + * </p> + * {@value} + */ + public static final int EF_ARM_ABI_FLOAT_HARD = 0x00000400; + + /** + * Set in executable file headers (e_type = ET_EXEC or ET_DYN) to note + * explicitly that the executable file was built to conform to the software + * floating-point procedure-call standard (the base standard). If both + * {@link #EF_ARM_ABI_FLOAT_HARD} and {@link #EF_ARM_ABI_FLOAT_SOFT} are clear, + * conformance to the base procedure-call standard is implied. + * <p> + * Compatible with legacy (pre version 5) gcc use as EF_ARM_SOFT_FLOAT. + * </p> + * <p> + * Note: This is not used (anymore) + * </p> + * {@value} + */ + public static final int EF_ARM_ABI_FLOAT_SOFT = 0x00000200; + + /** Public access to the elf header part-1 (CPU/ABI independent read) */ + public final ElfHeaderPart1 eh1; + + /** Public access to the raw elf header part-2 (CPU/ABI dependent read) */ + public final Ehdr_p2 raw; + + /** Lower case CPUType name */ + public final String cpuName; + public final CPUType cpuType; + public final ABIType abiType; + + /** Public access to the {@link SectionHeader} */ + public final SectionHeader[] sht; + + /** + * Note: The input stream shall stay untouch to be able to read sections! + * + * @param in input stream of a binary file at position zero + * @return + * @throws IOException if reading from the given input stream fails or less then ELF Header size bytes + * @throws IllegalArgumentException if the given input stream does not represent an ELF Header + */ + public static ElfHeaderPart2 read(final ElfHeaderPart1 eh1, final RandomAccessFile in) throws IOException, IllegalArgumentException { + return new ElfHeaderPart2(eh1, in); + } + + /** + * @param buf ELF Header bytes + * @throws IllegalArgumentException if the given buffer does not represent an ELF Header + * @throws IOException + */ + ElfHeaderPart2(final ElfHeaderPart1 eh1, final RandomAccessFile in) throws IllegalArgumentException, IOException { + this.eh1 = eh1; + // + // Part-2 + // + { + final byte[] buf = new byte[Ehdr_p2.size(eh1.machDesc.ordinal())]; + readBytes (in, buf, 0, buf.length); + final ByteBuffer eh2Bytes = ByteBuffer.wrap(buf, 0, buf.length); + raw = Ehdr_p2.create(eh1.machDesc.ordinal(), eh2Bytes); + } + sht = readSectionHeaderTable(in); + + if( CPUFamily.ARM == eh1.cpuType.family && eh1.cpuType.is32Bit ) { + // AArch64, has no SHT_ARM_ATTRIBUTES or SHT_AARCH64_ATTRIBUTES SectionHeader defined in our builds! + String armCpuName = null; + String armCpuRawName = null; + boolean abiVFPArgsAcceptsVFPVariant = false; + final SectionHeader sh = getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: Got ARM Attribs Section Header: "+sh); + } + if( null != sh ) { + final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: Got ARM Attribs Section Block : "+sArmAttrs); + } + final SectionArmAttributes.Attribute cpuNameArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.CPU_name); + if( null != cpuNameArgsAttr && cpuNameArgsAttr.isNTBS() ) { + armCpuName = cpuNameArgsAttr.getNTBS(); + } + final SectionArmAttributes.Attribute cpuRawNameArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.CPU_raw_name); + if( null != cpuRawNameArgsAttr && cpuRawNameArgsAttr.isNTBS() ) { + armCpuRawName = cpuRawNameArgsAttr.getNTBS(); + } + final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args); + if( null != abiVFPArgsAttr ) { + abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); + } + } + { + String _cpuName; + if( null != armCpuName && armCpuName.length() > 0 ) { + _cpuName = armCpuName.toLowerCase().replace(' ', '-'); + } else if( null != armCpuRawName && armCpuRawName.length() > 0 ) { + _cpuName = armCpuRawName.toLowerCase().replace(' ', '-'); + } else { + _cpuName = eh1.cpuName; + } + + // 1st-try: native name + CPUType _cpuType = queryCPUTypeSafe(_cpuName); + if( null == _cpuType ) { + // 2nd-try: "arm-" + native name + _cpuName = "arm-"+_cpuName; + _cpuType = queryCPUTypeSafe(_cpuName); + if( null == _cpuType ) { + // finally: Use ELF-1 + _cpuName = eh1.cpuName; + _cpuType = queryCPUTypeSafe(_cpuName); + if( null == _cpuType ) { + throw new InternalError("XXX: "+_cpuName+", "+eh1); // shall not happen + } + } + } + cpuName = _cpuName; + cpuType = _cpuType; + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: abiARM cpuName "+_cpuName+"[armCpuName "+armCpuName+", armCpuRawName "+armCpuRawName+"] -> "+cpuName+" -> "+cpuType+", abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); + } + } + if( cpuType.is32Bit ) { // always true, see above! + abiType = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; + } else { + abiType = eh1.abiType; + } + } else { + cpuName = eh1.cpuName; + cpuType = eh1.cpuType; + abiType = eh1.abiType; + } + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: cpuName "+cpuName+" -> "+cpuType+", "+abiType); + } + } + private static CPUType queryCPUTypeSafe(final String cpuName) { + CPUType res = null; + try { + res = CPUType.query(cpuName); + } catch (final Throwable t) { + if(ElfHeaderPart1.DEBUG) { + System.err.println("ELF-2: queryCPUTypeSafe("+cpuName+"): "+t.getMessage()); + } + } + return res; + } + + public final short getSize() { return raw.getE_ehsize(); } + + /** Returns the processor-specific flags associated with the file. */ + public final int getFlags() { + return raw.getE_flags(); + } + + /** Returns the ARM EABI version from {@link #getFlags() flags}, maybe 0 if not an ARM EABI. */ + public byte getArmABI() { + return (byte) ( ( ( EF_ARM_ABIMASK & raw.getE_flags() ) >> EF_ARM_ABISHIFT ) & 0xff ); + } + + /** Returns the ARM EABI legacy GCC {@link #getFlags() flags}, maybe 0 if not an ARM EABI or not having legacy GCC flags. */ + public int getArmLegacyGCCFlags() { + final int f = raw.getE_flags(); + return 0 != ( EF_ARM_ABIMASK & f ) ? ( EF_ARM_GCCMASK & f ) : 0; + } + + /** + * Returns the ARM EABI float mode from {@link #getFlags() flags}, + * i.e. 1 for {@link #EF_ARM_ABI_FLOAT_SOFT}, 2 for {@link #EF_ARM_ABI_FLOAT_HARD} + * or 0 for none. + * <p> + * Note: This is not used (anymore) + * </p> + */ + public byte getArmFloatMode() { + final int f = raw.getE_flags(); + if( 0 != ( EF_ARM_ABIMASK & f ) ) { + if( ( EF_ARM_ABI_FLOAT_HARD & f ) != 0 ) { + return 2; + } + if( ( EF_ARM_ABI_FLOAT_SOFT & f ) != 0 ) { + return 1; + } + } + return 0; + } + + /** Returns the 1st occurence of matching SectionHeader {@link SectionHeader#getType() type}, or null if not exists. */ + public final SectionHeader getSectionHeader(final int type) { + for(int i=0; i<sht.length; i++) { + final SectionHeader sh = sht[i]; + if( sh.getType() == type ) { + return sh; + } + } + return null; + } + + /** Returns the 1st occurence of matching SectionHeader {@link SectionHeader#getName() name}, or null if not exists. */ + public final SectionHeader getSectionHeader(final String name) { + for(int i=0; i<sht.length; i++) { + final SectionHeader sh = sht[i]; + if( sh.getName().equals(name) ) { + return sh; + } + } + return null; + } + + @Override + public final String toString() { + final int armABI = getArmABI(); + final String armFlagsS; + if( 0 != armABI ) { + armFlagsS=", arm[abi "+armABI+", lGCC "+getArmLegacyGCCFlags()+", float "+getArmFloatMode()+"]"; + } else { + armFlagsS=""; + } + return "ELF-2["+cpuType+", "+abiType+", flags["+toHexString(getFlags())+armFlagsS+"], sh-num "+sht.length+"]"; + } + + final SectionHeader[] readSectionHeaderTable(final RandomAccessFile in) throws IOException, IllegalArgumentException { + // positioning + { + final long off = raw.getE_shoff(); // absolute offset + if( 0 == off ) { + return new SectionHeader[0]; + } + seek(in, off); + } + final SectionHeader[] sht; + final int strndx = raw.getE_shstrndx(); + final int size = raw.getE_shentsize(); + final int num; + int i; + if( 0 == raw.getE_shnum() ) { + // Read 1st table 1st and use it's sh_size + final byte[] buf0 = new byte[size]; + readBytes(in, buf0, 0, size); + final SectionHeader sh0 = new SectionHeader(this, buf0, 0, size, 0); + num = (int) sh0.raw.getSh_size(); + if( 0 >= num ) { + throw new IllegalArgumentException("EHdr sh_num == 0 and 1st SHdr size == 0"); + } + sht = new SectionHeader[num]; + sht[0] = sh0; + i=1; + } else { + num = raw.getE_shnum(); + sht = new SectionHeader[num]; + i=0; + } + for(; i<num; i++) { + final byte[] buf = new byte[size]; + readBytes(in, buf, 0, size); + sht[i] = new SectionHeader(this, buf, 0, size, i); + } + if( SectionHeader.SHN_UNDEF != strndx ) { + // has section name string table + if( shortToInt(SectionHeader.SHN_LORESERVE) <= strndx ) { + throw new InternalError("TODO strndx: "+SectionHeader.SHN_LORESERVE+" < "+strndx); + } + final SectionHeader strShdr = sht[strndx]; + if( SectionHeader.SHT_STRTAB != strShdr.getType() ) { + throw new IllegalArgumentException("Ref. string Shdr["+strndx+"] is of type "+strShdr.raw.getSh_type()); + } + final Section strS = strShdr.readSection(in); + for(i=0; i<num; i++) { + sht[i].initName(strS, sht[i].raw.getSh_name()); + } + } + + return sht; + } +} diff --git a/src/java/jogamp/common/os/elf/IOUtils.java b/src/java/jogamp/common/os/elf/IOUtils.java index 62b47db..454a325 100644 --- a/src/java/jogamp/common/os/elf/IOUtils.java +++ b/src/java/jogamp/common/os/elf/IOUtils.java @@ -30,7 +30,6 @@ package jogamp.common.os.elf; import java.io.IOException; import java.io.RandomAccessFile; -import com.jogamp.common.os.Platform; import com.jogamp.common.util.Bitstream; class IOUtils { @@ -61,17 +60,12 @@ class IOUtils { in.seek(newPos); } - static int readUInt32(final byte[] in, final int offset) { - final int v = Bitstream.uint32LongToInt(Bitstream.readUInt32(!Platform.isLittleEndian(), in, offset)); + static int readUInt32(final boolean isBigEndian, final byte[] in, final int offset) { + final int v = Bitstream.uint32LongToInt(Bitstream.readUInt32(isBigEndian, in, offset)); if( 0 > v ) { throw new IllegalArgumentException("Read uint32 value "+toHexString(v)+" > int32-max "+toHexString(MAX_INT_VALUE)); } return v; - /** Need to fix endian for below path .. - checkBounds(in, offset, 4); - final byte[] uint = new byte[] { 0, 0, 0, 0, in[offset+0], in[offset+1], in[offset+2], in[offset+3] }; - final ByteBuffer b = ByteBuffer.wrap(uint, 0, 8).order(ByteOrder.nativeOrder()); - return b.asLongBuffer().get(0); */ } /** diff --git a/src/java/jogamp/common/os/elf/SectionArmAttributes.java b/src/java/jogamp/common/os/elf/SectionArmAttributes.java index 91e8c31..e6d9257 100644 --- a/src/java/jogamp/common/os/elf/SectionArmAttributes.java +++ b/src/java/jogamp/common/os/elf/SectionArmAttributes.java @@ -1,3 +1,30 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ package jogamp.common.os.elf; import static jogamp.common.os.elf.IOUtils.toHexString; @@ -172,7 +199,7 @@ public class SectionArmAttributes extends Section { SectionArmAttributes(final SectionHeader sh, final byte[] data, final int offset, final int length) throws IndexOutOfBoundsException, IllegalArgumentException { super(sh, data, offset, length); - this.vendorAttributesList = parse(data, offset, length); + this.vendorAttributesList = parse(sh, data, offset, length); } @Override @@ -208,6 +235,7 @@ public class SectionArmAttributes extends Section { } /** + * @param sh TODO * @param in byte source buffer to parse * @param offset offset within byte source buffer to start parsing * @param remaining remaining numbers of bytes to parse beginning w/ <code>sb_off</code>, @@ -215,7 +243,7 @@ public class SectionArmAttributes extends Section { * @throws IndexOutOfBoundsException if <code>offset + remaining > sb.length</code>. * @throws IllegalArgumentException if section parsing failed, i.e. incompatible version or data. */ - static List<VendorAttributes> parse(final byte[] in, final int offset, final int remaining) throws IndexOutOfBoundsException, IllegalArgumentException { + static List<VendorAttributes> parse(final SectionHeader sh, final byte[] in, final int offset, final int remaining) throws IndexOutOfBoundsException, IllegalArgumentException { Bitstream.checkBounds(in, offset, remaining); int i = offset; if( FORMAT_VERSION_A != in[ i ] ) { @@ -224,10 +252,11 @@ public class SectionArmAttributes extends Section { i++; final List<VendorAttributes> vendorAttributesList = new ArrayList<VendorAttributes>(); + final boolean isBigEndian = sh.eh2.eh1.isBigEndian(); while(i < remaining) { final int i_pre = i; - final int secLen = readUInt32(in, i); /* total section size: 4 + string + content, i.e. offset to next section */ + final int secLen = readUInt32(isBigEndian, in, i); /* total section size: 4 + string + content, i.e. offset to next section */ i+=4; final String vendor; @@ -241,7 +270,7 @@ public class SectionArmAttributes extends Section { while(i < secLen) { final int[] i_post = new int[] { 0 }; - parseSub(in, i, secLen - i, i_post, attributes); + parseSub(isBigEndian, in, i, secLen - i, i_post, attributes); i = i_post[0]; } @@ -261,6 +290,7 @@ public class SectionArmAttributes extends Section { } /** + * @param isBigEndian TODO * @param in byte source buffer to parse * @param offset offset within byte source buffer to start parsing * @param remaining remaining numbers of bytes to parse beginning w/ <code>sb_off</code>, @@ -268,7 +298,10 @@ public class SectionArmAttributes extends Section { * @throws IndexOutOfBoundsException if <code>offset + remaining > sb.length</code>. * @throws IllegalArgumentException if section parsing failed, i.e. incompatible version or data. */ - static void parseSub(final byte[] in, final int offset, final int remaining, final int[] offset_post, final List<Attribute> attributes) throws IndexOutOfBoundsException, IllegalArgumentException { + private static void parseSub(final boolean isBigEndian, final byte[] in, final int offset, final int remaining, + final int[] offset_post, final List<Attribute> attributes) + throws IndexOutOfBoundsException, IllegalArgumentException + { Bitstream.checkBounds(in, offset, remaining); // Starts w/ sub-section Tag @@ -283,7 +316,7 @@ public class SectionArmAttributes extends Section { case File: case Section: case Symbol: - subSecLen = readUInt32(in, i); + subSecLen = readUInt32(isBigEndian, in, i); i+=4; break; default: diff --git a/src/java/jogamp/common/os/elf/SectionHeader.java b/src/java/jogamp/common/os/elf/SectionHeader.java index 20a40a5..533c04b 100644 --- a/src/java/jogamp/common/os/elf/SectionHeader.java +++ b/src/java/jogamp/common/os/elf/SectionHeader.java @@ -133,6 +133,12 @@ public class SectionHeader { * {@value} */ public static final int SHT_ARM_ATTRIBUTES = 0x70000003; + + /** + * {@value}. FIXME: Same as {@link #SHT_ARM_ATTRIBUTES}, ok? + */ + public static final int SHT_AARCH64_ATTRIBUTES = 0x70000003; + /** * {@value} */ @@ -171,24 +177,28 @@ public class SectionHeader { */ public static final short SHN_HIRESERVE = (short)0xffff; + /** Public access to the elf header */ + public final ElfHeaderPart2 eh2; + /** Public access to the raw elf section header */ - public final Shdr d; + public final Shdr raw; private final int idx; private String name; - SectionHeader(final byte[] buf, final int offset, final int length, final int sectionIdx) { - this( ByteBuffer.wrap(buf, 0, buf.length), sectionIdx ); + SectionHeader(final ElfHeaderPart2 eh, final byte[] buf, final int offset, final int length, final int sectionIdx) { + this( eh, ByteBuffer.wrap(buf, 0, buf.length), sectionIdx ); } - SectionHeader(final java.nio.ByteBuffer buf, final int idx) { - d = Shdr.create(buf); + SectionHeader(final ElfHeaderPart2 eh, final java.nio.ByteBuffer buf, final int idx) { + this.eh2 = eh; + this.raw = Shdr.create(eh.eh1.machDesc.ordinal(), buf); this.idx = idx; - name = null; + this.name = null; } @Override public String toString() { - return "SectionHeader[idx "+idx+", name "+name+", type "+toHexString(getType())+", link "+d.getSh_link()+", info "+toHexString(d.getSh_info())+", flags "+toHexString(getFlags())+"]"; + return "SectionHeader[idx "+idx+", name "+name+", type "+toHexString(getType())+", link "+raw.getSh_link()+", info "+toHexString(raw.getSh_info())+", flags "+toHexString(getFlags())+"]"; } /** @@ -206,17 +216,17 @@ public class SectionHeader { /** Returns the type of this section. */ public int getType() { - return d.getSh_type(); + return raw.getSh_type(); } /** Returns the flags of this section. */ public long getFlags() { - return d.getSh_flags(); + return raw.getSh_flags(); } /** Returns the size of this section. */ public long getSize() { - return d.getSh_size(); + return raw.getSh_size(); } /** Returns this section name, maybe <code>null</code> if not read. */ @@ -232,9 +242,9 @@ public class SectionHeader { * @throws IllegalArgumentException if section offset or size mismatch including size > {@link Integer#MAX_VALUE} */ public Section readSection(final RandomAccessFile in) throws IOException, IllegalArgumentException { - final int s_size = long2Int(d.getSh_size()); + final int s_size = long2Int(raw.getSh_size()); if( 0 == s_size || 0 > s_size ) { - throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+d.getSh_size()+" -> "+s_size); + throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+raw.getSh_size()+" -> "+s_size); } final byte[] s_buf = new byte[s_size]; return readSectionImpl(in, s_buf, 0, s_size); @@ -252,9 +262,9 @@ public class SectionHeader { * @throws IllegalArgumentException if requested read length is > section size */ public Section readSection(final RandomAccessFile in, final byte[] b, final int b_off, final int r_len) throws IOException, IllegalArgumentException { - final int s_size = long2Int(d.getSh_size()); + final int s_size = long2Int(raw.getSh_size()); if( 0 == s_size || 0 > s_size ) { - throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+d.getSh_size()+" -> "+s_size); + throw new IllegalArgumentException("Shdr["+idx+"] has invalid int size: "+raw.getSh_size()+" -> "+s_size); } if( r_len > s_size ) { throw new IllegalArgumentException("Shdr["+idx+"] has only "+s_size+" bytes, while read request is of "+r_len+" bytes"); @@ -263,7 +273,7 @@ public class SectionHeader { } Section readSectionImpl(final RandomAccessFile in, final byte[] b, final int b_off, final int r_len) throws IOException, IllegalArgumentException { - final long s_off = d.getSh_offset(); + final long s_off = raw.getSh_offset(); seek(in, s_off); readBytes(in, b, b_off, r_len); if( SectionHeader.SHT_ARM_ATTRIBUTES == getType() ) { diff --git a/src/java/jogamp/common/os/elf/Shdr.java b/src/java/jogamp/common/os/elf/Shdr.java index e5fe147..0b75fd6 100644 --- a/src/java/jogamp/common/os/elf/Shdr.java +++ b/src/java/jogamp/common/os/elf/Shdr.java @@ -1,4 +1,4 @@ -/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Fri Jan 30 06:44:16 CET 2015 ----! */ +/* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Sun Feb 01 03:27:25 CET 2015 ----! */ package jogamp.common.os.elf; @@ -15,45 +15,30 @@ public class Shdr { StructAccessor accessor; - private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal(); - - private static final int[] Shdr_size = new int[] { 40 /* ARMle_EABI */, 40 /* X86_32_UNIX */, 64 /* X86_64_UNIX */, 40 /* X86_32_MACOS */, 40 /* X86_32_WINDOWS */, 64 /* X86_64_WINDOWS */, 40 /* SPARC_32_SUNOS */ }; - private static final int[] sh_name_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* X86_64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */, 0 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_name_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_type_offset = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_type_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_flags_offset = new int[] { 8 /* ARMle_EABI */, 8 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 8 /* X86_32_MACOS */, 8 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 8 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_flags_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_addr_offset = new int[] { 12 /* ARMle_EABI */, 12 /* X86_32_UNIX */, 16 /* X86_64_UNIX */, 12 /* X86_32_MACOS */, 12 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 12 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_addr_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_offset_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 24 /* X86_64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_offset_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_size_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 32 /* X86_64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 32 /* X86_64_WINDOWS */, 20 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_size_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_link_offset = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 40 /* X86_64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 40 /* X86_64_WINDOWS */, 24 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_link_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_info_offset = new int[] { 28 /* ARMle_EABI */, 28 /* X86_32_UNIX */, 44 /* X86_64_UNIX */, 28 /* X86_32_MACOS */, 28 /* X86_32_WINDOWS */, 44 /* X86_64_WINDOWS */, 28 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_info_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_addralign_offset = new int[] { 32 /* ARMle_EABI */, 32 /* X86_32_UNIX */, 48 /* X86_64_UNIX */, 32 /* X86_32_MACOS */, 32 /* X86_32_WINDOWS */, 48 /* X86_64_WINDOWS */, 32 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_addralign_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - private static final int[] sh_entsize_offset = new int[] { 36 /* ARMle_EABI */, 36 /* X86_32_UNIX */, 56 /* X86_64_UNIX */, 36 /* X86_32_MACOS */, 36 /* X86_32_WINDOWS */, 56 /* X86_64_WINDOWS */, 36 /* SPARC_32_SUNOS */ }; -//private static final int[] sh_entsize_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* X86_64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; - - public static int size() { - return Shdr_size[mdIdx]; - } - - public static Shdr create() { - return create(Buffers.newDirectByteBuffer(size())); - } - - public static Shdr create(java.nio.ByteBuffer buf) { - return new Shdr(buf); - } - - Shdr(java.nio.ByteBuffer buf) { - accessor = new StructAccessor(buf); - } + private final int mdIdx; + private final MachineDescription md; + + private static final int[] Shdr_size = new int[] { 40 /* ARMle_EABI */, 40 /* X86_32_UNIX */, 64 /* LP64_UNIX */, 40 /* X86_32_MACOS */, 40 /* X86_32_WINDOWS */, 64 /* X86_64_WINDOWS */, 40 /* SPARC_32_SUNOS */ }; + private static final int[] sh_name_offset = new int[] { 0 /* ARMle_EABI */, 0 /* X86_32_UNIX */, 0 /* LP64_UNIX */, 0 /* X86_32_MACOS */, 0 /* X86_32_WINDOWS */, 0 /* X86_64_WINDOWS */, 0 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_name_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_type_offset = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_type_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_flags_offset = new int[] { 8 /* ARMle_EABI */, 8 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 8 /* X86_32_MACOS */, 8 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 8 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_flags_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_addr_offset = new int[] { 12 /* ARMle_EABI */, 12 /* X86_32_UNIX */, 16 /* LP64_UNIX */, 12 /* X86_32_MACOS */, 12 /* X86_32_WINDOWS */, 16 /* X86_64_WINDOWS */, 12 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_addr_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_offset_offset = new int[] { 16 /* ARMle_EABI */, 16 /* X86_32_UNIX */, 24 /* LP64_UNIX */, 16 /* X86_32_MACOS */, 16 /* X86_32_WINDOWS */, 24 /* X86_64_WINDOWS */, 16 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_offset_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_size_offset = new int[] { 20 /* ARMle_EABI */, 20 /* X86_32_UNIX */, 32 /* LP64_UNIX */, 20 /* X86_32_MACOS */, 20 /* X86_32_WINDOWS */, 32 /* X86_64_WINDOWS */, 20 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_size_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_link_offset = new int[] { 24 /* ARMle_EABI */, 24 /* X86_32_UNIX */, 40 /* LP64_UNIX */, 24 /* X86_32_MACOS */, 24 /* X86_32_WINDOWS */, 40 /* X86_64_WINDOWS */, 24 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_link_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_info_offset = new int[] { 28 /* ARMle_EABI */, 28 /* X86_32_UNIX */, 44 /* LP64_UNIX */, 28 /* X86_32_MACOS */, 28 /* X86_32_WINDOWS */, 44 /* X86_64_WINDOWS */, 28 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_info_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 4 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 4 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_addralign_offset = new int[] { 32 /* ARMle_EABI */, 32 /* X86_32_UNIX */, 48 /* LP64_UNIX */, 32 /* X86_32_MACOS */, 32 /* X86_32_WINDOWS */, 48 /* X86_64_WINDOWS */, 32 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_addralign_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; + private static final int[] sh_entsize_offset = new int[] { 36 /* ARMle_EABI */, 36 /* X86_32_UNIX */, 56 /* LP64_UNIX */, 36 /* X86_32_MACOS */, 36 /* X86_32_WINDOWS */, 56 /* X86_64_WINDOWS */, 36 /* SPARC_32_SUNOS */ }; +//private static final int[] sh_entsize_size = new int[] { 4 /* ARMle_EABI */, 4 /* X86_32_UNIX */, 8 /* LP64_UNIX */, 4 /* X86_32_MACOS */, 4 /* X86_32_WINDOWS */, 8 /* X86_64_WINDOWS */, 4 /* SPARC_32_SUNOS */ }; public java.nio.ByteBuffer getBuffer() { return accessor.getBuffer(); @@ -83,46 +68,46 @@ public class Shdr { /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public Shdr setSh_flags(long val) { - accessor.setLongAt(sh_flags_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + accessor.setLongAt(sh_flags_offset[mdIdx], val, md.longSizeInBytes()); return this; } /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_flags() { - return accessor.getLongAt(sh_flags_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_flags_offset[mdIdx], md.longSizeInBytes()); } /** Setter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ public Shdr setSh_addr(long val) { - accessor.setLongAt(sh_addr_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + accessor.setLongAt(sh_addr_offset[mdIdx], val, md.longSizeInBytes()); return this; } /** Getter for native field: CType['ElfN_Addr' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_addr() { - return accessor.getLongAt(sh_addr_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_addr_offset[mdIdx], md.longSizeInBytes()); } /** Setter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ public Shdr setSh_offset(long val) { - accessor.setLongAt(sh_offset_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + accessor.setLongAt(sh_offset_offset[mdIdx], val, md.longSizeInBytes()); return this; } /** Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_offset() { - return accessor.getLongAt(sh_offset_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_offset_offset[mdIdx], md.longSizeInBytes()); } /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public Shdr setSh_size(long val) { - accessor.setLongAt(sh_size_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + accessor.setLongAt(sh_size_offset[mdIdx], val, md.longSizeInBytes()); return this; } /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_size() { - return accessor.getLongAt(sh_size_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_size_offset[mdIdx], md.longSizeInBytes()); } /** Setter for native field: CType['uint32_t', size [fixed true, lnx64 4], [int]] */ @@ -149,23 +134,43 @@ public class Shdr { /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public Shdr setSh_addralign(long val) { - accessor.setLongAt(sh_addralign_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + accessor.setLongAt(sh_addralign_offset[mdIdx], val, md.longSizeInBytes()); return this; } /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_addralign() { - return accessor.getLongAt(sh_addralign_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_addralign_offset[mdIdx], md.longSizeInBytes()); } /** Setter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public Shdr setSh_entsize(long val) { - accessor.setLongAt(sh_entsize_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + accessor.setLongAt(sh_entsize_offset[mdIdx], val, md.longSizeInBytes()); return this; } /** Getter for native field: CType['ElfN_size' (typedef), size [fixed false, lnx64 8], [int]] */ public long getSh_entsize() { - return accessor.getLongAt(sh_entsize_offset[mdIdx], MachineDescriptionRuntime.getStatic().md.longSizeInBytes()); + return accessor.getLongAt(sh_entsize_offset[mdIdx], md.longSizeInBytes()); + } + + // --- Begin CustomJavaCode .cfg declarations + public static int size(final int mdIdx) { + return Shdr_size[mdIdx]; + } + + public static Shdr create(final int mdIdx) { + return create(mdIdx, Buffers.newDirectByteBuffer(size(mdIdx))); + } + + public static Shdr create(final int mdIdx, final java.nio.ByteBuffer buf) { + return new Shdr(mdIdx, buf); + } + + Shdr(final int mdIdx, final java.nio.ByteBuffer buf) { + this.mdIdx = mdIdx; + this.md = MachineDescription.StaticConfig.values()[mdIdx].md; + this.accessor = new StructAccessor(buf); } + // ---- End CustomJavaCode .cfg declarations } diff --git a/src/junit/com/jogamp/common/os/TestElfReader01.java b/src/junit/com/jogamp/common/os/TestElfReader01.java index a750dd0..980a17a 100644 --- a/src/junit/com/jogamp/common/os/TestElfReader01.java +++ b/src/junit/com/jogamp/common/os/TestElfReader01.java @@ -8,7 +8,9 @@ import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.List; -import jogamp.common.os.elf.ElfHeader; +import jogamp.common.os.PlatformPropsImpl; +import jogamp.common.os.elf.ElfHeaderPart1; +import jogamp.common.os.elf.ElfHeaderPart2; import jogamp.common.os.elf.Section; import jogamp.common.os.elf.SectionArmAttributes; import jogamp.common.os.elf.SectionHeader; @@ -26,6 +28,7 @@ public class TestElfReader01 extends SingletonJunitCase { 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"; + static File userFile = null; private static boolean checkFileReadAccess(final File file) { try { @@ -49,49 +52,64 @@ public class TestElfReader01 extends SingletonJunitCase { } @Test - public void testGNULinuxSelfExe () throws IOException { - if( OSType.LINUX == Platform.getOSType() ) { - final File f = new File(GNU_LINUX_SELF_EXE); - if( checkFileReadAccess(f) ) { - testElfHeaderImpl(f, false); + public void test01GNULinuxSelfExe () throws IOException { + if( null == userFile ) { + if( OSType.LINUX == Platform.getOSType() ) { + final File f = new File(GNU_LINUX_SELF_EXE); + if( checkFileReadAccess(f) ) { + testElfHeaderImpl(f, false); + } } } } @Test - public void testJavaLib () throws IOException { - File jvmLib = findJVMLib("java"); - if( null == jvmLib ) { - jvmLib = findJVMLib("jvm"); + public void test02JavaLib () throws IOException { + if( null == userFile ) { + File jvmLib = findJVMLib("java"); + if( null == jvmLib ) { + jvmLib = findJVMLib("jvm"); + } + if( null != jvmLib ) { + testElfHeaderImpl(jvmLib, false); + } } - if( null != jvmLib ) { - testElfHeaderImpl(jvmLib, false); + } + + @Test + public void test99UserFile() throws IOException { + if( null != userFile ) { + testElfHeaderImpl(userFile, false); } } void testElfHeaderImpl(final File file, final boolean fileOutSections) throws IOException { + Platform.initSingleton(); System.err.println("Test file "+file.getAbsolutePath()); final RandomAccessFile in = new RandomAccessFile(file, "r"); try { - final ElfHeader eh; + final ElfHeaderPart1 eh1; + final ElfHeaderPart2 eh2; try { - eh = ElfHeader.read(in); + eh1 = ElfHeaderPart1.read(PlatformPropsImpl.OS_TYPE, in); + eh2 = ElfHeaderPart2.read(eh1, in); } catch (final Exception e) { System.err.println("Probably not an ELF file - or not in current format: (caught) "+e.getMessage()); e.printStackTrace(); return; } int i=0; - 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()); - System.err.println("SH num "+eh.sht.length); - if( 0 < eh.sht.length ) { - System.err.println("SH size "+eh.sht[0].d.getBuffer().limit()); + System.err.println(eh1); + System.err.println(eh2); + System.err.println("SH entsz "+eh2.raw.getE_shentsize()); + System.err.println("SH off "+toHexString(eh2.raw.getE_shoff())); + System.err.println("SH strndx "+eh2.raw.getE_shstrndx()); + System.err.println("SH num "+eh2.sht.length); + if( 0 < eh2.sht.length ) { + System.err.println("SH size "+eh2.sht[0].raw.getBuffer().limit()); } { - final SectionHeader sh = eh.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); + final SectionHeader sh = eh2.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); boolean abiVFPArgsAcceptsVFPVariant = false; if( null != sh ) { final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); @@ -102,8 +120,8 @@ public class TestElfReader01 extends SingletonJunitCase { } System.err.println("abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); } - for(i=0; i<eh.sht.length; i++) { - final SectionHeader sh = eh.sht[i]; + for(i=0; i<eh2.sht.length; i++) { + final SectionHeader sh = eh2.sht[i]; System.err.println(sh); final int type = sh.getType(); if( SectionHeader.SHT_STRTAB == type ) { @@ -132,6 +150,12 @@ public class TestElfReader01 extends SingletonJunitCase { } public static void main(final String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-file")) { + i++; + userFile = new File(args[i]); + } + } final String tstname = TestElfReader01.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/junit/com/jogamp/common/util/IntIntHashMapTest.java b/src/junit/com/jogamp/common/util/IntIntHashMapTest.java index 466e321..dc523f0 100644 --- a/src/junit/com/jogamp/common/util/IntIntHashMapTest.java +++ b/src/junit/com/jogamp/common/util/IntIntHashMapTest.java @@ -61,7 +61,7 @@ public class IntIntHashMapTest extends SingletonJunitCase { @BeforeClass public static void init() { - iterations = ( Platform.getCPUType().getFamily() == Platform.CPUFamily.ARM ) ? 20 : 10000; + iterations = ( Platform.getCPUType().family == Platform.CPUFamily.ARM ) ? 20 : 10000; pairs = new IntIntUniqueRndValues(iterations); } diff --git a/src/junit/com/jogamp/common/util/IntObjectHashMapTest.java b/src/junit/com/jogamp/common/util/IntObjectHashMapTest.java index 091a159..5573c1a 100644 --- a/src/junit/com/jogamp/common/util/IntObjectHashMapTest.java +++ b/src/junit/com/jogamp/common/util/IntObjectHashMapTest.java @@ -60,7 +60,7 @@ public class IntObjectHashMapTest extends SingletonJunitCase { @BeforeClass public static void init() { - iterations = ( Platform.getCPUType().getFamily() == Platform.CPUFamily.ARM ) ? 20 : 10000; + iterations = ( Platform.getCPUType().family == Platform.CPUFamily.ARM ) ? 20 : 10000; pairs = new IntIntObjUniqueRndValues(iterations); } |