|
From: <mic...@us...> - 2007-08-27 15:14:37
|
Revision: 174
http://pearcolator.svn.sourceforge.net/pearcolator/?rev=174&view=rev
Author: michael_baer
Date: 2007-08-27 08:14:38 -0700 (Mon, 27 Aug 2007)
Log Message:
-----------
- Added support for Big and Little Endian Applications on ARM
- Added memory implementations for big endian
Modified Paths:
--------------
rvmroot.patch
src/org/binarytranslator/arch/arm/decoder/ARM_Options.java
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/arm/os/process/linux/ARM_LinuxProcessSpace.java
src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java
src/org/binarytranslator/generic/os/loader/elf/ELF_File.java
src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java
Added Paths:
-----------
src/org/binarytranslator/generic/memory/ByteAddressedBigEndianMemory.java
src/org/binarytranslator/generic/memory/IntAddressedBigEndianMemory.java
Modified: rvmroot.patch
===================================================================
--- rvmroot.patch 2007-08-24 17:51:46 UTC (rev 173)
+++ rvmroot.patch 2007-08-27 15:14:38 UTC (rev 174)
@@ -146,7 +146,7 @@
[Lorg/jikesrvm/compilers/opt/OPT_Simplifier$DefUseEffect;
[Lorg/jikesrvm/compilers/opt/ir/OPT_Operator;
+[Lorg/binarytranslator/generic/os/loader/elf/ELF_File$ELF_Identity$AddressSize;
-+[Lorg/binarytranslator/generic/os/loader/elf/ELF_File$ELF_Identity$ByteOrder;
++[Lorg/binarytranslator/generic/os/loader/elf/ELF_File$ByteOrder;
+[Lorg/binarytranslator/generic/os/loader/elf/ELF_File$Header$ObjectFileType;
+[Lorg/binarytranslator/generic/os/loader/elf/ELF_File$SegmentRange;
+[Lorg/binarytranslator/vmInterface/DummyDynamicCodeRunner;
@@ -157,4 +157,6 @@
+[Lorg/binarytranslator/arch/arm/decoder/ARM_Instructions$Instruction$Condition;
+[Lorg/binarytranslator/arch/arm/decoder/ARM_Instructions$DataProcessing$Opcode;
+[Lorg/binarytranslator/arch/arm/decoder/ARM_Instructions$OperandWrapper$ShiftType;
++[Lorg/binarytranslator/arch/arm/decoder/ARM_Laziness$Operation;
++[Lorg/binarytranslator/arch/arm/decoder/ARM_Laziness$Flag;
\ No newline at end of file
Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Options.java
===================================================================
--- src/org/binarytranslator/arch/arm/decoder/ARM_Options.java 2007-08-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/arch/arm/decoder/ARM_Options.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -1,5 +1,7 @@
package org.binarytranslator.arch.arm.decoder;
+import org.binarytranslator.generic.os.loader.elf.ELF_File.ByteOrder;
+
public class ARM_Options {
public enum FlagBehaviour {
@@ -39,6 +41,9 @@
/** Sets the memory model that ARM shall use. */
public static MemoryModel memoryModel = MemoryModel.IntAddressed;
+ /** Override the byte order read from the ELF file. */
+ public static ByteOrder enforcedByteOrder = null;
+
public static void parseOption(String key, String value) {
if (key.equalsIgnoreCase("optimizeByProfiling")) {
optimizeTranslationByProfiling = Boolean.parseBoolean(value);
@@ -50,7 +55,9 @@
memoryModel = ARM_Options.MemoryModel.valueOf(value);
} else if (key.equalsIgnoreCase("optimizedFlags")) {
useOptimizedFlags = Boolean.parseBoolean(value);
- }
+ } else if (key.equalsIgnoreCase("byteOrder")) {
+ enforcedByteOrder = ByteOrder.valueOf(value);
+ }
else {
throw new Error("Unknown ARM option: " + key);
}
Modified: src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java
===================================================================
--- src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-08-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -10,9 +10,13 @@
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.ByteAddressedBigEndianMemory;
import org.binarytranslator.generic.memory.ByteAddressedLittleEndianMemory;
+import org.binarytranslator.generic.memory.IntAddressedBigEndianMemory;
import org.binarytranslator.generic.memory.IntAddressedLittleEndianMemory;
import org.binarytranslator.generic.os.loader.Loader;
+import org.binarytranslator.generic.os.loader.elf.ELF_Loader;
+import org.binarytranslator.generic.os.loader.elf.ELF_File.ByteOrder;
import org.binarytranslator.generic.os.process.ProcessSpace;
import org.binarytranslator.vmInterface.DBT_Trace;
import org.jikesrvm.compilers.opt.ir.OPT_GenerationContext;
@@ -20,11 +24,9 @@
public abstract class ARM_ProcessSpace extends ProcessSpace {
-
/** Registers used by this process */
public ARM_Registers registers;
-
/**
* Debug information
*
@@ -38,16 +40,44 @@
}
}
- protected ARM_ProcessSpace() {
+ protected ARM_ProcessSpace(ByteOrder byteOrder) {
registers = new ARM_Registers();
switch (ARM_Options.memoryModel) {
case ByteAddressed:
- memory = new ByteAddressedLittleEndianMemory();
+
+ switch (byteOrder)
+ {
+ case LittleEndian:
+ memory = new ByteAddressedLittleEndianMemory();
+ break;
+
+ case BigEndian:
+ memory = new ByteAddressedBigEndianMemory();
+ break;
+
+ default:
+ throw new RuntimeException("Unexpected byte order: " + byteOrder);
+ }
+
break;
case IntAddressed:
- memory = new IntAddressedLittleEndianMemory();
+
+ switch (byteOrder)
+ {
+ case LittleEndian:
+ memory = new IntAddressedLittleEndianMemory();
+ break;
+
+ case BigEndian:
+ memory = new IntAddressedBigEndianMemory();
+ break;
+
+ default:
+ throw new RuntimeException("Unexpected byte order: " + byteOrder);
+ }
+
break;
default:
@@ -79,12 +109,30 @@
public static ProcessSpace createProcessSpaceFromBinary(Loader loader)
throws IOException {
Loader.ABI abi = loader.getABI();
+
+ //determine the byte order for the memory implementation
+ ByteOrder byteOrder = ARM_Options.enforcedByteOrder;
+
+ if (byteOrder == null) {
+ if (loader instanceof ELF_Loader) {
+ //read the byte order from the elf file
+ byteOrder = ((ELF_Loader)loader).getFile().getByteOrder();
+ }
+ else {
+ byteOrder = ByteOrder.LittleEndian;
+ System.err.println("WARNING: Unable to deduce byte order from binary file. Defaulting to " + byteOrder);
+ }
+ }
+ else {
+ System.err.println("WARNING: Overriding byte order set by ELF file to " + byteOrder);
+ }
+
if (abi == Loader.ABI.ARM) {
report("Creating ARM Linux ABI Process space");
- return new ARM_LinuxProcessSpace();
+ return new ARM_LinuxProcessSpace(byteOrder);
} else {
report("Creating ARM image process space.");
- return new ARM_ImageProcessSpace();
+ return new ARM_ImageProcessSpace(byteOrder);
}
}
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-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -10,6 +10,7 @@
import org.binarytranslator.generic.execution.GdbController.GdbTarget;
import org.binarytranslator.generic.fault.InsufficientMemoryException;
import org.binarytranslator.generic.os.loader.Loader;
+import org.binarytranslator.generic.os.loader.elf.ELF_File.ByteOrder;
public class ARM_ImageProcessSpace extends ARM_ProcessSpace {
@@ -17,11 +18,8 @@
private final int STACK_SIZE = 4096 * 1000;
private final int HEAP_SIZE = 4096 * 1000;
- public ARM_ImageProcessSpace() {
- super();
-
- //make sure that pages of memory are automatically mapped in as they are requested.
- //memory = new AutoMappingMemory(memory);
+ public ARM_ImageProcessSpace(ByteOrder byteOrder) {
+ super(byteOrder);
}
private int allocateFreeMemoryArea(int stackSize) throws InsufficientMemoryException
Modified: src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java
===================================================================
--- src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-08-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -10,6 +10,7 @@
import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls;
import org.binarytranslator.generic.os.loader.Loader;
import org.binarytranslator.generic.os.loader.elf.ELF_Loader;
+import org.binarytranslator.generic.os.loader.elf.ELF_File.ByteOrder;
public class ARM_LinuxProcessSpace extends ARM_ProcessSpace {
@@ -31,7 +32,9 @@
*/
private int[] auxVector;
- public ARM_LinuxProcessSpace() {
+ public ARM_LinuxProcessSpace(ByteOrder byteOrder) {
+ super(byteOrder);
+
sysCallGenerator = new Legacy(this);
sysCalls = new ARM_LinuxSystemCalls(this, sysCallGenerator);
}
Added: src/org/binarytranslator/generic/memory/ByteAddressedBigEndianMemory.java
===================================================================
--- src/org/binarytranslator/generic/memory/ByteAddressedBigEndianMemory.java (rev 0)
+++ src/org/binarytranslator/generic/memory/ByteAddressedBigEndianMemory.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -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 ByteAddressedBigEndianMemory 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 ByteAddressedBigEndianMemory() {
+ this(null);
+ }
+
+ /**
+ * Constructor - used when deriving a class
+ *
+ * @param classType
+ * the name of the over-riding class
+ */
+ protected ByteAddressedBigEndianMemory(Class classType) {
+ super(classType != null ? classType : ByteAddressedBigEndianMemory.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) << 8) | loadUnsigned8(addr + 1);
+ }
+
+ /**
+ * 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) << 8) | loadUnsigned8(addr + 1);
+ }
+
+ /**
+ * 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) << 24) | (loadUnsigned8(addr + 1) << 16)
+ | (loadUnsigned8(addr + 2) << 8) | loadUnsigned8(addr + 3);
+ } 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) << 24)
+ | (loadInstruction8(addr + 1) << 16)
+ | (loadInstruction8(addr + 2) << 8) | loadInstruction8(addr + 3);
+ }
+
+ /**
+ * 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, value >> 8);
+ store8(addr + 1, 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, value >> 24);
+ store8(addr + 1, value >> 16);
+ store8(addr + 2, value >> 8);
+ store8(addr + 3, 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) << 8) | loadInstruction8(addr + 1);
+ }
+}
Added: src/org/binarytranslator/generic/memory/IntAddressedBigEndianMemory.java
===================================================================
--- src/org/binarytranslator/generic/memory/IntAddressedBigEndianMemory.java (rev 0)
+++ src/org/binarytranslator/generic/memory/IntAddressedBigEndianMemory.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -0,0 +1,669 @@
+/*
+ * 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.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 | ca| fe| ba| be|
+ * .........08 |'l'|'d'| \n| \0|
+ * .........04 |'o'|'W'|'o'|'r'|
+ * .........00 |'H'|'e'|'l'|'l'|
+ * </pre>
+ */
+public class IntAddressedBigEndianMemory 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 IntAddressedBigEndianMemory() {
+ this(null);
+ }
+
+ /**
+ * Constructor - used when deriving a class
+ *
+ * @param classType
+ * the type of the over-riding class
+ */
+ protected IntAddressedBigEndianMemory(Class classType) {
+ super(classType != null ? classType : IntAddressedBigEndianMemory.class);
+ readableMemory = new int[NUM_PAGES][];
+ writableMemory = new int[NUM_PAGES][];
+ executableMemory = new int[NUM_PAGES][];
+ }
+
+ /**
+ * Return the offset part of the address
+ */
+ @Inline
+ private static final 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 {
+
+ return file.readByte() << 24 | (file.readUnsignedByte() << 16)
+ | (file.readUnsignedByte() << 8) | (file.readUnsignedByte());
+ }
+
+ /**
+ * 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) << ((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) >> ((3 - (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;
+ case 1:
+ return (loadWordAligned32(addr) << 8) >> 16;
+ case 2:
+ return (loadWordAligned32(addr) << 16) >> 16;
+ case 3: // 2 loads to deal with spanning int problem
+ return ((loadWordAligned32(addr) << 24) >> 16)
+ | (loadWordAligned32(addr + 1) >>> 24);
+ }
+ }
+
+ /**
+ * 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) >>> 16;
+ case 1:
+ return (loadWordAligned32(addr) >> 8) & 0xFFFF;
+ case 2:
+ return loadWordAligned32(addr) & 0xFFFF;
+ case 3: // 2 loads to deal with spanning int problem
+ return ((loadWordAligned32(addr) << 8) & 0xFF00)
+ | loadWordAligned32(addr + 1) >>> 24;
+ }
+ }
+
+ /**
+ * 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) >>> 24)
+ | (loadWordAligned32(addr) << 8);
+ case 2: // 2 loads to deal with spanning int problem
+ return (loadWordAligned32(addr + 2) >>> 16)
+ | (loadWordAligned32(addr) << 16);
+ case 3: // 2 loads to deal with spanning int problem
+ return (loadWordAligned32(addr + 1) >>> 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) >>> 24;
+ case 1:
+ return (loadWordAlignedInstruction32(addr) >> 16) & 0xFF;
+ case 2:
+ return (loadWordAlignedInstruction32(addr) >> 8) & 0xFF;
+ case 3:
+ return loadWordAlignedInstruction32(addr) & 0xFF;
+ }
+ }
+
+ @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) << 8) & 0xFF00)
+ | (loadWordAlignedInstruction32(addr + 1) >>> 25);
+ }
+ }
+
+ /**
+ * 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) >>> 24)
+ | (loadWordAlignedInstruction32(addr) << 8);
+ case 2: // 2 loads to deal with spanning int problem
+ return (loadWordAlignedInstruction32(addr + 2) >>> 16)
+ | (loadWordAlignedInstruction32(addr) << 16);
+ case 3: // 2 loads to deal with spanning int problem
+ return (loadWordAlignedInstruction32(addr + 1) >>> 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) & 0x00FFFFFF)
+ | (value << 24));
+ break;
+ case 1:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFF00FFFF)
+ | ((value & 0xFF) << 16));
+ break;
+ case 2:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFF00FF)
+ | ((value & 0xFF) << 8));
+ break;
+ case 3:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFFFF00)
+ | (value & 0xFF));
+ 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) & 0x0000FFFF)
+ | (value << 16));
+ break;
+ case 1:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFF0000FF)
+ | ((value & 0xFFFF) << 8));
+ break;
+ case 2:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFF0000)
+ | (value & 0xFFFF));
+ break;
+ case 3:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFFFF00)
+ | ((value >> 8) & 0xFF));
+ storeWordAligned32(addr + 1,
+ (loadWordAligned32forWrite(addr + 1) & 0x00FFFFFF)
+ | (value << 24));
+ 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) & 0xFF000000)
+ | (value >>> 8));
+ storeWordAligned32(addr + 3,
+ (loadWordAligned32forWrite(addr + 3) & 0x00FFFFFF) | (value << 24));
+ break;
+ case 2:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFF0000)
+ | (value >>> 16));
+ storeWordAligned32(addr + 2,
+ (loadWordAligned32forWrite(addr + 2) & 0x0000FFFF) | (value << 16));
+ break;
+ case 3:
+ storeWordAligned32(addr, (loadWordAligned32forWrite(addr) & 0xFFFFFF00)
+ | (value >>> 24));
+ storeWordAligned32(addr + 1,
+ (loadWordAligned32forWrite(addr + 1) & 0x000000FF) | (value << 8));
+ break;
+ }
+ }
+}
Modified: src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java
===================================================================
--- src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java 2007-08-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/generic/memory/IntAddressedLittleEndianMemory.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -13,7 +13,6 @@
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;
/**
@@ -283,12 +282,8 @@
* @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);
- }
+ return file.readUnsignedByte() | (file.readUnsignedByte() << 8)
+ | (file.readUnsignedByte() << 16) | (file.readByte() << 24);
}
/**
Modified: src/org/binarytranslator/generic/os/loader/elf/ELF_File.java
===================================================================
--- src/org/binarytranslator/generic/os/loader/elf/ELF_File.java 2007-08-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/generic/os/loader/elf/ELF_File.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -22,7 +22,23 @@
import org.binarytranslator.generic.os.process.ProcessSpace;
public class ELF_File {
+
+ /** Represents accepted ELF byte orders. */
+ public enum ByteOrder implements IdentifiedEnum {
+ LittleEndian(1),
+ BigEndian(2);
+
+ private int identifier;
+
+ private ByteOrder(int identifier) {
+ this.identifier = identifier;
+ }
+ public int getIdentifier() {
+ return identifier;
+ }
+ }
+
/** Wrapper class used for reading the ELF file with the required endianness */
private BinaryReader reader;
@@ -31,6 +47,10 @@
/** Program segment headers */
private SegmentHeader segmentHeaders[];
+
+ public ByteOrder getByteOrder() {
+ return header.byteOrder;
+ }
/**
* Debug information
@@ -60,9 +80,9 @@
* @return
* An ELF_BinaryReader, that hides the details of the byte order.
*/
- public static BinaryReader create(ELF_Identity.ByteOrder byteOrder, RandomAccessFile file) {
+ public static BinaryReader create(ByteOrder byteOrder, RandomAccessFile file) {
- if (byteOrder == ELF_Identity.ByteOrder.BigEndian)
+ if (byteOrder == ByteOrder.BigEndian)
return new NonSwappingReader(file);
else
return new ByteSwappingReader(file);
@@ -296,22 +316,6 @@
}
}
- /** Represents accepted ELF byte orders. */
- private enum ByteOrder implements IdentifiedEnum {
- LittleEndian(1),
- BigEndian(2);
-
- private int identifier;
-
- private ByteOrder(int identifier) {
- this.identifier = identifier;
- }
-
- public int getIdentifier() {
- return identifier;
- }
- }
-
/* Symbolic names for the most widely used ABIs. This is not an enum, because the list isn't complete. */
private static final byte ELFOSABI_SYSTEMV = 0;
private static final byte ELFOSABI_HPUX = 1;
@@ -334,13 +338,13 @@
private static final byte ELF_MAGIC_VALUE[] = { 0x7f, 'E', 'L','F' };
/** Specifies the size of an address within this elf.*/
- private AddressSize addressSize;
+ AddressSize addressSize;
/** The byte order used by this elf.*/
- private ByteOrder byteOrder;
+ ByteOrder byteOrder;
/** The ABI that is used by this ELF.*/
- private byte abi;
+ byte abi;
/**
* Construct/read ELF identity
Modified: src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java
===================================================================
--- src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-08-24 17:51:46 UTC (rev 173)
+++ src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-08-27 15:14:38 UTC (rev 174)
@@ -1,7 +1,6 @@
package org.binarytranslator.generic.os.loader.elf;
import java.io.IOException;
-
import org.binarytranslator.DBT_Options;
import org.binarytranslator.generic.os.loader.Loader;
import org.binarytranslator.generic.os.process.ProcessSpace;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|