From: <mic...@us...> - 2007-03-29 13:54:53
|
Revision: 14 http://svn.sourceforge.net/pearcolator/?rev=14&view=rev Author: michael_baer Date: 2007-03-29 06:53:07 -0700 (Thu, 29 Mar 2007) Log Message: ----------- Loading ARM ELF binaries Modified Paths: -------------- src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java src/org/binarytranslator/generic/os/loader/Loader.java src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java src/org/binarytranslator/generic/os/process/ProcessSpace.java Added Paths: ----------- src/org/binarytranslator/arch/arm/ src/org/binarytranslator/arch/arm/os/ src/org/binarytranslator/arch/arm/os/abi/ src/org/binarytranslator/arch/arm/os/abi/linux/ src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java src/org/binarytranslator/arch/arm/os/process/ src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java src/org/binarytranslator/arch/arm/os/process/ARM_Registers.java src/org/binarytranslator/arch/arm/os/process/linux/ src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java Added: src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java =================================================================== --- src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java (rev 0) +++ src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java 2007-03-29 13:53:07 UTC (rev 14) @@ -0,0 +1,23 @@ +package org.binarytranslator.arch.arm.os.abi.linux; + +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls; + +public class ARM_LinuxSystemCalls extends LinuxSystemCalls { + + public ARM_LinuxSystemCalls(LinuxSystemCallGenerator src) { + super(src); + } + + @Override + protected String getMachine() { + //TODO: Grab this from a real machine + return "ARM"; + } + + @Override + public String sysCallToString(int syscall) { + throw new RuntimeException("Not yet implemented."); + } + +} Added: src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java (rev 0) +++ src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-03-29 13:53:07 UTC (rev 14) @@ -0,0 +1,158 @@ +package org.binarytranslator.arch.arm.os.process; + +import java.io.IOException; +import org.jikesrvm.opt.ir.OPT_HIRGenerator; +import org.jikesrvm.opt.ir.OPT_GenerationContext; +import org.binarytranslator.DBT_Options; +import org.binarytranslator.arch.arm.os.process.linux.ARM_LinuxProcessSpace; +import org.binarytranslator.arch.x86.decoder.X862IR; +import org.binarytranslator.arch.x86.os.process.X86_Registers; +import org.binarytranslator.arch.x86.os.process.linux.X86_LinuxProcessSpace; +import org.binarytranslator.generic.fault.BadInstructionException; +import org.binarytranslator.generic.memory.ByteAddressedMemory; +import org.binarytranslator.generic.os.loader.Loader; +import org.binarytranslator.generic.os.process.ProcessSpace; + +public abstract class ARM_ProcessSpace extends ProcessSpace { + + /* + * Instance data + */ + + /** + * Registers used by this process + */ + public ARM_Registers registers; + + /* GDB Interface */ + /** + * Read a register and turn into a byte array conforming to the endianness of + * the architecture + */ + public byte[] readRegisterGDB(int regNum) { + throw new RuntimeException("Not yet implemented"); + } + + /** + * Has frame base register? + */ + public boolean hasFrameBaseRegister() { + throw new RuntimeException("Not yet implemented"); + } + + /** + * Get the value of the frame base register + */ + public int getGDBFrameBaseRegister() { + throw new RuntimeException("Not yet implemented"); + } + + /** + * Get the value of the frame base register + */ + public int getGDBStackPointerRegister() { + throw new RuntimeException("Not yet implemented"); + } + + /** + * Get the value of the frame base register + */ + public int getGDBProgramCountRegister() { + throw new RuntimeException("Not yet implemented"); + } + + /* + * Utility functions + */ + + /** + * Debug information + * + * @param s + * string of debug information + */ + private static void report(String s) { + if (DBT_Options.debugLoader) { + System.out.print("ARM ProcessSpace:"); + System.out.println(s); + } + } + + /* + * Methods + */ + + /** + * Constructor + */ + protected ARM_ProcessSpace() { + registers = new ARM_Registers(); + memory = new ByteAddressedMemory(); + } + + /** + * Create an optimizing compiler HIR code generator suitable for this + * architecture + * + * @param context + * the generation context for the HIR generation + * @return a HIR generator + */ + public OPT_HIRGenerator createHIRGenerator(OPT_GenerationContext context) { + throw new RuntimeException("Not yet implemented"); + } + + /** + * Given an ELF binary loader, create the appropriate process space + * + * @param elf + * the elf binary loader + * @return the appropriate process space + */ + public static ProcessSpace createProcessSpaceFromBinary(Loader loader) + throws IOException { + if (loader.isARM_ABI()) { + report("ARM ABI"); + return new ARM_LinuxProcessSpace(); + } else { + throw new UnsupportedOperationException("Binary of " + loader.getABIString() + + " ABI is unsupported for the ARM architecture"); + } + } + + /** + * Run a single instruction + */ + public void runOneInstruction() throws BadInstructionException { + // TODO + throw new RuntimeException("Not yet implemented"); + } + + /** + * Return as an integer the current instruction's address + */ + public int getCurrentInstructionAddress() { + return registers.getPC(); + } + + /** + * Sets the current instruction's address + */ + public void setCurrentInstructionAddress(int pc) { + registers.setPC(pc); + } + + /** + * Return as an integer the current instruction's address + */ + public int getCurrentStackAddress() { + throw new RuntimeException("Not yet implemented"); + } + + /** + * Turn the process space into a string (for debug) + */ + public String toString() { + return registers.toString(); + } +} Added: src/org/binarytranslator/arch/arm/os/process/ARM_Registers.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/ARM_Registers.java (rev 0) +++ src/org/binarytranslator/arch/arm/os/process/ARM_Registers.java 2007-03-29 13:53:07 UTC (rev 14) @@ -0,0 +1,108 @@ +package org.binarytranslator.arch.arm.os.process; + +public final class ARM_Registers { + + /** + * The currently visible ARM general purpose registers. Register 15 also serves as the PC. + */ + private int regs[] = new int[16]; + + /** + * The ARM features a number of shadow registers, that are mapped into the register map + * depending on the operating mode. It contains + * 8 registers for fast IRQ handlers + * 3 registers for SWI handlers + * 3 registers for abort handlers + * 3 registers for irq handlers + * 3 registers for undefined instruction handlers + * 8 registers for temporarely storing the user mode registers during non-user modes + */ + private int shadowRegisters[] = new int[28]; + + /** + * The negative flag from the CPSR. + */ + private boolean flagNegative = false; + + /** + * The zero flag from the CPSR. + */ + private boolean flagZero = false; + + /** + * The carry flag from the CPSR. + */ + private boolean flagCarry = false; + + /** + * The overflow flag from the CPSR. + */ + private boolean flagOverflow = false; + + /** + * This flag from the CPSR denotes whether IRQs are currently accepted by the processor. + */ + private boolean flagIRQsDisabled = false; + + /** + * This flag from the CPSR denotes whether FIQs are currently accepted by the processor. + */ + private boolean flagFIQsDisabled = false; + + /** + * The operating mode from the CPSR register. Note that only the bottom five bits of this + * register may ever be set. + */ + private byte operatingMode = OPERATING_MODE_SVC; + + /** + * Definition of symbolic constants for all valid operating modes + */ + public final static byte OPERATING_MODE_USER = 0x10; + public final static byte OPERATING_MODE_FIQ = 0x11; + public final static byte OPERATING_MODE_IRQ = 0x12; + public final static byte OPERATING_MODE_SVC = 0x13; + public final static byte OPERATING_MODE_ABT = 0x17; + public final static byte OPERATING_MODE_UND = 0x1A; + + public ARM_Registers() { + } + + /** + * Sets the pc to a new value + */ + public void setPC(int pc) { + regs[15] = pc; + } + + /** + * Sets the pc to a new value + */ + public int getPC() { + return regs[15]; + } + + /** + * Returns the content of ARM's Current Program Status Register. + * @return + */ + public int getCPSR() { + return (flagNegative ? 1 << 31 : 0) | + (flagZero ? 1 << 30 : 0) | + (flagCarry ? 1 << 29 : 0) | + (flagOverflow ? 1 << 28 : 0) | + (flagIRQsDisabled ? 1 << 7 : 0) | + (flagFIQsDisabled ? 1 << 6 : 0) | + operatingMode; + } + + /** + * Restores the processor state to the state saved within the given CPSR. + * @param cpsr + * ARM CPSR register content + */ + private void setFlagsFromCPSR(int cpsr) { + throw new RuntimeException("Not yet implemented."); + } + +} Added: src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java (rev 0) +++ src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-03-29 13:53:07 UTC (rev 14) @@ -0,0 +1,91 @@ +package org.binarytranslator.arch.arm.os.process.linux; + +import org.binarytranslator.DBT_Options; +import org.binarytranslator.arch.arm.os.abi.linux.ARM_LinuxSystemCalls; +import org.binarytranslator.arch.arm.os.process.ARM_ProcessSpace; +import org.binarytranslator.generic.os.abi.linux.LinuxStackInitializer; +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls; +import org.binarytranslator.generic.os.loader.Loader; + +public class ARM_LinuxProcessSpace extends ARM_ProcessSpace implements LinuxSystemCallGenerator { + + /** + * A link to the current system call interface + */ + private final LinuxSystemCalls sysCalls; + + /** + * The top of the stack + */ + private static final int STACK_TOP = 0xC0000000; + + /** + * The top of the bss segment + */ + private int brk; + + public ARM_LinuxProcessSpace() { + sysCalls = new ARM_LinuxSystemCalls(this); + } + + @Override + public void doSysCall() { + sysCalls.doSysCall(); + } + + @Override + public void initialise(Loader loader, int pc, int brk, String[] args) { + registers.setPC(pc); + this.brk = brk; + + //initialize the stack + int[] auxVector = {LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO, 0xffffe400, + LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO_EHDR, 0xffffe000, + LinuxStackInitializer.AuxiliaryVectorType.AT_HWCAP, 0x78bfbff, + LinuxStackInitializer.AuxiliaryVectorType.AT_PAGESZ, 0x1000, + LinuxStackInitializer.AuxiliaryVectorType.AT_CLKTCK, 0x64, + LinuxStackInitializer.AuxiliaryVectorType.AT_PHDR, 0xBADADD8E, + LinuxStackInitializer.AuxiliaryVectorType.AT_PHNUM, 0xBAD2BAD2, + LinuxStackInitializer.AuxiliaryVectorType.AT_BASE, 0x0, + LinuxStackInitializer.AuxiliaryVectorType.AT_FLAGS, 0x0, + LinuxStackInitializer.AuxiliaryVectorType.AT_ENTRY, pc, + + LinuxStackInitializer.AuxiliaryVectorType.AT_UID, DBT_Options.UID, + LinuxStackInitializer.AuxiliaryVectorType.AT_EUID, DBT_Options.UID, + LinuxStackInitializer.AuxiliaryVectorType.AT_GID, DBT_Options.GID, + LinuxStackInitializer.AuxiliaryVectorType.AT_EGID, DBT_Options.GID, + + LinuxStackInitializer.AuxiliaryVectorType.AT_SECURE, 0, + LinuxStackInitializer.AuxiliaryVectorType.AT_NULL, 0x0}; + + LinuxStackInitializer.stackInit(memory, STACK_TOP, args, getEnvironmentVariables(), auxVector); + } + + public int getBrk() { + return brk; + } + + public int[] getSysCallArguments(int n) { + // TODO Auto-generated method stub + return null; + } + + public int getSysCallNumber() { + // TODO Auto-generated method stub + return 0; + } + + public void setBrk(int address) { + brk = address; + } + + public void setSysCallError(int r) { + // TODO Auto-generated method stub + } + + public void setSysCallReturn(int r) { + // TODO Auto-generated method stub + } + +} Modified: src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java 2007-03-28 13:09:58 UTC (rev 13) +++ src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java 2007-03-29 13:53:07 UTC (rev 14) @@ -4623,6 +4623,7 @@ * Also modifies XER[CA]. */ protected int translateXO_FORM(PPC2IR ppc2ir, PPC_Laziness lazy, int pc, int inst, int opcode, int rD, int rA, int rB, int OE, int secondaryOpcode, int Rc) { + if (VM.VerifyAssertions) VM._assert(rB == 0); // Get rA & rD OPT_RegisterOperand reg_rA = ppc2ir.getGPRegister(rA); Modified: src/org/binarytranslator/generic/os/loader/Loader.java =================================================================== --- src/org/binarytranslator/generic/os/loader/Loader.java 2007-03-28 13:09:58 UTC (rev 13) +++ src/org/binarytranslator/generic/os/loader/Loader.java 2007-03-29 13:53:07 UTC (rev 14) @@ -65,6 +65,11 @@ * Is the binary for the Power PC ISA? */ abstract public boolean isPPC_ISA(); + + /** + * Is the binary for the ARM ISA? + */ + abstract public boolean isARM_ISA(); /** * Does this file support the SysV ABI? @@ -75,6 +80,11 @@ * Does this file support the Linux ABI? */ abstract public boolean isLinuxABI(); + + /** + * Does this file support the ARM ABI? + */ + abstract public boolean isARM_ABI(); /* * Static methods Modified: src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java =================================================================== --- src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-03-28 13:09:58 UTC (rev 13) +++ src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-03-29 13:53:07 UTC (rev 14) @@ -192,6 +192,13 @@ public boolean isPPC_ISA() { return elfHeader.isPPC_ISA(); } + + /** + * Is this binary for the ARM architecture? + */ + public boolean isARM_ISA() { + return elfHeader.isARM_ISA(); + } /** * Does this file support the SysV ABI? @@ -205,6 +212,14 @@ public boolean isLinuxABI() { return elfHeader.isLinuxABI(); } + + /** + * Does this file support the ARM ABI? + * @return + */ + public boolean isARM_ABI() { + return elfHeader.isARM_ABI(); + } /* * Local classes holding structures from the ELF file @@ -341,7 +356,13 @@ * Hewlett-Packard Non-Stop Kernel */ private static final byte ELFOSABI_NSK = 14; + /** + * 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() { @@ -359,6 +380,7 @@ 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]; } @@ -375,6 +397,11 @@ 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 */ @@ -424,6 +451,13 @@ boolean isLinuxABI() { return identity.isLinuxABI(); } + + /** + * Does this file support the ARM ABI? + */ + boolean isARM_ABI() { + return identity.isARM_ABI(); + } /** * Object file type @@ -537,6 +571,13 @@ } /** + * 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() { Modified: src/org/binarytranslator/generic/os/process/ProcessSpace.java =================================================================== --- src/org/binarytranslator/generic/os/process/ProcessSpace.java 2007-03-28 13:09:58 UTC (rev 13) +++ src/org/binarytranslator/generic/os/process/ProcessSpace.java 2007-03-29 13:53:07 UTC (rev 14) @@ -26,436 +26,488 @@ import org.binarytranslator.generic.gdbstub.GDBStub; import org.binarytranslator.generic.os.loader.Loader; import org.binarytranslator.arch.x86.os.process.X86_ProcessSpace; +import org.binarytranslator.arch.arm.os.process.ARM_ProcessSpace; import org.binarytranslator.arch.ppc.os.process.PPC_ProcessSpace; /** - * A process space encapsulates a running process. This superclass - * contains non operating and architecture specific details of the - * process. + * A process space encapsulates a running process. This superclass contains non + * operating and architecture specific details of the process. */ public abstract class ProcessSpace { /* - * Runtime information - */ + * Runtime information + */ /** - * A record of branches to guide translation - */ + * A record of branches to guide translation + */ public final BranchLogic branchInfo; /** - * A hashtable containing translated traces of code - */ + * A hashtable containing translated traces of code + */ protected final Hashtable codeHash = new Hashtable(); /** - * Has a system call been called to terminate the process - */ + * Has a system call been called to terminate the process + */ public boolean finished = false; /* - * Interface to memory - */ + * Interface to memory + */ /** - * The memory for the process. As this is user mode code, it is a - * virtual address space - */ + * The memory for the process. As this is user mode code, it is a virtual + * address space + */ public Memory memory; /** - * Load a 32bit value from memory - */ + * Load a 32bit value from memory + */ public int memoryLoad32(int wordAddr) { - return memory.load32(wordAddr); + return memory.load32(wordAddr); } + /** - * Store a 32bit value to memory - */ + * Store a 32bit value to memory + */ public void memoryStore32(int address, int data) { - memory.store32(address,data); + memory.store32(address, data); } - + /** - * Load a 16bit value from memory - */ + * Load a 16bit value from memory + */ public int memoryLoad16(int hwAddr) { - return memory.loadSigned16(hwAddr); + return memory.loadSigned16(hwAddr); } + /** - * Store a 16bit value to memory - */ + * Store a 16bit value to memory + */ public void memoryStore16(int hwAddr, int iValue) { - memory.store16(hwAddr,iValue); + memory.store16(hwAddr, iValue); } /** - * Load a 8bit value from memory - */ + * Load a 8bit value from memory + */ public byte memoryLoad8(int address) { - return (byte)memory.loadSigned8(address); + return (byte) memory.loadSigned8(address); } + /** - * Store a 8bit value to memory - */ + * Store a 8bit value to memory + */ public void memoryStore8(int address, byte data) { - memory.store8(address, data); + memory.store8(address, data); } /** - * Read an ASCIIZ string from the process' memory into a Java String - */ + * Read an ASCIIZ string from the process' memory into a Java String + */ public String memoryReadString(int address) { - StringBuffer str = new StringBuffer(); - char c; - - while( (c = (char)memoryLoad8(address++)) != 0 ) - str.append(c); - - return str.toString(); + StringBuffer str = new StringBuffer(); + char c; + + while ((c = (char) memoryLoad8(address++)) != 0) + str.append(c); + + return str.toString(); } /** - * Write a Java string (crudely) to an ASCIIZ string in the process' - * memory - */ + * Write a Java string (crudely) to an ASCIIZ string in the process' memory + */ public void memoryWriteString(int byteAddr, String value) { - if (value != null) { - for(int i=0; i < value.length(); i++) { - memoryStore8(byteAddr+i, (byte)value.charAt(i)); - } - memoryStore8(byteAddr+value.length(), (byte)0); - } + if (value != null) { + for (int i = 0; i < value.length(); i++) { + memoryStore8(byteAddr + i, (byte) value.charAt(i)); + } + memoryStore8(byteAddr + value.length(), (byte) 0); + } } /** * Map an anonymous page of memory - * @param addr the address to map or NULL if don't care - * @param len the amount of memory to map - * @param read is the page readable - * @param write is the page writable - * @param exec is the page executable + * + * @param addr + * the address to map or NULL if don't care + * @param len + * the amount of memory to map + * @param read + * is the page readable + * @param write + * is the page writable + * @param exec + * is the page executable */ - public int memoryMap(int addr, int len, boolean read, boolean write, boolean exec) throws MemoryMapException - { - return memory.map(addr, len, read, write, exec); + public int memoryMap(int addr, int len, boolean read, boolean write, + boolean exec) throws MemoryMapException { + return memory.map(addr, len, read, write, exec); } /** - * Simulate an munmap system call. - * @param start start of memory area to unmap. - * @param length length of area. - */ - public int munmap(int start, int length) - { - memory.unmap(start,length); - return 0; + * Simulate an munmap system call. + * + * @param start + * start of memory area to unmap. + * @param length + * length of area. + */ + public int munmap(int start, int length) { + memory.unmap(start, length); + return 0; } /* - * Utility functions - */ + * Utility functions + */ /** - * Debug information - * @param s string of debug information - */ - private static void report(String s){ - if (DBT_Options.debugLoader) { - System.out.print("ProcessSpace:"); - System.out.println(s); - } + * Debug information + * + * @param s + * string of debug information + */ + private static void report(String s) { + if (DBT_Options.debugLoader) { + System.out.print("ProcessSpace:"); + System.out.println(s); + } } /* - * Methods - */ + * Methods + */ /** - * Create an optimizing compiler HIR code generator suitable for a - * particular architecture - * @param context the generation context for the HIR generation - * @return a HIR generator - */ - public abstract OPT_HIRGenerator createHIRGenerator(OPT_GenerationContext context); + * Create an optimizing compiler HIR code generator suitable for a particular + * architecture + * + * @param context + * the generation context for the HIR generation + * @return a HIR generator + */ + public abstract OPT_HIRGenerator createHIRGenerator( + OPT_GenerationContext context); /** - * Given an ELF binary loader, create the appropriate process space - * @param elf the elf binary loader - * @return the appropriate process space - */ - public static ProcessSpace createProcessSpaceFromBinary (Loader loader) throws IOException { - ProcessSpace result; - if (loader.isX86_ISA()) { - report("X86 ELF Binary"); - result = X86_ProcessSpace.createProcessSpaceFromBinary(loader); - } - else if(loader.isPPC_ISA()){ - report("PPC ELF Binary"); - result = PPC_ProcessSpace.createProcessSpaceFromBinary(loader); - } - else { - throw new IOException("Binary of " + loader.getArchitectureString() + " architecture is unsupported"); - } - return result; + * Given an ELF binary loader, create the appropriate process space + * + * @param elf + * the elf binary loader + * @return the appropriate process space + */ + public static ProcessSpace createProcessSpaceFromBinary(Loader loader) + throws IOException { + ProcessSpace result; + if (loader.isX86_ISA()) { + report("X86 ELF Binary"); + result = X86_ProcessSpace.createProcessSpaceFromBinary(loader); + } else if (loader.isPPC_ISA()) { + report("PPC ELF Binary"); + result = PPC_ProcessSpace.createProcessSpaceFromBinary(loader); + } else if (loader.isARM_ISA()) { + report("ARM ELF Binary"); + result = ARM_ProcessSpace.createProcessSpaceFromBinary(loader); + } else { + throw new UnsupportedOperationException("Binary of " + loader.getArchitectureString() + + " architecture is unsupported"); + } + return result; } + /** - * Create a segment - * @param RandomAccessFile 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(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 + ")less than file size (" + filesize + ")"); - } - // Are we mapping anything from a file? - if(filesize == 0) { - // No: map anonymously - memory.map(address, memsize, read, write, exec); - } - else { - // align offset and address - int alignedAddress; - long alignedOffset; - int alignedFilesize; - if (memory.isPageAligned(address)) { - // memory and therefore offset should be aligned - alignedAddress = address; - alignedOffset = offset; - alignedFilesize = filesize; - } - else { - // Address not aligned - alignedAddress = memory.truncateToPage(address); - int delta = address - alignedAddress; - // adjust offset and length too - alignedOffset = offset - delta; - alignedFilesize = filesize + delta; - } - memory.map(file, alignedOffset, alignedAddress, alignedFilesize, read, write, exec); - // Do we need to map in some blank pages at the end of the segment? - if (filesize < memsize) { - alignedAddress = memory.truncateToNextPage(address + filesize); - memory.map(alignedAddress, memsize-filesize, read, write, exec); - } - } + * Create a segment + * + * @param RandomAccessFile + * 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(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 + + ")less than file size (" + filesize + ")"); + } + // Are we mapping anything from a file? + if (filesize == 0) { + // No: map anonymously + memory.map(address, memsize, read, write, exec); + } else { + // align offset and address + int alignedAddress; + long alignedOffset; + int alignedFilesize; + if (memory.isPageAligned(address)) { + // memory and therefore offset should be aligned + alignedAddress = address; + alignedOffset = offset; + alignedFilesize = filesize; + } else { + // Address not aligned + alignedAddress = memory.truncateToPage(address); + int delta = address - alignedAddress; + // adjust offset and length too + alignedOffset = offset - delta; + alignedFilesize = filesize + delta; + } + memory.map(file, alignedOffset, alignedAddress, alignedFilesize, read, + write, exec); + // Do we need to map in some blank pages at the end of the segment? + if (filesize < memsize) { + alignedAddress = memory.truncateToNextPage(address + filesize); + memory.map(alignedAddress, memsize - filesize, read, write, exec); + } + } } /** - * Initialise the process space - * @param loader the loader that's created the process space - * @param pc the entry point - * @param brk the initial value for the top of BSS - * @param args command line arguments - */ + * Initialise the process space + * + * @param loader + * the loader that's created the process space + * @param pc + * the entry point + * @param brk + * the initial value for the top of BSS + * @param args + * command line arguments + */ public abstract void initialise(Loader loader, int pc, int brk, String args[]); /** - * Constructor - */ + * Constructor + */ protected ProcessSpace() { - branchInfo = new BranchLogic(); + branchInfo = new BranchLogic(); } /** - * Constructor - */ + * Constructor + */ public ProcessSpace(String[] args) throws IOException { - branchInfo = new BranchLogic(); + branchInfo = new BranchLogic(); } - /** - * Replace the compiled code for a trace (called by the adaptive - * system) - */ - public synchronized void replaceCompiledTrace(VM_CompiledMethod cm, DBT_Trace trace) { - VM_CodeArray code = cm.getEntryCodeArray(); - codeHash.put(trace.pc, code); + * Replace the compiled code for a trace (called by the adaptive system) + */ + public synchronized void replaceCompiledTrace(VM_CompiledMethod cm, + DBT_Trace trace) { + VM_CodeArray code = cm.getEntryCodeArray(); + codeHash.put(trace.pc, code); } - public synchronized VM_CodeArray getCodeForPC(int pc) { - VM_CodeArray code = (VM_CodeArray)codeHash.get(pc); - if(code == null) { - code = translateCode(new DBT_Trace(this, pc)); - } - return code; + VM_CodeArray code = (VM_CodeArray) codeHash.get(pc); + if (code == null) { + code = translateCode(new DBT_Trace(this, pc)); + } + return code; } - + private VM_CodeArray translateCode(DBT_Trace trace) { - if (DBT_Options.debugRuntime) { - report("Translating code for 0x" + Integer.toHexString(trace.pc)); - } - trace.compile(); - VM_CompiledMethod cm = trace.getCurrentCompiledMethod(); - replaceCompiledTrace(cm, trace); - return cm.getEntryCodeArray(); + if (DBT_Options.debugRuntime) { + report("Translating code for 0x" + Integer.toHexString(trace.pc)); + } + trace.compile(); + VM_CompiledMethod cm = trace.getCurrentCompiledMethod(); + replaceCompiledTrace(cm, trace); + return cm.getEntryCodeArray(); } /** * Record a branch instruction */ - public void recordUncaughtBranch(int location, int destination, int code) { - branchInfo.registerBranch(location, destination, code); + public void recordUncaughtBranch(int location, int destination, int code) { + branchInfo.registerBranch(location, destination, code); } /** - * Return as an integer the current instruction's address - */ + * Return as an integer the current instruction's address + */ public abstract int getCurrentInstructionAddress(); + /** - * Sets the current instruction's address - */ + * Sets the current instruction's address + */ public abstract void setCurrentInstructionAddress(int pc); + /** - * Return as an integer the current instruction's address - */ + * Return as an integer the current instruction's address + */ public abstract int getCurrentStackAddress(); + /** - * Print the stack - * @param words how many words to print from the stack - */ + * Print the stack + * + * @param words + * how many words to print from the stack + */ public void dumpStack(int words) { - int stackPtr = getCurrentStackAddress(); - for(int i=0; i < words; i++) { - if((i % 4) == 0) { - if(i != 0) { - System.out.println(); - } - System.out.print("0x" + Integer.toHexString(stackPtr)+":"); - } - String hexValue = Integer.toHexString(memory.load32(stackPtr)); - System.out.print(" 0x"); - for(int j=0; j < (8-hexValue.length()); j++) { - System.out.print("0"); - } - System.out.print(hexValue); - stackPtr+=4; - } - System.out.println(); + int stackPtr = getCurrentStackAddress(); + for (int i = 0; i < words; i++) { + if ((i % 4) == 0) { + if (i != 0) { + System.out.println(); + } + System.out.print("0x" + Integer.toHexString(stackPtr) + ":"); + } + String hexValue = Integer.toHexString(memory.load32(stackPtr)); + System.out.print(" 0x"); + for (int j = 0; j < (8 - hexValue.length()); j++) { + System.out.print("0"); + } + System.out.print(hexValue); + stackPtr += 4; + } + System.out.println(); } + /** - * Runtime loop, goes through the binary and looks in the Hashtable - * codeHash to see if we have already translated/compiled this piece - * of code, if not it is compiled. The compiled code is then run. + * Runtime loop, goes through the binary and looks in the Hashtable codeHash + * to see if we have already translated/compiled this piece of code, if not it + * is compiled. The compiled code is then run. */ public void run() { if (DBT_Options.debugRuntime) { System.out.println("Main: run"); } - - // The current block of compiled code. - VM_CodeArray code; - if(DBT_Options.debugPS) { + // The current block of compiled code. + VM_CodeArray code; + + if (DBT_Options.debugPS) { System.out.println("***** INITIAL PROCESS SPACE *****\n" + this); - System.out.println(this); - //dumpStack(20); + System.out.println(this); + // dumpStack(20); } - if(DBT_Options.gdbStub == false) { - try { - // interpretFrom(); // Interpreter - experimental - while(finished == false) { - // Get the compiled code - code = getCodeForPC(getCurrentInstructionAddress()); - // Run the compiled code. - setCurrentInstructionAddress(DynamicCodeRunner.invokeCode(code, this)); - } - } - catch(BadInstructionException e) { - System.out.println(e.toString()); - } - } - else { - GDBStub gdbStub = new GDBStub(DBT_Options.gdbStubPort, this); - gdbStub.run(); - } + if (DBT_Options.gdbStub == false) { + try { + // interpretFrom(); // Interpreter - experimental + while (finished == false) { + // Get the compiled code + code = getCodeForPC(getCurrentInstructionAddress()); + // Run the compiled code. + setCurrentInstructionAddress(DynamicCodeRunner.invokeCode(code, this)); + } + } catch (BadInstructionException e) { + System.out.println(e.toString()); + } + } else { + GDBStub gdbStub = new GDBStub(DBT_Options.gdbStubPort, this); + gdbStub.run(); + } } /** - * Entry point for system calls - */ + * Entry point for system calls + */ public abstract void doSysCall(); - private static final String[] env = {"HOSTNAME=softwood", "PVM_RSH=/usr/bin/rsh", - "HOST_JAVA_HOME=/home/amulocal/linux/appl/j2sdk1.4.2", "SHELL=/bin/bash", - "TERM=xterm", "HISTSIZE=1000", "SSH_CLIENT=130.88.194.110 8380 22", - "CVSROOT=/home/simgroup/cvsroot", "QTDIR=/usr/lib/qt-3.1", "SSH_TTY=/dev/pts/0", - "RVM_HOST_CONFIG=/home/matleyr/cvs/rvm/config/i686-pc-linux-gnu.ManCS", - "USER=matleyr", "LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:", "XENVIRONMENT=/home/matleyr/.Xdefaults", - "PVM_ROOT=/usr/share/pvm3", "CLASSPATH_ROOT=/home/matleyr/cvs/classpath", - "PATH=/home/matleyr/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/opt/lib/j2re1.3.1/bin:/home/matleyr/cvs/rvm/bin:/home/matleyr/bin", "MAIL=/var/spool/mail/matleyr", - "_=/bin/bash", "PWD=/home/matleyr/dhry", "INPUTRC=/etc/inputrc", - "LANG=en_GB.iso88591", "LAMHELPFILE=/etc/lam/lam-helpfile", - "SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass", - "CSHOME=ma...@an...:/home/M03/cc/matleyr", "HOME=/home/matleyr", - "SHLVL=1", "SIM=/home/simgroup/matleyr", "XPVM_ROOT=/usr/share/pvm3/xpvm", - "RVM_ROOT=/home/matleyr/cvs", "LOGNAME=matleyr", "PRINTER=happy_duplex", - "SSH_CONNECTION=130.88.194.110 2380 130.88.198.215 22", - "LESSOPEN=|/usr/bin/lesspipe.sh %s", "RVM_BUILD=/tmp/RVMbuild", - "DISPLAY=localhost:10.0", - "RVM_TARGET_CONFIG=/home/matleyr/cvs/rvm/config/i686-pc-linux-gnu.ManCS", - "G_BROKEN_FILENAMES=1"}; + private static final String[] env = { + "HOSTNAME=softwood", + "PVM_RSH=/usr/bin/rsh", + "HOST_JAVA_HOME=/home/amulocal/linux/appl/j2sdk1.4.2", + "SHELL=/bin/bash", + "TERM=xterm", + "HISTSIZE=1000", + "SSH_CLIENT=130.88.194.110 8380 22", + "CVSROOT=/home/simgroup/cvsroot", + "QTDIR=/usr/lib/qt-3.1", + "SSH_TTY=/dev/pts/0", + "RVM_HOST_CONFIG=/home/matleyr/cvs/rvm/config/i686-pc-linux-gnu.ManCS", + "USER=matleyr", + "LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:", + "XENVIRONMENT=/home/matleyr/.Xdefaults", + "PVM_ROOT=/usr/share/pvm3", + "CLASSPATH_ROOT=/home/matleyr/cvs/classpath", + "PATH=/home/matleyr/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/opt/lib/j2re1.3.1/bin:/home/matleyr/cvs/rvm/bin:/home/matleyr/bin", + "MAIL=/var/spool/mail/matleyr", "_=/bin/bash", "PWD=/home/matleyr/dhry", + "INPUTRC=/etc/inputrc", "LANG=en_GB.iso88591", + "LAMHELPFILE=/etc/lam/lam-helpfile", + "SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass", + "CSHOME=ma...@an...:/home/M03/cc/matleyr", + "HOME=/home/matleyr", "SHLVL=1", "SIM=/home/simgroup/matleyr", + "XPVM_ROOT=/usr/share/pvm3/xpvm", "RVM_ROOT=/home/matleyr/cvs", + "LOGNAME=matleyr", "PRINTER=happy_duplex", + "SSH_CONNECTION=130.88.194.110 2380 130.88.198.215 22", + "LESSOPEN=|/usr/bin/lesspipe.sh %s", "RVM_BUILD=/tmp/RVMbuild", + "DISPLAY=localhost:10.0", + "RVM_TARGET_CONFIG=/home/matleyr/cvs/rvm/config/i686-pc-linux-gnu.ManCS", + "G_BROKEN_FILENAMES=1" }; + /** - * Method to return environment variables - * @return an array of environment variable strings - */ + * Method to return environment variables + * + * @return an array of environment variable strings + */ protected String[] getEnvironmentVariables() { - /* Environment variables, exactly as on softwood. Not that the number 8380 in SSH_* varies. */ - return env; - /* - if (!DBT_Options.loadEnv) { - Process printenv = Runtime.exec("/usr/bin/printenv"); - InputStream variables = new DataInputStream(printenv.getInputStream()); - variables.readUTF(); - } - */ + /* + * Environment variables, exactly as on softwood. Not that the number 8380 + * in SSH_* varies. + */ + return env; + /* + * if (!DBT_Options.loadEnv) { Process printenv = + * Runtime.exec("/usr/bin/printenv"); InputStream variables = new + * DataInputStream(printenv.getInputStream()); variables.readUTF(); } + */ } /* GDB stub interface */ /** - * Read a register and turn into a byte array conforming to the - * endianness of the architecture - */ + * Read a register and turn into a byte array conforming to the endianness of + * the architecture + */ public abstract byte[] readRegisterGDB(int regNum); + /** - * Run a single instruction - */ + * Run a single instruction + */ public abstract void runOneInstruction() throws BadInstructionException; + /** - * Has frame base register? - */ + * Has frame base register? + */ public boolean hasFrameBaseRegister() { - return false; + return false; } + /** - * Get the value of the frame base register - */ + * Get the value of the frame base register + */ public int getGDBFrameBaseRegister() { - return -1; + return -1; } + /** - * Get the value of the frame base register - */ + * Get the value of the frame base register + */ public abstract int getGDBStackPointerRegister(); + /** - * Get the value of the frame base register - */ + * Get the value of the frame base register + */ public abstract int getGDBProgramCountRegister(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |