package com.jogamp.common.os; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.List; 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; import org.junit.Test; import com.jogamp.common.os.Platform.OSType; import com.jogamp.junit.util.SingletonJunitCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) 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 { return file.isFile() && file.canRead(); } catch (final Throwable t) { } return false; } static File findJVMLib(final String libName) { final ClassLoader cl = TestElfReader01.class.getClassLoader(); final List<String> possibleLibPaths = NativeLibrary.enumerateLibraryPaths(libName, libName, libName, true, cl); for(int i=0; i<possibleLibPaths.size(); i++) { final String libPath = possibleLibPaths.get(i); final File lib = new File(libPath); System.err.println("XXX2 #"+i+": test "+lib); if( checkFileReadAccess(lib) ) { return lib; } System.err.println("XXX2 #"+i+": "+lib+" not readable"); } return null; } @Test public void 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 test02JavaLib () throws IOException { if( null == userFile ) { File jvmLib = findJVMLib("java"); if( null == jvmLib ) { jvmLib = findJVMLib("jvm"); } 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 ElfHeaderPart1 eh1; final ElfHeaderPart2 eh2; try { 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(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 = eh2.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES); boolean abiVFPArgsAcceptsVFPVariant = false; if( null != sh ) { final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in); final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args); if( null != abiVFPArgsAttr ) { abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); } } System.err.println("abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); } 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 ) { dumpSection(in, sh, "SHT_STRTAB", fileOutSections); } else if( SectionHeader.SHT_ARM_ATTRIBUTES == type ) { dumpSection(in, sh, "SHT_ARM_ATTRIBUTES", fileOutSections); } } } finally { in.close(); } } static void dumpSection(final RandomAccessFile in, final SectionHeader sh, final String name, final boolean fileOut) throws IllegalArgumentException, IOException { final Section s = sh.readSection(in); if(fileOut) { final File outFile = new File("ElfSection-"+sh.getIndex()+"-"+name); final OutputStream out = new BufferedOutputStream(new FileOutputStream(outFile)); try { out.write(s.data, s.offset, s.length); } finally { out.close(); } } System.err.println(name+": read "+s.length+", "+s); } 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); } static String toHexString(final int i) { return "0x"+Integer.toHexString(i); } static String toHexString(final long i) { return "0x"+Long.toHexString(i); } }