|
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] |