From: <cap...@us...> - 2007-04-16 21:28:29
|
Revision: 59 http://svn.sourceforge.net/pearcolator/?rev=59&view=rev Author: captain5050 Date: 2007-04-16 14:28:29 -0700 (Mon, 16 Apr 2007) Log Message: ----------- Fix planting of bad instructions. Handle TLS ELF sections Modified Paths: -------------- src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java src/org/binarytranslator/generic/decoder/DecoderUtils.java src/org/binarytranslator/generic/memory/CallBasedMemory.java src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java src/org/binarytranslator/vmInterface/DBT_Trace.java Modified: src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java 2007-04-16 21:25:39 UTC (rev 58) +++ src/org/binarytranslator/arch/x86/decoder/X86_InstructionDecoder.java 2007-04-16 21:28:29 UTC (rev 59) @@ -12,6 +12,7 @@ import org.binarytranslator.arch.x86.os.process.X86_ProcessSpace; import org.binarytranslator.arch.x86.os.process.X86_Registers; import org.binarytranslator.generic.decoder.InstructionDecoder; +import org.binarytranslator.generic.decoder.Laziness; import org.binarytranslator.generic.fault.BadInstructionException; import org.binarytranslator.generic.os.process.ProcessSpace; import org.binarytranslator.vmInterface.DBT_OptimizingCompilerException; @@ -750,7 +751,7 @@ public int translate(X862IR translationHelper, ProcessSpace ps, X86_Laziness lazy, int pc) { TODO(); - return -1; + return 0xEBADC0DE; } /** @@ -763,9 +764,12 @@ */ public static int translateInstruction(X862IR translationHelper, ProcessSpace ps, X86_Laziness lazy, int pc) { + System.err.println("Translating "+pc); X86_InstructionDecoder decoder = getDecoder(ps, pc); if (DBT_Options.debugInstr) { + System.err.println("Disassembling "+pc); System.err.println(decoder.disassemble(ps, pc)); + System.err.println("After disassembling "+pc); } return decoder.translate(translationHelper, ps, lazy, pc); } @@ -796,6 +800,29 @@ * A decoder that faults with a bad instruction exception */ class X86_BadInstructionDecoder extends X86_InstructionDecoder { + /** + * Get the decoder with upto four or five(X86_64) prefix decoders but + * currently no opcode or operands + */ + protected X86_InstructionDecoder getDecoder(ProcessSpace ps, int pc, + int offset, X86_Group1PrefixDecoder prefix1, + X86_Group2PrefixDecoder prefix2, X86_Group3PrefixDecoder prefix3, + X86_Group4PrefixDecoder prefix4, X86_Group5PrefixDecoder prefix5) { + return this; + } + /** + * Translate a single instruction + * @param translationHelper the object containing the translation sequence + * @param ps the process space of the translation + * @param pc the address of the instruction to translate + * @return the address of the next instruction or -1 if this instruction has + * branched to the end of the trace + */ + public int translate(X862IR translationHelper, ProcessSpace ps, + X86_Laziness lazy, int pc) { + translationHelper.plantThrowBadInstruction(lazy, pc); + return -1; + } } /** Modified: src/org/binarytranslator/generic/decoder/DecoderUtils.java =================================================================== --- src/org/binarytranslator/generic/decoder/DecoderUtils.java 2007-04-16 21:25:39 UTC (rev 58) +++ src/org/binarytranslator/generic/decoder/DecoderUtils.java 2007-04-16 21:28:29 UTC (rev 59) @@ -117,9 +117,9 @@ BadInstructionException.class).asClass(); VM_MethodReference badInstrKlassInitMethRef = (VM_MethodReference) VM_MemberReference - .findOrCreate(badInstrKlass.getTypeRef(), VM_Atom - .findOrCreateAsciiAtom("<init>"), VM_Atom - .findOrCreateAsciiAtom("(I" + psTref.getName() + ")V")); + .findOrCreate(badInstrKlass.getTypeRef(), + VM_Atom.findOrCreateAsciiAtom("<init>"), + VM_Atom.findOrCreateAsciiAtom("(ILorg/binarytranslator/generic/os/process/ProcessSpace;)V")); badInstrKlassInitMethod = badInstrKlassInitMethRef.resolveInvokeSpecial(); VM_MethodReference recordUncaughtBranchMethRef = (VM_MethodReference) VM_MemberReference @@ -1218,62 +1218,57 @@ * the program counter of the bad instruction */ public void plantThrowBadInstruction(Laziness lazy, int pc) { - // There's a bug with this, so for now I'm just commenting it out :-( -- IAR - setReturnValueResolveLazinessAndBranchToFinish(lazy, - new OPT_IntConstantOperand(0xEBADC0DE)); - if (false) { - // Need to make sure that the PPC_ProcessSpace registers have - // the correct values before call to doSysCall(). - resolveLaziness(lazy); - spillAllRegisters(); + // Need to make sure that the PPC_ProcessSpace registers have + // the correct values before call to doSysCall(). + resolveLaziness(lazy); + spillAllRegisters(); - OPT_Operator newOperator; - OPT_TypeOperand typeOperand = new OPT_TypeOperand(badInstrKlass); - VM_TypeReference eTref = badInstrKlass.getTypeRef(); + OPT_Operator newOperator; + OPT_TypeOperand typeOperand = new OPT_TypeOperand(badInstrKlass); + VM_TypeReference eTref = badInstrKlass.getTypeRef(); - if (badInstrKlass.isInitialized() || badInstrKlass.isInBootImage()) { - newOperator = NEW; - } else { - newOperator = NEW_UNRESOLVED; - } + if (badInstrKlass.isInitialized() || badInstrKlass.isInBootImage()) { + newOperator = NEW; + } else { + newOperator = NEW_UNRESOLVED; + } - OPT_RegisterOperand eRef = gc.temps.makeTemp(eTref); + OPT_RegisterOperand eRef = gc.temps.makeTemp(eTref); - OPT_Instruction n = New.create(newOperator, eRef, typeOperand); - n.position = gc.inlineSequence; - n.bcIndex = DBT_Trace.BAD_INSTRUCTION_NEW; + OPT_Instruction n = New.create(newOperator, eRef, typeOperand); + n.position = gc.inlineSequence; + n.bcIndex = DBT_Trace.BAD_INSTRUCTION_NEW; - OPT_Operand psRef = gc.makeLocal(1, psTref); + appendInstructionToCurrentBlock(n); - OPT_Instruction c = Call.create(CALL, null, null, null, null, 3); + OPT_Operand psRef = gc.makeLocal(1, psTref); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL( - badInstrKlassInitMethod.getMemberRef().asMethodReference(), - badInstrKlassInitMethod); - Call.setParam(c, 0, eRef.copy()); // 'this' pointer in - // BadInstructionException.init - Call.setParam(c, 1, new OPT_IntConstantOperand(pc)); - Call.setParam(c, 2, psRef); - Call.setGuard(c, new OPT_TrueGuardOperand()); - Call.setMethod(c, methOp); - Call.setAddress(c, new OPT_AddressConstantOperand(badInstrKlassInitMethod - .getOffset())); - c.position = gc.inlineSequence; - c.bcIndex = DBT_Trace.BAD_INSTRUCTION_INIT; + OPT_Instruction c = Call.create(CALL, null, null, null, null, 3); - OPT_Instruction t = Athrow.create(ATHROW, eRef.copyRO()); - t.position = gc.inlineSequence; - t.bcIndex = DBT_Trace.BAD_INSTRUCTION_THROW; + OPT_MethodOperand methOp = OPT_MethodOperand.SPECIAL( + badInstrKlassInitMethod.getMemberRef().asMethodReference(), + badInstrKlassInitMethod); + Call.setParam(c, 0, eRef.copy()); // 'this' pointer in + // BadInstructionException.init + Call.setParam(c, 1, new OPT_IntConstantOperand(pc)); + Call.setParam(c, 2, psRef); + Call.setGuard(c, new OPT_TrueGuardOperand()); + Call.setMethod(c, methOp); + Call.setAddress(c, new OPT_AddressConstantOperand(badInstrKlassInitMethod + .getOffset())); + c.position = gc.inlineSequence; + c.bcIndex = DBT_Trace.BAD_INSTRUCTION_INIT; - appendInstructionToCurrentBlock(n); + appendInstructionToCurrentBlock(c); - appendInstructionToCurrentBlock(c); + OPT_Instruction t = Athrow.create(ATHROW, eRef.copyRO()); + t.position = gc.inlineSequence; + t.bcIndex = DBT_Trace.BAD_INSTRUCTION_THROW; - appendInstructionToCurrentBlock(t); + appendInstructionToCurrentBlock(t); - setReturnValueResolveLazinessAndBranchToFinish(lazy, - new OPT_IntConstantOperand(0xEBADC0DE)); - } + setReturnValueResolveLazinessAndBranchToFinish(lazy, + new OPT_IntConstantOperand(0xEBADC0DE)); } // -oO Trace helping methods Oo- Modified: src/org/binarytranslator/generic/memory/CallBasedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/CallBasedMemory.java 2007-04-16 21:25:39 UTC (rev 58) +++ src/org/binarytranslator/generic/memory/CallBasedMemory.java 2007-04-16 21:28:29 UTC (rev 59) @@ -8,6 +8,7 @@ */ package org.binarytranslator.generic.memory; +import org.binarytranslator.DBT; import org.binarytranslator.generic.os.process.ProcessSpace; import org.binarytranslator.vmInterface.DBT_Trace; import org.binarytranslator.vmInterface.TranslationHelper; @@ -436,8 +437,9 @@ case DBT_Trace.MEMORY_LOAD32: return load32.getMemberRef().asMethodReference(); default: - throw new Error("Error linking method at " + callAddress - + " for memory model " + this.getClass()); + DBT.write(callAddress); + DBT.fail("Trying to dynamic link inside a DBT trace for an unknown dynamic link location"); + return null; } } } Modified: src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java =================================================================== --- src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-04-16 21:25:39 UTC (rev 58) +++ src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-04-16 21:28:29 UTC (rev 59) @@ -44,7 +44,7 @@ * Debug information * @param s string of debug information */ - private static void report(String s){ + private static void report(String s) { if (DBT_Options.debugLoader) { System.out.print("ELF Loader:"); System.out.println(s); @@ -63,10 +63,12 @@ * Do we need to byte swap multi-byte values? */ private final boolean needsBswap; + /** * File to read from */ RandomAccessFile rFile; + /** * Constructor * @param rFile file to read from @@ -76,19 +78,23 @@ this.rFile = rFile; this.needsBswap = needsBswap; } + /** * Byte swap a 32-bit integer */ - private static int bswap (int x) { - return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | (x >>> 24); + private static int bswap(int x) { + return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) + | (x >>> 24); } + /** * Byte swap a 16-bit integer */ - private static short bswap (short x) { - short result = (short)(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); + private static short bswap(short x) { + short result = (short) (((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); return result; } + /** * Read a 32bit int value */ @@ -96,6 +102,7 @@ int result = rFile.readInt(); return needsBswap ? bswap(result) : result; } + /** * Read a 16bit short value */ @@ -103,6 +110,7 @@ short result = rFile.readShort(); return needsBswap ? bswap(result) : result; } + /** * Seek to location from beginning of file */ @@ -120,12 +128,11 @@ * @param filename the program file name * @return process space containing loaded binary */ - public ProcessSpace readBinary(String filename) throws IOException - { + public ProcessSpace readBinary(String filename) throws IOException { report("Opening File: " + filename); RandomAccessFile rFile = new RandomAccessFile(filename, "r"); - elfHeader = new ELF_Header(rFile); //NB also sets up reader + elfHeader = new ELF_Header(rFile); // NB also sets up reader report("ELF header read successfully"); ProcessSpace ps = ProcessSpace.createProcessSpaceFromBinary(this); @@ -135,52 +142,50 @@ segmentHeaders = readHeaders(); report("Creating program segments"); - for(int i=0; i < segmentHeaders.length; i++){ + for (int i = 0; i < segmentHeaders.length; i++) { report("Creating: " + segmentHeaders[i]); segmentHeaders[i].create(ps); } int brk; - if(segmentHeaders.length > 1) { + if (segmentHeaders.length > 1) { brk = segmentHeaders[1].getEnd(); } else { - brk = segmentHeaders[0].getEnd(); + brk = segmentHeaders[0].getEnd(); } - report("Initialising the process space: "+ - "entry = 0x" + Integer.toHexString(elfHeader.getEntryPoint()) + - " brk = 0x" + Integer.toHexString(brk) - ); + report("Initialising the process space: " + "entry = 0x" + + Integer.toHexString(elfHeader.getEntryPoint()) + " brk = 0x" + + Integer.toHexString(brk)); ps.initialise(this, elfHeader.getEntryPoint(), brk); return ps; } - + /** - * Determine if the id array corresponds with the initial part of an - * ELF binary + * Determine if the id array corresponds with the initial part of an ELF + * binary * @param filename Name of the file to check * @return whether this is an ELF binary */ public static boolean conforms(String filename) { - + RandomAccessFile rFile = null; report("Testing is file is ELF: " + filename); - + try { rFile = new RandomAccessFile(filename, "r"); byte[] id = new byte[4]; rFile.read(id); - - return (id[0] == 0x7f) && (id[1] == 'E') && (id[2] == 'L') && (id[3] == 'F'); - } - catch (Exception e) { + + return (id[0] == 0x7f) && (id[1] == 'E') && (id[2] == 'L') + && (id[3] == 'F'); + } catch (Exception e) { return false; - } - finally { + } finally { try { rFile.close(); + } catch (Exception e) { } - catch(Exception e) {} } } @@ -188,9 +193,10 @@ * Read and construct the program segment headers */ private ELF_ProgramSegmentHeader[] readHeaders() throws IOException { - ELF_ProgramSegmentHeader segmentHeaders[] = new ELF_ProgramSegmentHeader[elfHeader.getNumberOfProgramSegmentHeaders()]; + ELF_ProgramSegmentHeader segmentHeaders[] = new ELF_ProgramSegmentHeader[elfHeader + .getNumberOfProgramSegmentHeaders()]; reader.seek(elfHeader.getProgramSegmentHeaderOffset()); - for(int i=0; i < segmentHeaders.length; i++) { + for (int i = 0; i < segmentHeaders.length; i++) { segmentHeaders[i] = new ELF_ProgramSegmentHeader(); } return segmentHeaders; @@ -202,6 +208,7 @@ public String getABIString() { return elfHeader.getABIString(); } + /** * Return the architecture (ISA) supported by this file */ @@ -215,13 +222,14 @@ public boolean isX86_ISA() { return elfHeader.isX86_ISA(); } + /** * Is the ELF's machine field PowerPC */ public boolean isPPC_ISA() { return elfHeader.isPPC_ISA(); } - + /** * Is this binary for the ARM architecture? */ @@ -235,13 +243,14 @@ public boolean isSysV_ABI() { return elfHeader.isSysV_ABI(); } + /** * Does this file support the Linux ABI? */ public boolean isLinuxABI() { return elfHeader.isLinuxABI(); } - + /** * Does this file support the ARM ABI? * @return @@ -268,6 +277,7 @@ * Size of ELF identity structure */ private static final int EI_NIDENT = 16; + /** * Backing store for identity structure: * {0x7f,'E','L','F',class,data,version,padding..} @@ -277,24 +287,30 @@ /** * ELF Magic numbers locations in identity */ - private static final int EI_MAG0 = 0, EI_MAG1 = 1, EI_MAG2 = 2, EI_MAG3 = 3; + private static final int EI_MAG0 = 0, EI_MAG1 = 1, EI_MAG2 = 2, + EI_MAG3 = 3; + /** * ELF magic values indicating an ELF file */ - private static final byte ELFMAG0 = 0x7f, ELFMAG1 = 'E', ELFMAG2 = 'L', ELFMAG3 = 'F'; + private static final byte ELFMAG0 = 0x7f, ELFMAG1 = 'E', ELFMAG2 = 'L', + ELFMAG3 = 'F'; /** * Location of class data in identity structure */ private static final int EI_CLASS = 4; + /** * ELF file is invalid */ private static final byte ELFCLASSNONE = 0; + /** * ELF file contains 32bit data */ private static final byte ELFCLASS32 = 1; + /** * ELF file contains 64bit data */ @@ -304,30 +320,39 @@ * Location of data information in identity structure */ private static final int EI_DATA = 5; + /** * Invalid data encoding */ private static final byte ELFDATANONE = 0; + /** * LSB or little-endian encoding N.B. not the native Java format */ private static final byte ELFDATA2LSB = 1; + /** * MSB or big-endian encoding N.B. the native Java format */ private static final byte ELFDATA2MSB = 2; + /** * Is this ELF MSB encoded? */ boolean isMSB() throws IOException { switch (e_ident[EI_DATA]) { - case ELFDATA2LSB: return false; - case ELFDATA2MSB: return true; - default: throw new IOException("Unrecognized data encoding"); + case ELFDATA2LSB: + return false; + case ELFDATA2MSB: + return true; + default: + throw new IOException("Unrecognized data encoding"); } } + /** - * Location of version data - should be EV_CURRENT as defined by the ELF header + * Location of version data - should be EV_CURRENT as defined by the ELF + * header */ private static final int EI_VERSION = 6; @@ -335,104 +360,133 @@ * Location of OS ABI data */ private static final int EI_OSABI = 7; + /** * UNIX System V ABI. */ private static final byte ELFOSABI_SYSV = 0; + /** * HP-UX ABI */ private static final byte ELFOSABI_HPUX = 1; + /** * NetBSD ABI */ private static final byte ELFOSABI_NETBSD = 2; + /** * Linux ABI */ private static final byte ELFOSABI_LINUX = 3; + /** * Solaris ABI */ private static final byte ELFOSABI_SOLARIS = 6; + /** * AIX ABI */ private static final byte ELFOSABI_AIX = 7; + /** * IRIX ABI */ private static final byte ELFOSABI_IRIX = 8; + /** * FreeBSD ABI */ private static final byte ELFOSABI_FREEBSD = 9; + /** * TRU64 UNIX ABI */ private static final byte ELFOSABI_TRU64 = 10; + /** * Novell Modesto */ private static final byte ELFOSABI_MODESTO = 11; + /** * Open BSD */ private static final byte ELFOSABI_OPENBSD = 12; + /** * Open VMS */ private static final byte ELFOSABI_OPENVMS = 13; + /** * Hewlett-Packard Non-Stop Kernel */ private static final byte ELFOSABI_NSK = 14; - + /** - * ARM ABI, probably using the ARM AAPCS. + * ARM ABI, probably using the ARM AAPCS. */ private static final byte ELFOSABI_ARM = 97; - + /** * Return the application binary interface (ABI) supported by this file */ String getABIString() { - switch(e_ident[EI_OSABI]) { - case ELFOSABI_SYSV: return "SysV"; - case ELFOSABI_HPUX: return "HP-UX"; - case ELFOSABI_NETBSD: return "NetBSD"; - case ELFOSABI_LINUX: return "Linux"; - case ELFOSABI_SOLARIS: return "Solaris"; - case ELFOSABI_AIX: return "AIX"; - case ELFOSABI_IRIX: return "IRIX"; - case ELFOSABI_FREEBSD: return "FreeBSD"; - case ELFOSABI_TRU64: return "TRU64"; - case ELFOSABI_MODESTO: return "Novell Modesto"; - case ELFOSABI_OPENBSD: return "OpenBSD"; - case ELFOSABI_OPENVMS: return "OpenVMS"; - case ELFOSABI_NSK: return "Hewlett-Packard Non-Stop Kernel"; - case ELFOSABI_ARM: return "ARM ABI"; + switch (e_ident[EI_OSABI]) { + case ELFOSABI_SYSV: + return "SysV"; + case ELFOSABI_HPUX: + return "HP-UX"; + case ELFOSABI_NETBSD: + return "NetBSD"; + case ELFOSABI_LINUX: + return "Linux"; + case ELFOSABI_SOLARIS: + return "Solaris"; + case ELFOSABI_AIX: + return "AIX"; + case ELFOSABI_IRIX: + return "IRIX"; + case ELFOSABI_FREEBSD: + return "FreeBSD"; + case ELFOSABI_TRU64: + return "TRU64"; + case ELFOSABI_MODESTO: + return "Novell Modesto"; + case ELFOSABI_OPENBSD: + return "OpenBSD"; + case ELFOSABI_OPENVMS: + return "OpenVMS"; + case ELFOSABI_NSK: + return "Hewlett-Packard Non-Stop Kernel"; + case ELFOSABI_ARM: + return "ARM ABI"; default: return "Unknown ELF ABI: " + e_ident[EI_OSABI]; } } + /** * Does this file support the SysV ABI? */ boolean isSysV_ABI() { return e_ident[EI_OSABI] == ELFOSABI_SYSV; } + /** * Does this file support the Linux ABI? */ boolean isLinuxABI() { return e_ident[EI_OSABI] == ELFOSABI_LINUX; } - + boolean isARM_ABI() { return e_ident[EI_OSABI] == ELFOSABI_ARM; } - + /** * Location of OS ABI version data */ @@ -450,10 +504,8 @@ // Identification is in bytes and therefore is endian agnostic rFile.read(e_ident); // Check magic is correct - if ((ELFMAG0 != e_ident[EI_MAG0]) || - (ELFMAG1 != e_ident[EI_MAG1]) || - (ELFMAG2 != e_ident[EI_MAG2]) || - (ELFMAG3 != e_ident[EI_MAG3])) { + if ((ELFMAG0 != e_ident[EI_MAG0]) || (ELFMAG1 != e_ident[EI_MAG1]) + || (ELFMAG2 != e_ident[EI_MAG2]) || (ELFMAG3 != e_ident[EI_MAG3])) { throw new IOException("Bad ELF file magic: " + rFile); } } @@ -470,19 +522,21 @@ String getABIString() { return identity.getABIString(); } + /** * Does this file support the SysV ABI? */ boolean isSysV_ABI() { return identity.isSysV_ABI(); } + /** * Does this file support the Linux ABI? */ boolean isLinuxABI() { return identity.isLinuxABI(); } - + /** * Does this file support the ARM ABI? */ @@ -494,95 +548,117 @@ * Object file type */ private short e_type; + /** * No file type */ private static final short ET_NONE = 0; + /** * Relocatable file */ private static final short ET_REL = 1; + /** * Executable file */ private static final short ET_EXEC = 2; + /** * Shared object file */ private static final short ET_DYN = 3; + /** * Core file */ private static final short ET_CORE = 4; + /** * Number of defined types */ private static final short ET_NUM = 5; + /** * Start of OS reserved region */ - private static final short ET_LOOS = (short)0xfe00; + private static final short ET_LOOS = (short) 0xfe00; + /** * End of OS reserved region */ - private static final short ET_HIOS = (short)0xfeff; + private static final short ET_HIOS = (short) 0xfeff; + /** * Start of processor-specific reserved region */ - private static final short ET_LOPROC = (short)0xff00; + private static final short ET_LOPROC = (short) 0xff00; + /** * End of processor-specific reserved region */ - private static final short ET_HIPROC = (short)0xffff; + private static final short ET_HIPROC = (short) 0xffff; /** * The required architecture (machine) for the object file */ private short e_machine; + /** * No machine */ private static final short EM_NONE = 0; + /** * AT&T WE 32100 */ - private static final short EM_M32 = 1 ; + private static final short EM_M32 = 1; + /** * SPARC */ private static final short EM_SPARC = 2; + /** * Intel 80386 */ private static final short EM_386 = 3; + /** * Motoral 68000 */ private static final short EM_68K = 4; + /** * Motorola 88000 */ private static final short EM_88K = 5; - /** + + /** * Intel 80860 */ private static final short EM_860 = 7; - /** + + /** * MIPS RS3000 */ private static final short EM_MIPS = 8; + /** * PowerPC */ private static final short EM_PPC = 20; + /** * ARM */ private static final short EM_ARM = 40; + /** * Alpha */ private static final short EM_ALPHA = 41; + /** * Sparc V9 */ @@ -594,37 +670,50 @@ boolean isX86_ISA() { return e_machine == EM_386; } + /** * Is the ELF's machine field PowerPC */ boolean isPPC_ISA() { return e_machine == EM_PPC; } - + /** * Is the elf binary for an ARM architecture? */ boolean isARM_ISA() { return e_machine == EM_ARM; } - + /** * Return the architecture (ISA) supported by this file */ public String getArchitectureString() { - switch(e_machine) { - case EM_M32: return "AT&T WE 32100"; - case EM_SPARC: return "SPARC"; - case EM_386: return "Intel 80386"; - case EM_68K: return "Motorola 68000"; - case EM_88K: return "Motorola 88000"; - case EM_860: return "Intel 80860"; - case EM_MIPS: return "MIPS RS3000"; - case EM_PPC: return "PowerPC"; - case EM_ARM: return "ARM"; - case EM_ALPHA: return "Alpha"; - case EM_SPARCV9: return "SPARC V9"; - default: return "Unknown architecture " + e_machine; + switch (e_machine) { + case EM_M32: + return "AT&T WE 32100"; + case EM_SPARC: + return "SPARC"; + case EM_386: + return "Intel 80386"; + case EM_68K: + return "Motorola 68000"; + case EM_88K: + return "Motorola 88000"; + case EM_860: + return "Intel 80860"; + case EM_MIPS: + return "MIPS RS3000"; + case EM_PPC: + return "PowerPC"; + case EM_ARM: + return "ARM"; + case EM_ALPHA: + return "Alpha"; + case EM_SPARCV9: + return "SPARC V9"; + default: + return "Unknown architecture " + e_machine; } } @@ -632,20 +721,23 @@ * Object file version */ private int e_version; + /** * Invalid version */ private static final int EV_NONE = 0; + /** - * Current version + * Current version */ private static final int EV_CURRENT = 1; /** - * Entry point virtual address. The virtual address to which the - * system first transfers control, thus starting the process. + * Entry point virtual address. The virtual address to which the system + * first transfers control, thus starting the process. */ private int e_entry; + /** * Return the entry point of the binary */ @@ -657,6 +749,7 @@ * Program header table file offset */ private int e_phoff; + /** * What is the offset in the file of the program headers */ @@ -683,6 +776,7 @@ * Program header table entry size */ private short e_phentsize; + /** * What's the size of a program segment header? */ @@ -694,17 +788,19 @@ * Program header table entry count */ private short e_phnum; + /** * How many program segments are in this ELF binary? */ - int getNumberOfProgramSegmentHeaders(){ - return e_phnum; + int getNumberOfProgramSegmentHeaders() { + return e_phnum; } /** * Section header table entry size */ private short e_shentsize; + /** * Section header table entry count */ @@ -713,7 +809,7 @@ /** * Section header table index */ - private short e_shstrndx; + private short e_shstrndx; /** * Construct/read ELF header @@ -723,33 +819,31 @@ // Identification is in bytes and therefore is endian agnostic identity = new ELF_Identity(rFile); // Set up reader to handle endianness for the rest of the file - reader = new ELF_BinaryReader(rFile,!identity.isMSB()); + reader = new ELF_BinaryReader(rFile, !identity.isMSB()); // Read in rest of header - e_type = reader.readShort(); + e_type = reader.readShort(); e_machine = reader.readShort(); e_version = reader.readInt(); - e_entry = reader.readInt(); - e_phoff = reader.readInt(); - e_shoff = reader.readInt(); - e_flags = reader.readInt(); - e_ehsize = reader.readShort(); + e_entry = reader.readInt(); + e_phoff = reader.readInt(); + e_shoff = reader.readInt(); + e_flags = reader.readInt(); + e_ehsize = reader.readShort(); e_phentsize = reader.readShort(); - e_phnum = reader.readShort(); + e_phnum = reader.readShort(); e_shentsize = reader.readShort(); - e_shnum = reader.readShort(); - e_shstrndx = reader.readShort(); - } - catch(IOException e) { + e_shnum = reader.readShort(); + e_shstrndx = reader.readShort(); + } catch (IOException e) { throw new Error(e); } } } /** - * Header representing a segment in the process (e.g. stack, heap, - * code aka text) in the ELF file. These are known as program - * header's in the ELF literature, but they don't represent - * programs, rather separate segments. + * Header representing a segment in the process (e.g. stack, heap, code aka + * text) in the ELF file. These are known as program header's in the ELF + * literature, but they don't represent programs, rather separate segments. */ @SuppressWarnings("unused") class ELF_ProgramSegmentHeader { @@ -757,98 +851,120 @@ * Type of the segment */ private final int p_type; + /** * Null header, contains no data and can be ignored */ private static final int PT_NULL = 0; + /** * A loadable segment */ private static final int PT_LOAD = 1; + /** * Segment containing dynamic linking information */ private static final int PT_DYNAMIC = 2; + /** * A segment containing a string to invoke as interpreter for this file */ private static final int PT_INTERP = 3; + /** * A segment describing the location and size of auxiliary information */ private static final int PT_NOTE = 4; + /** * A reserved segment type with unspecified semantics */ private static final int PT_SHLIB = 5; + /** - * A segment describing the ELF's header, present once before any - * loadable segments + * A segment describing the ELF's header, present once before any loadable + * segments */ private static final int PT_PHDR = 6; + /** * Thread local storage (TLS) segment */ private static final int PT_TLS = 7; + /** * Number of defined types */ private static final int PT_NUM = 8; + /** * Start of OS reserved segment types */ private static final int PT_LOOS = 0x60000000; + /** * SUN unwind table segment */ private static final int PT_SUNW_UNWIND = 0x6464e550; + /** * GCC .eh_frame_hdr segment */ private static final int PT_GNU_EH_FRAME = 0x6474e550; + /** * Indicates stack executability */ private static final int PT_GNU_STACK = 0x6474e551; + /** * Read-only after relocation */ private static final int PT_GNU_RELRO = 0x6474e552; + /** * Start of SUN reserved segments */ private static final int PT_LOSUNW = 0x6ffffffa; + /** - * The array element has the same attributes as a PT_LOAD element - * and is used to describe a .SUNW_bss section. + * The array element has the same attributes as a PT_LOAD element and is + * used to describe a .SUNW_bss section. */ private static final int PT_SUNWBSS = 0x6ffffffa; + /** - * Describes a process stack. Only one PT_SUNWSTACK element can - * exist. Only access permissions, as defined in the p_flags - * field, are meaningful. + * Describes a process stack. Only one PT_SUNWSTACK element can exist. Only + * access permissions, as defined in the p_flags field, are meaningful. */ private static final int PT_SUNWSTACK = 0x6ffffffb; + /** * Reserved for internal use by dtrace */ private static final int PT_SUNWDTRACE = 0x6ffffffc; + /** * Specifies hardware capability requirements */ private static final int PT_SUNWCAP = 0x6ffffffd; + /** * End of SUN reserved segments */ private static final int PT_HISUNW = 0x6fffffff; + /** * End of OS reserved segment types */ private static final int PT_HIOS = 0x6fffffff; + /** * Start of processor reserved segment types */ private static final int PT_LOPROC = 0x70000000; + /** * End of processor reserved segment types */ @@ -865,7 +981,7 @@ private final int p_vaddr; /** - * Corresponding physical addressed used by some systems + * Corresponding physical addressed used by some systems */ private final int p_paddr; @@ -883,32 +999,37 @@ * Read/Write/Execute flags for segment in memory */ private final int p_flags; + /** * Executable flag */ private static final int PF_X = 0x1; + /** * Writable flag */ private static final int PF_W = 0x2; + /** * Readable flag */ private static final int PF_R = 0x4; + /** * OS specific reserved bits */ private static final int PF_MASKOS = 0x0ff00000; + /** * Processor specific reserved bits */ private static final int PF_MASKPROC = 0xf0000000; /** - * This member gives the value to which the segments are aligned in - * memory and in the file. Values 0 and 1 mean no alignment is - * required. Otherwise, p_align should be a positive, integral - * power of 2, and p_vaddr should equal p_offset, modulo p_align. + * This member gives the value to which the segments are aligned in memory + * and in the file. Values 0 and 1 mean no alignment is required. Otherwise, + * p_align should be a positive, integral power of 2, and p_vaddr should + * equal p_offset, modulo p_align. */ private final int p_align; @@ -927,65 +1048,59 @@ // Move file onto next program segment header offset reader.rFile.skipBytes(elfHeader.getProgramSegmentHeaderSize() - 32); } + /** * Load/create the program segment */ void create(ProcessSpace ps) { - switch(p_type) { + switch (p_type) { case PT_NULL: // Null header, contains no data and can be ignored break; case PT_LOAD: // A loadable segment try { - createSegment(ps.memory, - reader.rFile, - p_offset, p_vaddr, - p_filesz, p_memsz, - (p_flags & PF_R) != 0, (p_flags & PF_W) != 0, (p_flags & PF_X) != 0); - } - catch(MemoryMapException e) { + createSegment(ps.memory, reader.rFile, p_offset, p_vaddr, p_filesz, + p_memsz, (p_flags & PF_R) != 0, (p_flags & PF_W) != 0, + (p_flags & PF_X) != 0); + } catch (MemoryMapException e) { throw new Error("Error in creating: " + this, e); } break; - case PT_NOTE: // A segment describing the location and size of auxiliary information + case PT_NOTE: // A segment describing the location and size of auxiliary + // information // ignore break; case PT_GNU_STACK: // A segment describing the permissions for the stack // ignore break; - case PT_INTERP: // A segment containing a string to invoke as interpreter for this file + case PT_TLS: // A segment describing thread local storage + // ignore for now + break; + case PT_INTERP: // A segment containing a string to invoke as interpreter + // for this file case PT_DYNAMIC: // Segment containing dynamic linking information - case PT_SHLIB: // A reserved segment type with unspecified semantics - case PT_PHDR: // A segment describing the ELF's header; present once before any loadable segments + case PT_SHLIB: // A reserved segment type with unspecified semantics + case PT_PHDR: // A segment describing the ELF's header; present once + // before any loadable segments default: throw new Error("Segment type " + toString() + " not yet supported"); } } - + /** * Create a segment - * - * @param memory - * The memory into which the segment is to be mapped. - * @param file - * file to read segment data from if file size != 0 - * @param offset - * file offset - * @param address - * location of segment - * @param filesize - * size of segment in file - * @param memsize - * size of segment in memory - * @param read - * is segment readable - * @param write - * is segment writable - * @param exec - * is segment executable + * @param memory The memory into which the segment is to be mapped. + * @param file file to read segment data from if file size != 0 + * @param offset file offset + * @param address location of segment + * @param filesize size of segment in file + * @param memsize size of segment in memory + * @param read is segment readable + * @param write is segment writable + * @param exec is segment executable */ - public void createSegment(Memory memory, RandomAccessFile file, long offset, int address, - int filesize, int memsize, boolean read, boolean write, boolean exec) - throws MemoryMapException { + public void createSegment(Memory memory, RandomAccessFile file, + long offset, int address, int filesize, int memsize, boolean read, + boolean write, boolean exec) throws MemoryMapException { // Sanity check if (memsize < filesize) { throw new Error("Segment memory size (" + memsize @@ -1024,12 +1139,13 @@ } /** - * Round the give value up so that it is at the beginning of the - * next aligned region + * Round the give value up so that it is at the beginning of the next + * aligned region */ private int truncateToNextAlignment(int x) { return ((x + p_align - 1) / p_align) * p_align; } + /** * Get the end of the segment */ @@ -1041,20 +1157,23 @@ * String representation of header */ public String toString() { - switch(p_type) { + switch (p_type) { case PT_NULL: return "Null segment header (ignored)"; case PT_LOAD: - return - "Loadable segment (offset=0x" + Long.toHexString(p_offset) + - ", address=0x"+ Integer.toHexString(p_vaddr)+ - ", file size=" + p_filesz + - ", memory size=" + p_memsz + - ", permissions=" + - (((p_flags & PF_R) != 0) ? 'r' : '-') + - (((p_flags & PF_W) != 0) ? 'w' : '-') + - (((p_flags & PF_X) != 0) ? 'x' : '-') + - ")"; + return "Loadable segment (offset=0x" + Long.toHexString(p_offset) + + ", address=0x" + Integer.toHexString(p_vaddr) + ", file size=" + + p_filesz + ", memory size=" + p_memsz + ", permissions=" + + (((p_flags & PF_R) != 0) ? 'r' : '-') + + (((p_flags & PF_W) != 0) ? 'w' : '-') + + (((p_flags & PF_X) != 0) ? 'x' : '-') + ")"; + case PT_TLS: + return "TLS segment (offset=0x" + Long.toHexString(p_offset) + + ", address=0x" + Integer.toHexString(p_vaddr) + ", file size=" + + p_filesz + ", memory size=" + p_memsz + ", permissions=" + + (((p_flags & PF_R) != 0) ? 'r' : '-') + + (((p_flags & PF_W) != 0) ? 'w' : '-') + + (((p_flags & PF_X) != 0) ? 'x' : '-') + ")"; case PT_NOTE: return "Note: segment containing auxiliary information"; case PT_INTERP: @@ -1068,18 +1187,15 @@ case PT_GNU_STACK: return "GNU stack executability"; default: - if((p_type > PT_LOPROC) && (p_type <= PT_HIPROC)) { + if ((p_type > PT_LOPROC) && (p_type <= PT_HIPROC)) { return "Processor specific segment 0x" + Integer.toHexString(p_type); - } - else if ((p_type > PT_LOOS) && (p_type <= PT_HIOS)) { - if((p_type > PT_LOSUNW) && (p_type <= PT_HISUNW)){ - return "Sun OS specific segment 0x" + Integer.toHexString(p_type); + } else if ((p_type > PT_LOOS) && (p_type <= PT_HIOS)) { + if ((p_type > PT_LOSUNW) && (p_type <= PT_HISUNW)) { + return "Sun OS specific segment 0x" + Integer.toHexString(p_type); + } else { + return "OS specific segment 0x" + Integer.toHexString(p_type); } - else { - return "OS specific segment 0x" + Integer.toHexString(p_type); - } - } - else { + } else { return "Unknown segment: 0x" + Integer.toHexString(p_type); } } Modified: src/org/binarytranslator/vmInterface/DBT_Trace.java =================================================================== --- src/org/binarytranslator/vmInterface/DBT_Trace.java 2007-04-16 21:25:39 UTC (rev 58) +++ src/org/binarytranslator/vmInterface/DBT_Trace.java 2007-04-16 21:28:29 UTC (rev 59) @@ -235,7 +235,7 @@ break; case BAD_INSTRUCTION_INIT: dynamicLink.set(DecoderUtils.badInstrKlassInitMethod.getMemberRef() - .asMethodReference(), JBC_invokevirtual); + .asMethodReference(), JBC_invokespecial); break; case MEMORY_STORE8: case MEMORY_STORE16: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |