From: <mic...@us...> - 2007-08-20 14:13:04
|
Revision: 168 http://pearcolator.svn.sourceforge.net/pearcolator/?rev=168&view=rev Author: michael_baer Date: 2007-08-20 07:12:59 -0700 (Mon, 20 Aug 2007) Log Message: ----------- - Fixed bug in IntAddressed Memory for 16bit unsigned loads - Renamed IntAddressedMemory to IntAddressedLittleEndian Memory - Renamed ByteAddressedMemory to ByteAddressedLittleEndian Memory Modified Paths: -------------- src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java src/org/binarytranslator/arch/x86/os/process/X86_ProcessSpace.java src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java src/org/binarytranslator/generic/memory/IntAddressedPreSwappedMemory.java Added Paths: ----------- src/org/binarytranslator/generic/memory/ByteAddressedLittleEndianMemory.java src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java Removed Paths: ------------- src/org/binarytranslator/generic/memory/ByteAddressedMemory.java src/org/binarytranslator/generic/memory/IntAddressedMemory.java Modified: src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-08-20 14:12:59 UTC (rev 168) @@ -10,8 +10,8 @@ import org.binarytranslator.arch.arm.os.process.linux.ARM_LinuxProcessSpace; import org.binarytranslator.generic.decoder.CodeTranslator; import org.binarytranslator.generic.decoder.Interpreter; -import org.binarytranslator.generic.memory.ByteAddressedMemory; -import org.binarytranslator.generic.memory.IntAddressedMemory; +import org.binarytranslator.generic.memory.ByteAddressedLittleEndianMemory; +import org.binarytranslator.generic.memory.IntAddressedLittleEndianMemory; import org.binarytranslator.generic.os.loader.Loader; import org.binarytranslator.generic.os.process.ProcessSpace; import org.binarytranslator.vmInterface.DBT_Trace; @@ -43,11 +43,11 @@ switch (ARM_Options.memoryModel) { case ByteAddressed: - memory = new ByteAddressedMemory(); + memory = new ByteAddressedLittleEndianMemory(); break; case IntAddressed: - memory = new IntAddressedMemory(); + memory = new IntAddressedLittleEndianMemory(); break; default: Modified: src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-08-20 14:12:59 UTC (rev 168) @@ -14,8 +14,8 @@ public class ARM_ImageProcessSpace extends ARM_ProcessSpace { private AngelSystemCalls sysCalls; - private final int STACK_SIZE = 4096 * 10; - private final int HEAP_SIZE = 4096 * 10; + private final int STACK_SIZE = 4096 * 100; + private final int HEAP_SIZE = 4096 * 100; public ARM_ImageProcessSpace() { super(); Modified: src/org/binarytranslator/arch/x86/os/process/X86_ProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/x86/os/process/X86_ProcessSpace.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/arch/x86/os/process/X86_ProcessSpace.java 2007-08-20 14:12:59 UTC (rev 168) @@ -14,7 +14,7 @@ import org.jikesrvm.compilers.opt.ir.OPT_GenerationContext; import org.binarytranslator.DBT_Options; import org.binarytranslator.generic.os.process.ProcessSpace; -import org.binarytranslator.generic.memory.ByteAddressedMemory; +import org.binarytranslator.generic.memory.ByteAddressedLittleEndianMemory; import org.binarytranslator.generic.decoder.CodeTranslator; import org.binarytranslator.generic.execution.GdbController.GdbTarget; import org.binarytranslator.generic.fault.BadInstructionException; @@ -139,7 +139,7 @@ */ protected X86_ProcessSpace() { registers = new X86_Registers(); - memory = new ByteAddressedMemory(); + memory = new ByteAddressedLittleEndianMemory(); } /** Modified: src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java 2007-08-20 14:12:59 UTC (rev 168) @@ -29,7 +29,7 @@ * .........00 |'H'| * </pre> */ -final public class ByteAddressedByteSwapMemory extends ByteAddressedMemory { +final public class ByteAddressedByteSwapMemory extends ByteAddressedLittleEndianMemory { /** * Constructor - used when this is the instatiated class */ Copied: src/org/binarytranslator/generic/memory/ByteAddressedLittleEndianMemory.java (from rev 149, src/org/binarytranslator/generic/memory/ByteAddressedMemory.java) =================================================================== --- src/org/binarytranslator/generic/memory/ByteAddressedLittleEndianMemory.java (rev 0) +++ src/org/binarytranslator/generic/memory/ByteAddressedLittleEndianMemory.java 2007-08-20 14:12:59 UTC (rev 168) @@ -0,0 +1,550 @@ +/* + * This file is part of binarytranslator.org. The binarytranslator.org + * project is distributed under the Common Public License (CPL). + * A copy of the license is included in the distribution, and is also + * available at http://www.opensource.org/licenses/cpl1.0.php + * + * (C) Copyright Ian Rogers, The University of Manchester 2003-2006 + */ +package org.binarytranslator.generic.memory; + +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import org.binarytranslator.DBT_Options; +import org.binarytranslator.generic.fault.SegmentationFault; + +/** + * ByteAddressedMemory: + * + * Memory is arrays of bytes, no endian conversion is performed. + * + * The string helo followed by the int of 0xcafebabe appear as: + * + * <pre> + * Byte Address| + * ----------------- + * .........07 | ca| + * .........06 | fe| + * .........05 | ba| + * .........04 | be| + * .........03 |'o'| + * .........02 |'l'| + * .........01 |'e'| + * .........00 |'H'| + * </pre> + */ +public class ByteAddressedLittleEndianMemory extends CallBasedMemory { + + /** The size of a single page in bytes. */ + private static final int PAGE_SIZE = 4096; + + /** Bits in offset */ + private static final int OFFSET_BITS = 12; + + /** The number of pages */ + private static final int NUM_PAGES = 0x100000; + + /** The maximum amount of RAM available */ + protected static final long MAX_RAM = (long) PAGE_SIZE * (long) NUM_PAGES; + + /** The memory backing store */ + private byte readableMemory[][]; + private byte writableMemory[][]; + private byte executableMemory[][]; + + /** Do we have more optimal nio mmap operation? */ + private boolean HAVE_java_nio_FileChannelImpl_nio_mmap_file = false; + + /** + * Constructor - used when this is the instatiated class + */ + public ByteAddressedLittleEndianMemory() { + this(null); + } + + /** + * Constructor - used when deriving a class + * + * @param classType + * the name of the over-riding class + */ + protected ByteAddressedLittleEndianMemory(Class classType) { + super(classType != null ? classType : ByteAddressedLittleEndianMemory.class); + readableMemory = new byte[NUM_PAGES][]; + writableMemory = new byte[NUM_PAGES][]; + executableMemory = new byte[NUM_PAGES][]; + } + + /** + * Return the offset part of the address + */ + private static final int getOffset(int address) { + return address & (PAGE_SIZE - 1); + } + + /** + * Return the page table entry part of the address + */ + private static final int getPTE(int address) { + return address >>> OFFSET_BITS; + } + + /** + * Find free consecutive pages + * + * @param pages + * the number of pages required + * @return the address found + */ + private final int findFreePages(int pages) { + starting_page_search: for (int i = 0; i < NUM_PAGES; i++) { + if (getPage(i) == null) { + int start = i; + int end = i + pages; + for (; i <= end; i++) { + if (getPage(i) != null) { + continue starting_page_search; + } + } + return start << OFFSET_BITS; + } + } + throw new Error( + "No mappable consecutive pages found for an anonymous map of size" + + (pages * PAGE_SIZE)); + } + + /** + * 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 + */ + public int map(int addr, int len, boolean read, boolean write, boolean exec) + throws MemoryMapException { + // Check address is page aligned + if ((addr % PAGE_SIZE) != 0) { + MemoryMapException.unalignedAddress(addr); + } + + // Create memory + int num_pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + byte pages[][] = new byte[num_pages][PAGE_SIZE]; + + // Find address if not specified + if (addr == 0) { + addr = findFreePages(num_pages); + } + + if (DBT_Options.debugMemory) { + System.out.println("Anonymous mapping: addr=0x" + + Integer.toHexString(addr) + " len=" + len + (read ? " r" : " -") + + (write ? "w" : "-") + (exec ? "x" : "-")); + } + + // Get page table entry + int pte = getPTE(addr); + for (int i = 0; i < num_pages; i++) { + + // Check pages aren't already allocated + if (getPage(pte + i) != null) { + throw new Error("Memory map of already mapped location addr=0x" + + Integer.toHexString(addr) + " len=" + len); + } + + // Allocate pages + readableMemory[pte + i] = read ? pages[i] : null; + writableMemory[pte + i] = write ? pages[i] : null; + executableMemory[pte + i] = exec ? pages[i] : null; + } + + return addr; + } + + /** + * Map a page of memory from file + * + * @param file + * the file map in from + * @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 map(RandomAccessFile file, long offset, int addr, int len, + boolean read, boolean write, boolean exec) throws MemoryMapException { + // Check address is page aligned + if ((addr % PAGE_SIZE) != 0) { + MemoryMapException.unalignedAddress(addr); + } + + // Check file offset is page aligned + /*if ((offset % PAGE_SIZE) != 0) { + MemoryMapException.unalignedFileOffset(offset); + }*/ + + // Calculate number of pages + int num_pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + // Find address if not specified + if (addr == 0) { + addr = findFreePages(num_pages); + } + if (DBT_Options.debugMemory) { + System.out.println("Mapping file " + file + " offset=" + offset + + " addr=0x" + Integer.toHexString(addr) + " len=" + len + + (read ? " r" : " -") + (write ? "w" : "-") + (exec ? "x" : "-")); + } + try { + // Get page table entry + int pte = getPTE(addr); + // Can we optimise the reads to use mmap? + if (!HAVE_java_nio_FileChannelImpl_nio_mmap_file) { + // Sub-optimal + file.seek(offset); + for (int i = 0; i < num_pages; i++) { + // Check pages aren't already allocated + if (getPage(pte + i) != null) { + throw new Error("Memory map of already mapped location addr=0x" + + Integer.toHexString(addr) + " len=" + len); + } + // Allocate page + byte page[] = new byte[PAGE_SIZE]; + if (i == 0) { // first read, start from offset upto a page length + file.read(page, getOffset(addr), PAGE_SIZE - getOffset(addr)); + } else if (i == (num_pages - 1)) { // last read + file.read(page, 0, ((len - getOffset(addr)) % PAGE_SIZE)); + } else { + file.read(page); + } + + readableMemory[pte + i] = read ? page : null; + writableMemory[pte + i] = write ? page : null; + executableMemory[pte + i] = exec ? page : null; + } + } else { + for (int i = 0; i < num_pages; i++) { + // Check pages aren't already allocated + if (getPage(pte + i) != null) { + throw new Error("Memory map of already mapped location addr=0x" + + Integer.toHexString(addr) + " len=" + len); + } + + // Allocate page + if (read && write) { + readableMemory[pte + i] = file.getChannel().map( + FileChannel.MapMode.READ_WRITE, offset + (i * PAGE_SIZE), + PAGE_SIZE).array(); + writableMemory[pte + i] = readableMemory[pte + i]; + if (exec) { + executableMemory[pte + i] = readableMemory[pte + i]; + } + } else if (read) { + readableMemory[pte + i] = file.getChannel().map( + FileChannel.MapMode.READ_ONLY, offset + (i * PAGE_SIZE), + PAGE_SIZE).array(); + if (exec) { + executableMemory[pte + i] = readableMemory[pte + i]; + } + } else if (exec) { + executableMemory[pte + i] = file.getChannel().map( + FileChannel.MapMode.READ_ONLY, offset + (i * PAGE_SIZE), + PAGE_SIZE).array(); + } else { + throw new Error("Unable to map address 0x" + + Integer.toHexString(addr) + " with permissions " + + (read ? "r" : "-") + (write ? "w" : "-") + (exec ? "x" : "-")); + } + } + } + return addr; + } catch (java.io.IOException e) { + throw new Error(e); + } + } + + /** + * Returns the page currently mapped at the given page table entry. + * + * @param pte + * The page table entry, for which a page is to be retrieved. + * @return + * The page mapped at the given page table entry or null, if no page is currently mapped + * to that entry. + */ + private byte[] getPage(int pte) { + + if (readableMemory[pte] != null) + return readableMemory[pte]; + + if (writableMemory[pte] != null) + return writableMemory[pte]; + + if (executableMemory[pte] != null) + return executableMemory[pte]; + + return null; + } + + /** + * Unmap a page of memory + * + * @param addr + * the address to unmap + * @param len + * the amount of memory to unmap + */ + public void unmap(int addr, int len) { + for (int i = 0; i < len; i += PAGE_SIZE) { + + int pte = getPTE(addr + i); + if (getPage(pte) != null) { + readableMemory[pte] = null; + writableMemory[pte] = null; + executableMemory[pte] = null; + } + else { + throw new Error("Unmapping memory that's not mapped addr=0x" + + Integer.toHexString(addr) + " len=" + len); + } + } + } + + /** + * Is the given address mapped into memory? + * @param addr to check + * @return true => memory is mapped + */ + public boolean isMapped(int addr) { + return getPage(getPTE(addr)) != null; + } + + /** + * @return the size of a page + */ + public int getPageSize() { + return PAGE_SIZE; + } + + /** + * Is the given address aligned on a page boundary? + * + * @param addr + * the address to check + * @return whether the address is aligned + */ + public boolean isPageAligned(int addr) { + return (addr % PAGE_SIZE) == 0; + } + + /** + * Make the given address page aligned to the page beneath it + * + * @param addr + * the address to truncate + * @return the truncated address + */ + public int truncateToPage(int addr) { + return (addr >> OFFSET_BITS) << OFFSET_BITS; + } + + /** + * Make the given address page aligned to the page above it + * + * @param addr + * the address to truncate + * @return the truncated address + */ + public int truncateToNextPage(int addr) { + return ((addr + PAGE_SIZE - 1) >> OFFSET_BITS) << OFFSET_BITS; + } + + /** + * Perform a byte load where the sign extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the sign extended result + */ + final public int loadSigned8(int addr) { + try { + if (DBT_Options.debugMemory) + System.err.println("LoadS8 address: 0x" + Integer.toHexString(addr) + + " val: " + readableMemory[getPTE(addr)][getOffset(addr)]); + return readableMemory[getPTE(addr)][getOffset(addr)]; + } catch (NullPointerException e) { + System.err.println("Null pointer exception at address: 0x" + + Integer.toHexString(addr)); + throw e; + } + } + + /** + * Perform a byte load where the zero extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the zero extended result + */ + final public int loadUnsigned8(int addr) { + try { + if (DBT_Options.debugMemory) + System.err.println("LoadU8 address: 0x" + Integer.toHexString(addr) + + " val: " + readableMemory[getPTE(addr)][getOffset(addr)]); + return readableMemory[getPTE(addr)][getOffset(addr)] & 0xFF; + } catch (NullPointerException e) { + System.err.println("Null pointer exception at address: 0x" + + Integer.toHexString(addr)); + throw e; + } + } + + /** + * Perform a 16bit load where the sign extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the sign extended result + */ + public int loadSigned16(int addr) { + return (loadSigned8(addr + 1) << 8) | loadUnsigned8(addr); + } + + /** + * Perform a 16bit load where the zero extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the zero extended result + */ + public int loadUnsigned16(int addr) { + return (loadUnsigned8(addr + 1) << 8) | loadUnsigned8(addr); + } + + /** + * Perform a 32bit load + * + * @param addr + * the address of the value to load + * @return the result + */ + public int load32(int addr) { + try { + return (loadSigned8(addr + 3) << 24) | (loadUnsigned8(addr + 2) << 16) + | (loadUnsigned8(addr + 1) << 8) | loadUnsigned8(addr); + } catch (Exception e) { + throw new SegmentationFault(addr); + } + } + + /** + * Perform a 8bit load from memory that must be executable + * + * @param addr + * the address of the value to load + * @return the result + */ + public int loadInstruction8(int addr) { + if (DBT_Options.debugMemory) + System.err.println("LoadI8 address: 0x" + Integer.toHexString(addr) + + " val: " + executableMemory[getPTE(addr)][getOffset(addr)]); + return executableMemory[getPTE(addr)][getOffset(addr)] & 0xFF; + } + + /** + * Perform a 32bit load from memory that must be executable + * + * @param addr + * the address of the value to load + * @return the result + */ + public int loadInstruction32(int addr) { + return (loadInstruction8(addr + 3) << 24) + | (loadInstruction8(addr + 2) << 16) + | (loadInstruction8(addr + 1) << 8) | loadInstruction8(addr); + } + + /** + * Perform a byte store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + public final void store8(int addr, int value) { + if (DBT_Options.debugMemory) + System.err.println("Store8 address: 0x" + Integer.toHexString(addr) + + " val: 0x" + Integer.toHexString(value & 0xFF)); + writableMemory[getPTE(addr)][getOffset(addr)] = (byte) value; + } + + /** + * Perform a 16bit store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + public void store16(int addr, int value) { + store8(addr + 1, value >> 8); + store8(addr, value); + } + + /** + * Perform a 32bit store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + public void store32(int addr, int value) { + try { + store8(addr + 3, value >> 24); + store8(addr + 2, value >> 16); + store8(addr + 1, value >> 8); + store8(addr, value); + } catch (Exception e) { + throw new SegmentationFault(addr); + } + } + + @Override + public void changeProtection(int address, int len, boolean newRead, boolean newWrite, boolean newExec) { + + while (len > 0) { + int pte = getPTE(address); + byte[] page = getPage(pte); + + if (page == null) + throw new SegmentationFault(address); + + readableMemory[pte] = newRead ? page : null; + writableMemory[pte] = newWrite ? page : null; + executableMemory[pte] = newExec ? page : null; + + address += PAGE_SIZE; + len -= PAGE_SIZE; + } + } + + @Override + public int loadInstruction16(int addr) { + return (loadInstruction8(addr + 1) << 8) | loadInstruction8(addr); + } +} Deleted: src/org/binarytranslator/generic/memory/ByteAddressedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/ByteAddressedMemory.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/generic/memory/ByteAddressedMemory.java 2007-08-20 14:12:59 UTC (rev 168) @@ -1,550 +0,0 @@ -/* - * This file is part of binarytranslator.org. The binarytranslator.org - * project is distributed under the Common Public License (CPL). - * A copy of the license is included in the distribution, and is also - * available at http://www.opensource.org/licenses/cpl1.0.php - * - * (C) Copyright Ian Rogers, The University of Manchester 2003-2006 - */ -package org.binarytranslator.generic.memory; - -import java.io.RandomAccessFile; -import java.nio.channels.FileChannel; -import org.binarytranslator.DBT_Options; -import org.binarytranslator.generic.fault.SegmentationFault; - -/** - * ByteAddressedMemory: - * - * Memory is arrays of bytes, no endian conversion is performed. - * - * The string helo followed by the int of 0xcafebabe appear as: - * - * <pre> - * Byte Address| - * ----------------- - * .........07 | be| - * .........06 | ba| - * .........05 | fe| - * .........04 | ca| - * .........03 |'o'| - * .........02 |'l'| - * .........01 |'e'| - * .........00 |'H'| - * </pre> - */ -public class ByteAddressedMemory extends CallBasedMemory { - - /** The size of a single page in bytes. */ - private static final int PAGE_SIZE = 4096; - - /** Bits in offset */ - private static final int OFFSET_BITS = 12; - - /** The number of pages */ - private static final int NUM_PAGES = 0x100000; - - /** The maximum amount of RAM available */ - protected static final long MAX_RAM = (long) PAGE_SIZE * (long) NUM_PAGES; - - /** The memory backing store */ - private byte readableMemory[][]; - private byte writableMemory[][]; - private byte executableMemory[][]; - - /** Do we have more optimal nio mmap operation? */ - private boolean HAVE_java_nio_FileChannelImpl_nio_mmap_file = false; - - /** - * Constructor - used when this is the instatiated class - */ - public ByteAddressedMemory() { - this(null); - } - - /** - * Constructor - used when deriving a class - * - * @param classType - * the name of the over-riding class - */ - protected ByteAddressedMemory(Class classType) { - super(classType != null ? classType : ByteAddressedMemory.class); - readableMemory = new byte[NUM_PAGES][]; - writableMemory = new byte[NUM_PAGES][]; - executableMemory = new byte[NUM_PAGES][]; - } - - /** - * Return the offset part of the address - */ - private static final int getOffset(int address) { - return address & (PAGE_SIZE - 1); - } - - /** - * Return the page table entry part of the address - */ - private static final int getPTE(int address) { - return address >>> OFFSET_BITS; - } - - /** - * Find free consecutive pages - * - * @param pages - * the number of pages required - * @return the address found - */ - private final int findFreePages(int pages) { - starting_page_search: for (int i = 0; i < NUM_PAGES; i++) { - if (getPage(i) == null) { - int start = i; - int end = i + pages; - for (; i <= end; i++) { - if (getPage(i) != null) { - continue starting_page_search; - } - } - return start << OFFSET_BITS; - } - } - throw new Error( - "No mappable consecutive pages found for an anonymous map of size" - + (pages * PAGE_SIZE)); - } - - /** - * 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 - */ - public int map(int addr, int len, boolean read, boolean write, boolean exec) - throws MemoryMapException { - // Check address is page aligned - if ((addr % PAGE_SIZE) != 0) { - MemoryMapException.unalignedAddress(addr); - } - - // Create memory - int num_pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; - byte pages[][] = new byte[num_pages][PAGE_SIZE]; - - // Find address if not specified - if (addr == 0) { - addr = findFreePages(num_pages); - } - - if (DBT_Options.debugMemory) { - System.out.println("Anonymous mapping: addr=0x" - + Integer.toHexString(addr) + " len=" + len + (read ? " r" : " -") - + (write ? "w" : "-") + (exec ? "x" : "-")); - } - - // Get page table entry - int pte = getPTE(addr); - for (int i = 0; i < num_pages; i++) { - - // Check pages aren't already allocated - if (getPage(pte + i) != null) { - throw new Error("Memory map of already mapped location addr=0x" - + Integer.toHexString(addr) + " len=" + len); - } - - // Allocate pages - readableMemory[pte + i] = read ? pages[i] : null; - writableMemory[pte + i] = write ? pages[i] : null; - executableMemory[pte + i] = exec ? pages[i] : null; - } - - return addr; - } - - /** - * Map a page of memory from file - * - * @param file - * the file map in from - * @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 map(RandomAccessFile file, long offset, int addr, int len, - boolean read, boolean write, boolean exec) throws MemoryMapException { - // Check address is page aligned - if ((addr % PAGE_SIZE) != 0) { - MemoryMapException.unalignedAddress(addr); - } - - // Check file offset is page aligned - /*if ((offset % PAGE_SIZE) != 0) { - MemoryMapException.unalignedFileOffset(offset); - }*/ - - // Calculate number of pages - int num_pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; - // Find address if not specified - if (addr == 0) { - addr = findFreePages(num_pages); - } - if (DBT_Options.debugMemory) { - System.out.println("Mapping file " + file + " offset=" + offset - + " addr=0x" + Integer.toHexString(addr) + " len=" + len - + (read ? " r" : " -") + (write ? "w" : "-") + (exec ? "x" : "-")); - } - try { - // Get page table entry - int pte = getPTE(addr); - // Can we optimise the reads to use mmap? - if (!HAVE_java_nio_FileChannelImpl_nio_mmap_file) { - // Sub-optimal - file.seek(offset); - for (int i = 0; i < num_pages; i++) { - // Check pages aren't already allocated - if (getPage(pte + i) != null) { - throw new Error("Memory map of already mapped location addr=0x" - + Integer.toHexString(addr) + " len=" + len); - } - // Allocate page - byte page[] = new byte[PAGE_SIZE]; - if (i == 0) { // first read, start from offset upto a page length - file.read(page, getOffset(addr), PAGE_SIZE - getOffset(addr)); - } else if (i == (num_pages - 1)) { // last read - file.read(page, 0, ((len - getOffset(addr)) % PAGE_SIZE)); - } else { - file.read(page); - } - - readableMemory[pte + i] = read ? page : null; - writableMemory[pte + i] = write ? page : null; - executableMemory[pte + i] = exec ? page : null; - } - } else { - for (int i = 0; i < num_pages; i++) { - // Check pages aren't already allocated - if (getPage(pte + i) != null) { - throw new Error("Memory map of already mapped location addr=0x" - + Integer.toHexString(addr) + " len=" + len); - } - - // Allocate page - if (read && write) { - readableMemory[pte + i] = file.getChannel().map( - FileChannel.MapMode.READ_WRITE, offset + (i * PAGE_SIZE), - PAGE_SIZE).array(); - writableMemory[pte + i] = readableMemory[pte + i]; - if (exec) { - executableMemory[pte + i] = readableMemory[pte + i]; - } - } else if (read) { - readableMemory[pte + i] = file.getChannel().map( - FileChannel.MapMode.READ_ONLY, offset + (i * PAGE_SIZE), - PAGE_SIZE).array(); - if (exec) { - executableMemory[pte + i] = readableMemory[pte + i]; - } - } else if (exec) { - executableMemory[pte + i] = file.getChannel().map( - FileChannel.MapMode.READ_ONLY, offset + (i * PAGE_SIZE), - PAGE_SIZE).array(); - } else { - throw new Error("Unable to map address 0x" - + Integer.toHexString(addr) + " with permissions " - + (read ? "r" : "-") + (write ? "w" : "-") + (exec ? "x" : "-")); - } - } - } - return addr; - } catch (java.io.IOException e) { - throw new Error(e); - } - } - - /** - * Returns the page currently mapped at the given page table entry. - * - * @param pte - * The page table entry, for which a page is to be retrieved. - * @return - * The page mapped at the given page table entry or null, if no page is currently mapped - * to that entry. - */ - private byte[] getPage(int pte) { - - if (readableMemory[pte] != null) - return readableMemory[pte]; - - if (writableMemory[pte] != null) - return writableMemory[pte]; - - if (executableMemory[pte] != null) - return executableMemory[pte]; - - return null; - } - - /** - * Unmap a page of memory - * - * @param addr - * the address to unmap - * @param len - * the amount of memory to unmap - */ - public void unmap(int addr, int len) { - for (int i = 0; i < len; i += PAGE_SIZE) { - - int pte = getPTE(addr + i); - if (getPage(pte) != null) { - readableMemory[pte] = null; - writableMemory[pte] = null; - executableMemory[pte] = null; - } - else { - throw new Error("Unmapping memory that's not mapped addr=0x" - + Integer.toHexString(addr) + " len=" + len); - } - } - } - - /** - * Is the given address mapped into memory? - * @param addr to check - * @return true => memory is mapped - */ - public boolean isMapped(int addr) { - return getPage(getPTE(addr)) != null; - } - - /** - * @return the size of a page - */ - public int getPageSize() { - return PAGE_SIZE; - } - - /** - * Is the given address aligned on a page boundary? - * - * @param addr - * the address to check - * @return whether the address is aligned - */ - public boolean isPageAligned(int addr) { - return (addr % PAGE_SIZE) == 0; - } - - /** - * Make the given address page aligned to the page beneath it - * - * @param addr - * the address to truncate - * @return the truncated address - */ - public int truncateToPage(int addr) { - return (addr >> OFFSET_BITS) << OFFSET_BITS; - } - - /** - * Make the given address page aligned to the page above it - * - * @param addr - * the address to truncate - * @return the truncated address - */ - public int truncateToNextPage(int addr) { - return ((addr + PAGE_SIZE - 1) >> OFFSET_BITS) << OFFSET_BITS; - } - - /** - * Perform a byte load where the sign extended result fills the return value - * - * @param addr - * the address of the value to load - * @return the sign extended result - */ - final public int loadSigned8(int addr) { - try { - if (DBT_Options.debugMemory) - System.err.println("LoadS8 address: 0x" + Integer.toHexString(addr) - + " val: " + readableMemory[getPTE(addr)][getOffset(addr)]); - return readableMemory[getPTE(addr)][getOffset(addr)]; - } catch (NullPointerException e) { - System.err.println("Null pointer exception at address: 0x" - + Integer.toHexString(addr)); - throw e; - } - } - - /** - * Perform a byte load where the zero extended result fills the return value - * - * @param addr - * the address of the value to load - * @return the zero extended result - */ - final public int loadUnsigned8(int addr) { - try { - if (DBT_Options.debugMemory) - System.err.println("LoadU8 address: 0x" + Integer.toHexString(addr) - + " val: " + readableMemory[getPTE(addr)][getOffset(addr)]); - return readableMemory[getPTE(addr)][getOffset(addr)] & 0xFF; - } catch (NullPointerException e) { - System.err.println("Null pointer exception at address: 0x" - + Integer.toHexString(addr)); - throw e; - } - } - - /** - * Perform a 16bit load where the sign extended result fills the return value - * - * @param addr - * the address of the value to load - * @return the sign extended result - */ - public int loadSigned16(int addr) { - return (loadSigned8(addr + 1) << 8) | loadUnsigned8(addr); - } - - /** - * Perform a 16bit load where the zero extended result fills the return value - * - * @param addr - * the address of the value to load - * @return the zero extended result - */ - public int loadUnsigned16(int addr) { - return (loadUnsigned8(addr + 1) << 8) | loadUnsigned8(addr); - } - - /** - * Perform a 32bit load - * - * @param addr - * the address of the value to load - * @return the result - */ - public int load32(int addr) { - try { - return (loadSigned8(addr + 3) << 24) | (loadUnsigned8(addr + 2) << 16) - | (loadUnsigned8(addr + 1) << 8) | loadUnsigned8(addr); - } catch (Exception e) { - throw new SegmentationFault(addr); - } - } - - /** - * Perform a 8bit load from memory that must be executable - * - * @param addr - * the address of the value to load - * @return the result - */ - public int loadInstruction8(int addr) { - if (DBT_Options.debugMemory) - System.err.println("LoadI8 address: 0x" + Integer.toHexString(addr) - + " val: " + executableMemory[getPTE(addr)][getOffset(addr)]); - return executableMemory[getPTE(addr)][getOffset(addr)] & 0xFF; - } - - /** - * Perform a 32bit load from memory that must be executable - * - * @param addr - * the address of the value to load - * @return the result - */ - public int loadInstruction32(int addr) { - return (loadInstruction8(addr + 3) << 24) - | (loadInstruction8(addr + 2) << 16) - | (loadInstruction8(addr + 1) << 8) | loadInstruction8(addr); - } - - /** - * Perform a byte store - * - * @param value - * the value to store - * @param addr - * the address of where to store - */ - public final void store8(int addr, int value) { - if (DBT_Options.debugMemory) - System.err.println("Store8 address: 0x" + Integer.toHexString(addr) - + " val: 0x" + Integer.toHexString(value & 0xFF)); - writableMemory[getPTE(addr)][getOffset(addr)] = (byte) value; - } - - /** - * Perform a 16bit store - * - * @param value - * the value to store - * @param addr - * the address of where to store - */ - public void store16(int addr, int value) { - store8(addr + 1, value >> 8); - store8(addr, value); - } - - /** - * Perform a 32bit store - * - * @param value - * the value to store - * @param addr - * the address of where to store - */ - public void store32(int addr, int value) { - try { - store8(addr + 3, value >> 24); - store8(addr + 2, value >> 16); - store8(addr + 1, value >> 8); - store8(addr, value); - } catch (Exception e) { - throw new SegmentationFault(addr); - } - } - - @Override - public void changeProtection(int address, int len, boolean newRead, boolean newWrite, boolean newExec) { - - while (len > 0) { - int pte = getPTE(address); - byte[] page = getPage(pte); - - if (page == null) - throw new SegmentationFault(address); - - readableMemory[pte] = newRead ? page : null; - writableMemory[pte] = newWrite ? page : null; - executableMemory[pte] = newExec ? page : null; - - address += PAGE_SIZE; - len -= PAGE_SIZE; - } - } - - @Override - public int loadInstruction16(int addr) { - return (loadInstruction8(addr + 1) << 8) | loadInstruction8(addr); - } -} Modified: src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java 2007-08-20 14:12:59 UTC (rev 168) @@ -26,7 +26,7 @@ * .........00 |'H'|'e'|'l'|'l'| * </pre> */ -final public class IntAddressedByteSwapMemory extends IntAddressedMemory { +final public class IntAddressedByteSwapMemory extends IntAddressedLittleEndianMemory { /** * Constructor - used when this is the instatiated class */ Copied: src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java (from rev 164, src/org/binarytranslator/generic/memory/IntAddressedMemory.java) =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java (rev 0) +++ src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java 2007-08-20 14:12:59 UTC (rev 168) @@ -0,0 +1,673 @@ +/* + * This file is part of binarytranslator.org. The binarytranslator.org + * project is distributed under the Common Public License (CPL). + * A copy of the license is included in the distribution, and is also + * available at http://www.opensource.org/licenses/cpl1.0.php + * + * (C) Copyright Ian Rogers, The University of Manchester 2003-2006 + */ +package org.binarytranslator.generic.memory; + +import java.io.RandomAccessFile; + +import org.binarytranslator.DBT; +import org.binarytranslator.DBT_Options; +import org.binarytranslator.generic.fault.SegmentationFault; +import org.jikesrvm.VM_Configuration; +import org.vmmagic.pragma.Inline; + +/** + * IntAddressedMemory: + * + * Memory is arrays of ints, no endian conversion is performed. + * + * The string helloworld following by the int of 0xcafebabe appear as: + * + * <pre> + * Byte Address + * Int Address | 0 | 1 | 2 | 3 | + * ----------------------------- + * .........0c | be| ba| fe| ca| + * .........08 |'l'|'d'| \n| \0| + * .........04 |'o'|'W'|'o'|'r'| + * .........00 |'H'|'e'|'l'|'l'| + * </pre> + */ +public class IntAddressedLittleEndianMemory extends CallBasedMemory { + /** + * The size of pages + */ + protected static final int PAGE_SIZE = 4096; + + /** + * Bits in offset + */ + protected static final int OFFSET_BITS = 12; + + /** + * The number of pages + */ + protected static final int NUM_PAGES = 0x100000; + + /** + * The maximum amount of RAM available + */ + protected static final long MAX_RAM = (long) PAGE_SIZE * (long) NUM_PAGES; + + /** + * The memory backing store + */ + private int readableMemory[][]; + + private int writableMemory[][]; + + private int executableMemory[][]; + + /** + * Constructor - used when this is the instatiated class + */ + public IntAddressedLittleEndianMemory() { + this(null); + } + + /** + * Constructor - used when deriving a class + * + * @param classType + * the type of the over-riding class + */ + protected IntAddressedLittleEndianMemory(Class classType) { + super(classType != null ? classType : IntAddressedLittleEndianMemory.class); + readableMemory = new int[NUM_PAGES][]; + writableMemory = new int[NUM_PAGES][]; + executableMemory = new int[NUM_PAGES][]; + } + + /** + * Return the offset part of the address + */ + @Inline + protected int getOffset(int address) { + return (address & (PAGE_SIZE - 1)) >>> 2; + } + + /** + * Return the page table entry part of the address + */ + @Inline + private static final int getPTE(int address) { + return address >>> OFFSET_BITS; + } + + /** + * Is the given address mapped into memory? + * @param addr to check + * @return true => memory is mapped + */ + public boolean isMapped(int addr) { + return getPage(getPTE(addr)) != null; + } + + /** + * @return the size of a page + */ + public int getPageSize() { + return PAGE_SIZE; + } + + /** + * Is the given address aligned on a page boundary? + * + * @param addr + * the address to check + * @return whether the address is aligned + */ + public boolean isPageAligned(int addr) { + return (addr % PAGE_SIZE) == 0; + } + + /** + * Make the given address page aligned to the page beneath it + * + * @param addr + * the address to truncate + * @return the truncated address + */ + public int truncateToPage(int addr) { + return (addr >> OFFSET_BITS) << OFFSET_BITS; + } + + /** + * Make the given address page aligned to the page above it + * + * @param addr + * the address to truncate + * @return the truncated address + */ + public int truncateToNextPage(int addr) { + return ((addr + PAGE_SIZE - 1) >> OFFSET_BITS) << OFFSET_BITS; + } + + /** + * Find free consecutive pages + * + * @param pages + * the number of pages required + * @return the address found + */ + private final int findFreePages(int pages) { + starting_page_search: for (int i = 0; i < NUM_PAGES; i++) { + if (getPage(i) == null) { + int start = i; + int end = i + pages; + for (; i <= end; i++) { + if (getPage(i) != null) { + continue starting_page_search; + } + } + return start << OFFSET_BITS; + } + } + throw new Error( + "No mappable consecutive pages found for an anonymous map of size" + + (pages * PAGE_SIZE)); + } + + /** + * 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 + */ + public int map(int addr, int len, boolean read, boolean write, boolean exec) + throws MemoryMapException { + // Check that the address is page aligned + if ((addr % PAGE_SIZE) != 0) { + // if it is not, truncate the address down to the next page boundary and + // start mapping from there + int validPageCount = addr / PAGE_SIZE; + int oldStartAddress = addr; + addr = validPageCount * PAGE_SIZE; + + if (DBT.VerifyAssertions) + DBT._assert(oldStartAddress > addr); + + // we have to map more more memory now to reach the same end address + len += (oldStartAddress - addr); + } + + // Calculate number of pages + int num_pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + // Create memory + int pages[][] = new int[num_pages][PAGE_SIZE / 4]; + // Find address if not specified + if (addr == 0) { + addr = findFreePages(num_pages); + } + if (DBT_Options.debugRuntime) { + System.out.println("Anonymous mapping: addr=0x" + + Integer.toHexString(addr) + " len=" + len + (read ? " r" : " -") + + (write ? "w" : "-") + (exec ? "x" : "-")); + } + // Get page table entry + int pte = getPTE(addr); + for (int i = 0; i < num_pages; i++) { + // Check pages aren't already allocated + if (getPage(pte + i) != null) { + throw new Error("Memory map of already mapped location addr=0x" + + Integer.toHexString(addr) + " len=" + len); + } + + readableMemory[pte+i] = read ? pages[i] : null; + writableMemory[pte+i] = write ? pages[i] : null; + executableMemory[pte+i] = exec ? pages[i] : null; + } + return addr; + } + + /** + * Returns the page currently mapped at the given page table entry. + * + * @param pte + * The page table entry, for which a page is to be retrieved. + * @return + * The page mapped at the given page table entry or null, if no page is currently mapped + * to that entry. + */ + private int[] getPage(int pte) { + + if (readableMemory[pte] != null) + return readableMemory[pte]; + + if (writableMemory[pte] != null) + return writableMemory[pte]; + + if (executableMemory[pte] != null) + return executableMemory[pte]; + + return null; + } + + @Override + public void changeProtection(int address, int len, boolean newRead, boolean newWrite, boolean newExec) { + + while (len > 0) { + int pte = getPTE(address); + int[] page = getPage(pte); + + if (page == null) + throw new SegmentationFault(address); + + readableMemory[pte] = newRead ? page : null; + writableMemory[pte] = newWrite ? page : null; + executableMemory[pte] = newExec ? page : null; + + address += PAGE_SIZE; + len -= PAGE_SIZE; + } + } + + /** + * Read an int from RandomAccessFile ensuring that a byte swap isn't performed + * + * @param file + * file to read from + * @return native endian read int + */ + protected int readInt(RandomAccessFile file) throws java.io.IOException { + if (VM_Configuration.BuildForPowerPC) { + return file.readInt(); // NB this will always read in big-endian format + } else { + return file.readUnsignedByte() | (file.readUnsignedByte() << 8) + | (file.readUnsignedByte() << 16) | (file.readByte() << 24); + } + } + + /** + * Map a page of memory from file + * + * @param file + * the file map in from + * @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 final int map(RandomAccessFile file, long offset, int addr, int len, + boolean read, boolean write, boolean exec) throws MemoryMapException { + // Check address is page aligned + if ((addr % PAGE_SIZE) != 0) { + MemoryMapException.unalignedAddress(addr); + } + // Check file offset is page aligned + /*if ((offset % PAGE_SIZE) != 0) { + MemoryMapException.unalignedFileOffset(offset); + }*/ + + if (DBT_Options.debugRuntime) { + System.out.println("Mapping file " + file + " offset=" + offset + + " addr=0x" + Integer.toHexString(addr) + " len=" + len + + (read ? " r" : " -") + (write ? "w" : "-") + (exec ? "x" : "-")); + } + addr = map(addr, len, read, write, exec); + + try { + file.seek(offset); + for (int i = 0; i < len; i += 4) { + + int[] page = getPage(getPTE(addr + i)); + page[getOffset(addr + i)] = readInt(file); + } + + return addr; + + } + catch (java.io.IOException e) { + throw new Error(e); + } + } + + /** + * Unmap a page of memory + * + * @param addr + * the address to unmap + * @param len + * the amount of memory to unmap + */ + public final void unmap(int addr, int len) { + for (int i = 0; i < len; i += PAGE_SIZE) { + + int pte = getPTE(addr + i); + + if (getPage(pte) != null) { + readableMemory[pte] = null; + writableMemory[pte] = null; + executableMemory[pte] = null; + } + else { + throw new Error("Unmapping memory that's not mapped addr=0x" + + Integer.toHexString(addr) + " len=" + len); + } + } + } + + /** + * Perform a 32bit load where addr is word aligned + * + * @param addr + * the address of the value to load + * @return the result + */ + protected final int loadWordAligned32(int addr) { + return readableMemory[getPTE(addr)][getOffset(addr)]; + } + + /** + * Perform a 32bit load where addr is word aligned and executable + * + * @param addr + * the address of the value to load + * @return the result + */ + protected final int loadWordAlignedInstruction32(int addr) { + return executableMemory[getPTE(addr)][getOffset(addr)]; + } + + /** + * Perform a byte load where the sign extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the sign extended result + */ + public int loadSigned8(int addr) { + return (loadWordAligned32(addr) << ((3 - (addr & 0x3)) << 3)) >> 24; + // switch(addr & 3) { + // default: + // return (loadWordAligned32(addr) << 24) >> 24; + // case 1: + // return (loadWordAligned32(addr) << 16) >> 24; + // case 2: + // return (loadWordAligned32(addr) << 8) >> 24; + // case 3: + // return loadWordAligned32(addr) >> 24; + // } + } + + /** + * Perform a byte load where the zero extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the zero extended result + */ + public int loadUnsigned8(int addr) { + return (loadWordAligned32(addr) >> ((addr & 3) << 3)) & 0xFF; + // switch(addr & 3) { + // default: + // return loadWordAligned32(addr) & 0xFF; + // case 1: + // return (loadWordAligned32(addr) >> 8) & 0xFF; + // case 2: + // return (loadWordAligned32(addr) >> 16) & 0xFF; + // case 3: + // return loadWordAligned32(addr) >>> 24; + // } + } + + /** + * Perform a 16bit load where the sign extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the sign extended result + */ + public int loadSigned16(int addr) { + switch (addr & 3) { + default: + return (loadWordAligned32(addr) << 16) >> 16; + case 1: + return (loadWordAligned32(addr) << 8) >> 16; + case 2: + return loadWordAligned32(addr) >> 16; + case 3: // 2 loads to deal with spanning int problem + return (loadWordAligned32(addr) >>> 24) + | ((loadWordAligned32(addr + 1) << 24) >> 16); + } + } + + /** + * Perform a 16bit load where the zero extended result fills the return value + * + * @param addr + * the address of the value to load + * @return the zero extended result + */ + public int loadUnsigned16(int addr) { + switch (addr & 3) { + default: + return loadWordAligned32(addr) & 0xFFFF; + case 1: + return (loadWordAligned32(addr) >> 8) & 0xFFFF; + case 2: + return (loadWordAligned32(addr) >> 16) & 0xFFFF; + case 3: // 2 loads to deal with spanning int problem + return (loadWordAligned32(addr) >>> 24) + | ((loadWordAligned32(addr + 1) << 8) & 0xFF00); + } + } + + /** + * Perform a 32bit load + * + * @param addr + * the address of the value to load + * @return the result + */ + public int load32(int addr) { + switch (addr & 3) { + default: + return loadWordAligned32(addr); + case 1: // 2 loads to deal with spanning int problem + return ((loadWordAligned32(addr + 3) & 0xFF) << 24) + | (loadWordAligned32(addr) >>> 8); + case 2: // 2 loads to deal with spanning int problem + return ((loadWordAligned32(addr + 2) & 0xFFFF) << 16) + | (loadWordAligned32(addr) >>> 16); + case 3: // 2 loads to deal with spanning int problem + return ((loadWordAligned32(addr + 1) & 0xFFFFFF) << 8) + | (loadWordAligned32(addr) >>> 24); + } + } + + /** + * Perform a 8bit load from memory that must be executable + * + * @param addr + * the address of the value to load + * @return the result + */ + public int loadInstruction8(int addr) { + switch (addr & 3) { + default: + return loadWordAlignedInstruction32(addr) & 0xFF; + case 1: + return (loadWordAlignedInstruction32(addr) >> 8) & 0xFF; + case 2: + return (loadWordAlignedInstruction32(addr) >> 16) & 0xFF; + case 3: + return loadWordAlignedInstruction32(addr) >>> 24; + } + } + + @Override + public int loadInstruction16(int addr) { + switch (addr & 3) { + default: + return loadWordAlignedInstruction32(addr) >>> 16; + case 1: + return (loadWordAlignedInstruction32(addr) >> 8) & 0xFFFF; + case 2: + return loadWordAlignedInstruction32(addr) & 0xFFFF; + case 3: // 2 loads to deal with spanning int problem + return (loadWordAlignedInstruction32(addr) >>> 24) + | ((loadWordAlignedInstruction32(addr + 1) << 8) & 0xFF00); + } + } + + /** + * Perform a 32bit load from memory that must be executable + * + * @param addr + * the address of the value to load + * @return the result + */ + public int loadInstruction32(int addr) { + switch (addr & 3) { + default: + return loadWordAlignedInstruction32(addr); + case 1: // 2 loads to deal with spanning int problem + return ((loadWordAlignedInstruction32(addr + 3) & 0xFF) << 24) + | (loadWordAlignedInstruction32(addr) >>> 8); + case 2: // 2 loads to deal with spanning int problem + return ((loadWordAlignedInstruction32(addr + 2) & 0xFFFF) << 16) + | (loadWordAlignedInstruction32(addr) >>> 16); + case 3: // 2 loads to deal with spanning int problem + return ((loadWordAlignedInstruction32(addr + 1) & 0xFFFFFF) << 8) + | (loadWordAlignedInstruction32(addr) >>> 24); + } + } + + /** + * Perform a 32bit aligned store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + final protected void storeWordAligned32(int addr, int value) { + writableMemory[getPTE(addr)][getOffset(addr)] = value; + } + + /** + * Perform a 32bit load, from writable memory, where addr is word aligned + * + * @param addr + * the address of the value to load + * @return the result + */ + final protected int loadWordAligned32forWrite(int addr) { + return writableMemory[getPTE(addr)][getOffset(addr)]; + } + + /** + * Perform a byte store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + public void store8(int addr, int value) { + switch (addr & 3) { + default: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFFFF00) + | (value & 0xFF)); + break; + case 1: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFF00FF) + | ((value & 0xFF) << 8)); + break; + case 2: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFF00FFFF) + | ((value & 0xFF) << 16)); + break; + case 3: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0x00FFFFFF) + | (value << 24)); + break; + } + } + + /** + * Perform a 16bit store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + public void store16(int addr, int value) { + switch (addr & 3) { + default: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFF0000) + | (value & 0xFFFF)); + break; + case 1: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFF0000FF) + | ((value & 0xFFFF) << 8)); + break; + case 2: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0x0000FFFF) + | (value << 16)); + break; + case 3: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0x00FFFFFF) + | (value << 24)); + storeWordAligned32(addr + 1, + (loadWordAligned32forWrite(addr + 1) & 0xFFFFFF00) + | ((value >> 8) & 0xFF)); + break; + } + } + + /** + * Perform a 32bit store + * + * @param value + * the value to store + * @param addr + * the address of where to store + */ + public void store32(int addr, int value) { + switch (addr & 3) { + default: + storeWordAligned32(addr, value); + break; + case 1: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0x000000FF) + | (value << 8)); + storeWordAligned32(addr + 3, + (loadWordAligned32forWrite(addr + 3) & 0xFFFFFF00) | (value >>> 24)); + break; + case 2: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0x0000FFFF) + | (value << 16)); + storeWordAligned32(addr + 2, + (loadWordAligned32forWrite(addr + 2) & 0xFFFF0000) | (value >>> 16)); + break; + case 3: + storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0x00FFFFFF) + | (value << 24)); + storeWordAligned32(addr + 1, + (loadWordAligned32forWrite(addr + 1) & 0xFF000000) | (value >>> 8)); + break; + } + } +} Deleted: src/org/binarytranslator/generic/memory/IntAddressedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedMemory.java 2007-08-15 16:24:05 UTC (rev 167) +++ src/org/binarytranslator/generic/memory/IntAddressedMemory.java 2007-08-20 14:12:59 UTC (rev 168) @@ -1,673 +0,0 @@ -/* - * This file is part of binarytranslator.org. The binarytranslator.org - * project is distributed under the Common Public License (CPL). - * A copy of the license is included in the distribution, and is also - * available at http://www.opensource.org/licenses/cpl1.0.php - * - * (C) Copyright Ian Rogers, The University of Manchester 2003-2006 - */ -package org.bi... [truncated message content] |