incubator-kato-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccris...@apache.org
Subject svn commit: r754943 [1/3] - in /incubator/kato/trunk/import/org.apache.kato.common: ./ .settings/ src/ src/com/ src/com/ibm/ src/com/ibm/dtfj/ src/com/ibm/dtfj/addressspace/ src/com/ibm/dtfj/binaryreaders/ src/com/ibm/dtfj/corereaders/
Date Mon, 16 Mar 2009 16:41:41 GMT
Author: ccristal
Date: Mon Mar 16 16:41:40 2009
New Revision: 754943

URL: http://svn.apache.org/viewvc?rev=754943&view=rev
Log:
Initial code contribution from IBM.

Added:
    incubator/kato/trunk/import/org.apache.kato.common/
    incubator/kato/trunk/import/org.apache.kato.common/.classpath
    incubator/kato/trunk/import/org.apache.kato.common/.project
    incubator/kato/trunk/import/org.apache.kato.common/.settings/
    incubator/kato/trunk/import/org.apache.kato.common/.settings/org.eclipse.jdt.core.prefs
    incubator/kato/trunk/import/org.apache.kato.common/src/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/CommonAddressSpace.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/DumpReaderAddressSpace.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/IAbstractAddressSpace.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/LayeredAddressSpace.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/SimpleAddressSpace.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/ARReader.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/XCOFFReader.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Builder.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ClosingFileReader.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CoreReaderSupport.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CorruptCoreException.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DeprecatedCoreAPI.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Dump.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpException.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpFactory.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpReader.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/GenericThread.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ICoreFileReader.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/LittleEndianDumpReader.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryAccessException.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryRange.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NativeThreadContext.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NewAixDump.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NewElfDump.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/PageCache.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Register.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/StackFrame.java
    incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Symbol.java

Added: incubator/kato/trunk/import/org.apache.kato.common/.classpath
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/.classpath?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/.classpath (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/.classpath Mon Mar 16 16:41:40 2009
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: incubator/kato/trunk/import/org.apache.kato.common/.project
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/.project?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/.project (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/.project Mon Mar 16 16:41:40 2009
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.apache.kato.common</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: incubator/kato/trunk/import/org.apache.kato.common/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/.settings/org.eclipse.jdt.core.prefs?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/.settings/org.eclipse.jdt.core.prefs (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/.settings/org.eclipse.jdt.core.prefs Mon Mar 16 16:41:40 2009
@@ -0,0 +1,12 @@
+#Tue Jan 27 20:53:45 GMT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/CommonAddressSpace.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/CommonAddressSpace.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/CommonAddressSpace.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/CommonAddressSpace.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.addressspace;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import com.ibm.dtfj.corereaders.MemoryAccessException;
+import com.ibm.dtfj.corereaders.MemoryRange;
+
+/**
+ * Contains the common functionality shared by the current address space implementations
+ */
+public abstract class CommonAddressSpace implements IAbstractAddressSpace {
+	private static final int BUFFER_MAX = 4096;
+	private static final int MEMORY_CHECK_THRESHOLD = 0x100000;
+	
+	private MemoryRange[] _translations;
+	private Integer _lastTranslationUsed = new Integer(0);
+	private boolean _isLittleEndian;
+	private boolean _is64Bit;
+	private int lastAsid;
+	private int _is64BitAsid[];
+	
+	protected CommonAddressSpace(MemoryRange[] translations, boolean isLittleEndian, boolean is64Bit)
+	{
+		_translations = _sortRanges(translations);
+		_isLittleEndian = isLittleEndian;
+		_is64Bit = is64Bit;
+		set64Bitness();
+	}
+	
+	private static MemoryRange[] _sortRanges(MemoryRange[] ranges)
+	{
+		Arrays.sort(ranges, new Comparator(){
+			public int compare(Object arg0, Object arg1)
+			{
+				MemoryRange one = (MemoryRange)arg0;
+				MemoryRange two = (MemoryRange)arg1;
+				return compareAddress(one.getAsid(), one.getVirtualAddress(), two.getAsid(), two.getVirtualAddress()); 
+			}
+		});
+		return ranges;
+	}
+
+	/**
+	 * Walk through all the address ranges (presumed sorted by asid, address)
+	 * Add ASID to array if any address >= 0x100000000 i.e. 64-bit
+	 */
+	private void set64Bitness() {
+		// Promise of no 64-bit addresses
+		if (!_is64Bit) return;
+		int count = 0;
+		for (int i = 0; i < _translations.length; ++i) {
+			if (_translations[i].getVirtualAddress()+_translations[i].getSize() >= 0x100000000L) {
+				// Found 64-bit entry
+				int asid = _translations[i].getAsid();
+				
+				// Remember the ASID
+				int newa[] = new int[count+1];
+				for (int j = 0; j < count; ++j) {
+					newa[j] = _is64BitAsid[j];
+				}
+				newa[count] = asid;
+				_is64BitAsid = newa;
+				
+				++count;
+				
+				// Skip to the end of the ASID range
+				while (i < _translations.length && _translations[i].getAsid() == asid) ++i;
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getMemoryRanges()
+	 */
+	public Iterator getMemoryRanges()
+	{
+		return Arrays.asList(_translations).iterator();
+	}
+	
+	protected MemoryRange _residentRange(int asid, long address) throws MemoryAccessException
+	{
+		int range = findWhichMemoryRange(asid, address, _translations, _lastTranslationUsed, true);
+		
+		if (range >= 0) {
+			return _translations[range];
+		} else {
+			throw new MemoryAccessException(asid, address);
+		}
+	}
+	
+	/**
+	 * 
+	 * This searches memory ranges for an addr using a binary chop and returns an int indicating the memory range
+	 *  or -1 if address is not within any memory range...... 
+	 * @param asid TODO
+	 */
+	protected static int findWhichMemoryRange(int asid, long addr, MemoryRange[] ranges, Integer lastRange, boolean doLinearIfNotFound)
+	{
+		int retI=-1; //assume we won't find it
+		int last = lastRange.intValue();
+		int lastPlusOne = last+1;
+		
+		if ((last < ranges.length) && 
+			(ranges[last].contains(asid, addr)) && 
+			(ranges[last].isInCoreFile() || (!ranges[last].isInCoreFile() && ranges[last].getLibraryReader() != null))) { //TLB hit
+			retI = last;
+		} else if ((lastPlusOne < ranges.length) && 
+				   (ranges[lastPlusOne].contains(asid, addr)) && 
+				   (ranges[last].isInCoreFile() || (!ranges[last].isInCoreFile() && ranges[last].getLibraryReader() != null))) { //TLB hit
+			retI = lastPlusOne;
+		} else {
+			// TLB failed to do the search
+			
+			// Now effectively do a binary search find the right range....
+			// note: on some platforms we can have overlapping memory ranges!!
+			//   (ie. linux) so we always give back the first
+
+			int highpos = ranges.length-1;
+			int lowpos  = 0;
+			
+			while (lowpos <= highpos) {
+				int currentPos = lowpos + ((highpos-lowpos) >>> 1);
+				long mraStartAddr = ranges[currentPos].getVirtualAddress();
+				int mraAsid = ranges[currentPos].getAsid();
+
+				if (compareAddress(asid, addr, mraAsid, mraStartAddr) >= 0) {
+					if(compareAddress(asid, addr, mraAsid, mraStartAddr + ranges[currentPos].getSize()) < 0 && 
+					  (ranges[currentPos].isInCoreFile() || !ranges[currentPos].isInCoreFile() && ranges[currentPos].getLibraryReader() != null)) {
+						retI = currentPos;
+						break;
+					}
+					lowpos = currentPos + 1;
+				} else {
+					highpos = currentPos-1;
+				}					
+			}
+
+			// No match using binary chop, probably due to overlapping ranges => revert to a linear search
+			//  [stop at lowpos because this will either be currentPos or currentPos+1, when retI is -1]
+
+			if (-1 == retI && doLinearIfNotFound) {
+				for (int i = 0; i < lowpos; i++) {
+					long mraStartAddr = ranges[i].getVirtualAddress();
+					int mraAsid = ranges[i].getAsid();
+					if ((compareAddress(asid, addr, mraAsid, mraStartAddr) >= 0) && 
+						(compareAddress(asid, addr, mraAsid, mraStartAddr + ranges[i].getSize()) < 0) && 
+						(ranges[i].isInCoreFile() || (!ranges[i].isInCoreFile() && ranges[i].getLibraryReader() != null))) {
+						retI = i;
+						break;
+					}
+				}
+			}
+		}
+		if (-1 != retI) {
+			lastRange = new Integer(retI);
+		}
+		return retI;
+	}
+	
+	protected static int compareAddress(int lasid, long lhs, int rasid, long rhs) {
+		if (lasid < rasid) return -1;
+		if (lasid > rasid) return 1;
+		if (lhs == rhs) {
+			return 0;
+		} else if ((lhs >= 0 && rhs >= 0) || (lhs < 0 && rhs < 0)) {
+			return lhs < rhs ? -1 : 1;
+		} else {
+			return lhs < rhs ? 1 : -1;
+		}
+	}
+	
+	private boolean isMemoryAccessible(int asid, long address, int size)
+	{
+		// Scan the memory ranges to determine whether the memory from address
+		// to address+size is available to read. If so, return true else return false.
+		boolean rc = false;
+		long cumulativeSize = 0;
+		int startRange;
+		long hi;
+		long memhi;
+		
+		startRange = findWhichMemoryRange(asid, address, _translations, _lastTranslationUsed, true);
+		if (startRange == -1) {
+			// Range not found, so return false
+			return rc;
+		}
+		
+		// Now we have a start range, check if the size fits
+		hi = _translations[startRange].getVirtualAddress() + _translations[startRange].getSize();
+		memhi = address + size;
+		if (hi >= memhi) {
+			// found a fit, so return true
+			rc = true;
+		} else {
+			// size goes beyond the end of this range, so walk the contiguous
+			// ranges to find if it will still fit
+			cumulativeSize = hi - address;
+			
+			for (int i = startRange+1; i < _translations.length; i++) {
+				long rangeBaseAddress = _translations[i].getVirtualAddress();
+				long rangeSize = _translations[i].getSize();
+				long rangeTopAddress = rangeBaseAddress + rangeSize;
+				
+				if (rangeBaseAddress == hi) {
+					// contiguous range
+					cumulativeSize += rangeSize;
+					if (cumulativeSize >= size) {
+						// found a fit, so return true
+						rc = true;
+						break;
+					}
+				} else {
+					if (rangeBaseAddress < hi) {
+						if (rangeTopAddress < hi) {
+							// found a region contained within the range of the previous region
+							// so just ignore it
+							continue;
+						} else {
+							// found a region that overlaps with the previous region, so accumulate
+							// the difference in size.
+							cumulativeSize += rangeTopAddress - hi;
+							if (cumulativeSize >= size) {
+								// found a fit, so return true
+								rc = true;
+								break;
+							}
+						}
+					} else {
+						// non-contiguous, so abort
+						break;
+					}
+				}
+				// get the hi address of this range
+				hi = rangeTopAddress;
+			}
+		}
+		return rc;
+	}
+
+	public byte[] getMemoryBytes(long vaddr, int size)
+	{
+		return getMemoryBytes(lastAsid, vaddr, size);
+	}
+		
+	public byte[] getMemoryBytes(int asid, long vaddr, int size)
+	{
+		// This check is to help protect from OOM situations where a damaged core
+		// has given us a ridiculously large memory size to allocate. If size is 
+		// sufficiently large, then check if the memory really exists before trying
+		// to allocate it. Obviously, this does not stop OOM occurring, if the memory
+		// exists in the core file we may pass the test and still OOM on the allocation.
+		boolean getMem = true;
+		lastAsid = asid;
+		byte[] buffer = null;
+		
+		if (0 != vaddr) {
+			if (size > MEMORY_CHECK_THRESHOLD) {
+				getMem = isMemoryAccessible(0, vaddr, size);
+			}
+		
+			if (getMem) {
+				buffer = new byte[size];
+
+				try {
+					getBytesAt(asid, vaddr, buffer);
+				} catch (MemoryAccessException e) {
+					buffer = null;
+				}
+			}
+		}
+		return buffer;
+	}
+
+	public long findPattern(byte[] whatBytes, int alignment, long startFrom) {
+		int align = 0 == alignment ? 1 : alignment; // avoid divide-by-zero errors
+
+		// Ensure buffer size is a multiple of the alignment
+		int bufferMax = BUFFER_MAX;
+		if (bufferMax < align)
+			bufferMax = align;
+		else if (0 != bufferMax % align)
+			bufferMax -= bufferMax % align;
+
+		long location = -1;
+		Iterator ranges = getMemoryRanges();
+		
+		while ((-1 == location) && ranges.hasNext()) {
+			MemoryRange range = (MemoryRange) ranges.next();
+			// Skip over previous asids
+			if (range.getAsid() < lastAsid) continue;
+			// Reset start location for new asid
+			if (range.getAsid() > lastAsid) startFrom = 0;
+			location = findPatternInRange(whatBytes, align, startFrom, range, bufferMax);
+		}
+		// Reset asid as end of search
+		if (location == -1) lastAsid = 0;
+		return location;
+	}
+	
+	private static int match(byte[] whatBytes, int matchedSoFar, byte[] buffer, int index) {
+		int matched = matchedSoFar;
+		for (int i = index; i < buffer.length && matched < whatBytes.length; i++, matched++)
+			if (buffer[i] != whatBytes[matched])
+				return 0;
+		return matched;
+	}
+	
+	private long findPatternInRange(byte[] whatBytes, int alignment, long start, MemoryRange range, int bufferMax) {
+		if (range.getVirtualAddress() >= start || range.contains(start)) {
+			// Ensure the address is within the range and aligned
+			long addr = start;
+			if (addr < range.getVirtualAddress())
+				addr = range.getVirtualAddress();
+			if (0 != addr % alignment)
+				addr += alignment - (addr % alignment);
+
+			long edge = range.getVirtualAddress() + range.getSize();
+			
+			int asid = range.getAsid();
+
+			// FIXME this is somewhat inefficient - should use Boyer-Moore
+			int matched = 0;
+			long matchAddr = -1;
+			while (addr < edge) {
+				long bytesLeftInRange = edge - addr;
+				long count = bufferMax < bytesLeftInRange ? bufferMax : bytesLeftInRange;
+				
+				if (0 != addr) {
+					byte[] buffer = getMemoryBytes(asid, addr, (int)count);
+					
+					if (null != buffer) {
+						// Handle partial match
+						if (0 != matched) {
+							matched = match(whatBytes, matched, buffer, 0);
+						}
+						
+						// Handle no match
+						for (int i = 0; i < buffer.length && 0 == matched; i += alignment) {
+							matchAddr = addr + i;
+							matched = match(whatBytes, 0, buffer, i);
+						}
+						
+						// Check for a full match
+						if (whatBytes.length == matched) {
+							return matchAddr;
+						}
+					}
+				} else {
+					System.err.println("Looking for address 0");
+				}
+
+				addr += count;
+			}
+		}
+		return -1;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getLongAt(int, long)
+	 */
+	public long getLongAt(int asid, long address) throws MemoryAccessException
+	{
+		//allocate 8 bytes, do the read, then byte-swap if little endian
+		byte buffer[] = new byte[8];
+		getBytesAt(asid, address, buffer);
+		_byteSwap(buffer);
+		//by this point, the buffer is in big endian
+		return    (0xFF00000000000000L & (((long) buffer[0]) << 56))
+				| (0x00FF000000000000L & (((long) buffer[1]) << 48)) 
+				| (0x0000FF0000000000L & (((long) buffer[2]) << 40)) 
+				| (0x000000FF00000000L & (((long) buffer[3]) << 32)) 
+				| (0x00000000FF000000L & (((long) buffer[4]) << 24)) 
+				| (0x0000000000FF0000L & (((long) buffer[5]) << 16)) 
+				| (0x000000000000FF00L & (((long) buffer[6]) << 8)) 
+				| (0x00000000000000FFL & (buffer[7]));
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getIntAt(int, long)
+	 */
+	public int getIntAt(int asid, long address) throws MemoryAccessException
+	{
+		//allocate 4 bytes, do the read, then byte-swap if little endian
+		byte buffer[] = new byte[4];
+		getBytesAt(asid, address, buffer);
+		_byteSwap(buffer);
+		//by this point, the buffer is in big endian
+		return ((0xFF & buffer[0]) << 24) | ((0xFF & buffer[1]) << 16) | ((0xFF & buffer[2]) << 8) | (0xFF & buffer[3]);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getShortAt(int, long)
+	 */
+	public short getShortAt(int asid, long address)
+			throws MemoryAccessException
+	{
+		//allocate 2 bytes, do the read, then byte-swap if little endian
+		byte buffer[] = new byte[2];
+		getBytesAt(asid, address, buffer);
+		_byteSwap(buffer);
+		//by this point, the buffer is in big endian
+		return (short)(((0xFF & buffer[0]) << 8) | (0xFF & buffer[1]));
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getByteAt(int, long)
+	 */
+	public byte getByteAt(int asid, long address) throws MemoryAccessException
+	{
+		//allocate 1 byte
+		byte buffer[] = new byte[1];
+		getBytesAt(asid, address, buffer);
+		//by this point, the buffer is in big endian
+		return buffer[0];
+	}
+	
+	private void _byteSwap(byte[] buffer)
+	{
+		if (_isLittleEndian) {
+			int halfLength = buffer.length / 2;
+			for (int x= 0; x <halfLength; x++) {
+				byte temp = buffer[buffer.length - 1 -x];
+				buffer[buffer.length - 1 -x] = buffer[x];
+				buffer[x] = temp;
+			}
+		}
+	}
+
+	public long getPointerAt(int asid, long address) throws MemoryAccessException
+	{
+		long ptr = 0;
+		
+		if (bytesPerPointer(asid) == 8) {
+			ptr = getLongAt(asid, address);
+		} else {
+			ptr = (0xFFFFFFFFL & getIntAt(asid, address));
+		}
+		return ptr;
+	}
+	
+	public abstract int getBytesAt(int asid, long address, byte[] buffer) throws MemoryAccessException;
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#bytesPerPointer()
+	 */
+	public int bytesPerPointer(int asid)
+	{
+		// No 64-bit addresses
+		if (!_is64Bit || _is64BitAsid == null) return 4;
+		// Search the list of 64-bit ASIDs
+		for (int i = 0; i < _is64BitAsid.length; ++i) {
+			if (_is64BitAsid[i] == asid) return 8;
+		}
+		return 4;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/DumpReaderAddressSpace.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/DumpReaderAddressSpace.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/DumpReaderAddressSpace.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/DumpReaderAddressSpace.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.addressspace;
+
+import java.io.IOException;
+
+import com.ibm.dtfj.corereaders.DumpReader;
+import com.ibm.dtfj.corereaders.MemoryAccessException;
+import com.ibm.dtfj.corereaders.MemoryRange;
+
+public class DumpReaderAddressSpace extends CommonAddressSpace
+{
+	private DumpReader _reader;
+	
+	public DumpReaderAddressSpace(MemoryRange[] ranges, DumpReader reader, boolean isLittleEndian, boolean is64Bit)
+	{
+		super(ranges, isLittleEndian, is64Bit);
+		_reader = reader;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isExecutable(int, long)
+	 */
+	public boolean isExecutable(int asid, long address)
+			throws MemoryAccessException
+	{
+		MemoryRange match = _residentRange(asid, address);
+		return match.isExecutable();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isReadOnly(int, long)
+	 */
+	public boolean isReadOnly(int asid, long address)
+			throws MemoryAccessException
+	{
+		MemoryRange match = _residentRange(asid, address);
+		return match.isReadOnly();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isShared(int, long)
+	 */
+	public boolean isShared(int asid, long address)
+			throws MemoryAccessException
+	{
+		MemoryRange match = _residentRange(asid, address);
+		return match.isShared();
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getBytesAt(int, long, byte[])
+	 */
+	public int getBytesAt(int asid, long address, byte[] buffer) throws MemoryAccessException
+	{
+		int size, bytesRead=0;
+		while (bytesRead < buffer.length) {
+			long adjustedAddress = address + ((long)bytesRead & 0xFFFFFFFF);
+			MemoryRange match = _residentRange(asid, adjustedAddress);
+			long offset = adjustedAddress - match.getVirtualAddress();
+			long bytesAvailable = match.getSize() - offset;
+
+			// For 64-bit dumps, need to safely limit byte array size
+			if (bytesAvailable > (long)(Integer.MAX_VALUE)) {
+				size = buffer.length - bytesRead;
+			} else {
+				size = Math.min((int)bytesAvailable, buffer.length - bytesRead);
+			}
+			try {
+				if (match.isInCoreFile() == true) {
+					_reader.seek(match.getFileOffset() + offset);
+					byte[] temp = _reader.readBytes(size);
+					System.arraycopy(temp, 0, buffer, bytesRead, temp.length);
+				} else {
+					/*
+					 * This memory range is not mapped into the core file, but is resident in
+					 * an external library file, so read it from there.
+					 */
+					DumpReader reader = match.getLibraryReader();
+					if (reader != null) {
+						reader.seek(offset);
+						byte[] temp = reader.readBytes(size);
+						System.arraycopy(temp, 0, buffer, bytesRead, temp.length);
+					} else {
+						// No valid reader for this memory
+						throw new MemoryAccessException(asid, adjustedAddress, "Cannot read memory external to core file" );
+					}
+				}
+			} catch (IOException e) {
+				throw new MemoryAccessException(asid, adjustedAddress, "IOException reading core file: " + e.getMessage());
+			}
+			bytesRead += size;
+		}
+		return bytesRead;
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getLongAt(int, long)
+	 */
+	public long getLongAt(int asid, long address) throws MemoryAccessException
+	{
+		MemoryRange match = _residentRange(asid, address);
+		
+		if (null != match) {
+			if (match.isInCoreFile()) {
+				long fileOffset = match.getFileOffset() + (address - match.getVirtualAddress());
+				try {
+					_reader.seek(fileOffset);
+					return _reader.readLong();
+				} catch (IOException e) {
+					throw new MemoryAccessException(asid, address);
+				}
+			} else {
+				return super.getLongAt(asid, address);
+			}
+		} else {
+			throw new MemoryAccessException(asid, address);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getIntAt(int, long)
+	 */
+	public int getIntAt(int asid, long address) throws MemoryAccessException
+	{
+		MemoryRange match = _residentRange(asid, address);
+		
+		if (null != match) {
+			if (match.isInCoreFile()) {
+				long fileOffset = match.getFileOffset() + (address - match.getVirtualAddress());
+				try {
+					_reader.seek(fileOffset);
+					return _reader.readInt();
+				} catch (IOException e) {
+					throw new MemoryAccessException(asid, address);
+				}
+			} else {
+				return super.getIntAt(asid, address);
+			}
+		} else {
+			throw new MemoryAccessException(asid, address);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getShortAt(int, long)
+	 */
+	public short getShortAt(int asid, long address)
+			throws MemoryAccessException
+	{
+		MemoryRange match = _residentRange(asid, address);
+		
+		if (null != match) {
+			if (match.isInCoreFile()) {
+				long fileOffset = match.getFileOffset() + (address - match.getVirtualAddress());
+				try {
+					_reader.seek(fileOffset);
+					return _reader.readShort();
+				} catch (IOException e) {
+					throw new MemoryAccessException(asid, address);
+				}
+			} else {
+				return super.getShortAt(asid, address);
+			}
+		} else {
+			throw new MemoryAccessException(asid, address);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getByteAt(int, long)
+	 */
+	public byte getByteAt(int asid, long address) throws MemoryAccessException
+	{
+		
+		MemoryRange match = _residentRange(asid, address);
+		
+		if (null != match) {
+			if (match.isInCoreFile()) {
+				long fileOffset = match.getFileOffset() + (address - match.getVirtualAddress());
+				try {
+					_reader.seek(fileOffset);
+					return _reader.readByte();
+				} catch (IOException e) {
+					throw new MemoryAccessException(asid, address);
+				}
+			} else {
+				return super.getByteAt(asid, address);
+			}
+		} else {
+			throw new MemoryAccessException(asid, address);
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/IAbstractAddressSpace.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/IAbstractAddressSpace.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/IAbstractAddressSpace.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/IAbstractAddressSpace.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.addressspace;
+
+import java.util.Iterator;
+
+import com.ibm.dtfj.corereaders.DeprecatedCoreAPI;
+import com.ibm.dtfj.corereaders.MemoryAccessException;
+import com.ibm.dtfj.corereaders.MemoryRange;
+
+/**
+ * The interface for the abstract interface.  Note that there will probably only ever be one implementor of 
+ * this interface so it will probably be flattened once it is frozen
+ */
+public interface IAbstractAddressSpace extends DeprecatedCoreAPI
+{
+	/**
+	 * @return An iterator of the MemoryRange objects making up the address space
+	 * @see MemoryRange
+	 */
+	public Iterator getMemoryRanges();
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return true if this memory address is within an executable page
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public boolean isExecutable(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return true if write access to this memory address was disabled in the image
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public boolean isReadOnly(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return true if this memory address is shared between processes
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public boolean isShared(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 64-bit long stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public long getLongAt(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 32-bit int stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public int getIntAt(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 16-bit short stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public short getShortAt(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 8-bit byte stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	public byte getByteAt(int asid, long address) throws MemoryAccessException;
+	
+	public long getPointerAt(int asid, long address) throws MemoryAccessException;
+	
+	public int getBytesAt(int asid, long address, byte[] buffer) throws MemoryAccessException;
+	
+	/**
+	 * Provided so that callers can determine more complicated memory geometry than what can be expressed
+	 * with offsets and the above scalar data readers.
+	 * @param asid The address space id.
+	 * @return The number of bytes which are required to express a native pointer in the underlying address
+	 * space. 
+	 */
+	public int bytesPerPointer(int asid);
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/LayeredAddressSpace.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/LayeredAddressSpace.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/LayeredAddressSpace.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/LayeredAddressSpace.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.addressspace;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import com.ibm.dtfj.corereaders.ClosingFileReader;
+import com.ibm.dtfj.corereaders.MemoryAccessException;
+import com.ibm.dtfj.corereaders.MemoryRange;
+
+public class LayeredAddressSpace extends CommonAddressSpace
+{
+	private TreeMap _moduleRanges = new TreeMap();
+	private IAbstractAddressSpace _base;
+	private MemoryRange[] _moduleRangesArray = null; 
+	private Integer _lastModuleRange = new Integer(0);
+	
+	public LayeredAddressSpace(IAbstractAddressSpace base, boolean isLittleEndian, boolean is64Bit)
+	
+	
+	{
+		super(_extractRanges(base.getMemoryRanges()), isLittleEndian, is64Bit);
+		_base = base;
+	}
+
+	private static MemoryRange[] _extractRanges(Iterator memoryRanges)
+	{
+		Vector ranges = new Vector();
+		while (memoryRanges.hasNext()) {
+			ranges.add(memoryRanges.next());
+		}
+		return (MemoryRange[])ranges.toArray(new MemoryRange[ranges.size()]);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getMemoryRanges()
+	 */
+	public Iterator getMemoryRanges()
+	{
+		//TODO:  hook in here to stich on the extra ranges which have been added at the beginning of the iterator
+		return super.getMemoryRanges();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isExecutable(int, long)
+	 */
+	public boolean isExecutable(int asid, long address)
+			throws MemoryAccessException
+	{
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isReadOnly(int, long)
+	 */
+	public boolean isReadOnly(int asid, long address)
+			throws MemoryAccessException
+	{
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isShared(int, long)
+	 */
+	public boolean isShared(int asid, long address)
+			throws MemoryAccessException
+	{
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#getBytesAt(int, long, byte[])
+	 */
+	public int getBytesAt(int asid, long address, byte[] buffer)
+			throws MemoryAccessException
+	{
+		if ( null == _moduleRangesArray) {
+			_moduleRangesArray = (MemoryRange[]) _moduleRanges.keySet().toArray(new MemoryRange[0]);
+		}
+
+		int retI = findWhichMemoryRange(asid, address, _moduleRangesArray, _lastModuleRange, false);
+		
+		if (retI > -1) {
+			MemoryRange range = (MemoryRange) _moduleRangesArray[retI];
+			if (range.contains(address)) {
+				ClosingFileReader readable = (ClosingFileReader) _moduleRanges.get(range);
+				try {
+					long fileOffset = range.getFileOffset() + (address - range.getVirtualAddress());
+					readable.seek(fileOffset);
+					readable.readFully(buffer);
+					return buffer.length;
+				} catch (IOException ex) {
+					System.out.println(">> Memory access exception in getBytesAt");
+					throw new MemoryAccessException(asid, address);
+				}
+			}
+		}
+
+		//this must not be in one of the newer regions
+		return _base.getBytesAt(asid, address, buffer);
+	}
+
+
+	public void mapRegion(long virtualAddress, ClosingFileReader residentFile, long fileOffset, long size)
+	{
+		MemoryRange range = new MemoryRange(virtualAddress, fileOffset, size);
+		_moduleRanges.put(range,residentFile);
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/SimpleAddressSpace.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/SimpleAddressSpace.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/SimpleAddressSpace.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/addressspace/SimpleAddressSpace.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.addressspace;
+
+import java.io.IOException;
+
+import com.ibm.dtfj.corereaders.ClosingFileReader;
+import com.ibm.dtfj.corereaders.MemoryAccessException;
+import com.ibm.dtfj.corereaders.MemoryRange;
+
+/**
+ * Exists to provide a bridge by which to support the deprecated core readers while we use IAbstractAddressSpace
+ * to enhance the capability of memory reading for more complicated platforms.
+ * 
+ * Ideally, this will be deprecated in the future.
+ */
+public class SimpleAddressSpace  extends CommonAddressSpace
+{
+	private ClosingFileReader _backing;
+	
+	
+	public SimpleAddressSpace(MemoryRange[] deprecatedMemoryRanges, ClosingFileReader file, boolean isLittleEndian, boolean is64Bit)
+	{
+		super(deprecatedMemoryRanges, isLittleEndian, is64Bit);
+		_backing = file;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isExecutable(int, long)
+	 */
+	public boolean isExecutable(int asid, long address)
+			throws MemoryAccessException
+	{
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isReadOnly(int, long)
+	 */
+	public boolean isReadOnly(int asid, long address)
+			throws MemoryAccessException
+	{
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.addressspace.IAbstractAddressSpace#isShared(int, long)
+	 */
+	public boolean isShared(int asid, long address)
+			throws MemoryAccessException
+	{
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	public int getBytesAt(int asid, long address, byte[] buffer) throws MemoryAccessException
+	{
+		MemoryRange resident = _residentRange(asid, address);
+		long readLocation = resident.getFileOffset() + (address - resident.getVirtualAddress());
+		try {
+			_backing.seek(readLocation);
+			_backing.readFully(buffer);
+		} catch (IOException e) {
+			throw new MemoryAccessException(asid, address);
+		}
+		return buffer.length;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/ARReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/ARReader.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/ARReader.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/ARReader.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.binaryreaders;
+
+import java.io.IOException;
+
+import com.ibm.dtfj.corereaders.ClosingFileReader;
+
+
+/**
+ * Reads the AR files used to store a flat list of shared libraries on AIX
+ */
+public class ARReader
+{
+	private ClosingFileReader _backing;
+	private long _firstModuleHeader;
+	
+		
+	public ARReader(ClosingFileReader file)
+	{
+		_backing = file;
+		try {
+			_backing.seek(0);
+			byte[] magic = new byte[8];
+			_backing.readFully(magic);
+			if (!"<bigaf>\n".equals(new String(magic))) {
+				throw new IllegalArgumentException();
+			}
+			_backing.seek(68);
+			byte[] firstOffset = new byte[20];
+			_backing.readFully(firstOffset);
+			_firstModuleHeader = _longFromBuffer(firstOffset);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public long offsetOfModule(String name)
+	{
+		long next = _firstModuleHeader;
+		
+		while (0 != next) {
+			try {
+				_backing.seek(next);
+				byte[] buffer = new byte[20];
+				_backing.readFully(buffer);
+				long length = _longFromBuffer(buffer);
+				_backing.readFully(buffer);
+				long nextOffset = _longFromBuffer(buffer);
+				_backing.readFully(buffer);
+				long prevOffset = _longFromBuffer(buffer);
+				_backing.seek(next+ 108);
+				buffer = new byte[4];
+				_backing.readFully(buffer);
+				int nameLen = (int)_longFromBuffer(buffer);
+				buffer = new byte[nameLen];
+				_backing.readFully(buffer);
+				String moduleName = null;
+				if ((0 < nameLen) && ('`' == buffer[0]) && ('\n' == buffer[1])) {
+					moduleName = "";
+				} else {
+					moduleName = new String(buffer, 0, nameLen);
+				}
+				if (moduleName.equals(name)) {
+					long offset = next + 112 + nameLen;
+					if (1 == (offset % 2)) {
+						offset += 3;
+					} else {
+						offset += 2;
+					}
+					return offset;
+				}
+				next = nextOffset;
+			} catch (IOException e) {
+				return -1;
+			}
+		}
+		return -1;
+	}
+	
+	public long sizeOfModule(String name)
+	{
+		long next = _firstModuleHeader;
+		
+		while (0 != next) {
+			try {
+				_backing.seek(next);
+				byte[] buffer = new byte[20];
+				_backing.readFully(buffer);
+				long length = _longFromBuffer(buffer);
+				_backing.readFully(buffer);
+				long nextOffset = _longFromBuffer(buffer);
+				_backing.readFully(buffer);
+				long prevOffset = _longFromBuffer(buffer);
+				_backing.seek(next+ 108);
+				buffer = new byte[4];
+				_backing.readFully(buffer);
+				int nameLen = (int)_longFromBuffer(buffer);
+				buffer = new byte[nameLen];
+				_backing.readFully(buffer);
+				String moduleName = null;
+				if ((0 < nameLen) && ('`' == buffer[0]) && ('\n' == buffer[1])) {
+					moduleName = "";
+				} else {
+					moduleName = new String(buffer, 0, nameLen);
+				}
+				if (moduleName.equals(name)) {
+					return length;
+				}
+				next = nextOffset;
+			} catch (IOException e) {
+				return -1;
+			}
+		}
+		return -1;
+	}
+
+	
+	/**
+	 * @param buffer
+	 * 
+	 */
+	private long _longFromBuffer(byte[] buffer)
+	{
+		int total = buffer.length;
+		while (' ' == buffer[total-1]) {
+			total--;
+		}
+		long length = Long.parseLong(new String(buffer, 0, total));
+		return length;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/XCOFFReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/XCOFFReader.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/XCOFFReader.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/binaryreaders/XCOFFReader.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.binaryreaders;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import com.ibm.dtfj.corereaders.Builder;
+import com.ibm.dtfj.corereaders.ClosingFileReader;
+
+public class XCOFFReader
+{
+	private static final short XCOFF_MAGIC_NUMBER_AIX32 = 0x01DF;
+	private static final short XCOFF_MAGIC_NUMBER_AIX64_PRE43 = 0x01EF;
+	private static final short XCOFF_MAGIC_NUMBER_AIX64_POST51 = 0x01F7;
+	private ClosingFileReader _backing;
+	private long _startOffset;
+	private long _size;
+	private boolean _is64Bit;
+	
+	private long _textSegmentOffset = -1;
+	private long _textSegmentSize = -1;
+	private long _sybolTableOffset = -1;
+	
+	//values held purely for module properties
+	/**
+	 * The creation time and date of the module in milliseconds since the epoch
+	 */
+	private long _timeAndDate = 0;
+	private short _flags = 0;
+	
+	public XCOFFReader(ClosingFileReader backing, long offsetIntoFile, long size) throws IOException
+	{
+		_startOffset = offsetIntoFile;
+		_size = size;
+		_backing = backing;
+		
+		//by this point, the basic support for reading the file complete so on to looking into the file
+		seekFileRelative(0);
+		short magic = _backing.readShort();
+		if (!((XCOFF_MAGIC_NUMBER_AIX32 == magic) || (XCOFF_MAGIC_NUMBER_AIX64_PRE43 == magic) || (XCOFF_MAGIC_NUMBER_AIX64_POST51 == magic))) {
+			throw new IllegalArgumentException();
+		}
+		_is64Bit = ((XCOFF_MAGIC_NUMBER_AIX64_PRE43 == magic) || (XCOFF_MAGIC_NUMBER_AIX64_POST51 == magic));
+		short numberOfSections = _backing.readShort();
+		//time and date in XCOFF is _seconds_ since epoch while in Java it is _milliseconds_ since epoch
+		_timeAndDate = 1000L * (0xFFFFFFFFL & _backing.readInt());
+		//by this point, the file pointer is at 8 so get the offset to the symbol table
+		_sybolTableOffset = (_is64Bit ? _backing.readLong() : (0xFFFFFFFFL & _backing.readInt()));
+		seekFileRelative(16);
+		short optionalHeaderSize = _backing.readShort();
+		_flags = _backing.readShort();
+		long nextSectionAddress = 20 + optionalHeaderSize;
+		for(int x =0 ;x < numberOfSections; x++) {
+			seekFileRelative(nextSectionAddress);
+			byte[] buffer = new byte[8];
+			_backing.readFully(buffer);
+			String sectionName = new String(buffer);
+			seekFileRelative(nextSectionAddress + (_is64Bit ? 24 : 16));
+			long sectionSize = (_is64Bit ? _backing.readLong() : _backing.readInt());
+			long fileOffset = (_is64Bit ? _backing.readLong() : _backing.readInt());
+			nextSectionAddress += (_is64Bit ? 72 : 40);
+			if (sectionName.startsWith(".text")) {
+				_textSegmentOffset = fileOffset + _startOffset;
+				_textSegmentSize = sectionSize;
+			}
+		}
+	}
+	
+	public XCOFFReader(ClosingFileReader backing) throws IOException
+	{
+		this(backing, 0, backing.length());
+	}
+	
+	public long getTextSegmentOffset()
+	{
+		return _textSegmentOffset;
+	}
+	
+	private void seekFileRelative(long offset) throws IOException
+	{
+		_backing.seek(_startOffset + offset);
+	}
+
+	public long getTextSegmentSize()
+	{
+		return _textSegmentSize;
+	}
+	
+	private long _symbolTableOffset() throws IOException
+	{
+		return _sybolTableOffset;
+	}
+	
+	private int _numberOfSymbols() throws IOException
+	{
+		seekFileRelative(_is64Bit ? 20 : 12);
+		return _backing.readInt();
+	}
+	
+	private String _stringFromArray(byte[] rawData, int start)
+	{
+		int end = start;
+		while ((end < rawData.length) && ('\0' != rawData[end])) {
+			end++;
+		}
+		return new String(rawData, start, end - start);
+	}
+
+	public ClosingFileReader underlyingFile()
+	{
+		return _backing;
+	}
+	
+	public long baseFileOffset()
+	{
+		return _startOffset;
+	}
+	
+	public long logicalSize()
+	{
+		return _size;
+	}
+
+	private static final short F_RELFLG = 0x0001;
+	private static final short F_EXEC = 0x0002;
+	private static final short F_LNNO = 0x0004;
+	private static final short F_AR32W = 0x0200;
+	private static final short F_DYNLOAD = 0x1000;
+	private static final short F_SHROBJ = 0x2000;
+	private static final short F_LOADONLY = 0x4000;
+	
+	public Properties moduleProperties()
+	{
+		Properties props = new Properties();
+		props.put("Time and Date", (new Date(_timeAndDate)).toString());
+		String flagRep = ((0 != (_flags & F_RELFLG)) ? "F_RELFLG " : "")
+							+ ((0 != (_flags & F_EXEC)) ? "F_EXEC " : "")
+							+ ((0 != (_flags & F_LNNO)) ? "F_LNNO " : "")
+							+ ((0 != (_flags & F_AR32W)) ? "F_AR32W " : "")
+							+ ((0 != (_flags & F_DYNLOAD)) ? "F_DYNLOAD " : "")
+							+ ((0 != (_flags & F_SHROBJ)) ? "F_SHROBJ " : "")
+							+ ((0 != (_flags & F_LOADONLY)) ? "F_LOADONLY " : "");
+		props.put("Flags", flagRep);
+		return props;
+	}
+
+	public List buildSymbols(Builder builder, Object addressSpace, long relocationBase)
+	{
+		LinkedList symbols = new LinkedList();
+		
+		try {
+			long symbolTableOffset = _symbolTableOffset();
+			int numberOfSymbols = _numberOfSymbols();
+
+			if (0 != symbolTableOffset) {
+				//read the strings first
+				seekFileRelative(symbolTableOffset + (18 * numberOfSymbols));
+				int stringTableLength = _backing.readInt();
+				// "If a string table is not used, it may be omitted entirely, or a string table
+				//  consisting of only the length field (containing a value of 0 or 4) may be used.
+				//  A value of 4 is preferable."
+				if (4 != stringTableLength && 0 != stringTableLength) {
+					byte[] rawStringTable = new byte[stringTableLength-4];
+					_backing.readFully(rawStringTable);
+					
+					//now read the symbol table
+					seekFileRelative(symbolTableOffset);
+					byte[] symbolTableEntry = new byte[18];
+					int skipNext = 0;
+					for (int x = 0; x < numberOfSymbols; x++) {
+						_backing.readFully(symbolTableEntry);
+						if (skipNext > 0) {
+							skipNext--;
+						} else {
+							int stringTableOffset = 0;
+							String symbolName = null;
+							
+							if (_is64Bit) {
+								stringTableOffset = ((0xFF & symbolTableEntry[8]) << 24)
+										| ((0xFF & symbolTableEntry[9]) << 16)
+										| ((0xFF & symbolTableEntry[10]) << 8)
+										| ((0xFF & symbolTableEntry[11]));
+							} else {
+								if ((0 == symbolTableEntry[0]) && (0 == symbolTableEntry[1])
+										&& (0 == symbolTableEntry[2]) && (0 == symbolTableEntry[3])) {
+									// string offset
+									stringTableOffset = ((0xFF & symbolTableEntry[4]) << 24)
+											| ((0xFF & symbolTableEntry[5]) << 16)
+											| ((0xFF & symbolTableEntry[6]) << 8)
+											| ((0xFF & symbolTableEntry[7]));
+								} else {
+									// literal
+									symbolName = _stringFromArray(symbolTableEntry, 0);
+								}
+							}
+							if ((null == symbolName) && (0 == (symbolTableEntry[16] & 0x80)) && (0 != stringTableOffset) && (stringTableOffset < (stringTableLength - 4))) {
+								//read the string from the table
+								symbolName = _stringFromArray(rawStringTable, stringTableOffset - 4);
+							} else if ((0 == (symbolTableEntry[16] & 0x80)) && (stringTableOffset > (stringTableLength - 4))) {
+								//XXX: this problem is known to happen when parsing the 64-bit /usr/lib/libiconv.a file.
+								// Currently, the cause is unknown so this work-around is put in until we can find the real cause
+								symbolName = "(string out of table bounds)";
+							}
+							if (null == symbolName) {
+								symbolName = "";
+							}
+							long value = 0;
+							if (_is64Bit) {
+								value = ((0xFF & symbolTableEntry[0]) << 56)
+								| ((0xFF & symbolTableEntry[1]) << 48)
+								| ((0xFF & symbolTableEntry[2]) << 40)
+								| ((0xFF & symbolTableEntry[3]) << 32)
+								| ((0xFF & symbolTableEntry[4]) << 24)
+								| ((0xFF & symbolTableEntry[5]) << 16)
+								| ((0xFF & symbolTableEntry[6]) << 8)
+								| ((0xFF & symbolTableEntry[7]));
+							} else {
+								value = ((0xFF & symbolTableEntry[8]) << 24)
+								| ((0xFF & symbolTableEntry[9]) << 16)
+								| ((0xFF & symbolTableEntry[10]) << 8)
+								| ((0xFF & symbolTableEntry[11]));
+							}
+							symbols.add(builder.buildSymbol(addressSpace, symbolName, value + relocationBase));
+							skipNext = symbolTableEntry[17];
+						}
+					}
+				}
+			}
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return symbols;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Builder.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Builder.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Builder.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Builder.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+import java.io.FileNotFoundException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+public interface Builder {
+
+	public Object buildProcess(Object addressSpace, String pid, String commandLine, Properties environment, Object currentThread, Iterator threads, Object executable, Iterator libraries, int addressSize);
+
+	public Object buildAddressSpace(String name, int id);
+
+	public Object buildRegister(String name, Number value);
+
+	public Object buildStackSection(Object addressSpace, long stackStart, long stackEnd);
+
+	public Object buildThread(String name, Iterator registers, Iterator stackSections, Iterator stackFrames, Properties properties, int signalNumber);
+
+	public Object buildModuleSection(Object addressSpace, String name, long imageStart, long imageEnd);
+
+	public Object buildModule(String name, Properties properties, Iterator sections, Iterator symbols, long startAddress);
+
+	public Object buildStackFrame(Object addressSpace, long stackBasePointer, long pc);
+
+	public Object buildSymbol(Object addressSpace, String functionName, long relocatedFunctionAddress);
+
+	public Object buildCorruptData(Object addressSpace, String message, long address);
+
+	public ClosingFileReader openFile(String filename) throws FileNotFoundException;
+	
+	public long getEnvironmentAddress();
+
+	public long getValueOfNamedRegister(List registers, String string);
+
+	/**
+	 * Called to inform the builder that the executable data cannot be trusted.
+	 * Note that this also set the libraries unavailable as a side-effect
+	 * 
+	 * @param description
+	 */
+	public void setExecutableUnavailable(String description);
+
+	public void setCPUType(String cpuType);
+
+	public void setCPUSubType(String subType);
+
+	public void setCreationTime(long millis);
+
+	public void setOSType(String osType);
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ClosingFileReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ClosingFileReader.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ClosingFileReader.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ClosingFileReader.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,421 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageInputStreamImpl;
+
+
+
+/**
+ * A wrapper around the functionality that we require from RandomAccessFiles but with the added auto-closing
+ * functionality that we require.  Since it is not always easy to determine who "owns" a file and we do not want
+ * to introduce the concept of state, this class will manage all such file ownership.
+ * 
+ */
+public class ClosingFileReader extends ImageInputStreamImpl
+{
+	private static final int PAGE_SIZE = 4096;
+	private static final int BUFFER_PAGES = 4;
+	private static final int BUFFER_SIZE = BUFFER_PAGES * PAGE_SIZE;
+	private IRandomAccessFile _file;
+	//used for creating the stream
+	private File _fileRef;
+	private byte[] _buffer = new byte[BUFFER_SIZE];
+	private long _bufferBase = -1;
+	private long _bufferEnd = -1;
+	private boolean deleteOnClose = false;
+	private int _page_size = PAGE_SIZE;
+	
+	/**
+	 * Interface that mimics java.io.RandomAccessFile 
+	 */
+	static interface IRandomAccessFile 
+	{
+		public void close() throws IOException;
+		public long length() throws IOException;
+		public int read() throws IOException;
+		public void readFully(byte[] b) throws IOException;
+		public void readFully(byte[] b, int off, int len) throws IOException;
+		public void seek(long pos) throws IOException;
+	}
+	
+	static class EORFException extends EOFException 
+	{
+		private static final long serialVersionUID = 1L;
+		public int bytesRead;
+		
+		public EORFException(int n) {
+			bytesRead = n;
+		}
+	};
+	
+	/**
+	 * Base implementation of IRandomAccessFile - delegates to java.io.RandomAccessFile
+	 */
+	private static class BaseRandomAccessFile implements IRandomAccessFile
+	{
+		private RandomAccessFile _file;
+		
+		public BaseRandomAccessFile(File file, String mode) throws FileNotFoundException {
+			_file = new RandomAccessFile( file, mode);
+		}
+		public void close() throws IOException {
+			_file.close();
+		}
+		public long length() throws IOException {
+			return _file.length();
+		}
+		public int read() throws IOException {
+			return _file.read();
+		}
+		public void readFully(byte[] b) throws IOException {
+			_file.readFully(b);
+		}
+		public void readFully(byte[] b, int off, int len) throws IOException {
+			_file.readFully(b, off, len);
+		}
+		public void seek(long pos) throws IOException {
+			_file.seek(pos);
+		}
+	}
+
+	/**
+	 * Stream implementation of IRandomAccessFile - delegates to ImageInputStream
+	 */
+	private static class StreamRandomAccessFile implements IRandomAccessFile
+	{
+		private ImageInputStream _file;
+		public StreamRandomAccessFile(ImageInputStream file) {
+			_file = file;
+		}		
+		public void close() throws IOException
+		{
+			_file.close();
+		}
+		public long length() throws IOException
+		{
+			// ImageInputStream does not always provide file length, so we handle using EOF
+			return _file.length();
+		}
+		public int read() throws IOException
+		{
+			return _file.read();
+		}
+		public void readFully(byte[] b) throws IOException
+		{
+			readFully(b, 0, b.length);
+		}
+		public void readFully(byte[] b, int off, int len) throws IOException
+		{
+			int sofar = 0;
+					
+			do {
+				int nbytes = _file.read(b, off + sofar, len - sofar);
+				//if (nbytes <= 0) throw new EORFException(sofar);
+				if (nbytes <= 0) throw new EOFException();
+				sofar += nbytes;
+			} while (sofar < len);
+			
+		}
+		public void seek(long pos) throws IOException
+		{
+			_file.seek(pos);
+		}
+	}
+	
+	public ClosingFileReader(File file) throws FileNotFoundException
+	{
+		_fileRef = file;
+		_file = new BaseRandomAccessFile(_fileRef, "r");
+	}
+	
+	/**
+	 * Create a closing file reader from a stream
+	 * @param file An ImageInputStream
+	 * @throws FileNotFoundException
+	 */
+	public ClosingFileReader(final ImageInputStream file) throws FileNotFoundException
+	{
+		_file = new StreamRandomAccessFile(file);
+	}
+
+	/**
+	 * Create a closing file reader which can close/delete the backing file on shutdown
+	 * @param file
+	 * @param deleteOnCloseOrExit Whether to delete the file when the file is closed or at shutdown
+	 * @throws FileNotFoundException
+	 */
+	public ClosingFileReader(final File file, boolean deleteOnCloseOrExit) throws FileNotFoundException
+	{
+		this(file);
+		if (deleteOnCloseOrExit) {
+			deleteOnClose = true;
+			/*  
+			 * Ensure this file is closed on shutdown so that it can be deleted if required.
+			 */
+			Runtime.getRuntime().addShutdownHook(new Thread() {
+				public void run() {
+					try {
+						close();
+					} catch (IOException e) {
+						// Ignore errors e.g. if file is already closed
+					}
+				}
+			});
+		}
+	}
+	
+	public byte[] readBytes(int n) throws IOException
+	{
+		byte[] buffer = new byte[n];
+		readFully(buffer);
+		return buffer;
+	}
+	
+	public int readInt() throws IOException
+	{
+		byte[] buffer = new byte[4];
+		readFully(buffer);
+		return (int)(((buffer[0] & 0xFFL) << 24)
+				| ((buffer[1] & 0xFFL) << 16)
+				| ((buffer[2] & 0xFFL) << 8)
+				| (buffer[3] & 0xFFL));
+	}
+	
+	public void seek(long position) throws IOException
+	{
+		streamPos = position;
+	}
+	
+	public long readLong() throws IOException
+	{
+		byte[] buffer = new byte[8];
+		readFully(buffer);
+		return (((buffer[0] & 0xFFL) << 56)
+				| ((buffer[1] & 0xFFL) << 48)
+				| ((buffer[2] & 0xFFL) << 40)
+				| ((buffer[3] & 0xFFL) << 32)
+				| ((buffer[4] & 0xFFL) << 24)
+				| ((buffer[5] & 0xFFL) << 16)
+				| ((buffer[6] & 0xFFL) << 8)
+				| (buffer[7] & 0xFFL));
+	}
+	
+	public short readShort() throws IOException
+	{
+		byte[] buffer = new byte[2];
+		readFully(buffer);
+		return (short)(((buffer[0] & 0xFF) << 8)
+				| (buffer[1] & 0xFF));
+	}
+	
+	public byte readByte() throws IOException
+	{
+		byte[] buffer = new byte[1];
+		readFully(buffer);
+		return buffer[0];
+	}
+	
+	public void finalize() throws Throwable
+	{
+		try {
+			close();
+		} finally {
+			super.finalize();
+		}
+	}
+	
+	public void readFully(byte[] buffer) throws IOException
+	{
+		int x  = 0;
+		while (x < buffer.length) {
+			int chunk = Math.min(_buffer.length, buffer.length - x);
+			int didRead = read(buffer, x, chunk);
+			
+			if (didRead <= 0) {
+				//make sure that we don't loop here on EOF
+				throw new EOFException("Read "+x+" bytes ");
+			}
+			x+= didRead;
+		}
+	}
+	
+	/**
+	 * @param buffer
+	 * @param bStart
+	 * @param length
+	 * @return The number of bytes actually read
+	 * @throws IOException
+	 */
+	public int read(byte[] buffer, int bStart, int length) throws IOException
+	{
+		int readSize=0;
+		try {
+			if (-1 == _bufferBase) {
+				//cache never used so initialize it
+				_recache();
+			}
+			//the buffer is valid so calculate the overlap
+			long bLow = _bufferBase;
+			long bHigh = _bufferEnd;
+			long fLow = streamPos;
+			long fHigh = streamPos + length;
+			long overlapStart = Math.max(bLow, fLow);
+			long overlapEnd = Math.min(bHigh, fHigh);
+			
+			if ((overlapEnd <= overlapStart) || (streamPos < _bufferBase)) {
+				//disjoint memory regions - recache before read
+				_recache();
+				bLow = _bufferBase;
+				bHigh = _bufferEnd;
+				overlapStart = Math.max(bLow, fLow);
+				overlapEnd = Math.min(bHigh, fHigh);
+			}
+
+			// By this point, the region in [start, end) is in the buffer and can be read (be sure to correct for the delta from the _bufferBase)
+			//now read
+			int offset = (int)(overlapStart - _bufferBase);
+			readSize = (int) (overlapEnd - overlapStart);
+			
+			try {
+				System.arraycopy(_buffer, offset, buffer, bStart, readSize);
+			} catch (ArrayIndexOutOfBoundsException e) {
+				ArrayIndexOutOfBoundsException e1 = new ArrayIndexOutOfBoundsException("System.arraycopy("+_buffer+" length="+_buffer.length+","+offset+","+buffer+" length="+buffer.length+","+bStart+","+readSize+")");
+				e1.initCause(e);
+				throw e1;
+			}
+			
+			//note that length != (end - start) in all cases.  If, for example, we are reading the end of the file, the length will be the full buffer while the delta of end and start will be the part of the file we can read
+			streamPos += readSize;
+			if (readSize ==0 && length > 0) {
+				// Force EndOfFile indication
+				readSize = -1;
+			}
+		} catch (EOFException e) {
+			readSize = -1;
+		}
+		return readSize;
+	}
+	
+	/**
+	 * Updates the cache to hold the data following the current _readPointer
+	 * @throws IOException 
+	 */
+	private void _recache() throws IOException
+	{
+		// -1 means unknown length
+		long fileLength = _file.length();
+		if (fileLength == -1 || fileLength > streamPos) {
+			//round down to a page
+			long offset = streamPos % _page_size;
+			long aligned = streamPos - offset;
+
+			_bufferBase = aligned;
+			_bufferEnd = aligned;
+			try {
+				_file.seek(aligned);
+				_file.readFully(_buffer);
+				_bufferEnd = aligned + _buffer.length;
+			} catch (EORFException e) {
+				// exception tells us how many bytes were left
+				_file.seek(aligned);
+				_file.readFully(_buffer, 0, e.bytesRead);
+				_bufferEnd = aligned + e.bytesRead;				
+			} catch (EOFException e) {
+				//check how big the file is and make sure that we only read what is there
+				if (fileLength != -1) {
+					_bufferEnd = fileLength;
+					_file.seek(aligned);
+					_file.readFully(_buffer, 0, (int) (_bufferEnd - aligned));
+				} else {
+					// Try byte by byte
+					_file.seek(aligned);
+					_bufferEnd = aligned;
+					for (int i = 0; i < _buffer.length; ++i) {
+						int r = _file.read();
+						if (r == -1) break;						
+						_buffer[i] = (byte)r;
+						++_bufferEnd;
+					}
+					if (_bufferEnd == aligned) throw new EOFException("trying to cache beyond end of file");
+				}
+			}
+		} else {
+			throw new EOFException("trying to cache beyond end of file");
+		}
+	}
+	
+	/**
+	 * Currently this attempts to fill the entire buffer
+	 */
+	public int read(byte[] buffer) throws IOException
+	{
+		return read(buffer, 0, buffer.length);
+	}
+	
+	public int read() throws IOException 
+	{
+		byte b[] = new byte[1];
+		int r = read(b);
+		if (r < 0) return r;
+		return b[0] & 0xff;
+	}
+	
+	public long length()
+	{
+		try {
+			return _file.length();
+		} catch (IOException e) {
+			return -1L;
+		}
+	}
+	
+	public void close() throws IOException
+	{
+		_file.close();
+		if (this.deleteOnClose) {
+			_fileRef.delete();
+		}
+	}
+	
+	/**
+	 * @return A new stream for reading from the underlying file
+	 * 
+	 * @throws FileNotFoundException If this file has moved since the ClosingFileReader was created (since we would have failed in the constructor if the file was ever there)
+	 */
+	public InputStream streamFromFile() throws FileNotFoundException
+	{
+		return new FileInputStream(_fileRef);
+	}
+	
+	public String getAbsolutePath()
+	{
+		if (_fileRef == null) return null;
+		return _fileRef.getAbsolutePath();
+	}
+	
+	public boolean isMVSFile()
+	{
+		return false;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CoreReaderSupport.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CoreReaderSupport.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CoreReaderSupport.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CoreReaderSupport.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+import java.io.IOException;
+
+import com.ibm.dtfj.addressspace.DumpReaderAddressSpace;
+import com.ibm.dtfj.addressspace.IAbstractAddressSpace;
+
+public abstract class CoreReaderSupport implements ICoreFileReader {
+	private DumpReader _reader;
+	private IAbstractAddressSpace _addressSpace = null;
+
+	protected abstract MemoryRange[] getMemoryRangesAsArray();
+	protected abstract boolean isLittleEndian();
+	protected abstract boolean is64Bit();
+
+	public CoreReaderSupport(DumpReader reader) {
+		_reader = reader;
+	}
+	
+	protected int coreReadInt() throws IOException {
+		return _reader.readInt();
+	}
+	
+	protected void coreSeek(long position) throws IOException {
+		_reader.seek(position);
+	}
+	
+	protected long coreReadLong() throws IOException {
+		return _reader.readLong();
+	}
+	
+	protected long coreReadAddress() throws IOException {
+		return _reader.readAddress();
+	}
+	
+	protected short coreReadShort() throws IOException {
+		return _reader.readShort();
+	}
+
+	protected byte coreReadByte() throws IOException {
+		return _reader.readByte();
+	}
+	
+	protected byte[] coreReadBytes(int n) throws IOException {
+		return _reader.readBytes(n);
+	}
+
+	public IAbstractAddressSpace getAddressSpace() {
+		if (null == _addressSpace) {
+			MemoryRange[] ranges = getMemoryRangesAsArray();
+			if (null == ranges) {
+				_addressSpace = null;
+			} else {
+				_addressSpace = new DumpReaderAddressSpace(ranges, _reader, isLittleEndian(), is64Bit());
+			}
+		}
+		return _addressSpace;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CorruptCoreException.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CorruptCoreException.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CorruptCoreException.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/CorruptCoreException.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+/**
+ * Used by the core readers when they recognize a core file as a certain type but know that it is damaged and unusable
+ */
+public class CorruptCoreException extends Exception
+{
+	public CorruptCoreException(String string)
+	{
+		super(string);
+	}
+
+	private static final long serialVersionUID = 1309758016402653159L;
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DeprecatedCoreAPI.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DeprecatedCoreAPI.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DeprecatedCoreAPI.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DeprecatedCoreAPI.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+public interface DeprecatedCoreAPI
+{
+	/**
+	 * @param vaddr
+	 * @param size
+	 * 
+	 * @deprecated This method does not work properly with multiple address spaces
+	 */
+	public byte[] getMemoryBytes(long vaddr, int size);
+	
+	/**
+	 * @param whatBytes The pattern to search for
+	 * @param alignment The alignment boundary where the pattern can be expected to start
+	 * @param startFrom The first memory address to start searching in
+	 * 
+	 * 
+	 * @deprecated This method needs to be reworked to account for multiple address spaces
+	 */
+	public long findPattern(byte[] whatBytes, int alignment, long startFrom);
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Dump.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Dump.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Dump.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/Dump.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+import java.util.Iterator;
+
+public interface Dump extends ICoreFileReader
+{
+	/**
+	 * @return the precise model of the CPU (note that this can be an empty string but not null).
+	 * <br>
+	 * e.g. "Pentium IV step 4"
+	 */
+	String getProcessorSubtype();
+	
+	/**
+	 * Determines when the image was created
+	 * @return the time in milliseconds since 1970
+	 */
+	long getCreationTime();
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return true if this memory address is within an executable page
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	boolean isExecutable(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return true if write access to this memory address was disabled in the image
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	boolean isReadOnly(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return true if this memory address is shared between processes
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	boolean isShared(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 64-bit long stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	long getLongAt(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 32-bit int stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	int getIntAt(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 16-bit short stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	short getShortAt(int asid, long address) throws MemoryAccessException;
+
+	/**
+	 * @param asid an address space ID
+	 * @param address a byte-offset into the asid
+	 * @return the 8-bit byte stored at address in asid
+	 * @throws MemoryAccessException if the memory cannot be read
+	 */
+	byte getByteAt(int asid, long address) throws MemoryAccessException;
+	
+	/**
+	 * @return An iterator of the MemoryRange objects making up the address space
+	 * @see MemoryRange
+	 */
+	public Iterator getMemoryRanges();
+
+	/**
+	 * @return An iterator of String object specifying names of additional files needed by the Dump
+	 */
+	Iterator getAdditionalFileNames();
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpException.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpException.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpException.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpException.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.corereaders;
+
+/**
+ * This class is the superclass of all exceptions thrown by Dump classes
+ */
+public class DumpException extends Exception {
+	private static final long serialVersionUID = -7947427629541393731L;
+
+	private int _asid;
+	private long _address;
+	private Dump _dump;
+
+	public DumpException(Dump dump, int asid, long address, String description) {
+		super(description);
+		_dump = dump;
+		_asid = asid;
+		_address = address;
+	}
+
+	public DumpException(Dump dump, int asid, long address) {
+		super();
+		_dump = dump;
+		_asid = asid;
+		_address = address;
+	}
+
+	/**
+	 * @return the Dump where the exception was raised
+	 */
+	public Dump getDump() {
+		return _dump;
+	}
+
+	/**
+	 * @return the address in the addressSpaceId of the Dump where the exception
+	 *         was raised
+	 */
+	public long getAddress() {
+		return _address;
+	}
+
+	/**
+	 * @return the addressSpaceId of the Dump where the exception was raised
+	 */
+	public int getAddressSpaceId() {
+		return _asid;
+	}
+}



Mime
View raw message