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 [2/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
Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpFactory.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpFactory.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpFactory.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpFactory.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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;
+
+
+
+
+public class DumpFactory {
+	public static ICoreFileReader createDumpForCore(ClosingFileReader file) throws IOException {
+		return createDumpForCore(file, false);
+	}
+	
+	public static ICoreFileReader createDumpForCore(ClosingFileReader file, boolean verbose) throws IOException {
+		// TODO try next format if there is an IOException thrown from the test
+		ICoreFileReader corefile = null;
+		if (NewWinDump.isSupportedDump(file)) {
+			corefile = NewWinDump.dumpFromFile(file);
+		} else if (NewElfDump.isSupportedDump(file)) {
+			corefile = NewElfDump.dumpFromFile(file, verbose);
+		} else if (NewAixDump.isSupportedDump(file)) {
+			corefile = NewAixDump.dumpFromFile(file);
+		} //TODO: extend for other platforms
+			
+		return corefile;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpReader.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpReader.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/DumpReader.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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 javax.imageio.stream.ImageInputStream;
+
+
+public class DumpReader {
+	private ImageInputStream _file;
+	private boolean _is64Bit;
+
+	public DumpReader(ImageInputStream f, boolean is64Bit) {
+		_file = f;
+		_is64Bit = is64Bit;
+	}
+
+	public byte[] readBytes(int n) throws IOException {
+		byte[] buffer = new byte[n];
+		_file.readFully(buffer);
+		return buffer;
+	}
+
+	public int readInt() throws IOException {
+		return _file.readInt();
+	}
+
+	public void seek(long position) throws IOException {
+		_file.seek(position);
+	}
+
+	public long readLong() throws IOException {
+		return _file.readLong();
+	}
+
+	public short readShort() throws IOException {
+		return _file.readShort();
+	}
+
+	public byte readByte() throws IOException {
+		return _file.readByte();
+	}
+	
+	public long readAddress() throws IOException
+	{
+		long ptr = 0;
+		
+		if (_is64Bit) {
+			ptr = readLong();
+		} else {
+			ptr = (0xFFFFFFFFL & readInt());
+		}
+		return ptr;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/GenericThread.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/GenericThread.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/GenericThread.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/GenericThread.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+/*
+ *
+ * This represents a single "generic" thread within the dump and is basically a 
+ * data holding class (together with a toString() that allows a nice view of the 
+ * class ..... 
+ *  - what attributes does a "generic thread" have as against extenders representing
+ * a specific type of thread. System threads are generic threads and 
+ *  do not necessarily have same detail as java threads 
+ */
+package com.ibm.dtfj.corereaders;
+
+ 
+import java.util.Iterator;
+import java.util.Vector;
+
+ 
+public class GenericThread {
+	protected String threadId;
+	protected String javaLangThreadObjectAddress;
+	 
+	protected String threadDetails;
+	protected String threadName;
+	protected String state;
+	protected String monitorId;
+	boolean isJavaThread;
+	long stackstart = 0; // used by system threads
+	int stacksize = 0;	// used by system threads
+	int rva = 0;		// used by system threads
+	Vector registers = new Vector();
+	Vector nativeFrames = new Vector();
+	protected NativeThreadContext context = null;
+	
+	
+	public GenericThread(GenericThread thread) {
+		threadId = thread.getThreadId();
+		javaLangThreadObjectAddress = thread.javaLangThreadObjectAddress();
+		state = thread.getState();
+		monitorId = thread.getMonitorId();
+		isJavaThread = true; // only java threads use this constructor
+		 
+	}
+	
+	public GenericThread(String threadId, long stackstart, int stacksize,int rva) {
+		this.threadId = threadId; 
+		this.stackstart = stackstart;
+		this.stacksize = stacksize;
+		this.rva = rva;
+		this.state = "Unknown";
+		isJavaThread = false; // Only system threads use this constructor 
+	}	
+	
+	public GenericThread(String id, String obj,String state,String monitor) {
+		threadId = id;
+		javaLangThreadObjectAddress = obj;
+		this.state = state;
+		monitorId = monitor;
+		isJavaThread = true; // only java threads use this constructor
+	}
+
+	/**
+	 * 
+	 */
+	public   String javaLangThreadObjectAddress() {
+		// we assume they want details - so will fill in the details at ths point!
+		 
+		return javaLangThreadObjectAddress;
+	}
+
+	/**
+	 * 
+	 */
+	public   String getThreadId() {
+		return threadId;
+	}
+	
+	
+
+	/**
+	 * 
+	 */
+	public String getMonitorId() {
+		return monitorId;
+	}
+
+	/**
+	 * 
+	 */
+	public String getState() {
+		return state;
+	}
+
+	/**
+	 * 
+	 */
+	public String getThreadName() {
+		if (null == threadName) return " Un-established";
+		return threadName;
+	}
+
+	/**
+	 * 
+	 */	
+	public boolean isJavaThread() {
+		return false; 
+		
+	}
+	
+	/**
+	 * 
+	 */	
+	public void addRegister(Register r) {
+		 registers.add(r); 
+		
+	}
+	
+	public void addNativeFrame(StackFrame f) {
+		nativeFrames.add(f);
+	}
+	
+	public Register getNamedRegister(String name) {
+		// allow uppercase or lower case in the name
+		 
+		
+		String name1 = name.toUpperCase();
+		Iterator it = getRegisters();
+		while (it.hasNext()) {
+			 Register r = (Register)it.next();
+			 if (r.name.toUpperCase().equals(name1)) {
+			 	return r;
+			 }
+	
+		}
+
+		
+		return null;
+		
+	}
+	
+	public Iterator getRegisters() {
+		return registers.iterator();
+	}
+	
+	public Iterator getNativeFrames() {
+		return nativeFrames.iterator();
+	}
+
+	/**
+	 * @return Returns the stacksize.
+	 */
+	public int getStacksize() {
+		return stacksize;
+	}
+	
+	/**
+	 * @return Returns the stackstart.
+	 */
+	public long getStackstart() {
+		return stackstart;
+	}
+	
+	public String toString() {
+		
+		StringBuffer  sb = new StringBuffer();
+		
+		printHeader(sb);
+ 
+		 
+		sb.append(" System thread\n");
+		sb.append("  Id      : "+threadId + "\n");
+ 		
+		sb.append("  State   : "+ this.state);
+		
+		printNativeFrames(sb);
+		
+		sb.append("\n");
+		return sb.toString();
+		
+	}
+
+	public void printHeader(StringBuffer sb) {
+		sb.append("Info for system thread - "+ threadId + "\n====================================\n");
+	}
+
+	public void printNativeFrames(StringBuffer sb) {
+		if (0 != nativeFrames.size()) {
+			sb.append("\n\tStack:\n");
+			for (int i=0; i<nativeFrames.size();i++ ) {
+				StackFrame frameInfo = (StackFrame) nativeFrames.get(i);
+				if (null != frameInfo) {
+					sb.append("\t\t" + frameInfo.toString() + "\n");
+				}
+			}
+		} else sb.append("\n\t No Stack available");
+	}
+	
+	/**
+	 * @return Returns the context.
+	 */
+	public NativeThreadContext getContext() {
+		return context;
+	}
+	/**
+	 * @param context The context to set.
+	 */
+	public void setContext(NativeThreadContext context) {
+		this.context = context;
+	}
+	/**
+	 * @return Returns the javaLangThreadObjectAddress.
+	 */
+	public String getJavaLangThreadObjectAddress() {
+		return javaLangThreadObjectAddress;
+	}
+	/**
+	 * @param stacksize The stacksize to set.
+	 */
+	public void setStacksize(int stacksize) {
+		this.stacksize = stacksize;
+	}
+	/**
+	 * @param stackstart The stackstart to set.
+	 */
+	public void setStackstart(long stackstart) {
+		this.stackstart = stackstart;
+	}
+
+	public boolean matchIdOrName(String key) {
+		if ("*".equals(key)) {
+			return true;
+		} else {
+			String tid = getThreadId();
+			String name = getThreadName();
+			
+			if (tid.equals(key) ||
+				tid.toUpperCase().equals(key.toUpperCase()) ||
+				tid.equals("0x"+key) ||
+				tid.toUpperCase().equals(("0x"+key).toUpperCase())) {
+				
+				return true;
+			}
+			
+			if (null != name) {
+				if (name.equals(key) || 
+				name.toUpperCase().equals(key.toUpperCase()) ||
+				name.startsWith(key) ||
+				name.toUpperCase().startsWith(key.toUpperCase())) {
+					return true;
+				}
+			}
+			
+			String deriveThread = new String(key);
+			
+			if (deriveThread.toUpperCase().startsWith("0x")) {
+				deriveThread = deriveThread.substring(2);
+			}
+			while (deriveThread.startsWith("0")) {
+				deriveThread = deriveThread.substring(1);
+			}
+			deriveThread = "0x" + deriveThread;
+			deriveThread = deriveThread.toUpperCase();
+			if (tid.toUpperCase().equals(deriveThread)) {
+				return true;
+			}
+			
+		}
+		return false;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ICoreFileReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ICoreFileReader.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ICoreFileReader.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/ICoreFileReader.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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;
+
+import com.ibm.dtfj.addressspace.IAbstractAddressSpace;
+
+/**
+ * The top-level abstraction for reading core files.  This is the set of methods which are required by DTFJ.
+ */
+public interface ICoreFileReader
+{
+	/**
+	 * Used to extract OS-specific data.  Called with a builder which is a sort of factory which will create
+	 * the required implementation-specific data structures exist solely above the layer of this project.
+	 * 
+	 * @param builder
+	 */
+	public void extract(Builder builder);
+	
+	/**
+	 * @return An iterator of String object specifying names of additional files needed by the Dump
+	 * 
+	 * @see java.lang.String
+	 */
+	public Iterator getAdditionalFileNames();
+	
+	/**
+	 * Creates a representation of the address space capable of reading data from memory as a flat address
+	 * space even though it may be fragmented across regions of several files or transport media.
+	 * 
+	 * Note that this method is expected to be called several times and should always return the same instance.
+	 * 
+	 */
+	public IAbstractAddressSpace getAddressSpace();
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/LittleEndianDumpReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/LittleEndianDumpReader.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/LittleEndianDumpReader.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/LittleEndianDumpReader.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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;
+
+
+public class LittleEndianDumpReader extends DumpReader {
+	public LittleEndianDumpReader(ClosingFileReader f, boolean is64Bit)
+	{
+		super(f, is64Bit);
+	}
+
+	public short readShort() throws IOException {
+		return byteSwap(super.readShort());
+	}
+
+	public int readInt() throws IOException {
+		return byteSwap(super.readInt());
+	}
+
+	public long readLong() throws IOException {
+		return byteSwap(super.readLong());
+	}
+
+	private short byteSwap(short s) {
+		return (short)(((s >> 8) & 0x00ff) | ((s << 8) & 0xff00));
+	}
+
+	private int byteSwap(int i) {
+		return
+			((i >> 24) & 0x000000ff) |
+			((i >>  8) & 0x0000ff00) |
+			((i <<  8) & 0x00ff0000) |
+			((i << 24) & 0xff000000);
+	}
+
+	private long byteSwap(long l) {
+		return
+			((l >> 56) & 0x00000000000000ffL) |
+			((l >> 40) & 0x000000000000ff00L) |
+			((l >> 24) & 0x0000000000ff0000L) |
+			((l >>  8) & 0x00000000ff000000L) |
+			((l <<  8) & 0x000000ff00000000L) |
+			((l << 24) & 0x0000ff0000000000L) |
+			((l << 40) & 0x00ff000000000000L) |
+			((l << 56) & 0xff00000000000000L);
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryAccessException.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryAccessException.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryAccessException.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryAccessException.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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;
+
+/**
+ * Indicates that an attempt was made to access memory which is not included
+ * within the image
+ * 
+ */
+public class MemoryAccessException extends DumpException {
+	private static final long serialVersionUID = -5005905498150186101L;
+
+	public MemoryAccessException(int asid, long address, String description) {
+		super(null, asid, address, description);
+	}
+
+	public MemoryAccessException(int asid, long address) {
+		super(null, asid, address);
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryRange.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryRange.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryRange.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/MemoryRange.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+/*
+ * Dumps contain lots of memory - segmented across a range of virtual 
+ * addresses....... 
+ */
+package com.ibm.dtfj.corereaders;
+
+public class MemoryRange implements Comparable {
+	private static final String printableEBCDIC[] = {
+		"40"," ",
+		"F0","0",	"F1","1",	"F2","2",	"F3","3",	"F4","4",	"F5","5",
+		"F6","6",	"F7","7",	"F8","8",	"F9","9",	 	
+		"C1","A",	"C2","B",	"C3","C",	"C4","D",	"C5","E",
+		"C6","F",	"C7","G",	"C8","H",	"C9","I",	"D1","J",	"D2","K",
+		"D3","L",	"D4","M",	"D5","N",	"D6","O",	"D7","P",	"D8","Q",
+		"D9","R",	"E2","S",	"E3","T",	"E4","U",	"E5","V",	"E6","W",
+		"E7","X",	"E8","Y",	"E9","Z",
+		"81","a",	"82","b",	"83","c",	"84","d",	"85","e",
+		"86","f",	"87","g",	"88","h",	"89","i",	"91","j",	"92","k",
+		"93","l",	"94","m",	"95","n",	"96","o",	"97","p",	"98","q",
+		"99","r",	"A2","s",	"A3","t",	"A4","u",	"A5","v",	"A6","w",
+		"A7","x",	"A8","y",	"A9","z"
+	};
+	
+	private DumpReader _libraryReader = null;
+	private long _virtualAddress;
+	private long _fileOffset;
+	private long _size;
+	private boolean _inCoreFile = true;
+	private int _asid = 0;
+	private boolean _shared = false;
+	private boolean _readOnly = false;
+	private boolean _executable = true;
+	private boolean _permissionsSupported = false;	//this assumes that all permissions are either supported, or not.  This may not be valid
+
+	public MemoryRange(long virtualAddress, long fileOffset, long size)
+	{
+		_virtualAddress = virtualAddress;
+		_fileOffset = fileOffset;
+		_size = size;
+	}
+
+	public MemoryRange(long virtualAddress, long fileOffset, long size, int asid)
+	{
+		this(virtualAddress, fileOffset, size);
+		_asid = asid;
+	}
+
+	public MemoryRange(long virtualAddress, long fileOffset, long size, int asid, boolean isShared, boolean isReadOnly, boolean isExecutable)
+	{
+		this(virtualAddress, fileOffset, size, asid);
+		_shared = isShared;
+		_readOnly = isReadOnly;
+		_executable = isExecutable;
+		_permissionsSupported = true;
+	}
+
+	public MemoryRange(long virtualAddress, long fileOffset, long size, int asid, boolean isShared, boolean isReadOnly, boolean isExecutable, boolean inCoreFile)
+	{
+		this(virtualAddress, fileOffset, size, asid, isShared, isReadOnly, isExecutable);
+		_inCoreFile = inCoreFile;
+	}
+	
+	/**
+	 * Copy constructor, used when copying shared memory ranges into another address space
+	 * 
+	 * *return the new copy of the MemoryRange
+	 */
+	public MemoryRange(MemoryRange range, int asid)
+	{
+		this(range.getVirtualAddress(), range.getFileOffset(), range.getSize(), asid);
+		
+		_permissionsSupported = true;
+		try {
+			_shared = range.isShared();
+			_readOnly = range.isReadOnly();
+			_executable = range.isExecutable();
+			_inCoreFile = range.isInCoreFile();
+			_libraryReader = range.getLibraryReader();
+		} catch (MemoryAccessException exc) {
+			_permissionsSupported = false;
+		}
+	}
+
+	public boolean contains(long address)
+	{
+		return getVirtualAddress() <= address && address < getVirtualAddress() + getSize();
+	}
+
+	
+	public boolean contains(int asid, long address)
+	{
+		return (asid == _asid) && contains(address);
+	}
+	
+	/**
+	 * @return the file offset
+	 */
+	public long getFileOffset()
+	{
+		return _fileOffset;
+	}
+
+	/**
+	 * @return the number of bytes in this MemoryRange
+	 */
+	public long getSize()
+	{
+		return _size;
+	}
+	
+	/**
+	 * @return the base virtual address
+	 */
+	public long getVirtualAddress()
+	{
+		return _virtualAddress;
+	}
+
+	/**
+	 * @return true if this MemoryRange is located in the core file
+	 */
+	public boolean isInCoreFile()
+	{
+		return _inCoreFile;
+	}
+	
+	/**
+	 * @return the DumpReader for this MemoryRange
+	 */
+	public DumpReader getLibraryReader()
+	{
+		return _libraryReader;
+	}
+	
+	/**
+	 * Set the DumpReader for this MemoryRange
+	 * @return void
+	 */
+	public void setLibraryReader(DumpReader libraryReader)
+	{
+		_libraryReader = libraryReader;
+	}
+
+	public String toString()
+	{
+		StringBuffer sb = new StringBuffer();
+
+		sb.append("Addr: 0x" + Long.toHexString(getVirtualAddress()));
+		sb.append("   Size: 0x" + Long.toHexString(getSize()) + " (" + getSize() + ")");
+		sb.append("   File Offset: 0x" + Long.toHexString(getFileOffset()));
+		sb.append(" (" + getFileOffset() + ")");
+
+		if (_asid != 0) {
+			String tempASID = Integer.toHexString(_asid);
+			// OK we look to see it the complete ASID is in valid ebcdic 
+			// printable chars ..... if so convert to string so we can see the
+			// asid "name" such as SYS1 CICS etc.....
+			boolean bIsReadable = false;
+			StringBuffer sBuff = new StringBuffer("");
+			if (8 == tempASID.length()) {
+				bIsReadable = true;
+				for (int i = 0; i < 8 && bIsReadable; i = i + 2) {
+
+					String x = tempASID.substring(i, i + 2);
+					String y = isPrintableEbcdic(x);
+					if (null == y) {
+						bIsReadable = false;
+					} else {
+						sBuff.append(y);
+					}
+
+				}
+			}
+			if (true == bIsReadable) {
+				sb.append("   asid: " + sBuff);
+			} else {
+				sb.append("   asid: 0x" + Integer.toHexString(_asid));
+			}
+		}
+
+		return sb.toString();
+	}
+
+	// very simplistic and inefficient way of figuring out an ebcdic 
+	// printable char from hex characters
+	private String isPrintableEbcdic(String in)
+	{
+		in = in.toUpperCase();
+		for (int i = 0; i < printableEBCDIC.length; i = i + 2) {
+			if (in.equals(printableEBCDIC[i])) {
+				return printableEBCDIC[i + 1];
+			}
+
+		}
+
+		return null;
+	}
+
+	/**
+	 * 
+	 */
+	public int getAsid()
+	{
+		return _asid;
+	}
+
+	/**
+	 * @return true if this MemoryRange is marked executable
+	 * @throws MemoryAccessException 
+	 */
+	public boolean isExecutable() throws MemoryAccessException
+	{
+		if (_permissionsSupported) {
+			return _executable;
+		} else {
+			throw new MemoryAccessException(getAsid(), getVirtualAddress());
+		}
+	}
+
+	/**
+	 * @return true if this MemoryRange is marked read-only
+	 * @throws MemoryAccessException 
+	 */
+	public boolean isReadOnly() throws MemoryAccessException
+	{
+		if (_permissionsSupported) {
+			return _readOnly;
+		} else {
+			throw new MemoryAccessException(getAsid(), getVirtualAddress());
+		}
+	}
+
+	/**
+	 * @return true if this MemoryRange is marked shared
+	 * @throws MemoryAccessException 
+	 */
+	public boolean isShared() throws MemoryAccessException
+	{
+		if (_permissionsSupported) {
+			return _shared;
+		} else {
+			throw new MemoryAccessException(getAsid(), getVirtualAddress());
+		}
+	}
+
+	/**
+	 * @return Virtual address comparator.
+	 */
+	public int compareTo(Object o)
+	{
+		MemoryRange rhs = (MemoryRange) o;
+		// Take account of address spaces
+		if (_asid < rhs._asid) return -1;
+		if (_asid > rhs._asid) return 1;
+		
+		// Then compare addresses as unsigned quantities
+		if (_virtualAddress == rhs._virtualAddress) {
+			return 0;
+		} else if ((_virtualAddress >= 0 && rhs._virtualAddress >= 0)
+				|| (_virtualAddress < 0 && rhs._virtualAddress < 0)) {
+			return _virtualAddress < rhs._virtualAddress ? -1 : 1;
+		} else {
+			return _virtualAddress < rhs._virtualAddress ? 1 : -1;
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NativeThreadContext.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NativeThreadContext.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NativeThreadContext.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NativeThreadContext.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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;
+
+/**
+ * Basically used to help try and generalise stack traversal
+ */
+public class NativeThreadContext {
+	
+	long ee;
+    long pc;
+    long lr;
+    long sp;
+    long bp;
+
+
+    public NativeThreadContext () {}
+
+    public NativeThreadContext (int size, long ee, long pc, long lr, long sp, long bp ) {
+        long anderFlag = 0x00000000ffffffffL;
+        if (size == 64) {
+        	anderFlag = 0xffffffffffffffffL;
+        }
+    	this.ee = ee & anderFlag;
+        this.pc = pc & anderFlag;
+        this.lr = lr & anderFlag;
+        this.sp = sp & anderFlag;
+        this.bp = bp & anderFlag;
+    }
+
+    public void setEE(long ee) { this.ee = ee; }
+    public void setPc(long pc) { this.pc = pc; }
+    public void setLr(long lr) { this.lr = lr; }
+    public void setSp(long sp) { this.sp = sp; }
+    public void setBp(long bp) { this.bp = bp; }
+
+    public long getEE() { return ee; }
+    public long getPc() { return pc; }
+    public long getSp() { return sp; }
+    public long getBp() { return bp; }
+    public long getLr() { return lr; }
+
+}

Added: incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NewAixDump.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NewAixDump.java?rev=754943&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NewAixDump.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.common/src/com/ibm/dtfj/corereaders/NewAixDump.java Mon Mar 16 16:41:40 2009
@@ -0,0 +1,801 @@
+/*******************************************************************************
+ * 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.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import com.ibm.dtfj.addressspace.IAbstractAddressSpace;
+import com.ibm.dtfj.addressspace.LayeredAddressSpace;
+import com.ibm.dtfj.binaryreaders.ARReader;
+import com.ibm.dtfj.binaryreaders.XCOFFReader;
+
+public abstract class NewAixDump extends CoreReaderSupport {
+	private static final long PI_FLAGS2_OFFSET = 0x4fc;
+	private static final long FAULTING_THREAD_OFFSET = 216; // offsetof(core_dumpx, c_flt)
+	private static final int S64BIT = 0x00000001; // indicates a 64-bit process
+
+	private static final int POWER_RS1 = 0x0001;
+	private static final int POWER_RSC = 0x0002;
+	private static final int POWER_RS2 = 0x0004;
+	private static final int POWER_601 = 0x0008;
+	private static final int POWER_603 = 0x0020;
+	private static final int POWER_604 = 0x0010;
+	private static final int POWER_620 = 0x0040;
+	private static final int POWER_630 = 0x0080;
+	private static final int POWER_A35 = 0x0100;
+	private static final int POWER_RS64II = 0x0200;
+	private static final int POWER_RS64III = 0x0400;
+	private static final int POWER_4 = 0x0800;
+	//private static final int POWER_RS64IV = POWER_4;
+	private static final int POWER_MPC7450 = 0x1000;
+	private static final int POWER_5 = 0x2000;
+
+	protected NewAixDump(DumpReader reader)
+	{
+		super(reader);
+	}
+	
+	private static class Aix32Dump extends NewAixDump {
+		private static final int CONTEXT_OFFSET_IN_THREAD = 200; // offsetof(thrdctx, hctx)
+		private static final int IAR_OFFSET_IN_CONTEXT = 24; // offsetof(mstsave, iar)
+		private static final int GPR_OFFSET_IN_CONTEXT = 208; // offsetof(mstsave, gpr)
+		private static final int GPR_COUNT = 32;
+		//private static final int FPR_COUNT = 32;
+		
+		protected Aix32Dump(DumpReader reader) throws IOException
+		{
+			super(reader);
+			readCore();
+		}
+
+		protected int readLoaderInfoFlags() throws IOException {
+			return 0; // Do nothing
+		}
+
+		protected long userInfoOffset() {
+			// offsetof(core_dumpx, c_u)
+			return 1008;
+		}
+
+		protected int pointerSize() {
+			return 32;
+		}
+
+		protected Map readRegisters(long threadOffset) throws IOException {
+			Map registers = new TreeMap();
+			coreSeek(threadOffset + CONTEXT_OFFSET_IN_THREAD + IAR_OFFSET_IN_CONTEXT);
+			registers.put("iar", new Integer(coreReadInt()));
+			registers.put("msr", new Integer(coreReadInt()));
+			registers.put("cr", new Integer(coreReadInt()));
+			registers.put("lr", new Integer(coreReadInt()));
+			registers.put("ctr", new Integer(coreReadInt()));
+			registers.put("xer", new Integer(coreReadInt()));
+			registers.put("mq", new Integer(coreReadInt()));
+			registers.put("tid", new Integer(coreReadInt()));
+			registers.put("fpscr", new Integer(coreReadInt()));
+			coreSeek(threadOffset + CONTEXT_OFFSET_IN_THREAD + GPR_OFFSET_IN_CONTEXT);
+			for (int i = 0; i < GPR_COUNT; i++)
+				registers.put("gpr" + i, new Integer(coreReadInt()));
+			return registers;
+		}
+
+		protected long threadSize() {
+			// sizeof(thrdctx)
+			return 792;
+		}
+
+		protected long getStackPointerFrom(Map registers) {
+			return ((Integer) registers.get("gpr1")).intValue() & 0xffffffffL;
+		}
+
+		protected long getInstructionPointerFrom(Map registers) {
+			return ((Integer) registers.get("iar")).intValue() & 0xffffffffL;
+		}
+
+		protected long getLinkRegisterFrom(Map registers) {
+			return ((Integer) registers.get("lr")).intValue() & 0xffffffffL;
+		}
+		
+		protected int sizeofTopOfStack() {
+			// see struct top_of_stack in execargs.h
+			return 140 + 4;	//this is sizeof(top_of_stack) aligned to 8 bytes since that seems to be an unspoken requirement of this structure
+		}
+	}
+
+	private static class Aix64Dump extends NewAixDump {
+		private static final long CONTEXT_OFFSET_IN_THREAD = 424; // offsetof(thrdctx64, r64)
+		private static final int GPR_COUNT = 32;
+		//private static final int FPR_COUNT = 32;
+
+		protected Aix64Dump(DumpReader reader) throws IOException
+		{
+			super(reader);
+			readCore();
+		}
+
+		protected int readLoaderInfoFlags() throws IOException {
+			return coreReadInt();
+		}
+		
+		protected long userInfoOffset() {
+			// offsetof(core_dumpxx, c_u)
+			return 1216;
+		}
+
+		protected int pointerSize() {
+			return 64;
+		}
+
+		protected Map readRegisters(long threadOffset) throws IOException {
+			coreSeek(threadOffset + CONTEXT_OFFSET_IN_THREAD);
+			Map registers = new TreeMap();
+			for (int i = 0; i < GPR_COUNT; i++)
+				registers.put("gpr" + i, new Long(coreReadLong()));
+			registers.put("msr", new Long(coreReadLong()));
+			registers.put("iar", new Long(coreReadLong()));
+			registers.put("lr", new Long(coreReadLong()));
+			registers.put("ctr", new Long(coreReadLong()));
+			registers.put("cr", new Integer(coreReadInt()));
+			registers.put("xer", new Integer(coreReadInt()));
+			registers.put("fpscr", new Integer(coreReadInt()));
+			return registers;
+		}
+
+		protected long threadSize() {
+			// sizeof(thrdctx64)
+			return 1000;
+		}
+
+		protected long getStackPointerFrom(Map registers) {
+			return ((Long) registers.get("gpr1")).longValue();
+		}
+
+		protected long getInstructionPointerFrom(Map registers) {
+			return ((Long) registers.get("iar")).longValue();
+		}
+
+		protected long getLinkRegisterFrom(Map registers) {
+			return ((Long) registers.get("lr")).longValue();
+		}
+		
+		protected int sizeofTopOfStack() {
+			// see struct top_of_stack in execargs.h
+			return 304;	//this is sizeof(top_of_stack)
+		}
+	}
+	
+	private List _memoryRanges = new ArrayList();
+	private Set _additionalFileNames = new TreeSet();
+	private int _implementation;
+	private int _threadCount;
+	private long _threadOffset;
+	private long _lastModified;
+	private long _loaderOffset;
+	private long _loaderSize;
+	private LayeredAddressSpace _addressSpace;
+	private MemoryRange _stackRange = null;
+	//addresses required to find the bottom of the main thread's stack (for some reason called the "top of stack" in AIX documentation)
+	private long _structTopOfStackVirtualAddress;
+	
+	public static boolean isSupportedDump(ClosingFileReader f) throws IOException {
+		// There are no magic signatures in an AIX dump header.  Some simple validation of the header
+		// allows a best guess about validity of the file.
+		f.seek(8);
+		long fdsinfox = f.readLong();
+		long loader = f.readLong();
+		long filesize = f.length();
+		return fdsinfox > 0 && loader > 0 && loader > fdsinfox && fdsinfox < filesize && loader < filesize;
+	}
+
+	public static ICoreFileReader dumpFromFile(ClosingFileReader f) throws IOException {
+		assert isSupportedDump(f);
+		f.seek(PI_FLAGS2_OFFSET);
+		boolean is64Bit = (0 != (f.readInt() & S64BIT));
+		DumpReader reader = new DumpReader(f, is64Bit);
+		if (is64Bit) {
+			return new Aix64Dump(reader);
+		} else {
+			return new Aix32Dump(reader);
+		}
+	}
+	
+	protected void readCore() throws IOException
+	{
+		//Note that this structure is core_dumpx defined in "/usr/include/sys/core.h"
+		coreSeek(0);
+		coreReadByte(); // Ignore signalNumber
+		coreReadByte(); // Ignore flag (e.g. CORE_TRUNC == 0x80)
+		coreReadShort(); // Ignore entryCount
+		coreReadInt(); // Ignore version (core file format number)
+		coreReadLong(); // Ignore fdsinfox
+		_loaderOffset = coreReadLong();
+		_loaderSize = coreReadLong();
+		_threadCount = coreReadInt();
+		coreReadInt(); // Ignore padding
+		_threadOffset = coreReadLong();
+		long segmentCount = coreReadLong();
+		long segmentOffset = coreReadLong();
+
+		// Stack - this appears to be special handling for the main thread first attached to the address space
+		//		   (this is helpful for us since that is how we can find command line and env vars)
+		long stackOffset = coreReadLong();
+		long stackVirtualAddress = coreReadLong();
+		long stackSize = coreReadLong();
+		_structTopOfStackVirtualAddress = stackVirtualAddress  + stackSize  - sizeofTopOfStack();
+		
+		MemoryRange memoryRange1 = new MemoryRange(stackVirtualAddress, stackOffset, stackSize);
+		//memoryRange1.setDescription("stack");
+		_memoryRanges.add(memoryRange1);
+		
+		_stackRange  = memoryRange1;
+
+		// User data
+		long dataOffset = coreReadLong();
+		long dataVirtualAddress = coreReadLong();
+		long dataSize = coreReadLong();
+		MemoryRange memoryRange = new MemoryRange(dataVirtualAddress, dataOffset, dataSize);
+		//memoryRange.setDescription("user data");
+		_memoryRanges.add(memoryRange);
+
+		coreReadLong();	// Ignore sdataVirtualAddress
+		coreReadLong(); // Ignore sdataSize
+		
+		long vmRegionCount = coreReadLong();
+		long vmRegionOffset = coreReadLong();
+		_implementation = coreReadInt();
+		coreReadInt(); // Ignore padding
+		coreReadLong();	// Ignore checkpointRestartOffset
+		coreReadLong();	// Ignore unsigned long long c_extctx;    (Extended Context Table offset)
+
+		coreReadBytes(6 * 8); // Ignore padding (6 longs)
+		
+		//ignore struct thrdctx     c_flt;    (faulting thread's context)	//this is resolved later via that constant "FAULTING_THREAD_OFFSET"
+		//ignore struct userx       c_u;       (copy of the user structure)
+		//>> end of core_dumpx structure
+		
+		readVMRegions(vmRegionOffset, vmRegionCount);
+		readSegments(segmentOffset, segmentCount);
+		readLoaderInfoAsMemoryRanges();
+	}
+
+	private void readVMRegions(long offset, long count) throws IOException {
+		coreSeek(offset);
+		for (int i = 0; i < count; i++) {
+			long address = coreReadLong();
+			long size = coreReadLong();
+			long off = coreReadLong();
+			// Anonymously mapped area
+			MemoryRange memoryRange = new MemoryRange(address, off, size);
+			//memoryRange.setDescription("anon vm region");
+			_memoryRanges.add(memoryRange);
+		}
+	}
+
+	private void readSegments(long offset, long count) throws IOException {
+		coreSeek(offset);
+		for (int i = 0; i < count; i++) {
+			long address = coreReadLong();
+			long size = coreReadLong();
+			long off = coreReadLong();
+			coreReadInt(); // Ignore segmentFlags
+			coreReadInt(); // Ignore padding
+			// Anonymously mapped area
+			MemoryRange memoryRange = new MemoryRange(address, off, size);
+			//memoryRange.setDescription("anon segment");
+			_memoryRanges.add(memoryRange);
+		}
+	}
+	
+	private void readLoaderInfoAsMemoryRanges() throws IOException {
+		int next = 0;
+		long current = _loaderOffset;
+		do {
+			current += next;
+			coreSeek(current);
+			next = coreReadInt();
+			readLoaderInfoFlags(); // Ignore flags
+			long dataOffset = coreReadAddress();
+			coreReadAddress(); // Ignore textOrigin
+			coreReadAddress(); // Ignore textSize
+			long dataVirtualAddress = coreReadAddress();
+			long dataSize = coreReadAddress();
+			//String name = readString();
+			//String subname = readString();
+			//if (0 < subname.length())
+			//	name += "(" + subname + ")";
+			if (0 != dataOffset) {
+				MemoryRange memoryRange = new MemoryRange(dataVirtualAddress, dataOffset, dataSize);
+				//memoryRange.setDescription(name + " " + Long.toHexString(textOrigin) + "-" + Long.toHexString(textOrigin + textSize));
+				_memoryRanges.add(memoryRange);
+			}
+		} while (0 != next && current + next < _loaderOffset + _loaderSize);
+	}
+	
+	private List readLoaderInfoAsModules(Builder builder, Object addressSpace) throws IOException
+	{
+		List modules = new ArrayList();
+		int next = 0;
+		long current = _loaderOffset;
+		do {
+			current += next;
+			coreSeek(current);
+			next = coreReadInt();
+			readLoaderInfoFlags(); // Ignore flags
+			coreReadAddress(); // Ignore dataOffset
+			long textVirtualAddress = coreReadAddress();
+			long textSize = coreReadAddress();
+			long dataVirtualAddress = coreReadAddress();
+			long dataSize = coreReadAddress();
+			String fileName = readString();
+			String objectName = readString();
+			String moduleName = fileName;
+			if (0 < objectName.length()) {
+				moduleName += "(" + objectName + ")";
+			}
+			Object text = builder.buildModuleSection(addressSpace, ".text", textVirtualAddress, textVirtualAddress + textSize);
+			Object data = builder.buildModuleSection(addressSpace, ".data", dataVirtualAddress, dataVirtualAddress + dataSize);
+			List sections = new ArrayList();
+			sections.add(text);
+			sections.add(data);
+			XCOFFReader libraryReader = _openLibrary(builder, fileName, objectName);
+			_additionalFileNames.add(fileName);
+			if (null != libraryReader) {
+				Properties properties = libraryReader.moduleProperties();
+				List symbols = libraryReader.buildSymbols(builder, addressSpace, textVirtualAddress);
+				modules.add(builder.buildModule(moduleName, properties, sections.iterator(), symbols.iterator(),textVirtualAddress));
+				internalAddressSpace().mapRegion(textVirtualAddress, libraryReader.underlyingFile(), libraryReader.baseFileOffset(), textSize);
+			} else {
+				List symbols = Collections.singletonList(builder.buildCorruptData(addressSpace, "unable to find module " + moduleName, textVirtualAddress));
+				//here we will pass out a null for properties which can be thrown, from the other side, as DataUnavailable
+				modules.add(builder.buildModule(moduleName, null, sections.iterator(), symbols.iterator(),textVirtualAddress));
+			}
+		} while (0 != next && current + next < _loaderOffset + _loaderSize);
+		return modules;
+	}
+
+	/**
+	 * Returns an XCOFFReader for the library at the specified fileName.  If the library is an archive, the objectName is used to find the library
+	 * inside the archive and the reader will be for that "file"
+	 * 
+	 * Returns null if the library cannot be found or is not an understood XCOFF or AR archive
+	 * 
+	 * @param fileName
+	 * @param objectName
+	 * 
+	 */
+	private XCOFFReader _openLibrary(Builder builder, String fileName, String objectName)
+	{
+		//Note:  objectName is required to look up the actual module inside a library
+		XCOFFReader libraryReader = null;
+		ClosingFileReader library = null;
+		try {
+			library = builder.openFile(fileName);
+		} catch (FileNotFoundException e) {
+			//this is safe since we will just produce incomplete data
+		}
+		
+		if (null != library) {
+			//we found the library so figure out what it is and open it
+			long fileOffset = 0;
+			long fileSize = 0;
+			try {
+				try {
+					libraryReader = new XCOFFReader(library);
+					fileSize = library.length();
+				} catch (IllegalArgumentException e) {
+					//this will happen if we are looking at a .a file, for example
+					try {
+						ARReader archive = new ARReader(library);
+						fileSize = archive.sizeOfModule(objectName);
+						fileOffset = archive.offsetOfModule(objectName);
+						libraryReader = new XCOFFReader(library, fileOffset, fileSize);
+					} catch (IllegalArgumentException e2) {
+						//this might occur if we are on a different platform but have the same libraries around
+						libraryReader = null;
+					}
+				}
+			} catch (IOException e) {
+			}
+		}
+		return libraryReader;
+	}
+
+	private void readUserInfo(Builder builder, Object addressSpace) throws IOException {
+		
+		// Get the process ID
+		coreSeek(userInfoOffset());
+		int pid = coreReadInt();
+		
+		// Get the process command line. For AIX dumps we find the registers in the initial (top - this is to be consistent with AIX headers) 
+		// stack frame. Register 3 has the number of command line arguments (argc), register 4 has 
+		// a pointer to a list of pointers to the command line arguments (argv), and register 5 contains the pointer to the environment vars
+		String commandLine = "";
+		try
+		{
+			coreSeekVirtual(_structTopOfStackVirtualAddress);
+		}
+		catch (MemoryAccessException e)
+		{
+			//we will be unable to collect data from the core so return without populating (it is probably incomplete and provides no mapping for this part of memory)
+			return;
+		}
+		coreReadAddress();	//ignore GPR0
+		coreReadAddress();	//ignore GPR1
+		coreReadAddress();	//ignore GPR2
+		long reg3 = coreReadAddress();	//argc
+		long reg4 = coreReadAddress();	//argv
+		long reg5 = coreReadAddress();	//env
+		int argc = (int)reg3; // truncate to integer
+		
+		long[] addresses = new long[argc];
+		try
+		{
+			coreSeekVirtual(reg4);
+			for (int i = 0; i < reg3; i++) {
+				addresses[i] = coreReadAddress();
+			}
+			for (int i = 0; i < reg3; i++) {
+				try
+				{
+					coreSeekVirtual(addresses[i]);
+					commandLine += readString() + " ";
+				}
+				catch (MemoryAccessException e)
+				{
+					//this one is missing but we still want to collect the others - shouldn't happen
+				}
+			}
+		}
+		catch (MemoryAccessException e1)
+		{
+			//failed to read the command line so set it null so that we can detect it wasn't just empty (which would also be wrong but it a less obvious way)
+			commandLine = null;
+		}
+		
+		// NOTE modules must be read before thread information in order to properly support stack traces.
+		// Thread information is required before building the process, so the following order must be maintained:
+		// 1) Read module information.
+		// 2) Read thread information.
+		// 3) Build process.
+		List modules = readLoaderInfoAsModules(builder, addressSpace);
+		Object executable = null;
+		Iterator libraries = modules.iterator();
+		if (libraries.hasNext()) {
+			executable = libraries.next();
+		}
+		
+		List threads = readThreads(builder, addressSpace);
+		//the current thread is parsed before the rest so it is put first
+		Object currentThread = threads.get(0);
+
+		// Get the process environment variables
+		Properties environment = new Properties();
+		//on AIX, we should truse the env var pointer found in the core and ignore whatever the XML told us it is since this internal value is more likely correct
+		environment = getEnvironmentVariables(reg5);
+		
+		builder.buildProcess(addressSpace, String.valueOf(pid), commandLine, environment, currentThread, threads.iterator(), executable, libraries, pointerSize());
+	}
+	
+	/**
+	 * The environment structure is a null-terminated list of addresses which point to strings of form x=y
+	 * 
+	 * @param environmentAddress The pointer to the environment variables data structure
+	 * @return A property list of the key-value pairs found for the env vars
+	 * @throws IOException Failure reading the underlying core file
+	 */
+	private Properties getEnvironmentVariables(long environmentAddress) throws IOException
+	{
+		//make sure that the pointer is valid
+		if (0 == environmentAddress) {
+			return null;
+ 		}
+		
+		// Get the environment variable addresses
+		List addresses = new ArrayList();
+		try
+		{
+			coreSeekVirtual(environmentAddress);
+		}
+		catch (MemoryAccessException e1)
+		{
+			//the env var structure appears not to be mapped or the pointer is corrupt
+			return null;
+		}
+		long address = coreReadAddress();
+		while (address != 0) {
+			addresses.add(new Long(address));
+			address = coreReadAddress();
+		}
+
+         // Get the environment variables
+         Properties environment = new Properties();
+         for (Iterator iter = addresses.iterator(); iter.hasNext();) {
+        	 Long varAddress = (Long)iter.next();
+        	 String pair = null;
+             try {
+            	 coreSeekVirtual(varAddress.longValue());
+            	 pair = readString();
+             } catch (MemoryAccessException e) {
+                 // catch errors here, we can carry on getting other environment variables - unlikely to be missing only some of these
+                 continue;
+             }
+             if (null != pair)
+             {
+                 // Pair is the x=y string, now break it into key and value
+                 int equalSignIndex = pair.indexOf('=');
+                 if (equalSignIndex >= 0)
+                 {
+                     String key = pair.substring(0, equalSignIndex);
+                     String value = pair.substring(equalSignIndex + 1);
+                     environment.put(key, value);
+                 }
+             }
+         }
+
+         return environment;
+ }
+
+	private List readThreads(Builder builder, Object addressSpace) throws IOException {
+		List threads = new ArrayList();
+		threads.add(readThread(builder, addressSpace, FAULTING_THREAD_OFFSET));
+		for (int i = 0; i < _threadCount; i++) {
+			threads.add(readThread(builder, addressSpace, _threadOffset + i * threadSize()));
+		}
+		return threads;
+	}
+
+	private Object readThread(Builder builder, Object addressSpace, long offset) throws IOException
+	{
+		//Note that we appear to be parsing a "struct thrdsinfo" here which is described in "/usr/include/procinfo.h"
+		//	however, the shape for 64-bit is somewhat guessed since the structs thrdentry64 and thrdsinfo64 (for 64 and 32 bit dumps, respectively), which are listed in the documentation, don't appear to be the actual structures at work here
+		coreSeek(offset);
+		//tid is 64-bits one 64-bit platforms but 32-bits on 32-bit platforms
+		long tid = coreReadAddress();	//	unsigned long            ti_tid;      /* thread identifier */
+		coreReadInt();	//	unsigned long            ti_pid;      /* process identifier */
+        /* scheduler information */
+		int ti_policy = coreReadInt();	//	unsigned long               ti_policy;   /* scheduling policy */
+		int ti_pri = coreReadInt();	//	unsigned long               ti_pri;      /* current effective priority */
+		int ti_state = coreReadInt();	//	unsigned long               ti_state;    /* thread state -- from thread.h */
+		int ti_flag = coreReadInt();	//	unsigned long               ti_flag;     /* thread flags -- from thread.h */
+		int ti_scount = coreReadInt();	//	unsigned long               ti_scount;   /* suspend count */
+		int ti_wtype = coreReadInt();	//	unsigned long               ti_wtype;    /* type of thread wait */
+		int ti_wchan = coreReadInt();	//	unsigned long   ti_wchan;       /* wait channel */
+		int ti_cpu = coreReadInt();	//	unsigned long               ti_cpu;      /* processor usage */
+		int ti_cpuid = coreReadInt();	//	cpu_t              ti_cpuid;    /* processor on which I'm bound */
+		coreReadSigset();	//  sigset_t		ti_sigmask		/* sigs to be blocked */
+		coreReadSigset();	//  sigset_t        ti_sig;         /* pending sigs */
+		coreReadInt();	//  unsigned long   ti_code;        /* iar of exception */
+		coreReadAddress();	//  struct sigcontext *ti_scp;      /* sigctx location in user space */
+		int signalNumber = 0xFF & coreReadByte();	//  char            ti_cursig;      /* current/last signal taken */
+		
+	    Map registers = readRegisters(offset);
+	    Properties properties = new Properties();
+	    properties.put("scheduling policy", Integer.toHexString(ti_policy));
+	    properties.put("current effective priority", Integer.toHexString(ti_pri));
+	    properties.put("thread state", Integer.toHexString(ti_state));
+	    properties.put("thread flags", Integer.toHexString(ti_flag));
+	    properties.put("suspend count", Integer.toHexString(ti_scount));
+	    properties.put("type of thread wait", Integer.toHexString(ti_wtype));
+	    properties.put("wait channel", Integer.toHexString(ti_wchan));
+	    properties.put("processor usage", Integer.toHexString(ti_cpu));
+	    properties.put("processor on which I'm bound", Integer.toHexString(ti_cpuid));
+	    //the signal number should probably be exposed through a real API for, for now, it is interesting info so just return it
+	    properties.put("current/last signal taken", Integer.toHexString(signalNumber));
+	    
+	    List sections = new ArrayList();
+	    List frames = new ArrayList();
+	    long stackPointer = getStackPointerFrom(registers);
+	    long instructionPointer = getInstructionPointerFrom(registers);
+	    if (0 == instructionPointer || false == isValidAddress(instructionPointer)) {
+	    		instructionPointer = getLinkRegisterFrom(registers);
+	    }
+	    try {
+			if (0 != instructionPointer && 0 != stackPointer && isValidAddress(instructionPointer) && isValidAddress(stackPointer)) {
+				MemoryRange range = memoryRangeFor(stackPointer);
+				sections.add(builder.buildStackSection(addressSpace, range.getVirtualAddress(), range.getVirtualAddress() + range.getSize()));
+				frames.add(builder.buildStackFrame(addressSpace, stackPointer, instructionPointer));
+				IAbstractAddressSpace memory = getAddressSpace();
+				
+				while (range.contains(stackPointer)) {
+					stackPointer = memory.getPointerAt(0, stackPointer);
+					long stepping = ((64 == pointerSize()) ? 8 : 4);
+					long addressToRead = stackPointer + stepping;
+					addressToRead += stepping;//readAddress(); // Ignore conditionRegister
+					instructionPointer = memory.getPointerAt(0, addressToRead);
+					frames.add(builder.buildStackFrame(addressSpace, stackPointer, instructionPointer));
+				}
+			} else {
+	    			sections.add(builder.buildStackSection(addressSpace, _stackRange.getVirtualAddress(), _stackRange.getVirtualAddress() + _stackRange.getSize()));
+			}
+	    } catch (MemoryAccessException e) {
+	    		// Ignore
+	    }
+		return builder.buildThread(String.valueOf(tid), registersAsList(builder, registers).iterator(),
+				   				   sections.iterator(), frames.iterator(), properties, signalNumber);
+	}
+	
+	private void coreReadSigset() throws IOException
+	{
+		coreReadBytes(is64Bit() ? 32 : 8);
+	}
+
+	private boolean isValidAddress(long address)
+	{
+		try {
+			getAddressSpace().getByteAt(0, address);
+			return true;
+		} catch (MemoryAccessException e) {
+			return false;
+		}
+	}
+	
+	private MemoryRange memoryRangeFor(long address)
+	{
+		//TODO:  change the callers of this method to use some mechanism which will work better within the realm of the new address spaces
+		Iterator ranges = _memoryRanges.iterator();
+		MemoryRange match = null;
+		
+		while ((null == match) && ranges.hasNext()) {
+			MemoryRange range = (MemoryRange) ranges.next();
+			
+			if (range.contains(address)) {
+				match = range;
+			}
+		}
+		return match;
+	}
+	
+	private String readString() throws IOException {
+		StringBuffer buffer = new StringBuffer();
+		byte b = coreReadByte();
+		while (0 != b) {
+			buffer.append(new String(new byte[]{b}, "ASCII"));
+			b = coreReadByte();
+		}
+		return buffer.toString();
+	}
+
+	private List registersAsList(Builder builder, Map registers) {
+		List list = new ArrayList();
+		for (Iterator iter = registers.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry = (Map.Entry) iter.next();
+			list.add(builder.buildRegister((String) entry.getKey(), (Number) entry.getValue()));
+		}
+		return list;
+	}
+
+	protected abstract Map readRegisters(long threadOffset) throws IOException;
+	protected abstract int readLoaderInfoFlags() throws IOException;
+	protected abstract long userInfoOffset();
+	protected abstract long threadSize();
+	protected abstract int pointerSize();
+	protected abstract long getStackPointerFrom(Map registers);
+	protected abstract long getInstructionPointerFrom(Map registers);
+	protected abstract long getLinkRegisterFrom(Map registers);
+	protected abstract int sizeofTopOfStack();
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.corereaders.Dump#getMemoryRanges()
+	 */
+	public Iterator getMemoryRanges()
+	{
+		return _memoryRanges.iterator();
+	}
+
+	public void extract(Builder builder) {
+		try {
+			Object addressSpace = builder.buildAddressSpace("AIX Address Space", 0);
+			readUserInfo(builder, addressSpace);
+		} catch (IOException e) {
+			// Ignore
+		}
+		builder.setOSType("AIX");
+		builder.setCPUType("PowerPC");
+		builder.setCPUSubType(getProcessorSubtype());
+		builder.setCreationTime(getCreationTime());
+	}
+
+	public String getProcessorSubtype() {
+		switch (_implementation) {
+		case POWER_RS1: return "RS1";
+		case POWER_RSC: return "RSC";
+		case POWER_RS2: return "RS2";
+		case POWER_601: return "601";
+		case POWER_603: return "603";
+		case POWER_604: return "604";
+		case POWER_620: return "620";
+		case POWER_630: return "630";
+		case POWER_A35: return "A35";
+		case POWER_RS64II: return "RS64-II";
+		case POWER_RS64III: return "RS64-III";
+		case POWER_4: return "POWER 4";
+		case POWER_MPC7450: return "MPC7450";
+		case POWER_5: return "POWER 5";
+		default: return "";
+		}
+	}
+
+	public long getCreationTime() {
+		return _lastModified;
+	}
+
+	public Iterator getAdditionalFileNames() {
+		return _additionalFileNames.iterator();
+	}
+	
+	protected MemoryRange[] getMemoryRangesAsArray() {
+		return (MemoryRange[])_memoryRanges.toArray(new MemoryRange[_memoryRanges.size()]);
+	}
+	
+	private LayeredAddressSpace internalAddressSpace()
+	{
+		if (null == _addressSpace) {
+			IAbstractAddressSpace base = super.getAddressSpace();
+			_addressSpace = new LayeredAddressSpace(base, false, (64 == pointerSize()));
+		}
+		return _addressSpace;
+	}
+	
+	public IAbstractAddressSpace getAddressSpace()
+	{
+		return internalAddressSpace();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.corereaders.CoreReaderSupport#is64Bit()
+	 */
+	protected boolean is64Bit()
+	{
+		return (64 == pointerSize());
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ibm.dtfj.corereaders.CoreReaderSupport#isLittleEndian()
+	 */
+	protected boolean isLittleEndian()
+	{
+		//currently, all the AIX platforms we work with are big endian
+		return false;
+	}
+	
+	/**
+	 * Seeks the core file reader to the on-disk location of the given virtual address
+	 * @param virtualAddress The address we wish to seek to in the process's virtual address space
+	 * @throws MemoryAccessException If the virtual address does not map to a location on disk (either invalid location or unmapped in the core)
+	 * @throws IOException If the underlying file seek operation fails
+	 */
+	private void coreSeekVirtual(long virtualAddress) throws MemoryAccessException, IOException
+	{
+		MemoryRange range = memoryRangeFor(virtualAddress);
+		if (null == range)
+		{
+			throw new MemoryAccessException(0, virtualAddress);
+		}
+		else
+		{
+			long onDisk = range.getFileOffset() + (virtualAddress - range.getVirtualAddress());
+			coreSeek(onDisk);
+		}
+	}
+}



Mime
View raw message