Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Binary parser for AIX XCOFF32

This patch contains a binary parser core and UI elements to 'support' AIX 
XCOFF32 binaries.

Several notes:
- GNUXCoffBinaryParserPage inherits from GNUElfBinaryParserPage. It seems 
that GNU binutils look common on all platforms, so as a part of future 
work (HPUX SOM binary parser) I am planing to refactor common stuff to 
AbstractGNUBinaryParserPage.
- Not sure if it is intended behavior, but when addr2line actually returns 
a file name for a symbol address, CView only shows that filename as a 
child of a binary object file. Symbols inside the file cannot be seen.

Attached is a zip file with a sample project, with AIX XCOFF32 binaries, 
for committer's own joy and amusement. Make sure to turn off 'TAR file 
smart CR/LF conversion' before unzipping... :--).


For core ChangeLog.txt

Implementation of AIX XCOFF32 binary parser.

+ utils/org/eclipse/cdt/utils/xcoff/AR.java
+ utils/org/eclipse/cdt/utils/xcoff/XCoff32.java

+ utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java
+ utils/org/eclipse/cdt/utils/xcoff/parser/BinaryArchive.java
+ utils/org/eclipse/cdt/utils/xcoff/parser/XCOFF32Parser.java
+ utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java

For ui ChangeLog.txt

Implementation of AIX XCOFF32 binary parser page.

* src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java
+ src/org/eclipse/cdt/ui/dialogs/GNUXCoffBinaryParserPage.java


Thanks,
Vmir

Index: plugin.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/plugin.properties,v
retrieving revision 1.20
diff -u -r1.20 plugin.properties
--- plugin.properties	21 Jun 2004 15:34:49 -0000	1.20
+++ plugin.properties	21 Jun 2004 19:38:37 -0000
@@ -19,6 +19,7 @@
 GNUElfParser.name=GNU Elf Parser
 PEWindowsParser.name=PE Windows Parser
 CygwinPEParser.name=Cygwin PE Parser
+XCOFF32Parser.name=AIX XCOFF32 Parser
 
 CDTGNUCErrorParser.name=CDT GNU C/C++ Error Parser
 CDTGNUAssemblerErrorParser.name=CDT GNU Assembler Error Parser
Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/plugin.xml,v
retrieving revision 1.58
diff -u -r1.58 plugin.xml
--- plugin.xml	9 Jun 2004 12:37:19 -0000	1.58
+++ plugin.xml	21 Jun 2004 19:38:37 -0000
@@ -97,6 +97,16 @@
          </run>
       </cextension>
    </extension>
+   <extension
+         id="XCOFF32"
+         name="%XCOFF32Parser.name"
+         point="org.eclipse.cdt.core.BinaryParser">
+      <cextension>
+         <run
+               class="org.eclipse.cdt.utils.xcoff.parser.XCOFF32Parser">
+         </run>
+      </cextension>
+   </extension>
    <!-- This is for backward compatibility: an Typo was introduce in on of the realease
         and "ELF" instead of "Elf" -->
    <extension
Index: src/org/eclipse/cdt/internal/core/CCorePluginResources.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties,v
retrieving revision 1.14
diff -u -r1.14 CCorePluginResources.properties
--- src/org/eclipse/cdt/internal/core/CCorePluginResources.properties	10 Jun 2004 00:05:46 -0000	1.14
+++ src/org/eclipse/cdt/internal/core/CCorePluginResources.properties	21 Jun 2004 19:38:38 -0000
@@ -47,6 +47,7 @@
 Util.exception.notPE=Not a PE format
 Util.exception.notELF=Not ELF format
 Util.exception.notDOSFormat=Not DOS EXE format
+Util.exception.notXCOFF32=Not XCOFF32 format
 Util.exception.unknownFormat=Unknow machine/format
 Util.exception.nullPath=Path is null
 Util.exception.noFileAssociation=No file associated with Binary
Index: utils/org/eclipse/cdt/utils/xcoff/AR.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/xcoff/AR.java
diff -N utils/org/eclipse/cdt/utils/xcoff/AR.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/xcoff/AR.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,380 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.utils.xcoff;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Vector;
+
+import org.eclipse.cdt.core.CCorePlugin;
+
+/**
+ *  The <code>AR</code> class is used for parsing standard XCOFF32 archive (ar) files.
+ *
+ *  Each object within the archive is represented by an ARHeader class.  Each of
+ *  of these objects can then be turned into an XCOFF32 object for performing XCOFF32
+ *  class operations.
+ *  @see MemberHeader
+ * 
+ * @author vhirsl
+ */
+public class AR {
+	protected String filename;
+	protected RandomAccessFile file;
+	private ARHeader header;
+	private MemberHeader[] memberHeaders;
+
+	/**
+	 * TODO Provide description
+	 * 
+	 * @author vhirsl
+	 */
+	public class ARHeader {
+		private final static int SAIAMAG = 8;
+		
+		private byte[] fl_magic = new byte[SAIAMAG];// Archive magic string
+		private byte[] fl_memoff = new byte[20];	// Offset to member table
+		private byte[] fl_gstoff = new byte[20];	// Offset to global symbol table
+		private byte[] fl_gst64off = new byte[20];	// Offset to global symbol table for 64-bit objects  
+		private byte[] fl_fstmoff = new byte[20];	// Offset to first archive member
+		private byte[] fl_lstmoff = new byte[20];	// Offset to last archive member
+		private byte[] fl_freeoff = new byte[20];	// Offset to first member on free list
+		
+		private long fstmoff = 0;
+		private long lstmoff = 0;
+		private long memoff = 0;
+		
+		public ARHeader() throws IOException {
+			try {
+				getRandomAccessFile();
+				file.seek(0);
+				file.read(fl_magic);
+				if (isARHeader(fl_magic)) {
+					file.read(fl_memoff);
+					file.read(fl_gstoff);
+					file.read(fl_gst64off);
+					file.read(fl_fstmoff);
+					file.read(fl_lstmoff);
+					file.read(fl_freeoff);
+					fstmoff = Long.parseLong(removeBlanks(new String(fl_fstmoff)));
+					lstmoff = Long.parseLong(removeBlanks(new String(fl_lstmoff)));
+					memoff = Long.parseLong(removeBlanks(new String(fl_memoff)));
+				}
+				
+			} catch (IOException e) {
+				dispose();
+				CCorePlugin.log(e);
+			}
+		}
+
+		/**
+		 * @return boolean
+		 */
+		public boolean isXcoffARHeader() {
+			return (fstmoff != 0);
+		}
+
+	}
+
+	/**
+	 *  Creates a new <code>AR</code> object from the contents of 
+	 *  the given file.
+	 *
+	 *  @param filename The file to process.
+	 *  @throws IOException The file is not a valid archive.
+	 */
+	public AR(String filename) throws IOException {
+		this.filename = filename;
+		file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
+		header = new ARHeader();
+		if (!header.isXcoffARHeader()) {
+			file.close();
+			throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$
+		}
+	}
+
+	public void dispose() {
+		try {
+			if (file != null) {
+				file.close();
+				file = null;
+			}
+		} catch (IOException e) {
+		}
+	}
+
+	protected void finalize() throws Throwable {
+		try {
+			dispose();
+		} finally {
+			super.finalize();
+		}
+	}
+
+	public static boolean isARHeader(byte[] ident) {
+		if (ident.length < 8
+			|| ident[0] != '<'
+			|| ident[1] != 'b'
+			|| ident[2] != 'i'
+			|| ident[3] != 'g'
+			|| ident[4] != 'a'
+			|| ident[5] != 'f'
+			|| ident[6] != '>'
+			|| ident[7] != '\n')
+			return false;
+		return true;
+	}
+
+	/**
+	 * The <code>ARHeader</code> class is used to store the per-object file 
+	 *  archive headers.  It can also create an XCOFF32 object for inspecting
+	 *  the object file data.
+	 */
+	public class MemberHeader {
+		byte[] ar_size = new byte[20];		// File member size - decimal
+		byte[] ar_nxtmem = new byte[20];	// Next member offset - decimal
+		byte[] ar_prvmem = new byte[20];	// Previous member offset - decimal
+		byte[] ar_date = new byte[12];		// File member date - decimal
+		byte[] ar_uid = new byte[12];		// File member userid - decimal
+		byte[] ar_gid = new byte[12];		// File member group id - decimal
+		byte[] ar_mode = new byte[12];		// File member mode - octal
+		byte[] ar_namlen = new byte[4];		// File member name length -decimal
+		byte[] ar_name;						// Start of member name
+		byte[] ar_fmag = new byte[2];		// AIAFMAG - string to end "`\n"
+		
+		// converted values
+		long size;
+		long nxtmem;
+		long prvmem;
+		int namlen;
+		String name;
+		
+		long file_offset;
+
+		/**
+		 * Remove the padding from the archive header strings.
+		 */
+		private String removeBlanks(String str) {
+			while (str.charAt(str.length() - 1) == ' ')
+				str = str.substring(0, str.length() - 1);
+			return str;
+		}
+
+		/**
+		 * Look up the name stored in the archive's string table based
+		 * on the offset given. 
+		 *
+		 * Maintains <code>file</code> file location.
+		 *
+		 * @param offset 
+		 *    Offset into the string table for first character of the name.
+		 * @throws IOException 
+		 *    <code>offset</code> not in string table bounds.
+		 */
+//		private String nameFromStringTable(long offset) throws IOException {
+//			StringBuffer name = new StringBuffer(0);
+//			long pos = file.getFilePointer();
+//
+//			try {
+//				if (strtbl_pos != -1) {
+//					byte temp;
+//					file.seek(strtbl_pos + offset);
+//					while ((temp = file.readByte()) != '\n')
+//						name.append((char) temp);
+//				}
+//			} finally {
+//				file.seek(pos);
+//			}
+//
+//			return name.toString();
+//		}
+
+		/**
+		 * Creates a new archive header object.  
+		 *
+		 * Assumes that file is already at the correct location in the file.
+		 *
+		 * @throws IOException 
+		 *    There was an error processing the header data from the file.
+		 */
+		public MemberHeader() throws IOException {
+			//
+			// Read in the archive header data. Fixed sizes.
+			//
+			file.read(ar_size);
+			file.read(ar_nxtmem);
+			file.read(ar_prvmem);
+			file.read(ar_date);
+			file.read(ar_uid);
+			file.read(ar_gid);
+			file.read(ar_mode);
+			file.read(ar_namlen);
+			namlen = Integer.parseInt(removeBlanks(new String(ar_namlen)));
+			ar_name = new byte[namlen];
+			file.read(ar_name);
+			file.read(ar_fmag);
+
+			size = Long.parseLong(removeBlanks(new String(ar_size)));
+			nxtmem = Long.parseLong(removeBlanks(new String(ar_nxtmem)));
+			prvmem = Long.parseLong(removeBlanks(new String(ar_prvmem)));
+			name = new String(ar_name, 0, namlen);
+			
+			//
+			// Save this location so we can create the XCOFF32 object later.
+			//
+			file_offset = file.getFilePointer();
+			if ((file_offset % 2) == 1) {
+				++file_offset;
+			}
+		}
+
+		/** Get the name of the object file */
+		public String getObjectName() {
+			return name;
+		}
+
+		/** Get the size of the object file . */
+		public long getSize() {
+			return size;
+		}
+		
+		public String getArchiveName() {
+			return filename;
+		}
+
+		/**
+		 *  Create an new XCOFF32 object for the object file.
+		 *
+		 * @throws IOException 
+		 *    Not a valid XCOFF32 object file.
+		 * @return A new XCOFF32 object.  
+		 * @see XCoff32#XCoff32( String, long )
+		 */
+		public XCoff32 getXCoff() throws IOException {
+			return new XCoff32(filename, file_offset);
+		}
+
+		public byte[] getObjectData() throws IOException {
+			byte[] temp = new byte[(int) size];
+			file = getRandomAccessFile();
+			file.seek(file_offset);
+			file.read(temp);
+			dispose();
+			return temp;
+		}
+	}
+
+	/** Load the headers from the file (if required).  */
+	private void loadHeaders() throws IOException {
+		if (memberHeaders != null)
+			return;
+
+		Vector v = new Vector();
+		try {
+			//
+			// Check for EOF condition
+			//
+			MemberHeader aHeader;
+			for (long pos = header.fstmoff; pos < file.length(); pos = aHeader.nxtmem) {
+				file.seek(pos);
+				aHeader = new MemberHeader();
+				String name = aHeader.getObjectName();
+				v.add(aHeader);
+				if (pos == 0 || pos == header.lstmoff) {	// end of double linked list
+					break;
+				}
+			}
+		} catch (IOException e) {
+		}
+		memberHeaders = (MemberHeader[]) v.toArray(new MemberHeader[0]);
+	}
+
+	/**
+	 *  Get an array of all the object file headers for this archive.
+	 * 
+	 * @throws IOException 
+	 *    Unable to process the archive file.
+	 * @return An array of headers, one for each object within the archive.
+	 * @see ARHeader
+	 */
+	public MemberHeader[] getHeaders() throws IOException {
+		loadHeaders();
+		return memberHeaders;
+	}
+
+	public String[] extractFiles(String outdir, String[] names) throws IOException {
+		Vector names_used = new Vector();
+		String object_name;
+		int count;
+
+		loadHeaders();
+
+		count = 0;
+		for (int i = 0; i < memberHeaders.length; i++) {
+			object_name = memberHeaders[i].getObjectName();
+			if (names != null && !stringInStrings(object_name, names))
+				continue;
+
+			object_name = "" + count + "_" + object_name; //$NON-NLS-1$ //$NON-NLS-2$
+			count++;
+
+			byte[] data = memberHeaders[i].getObjectData();
+			File output = new File(outdir, object_name);
+			names_used.add(object_name);
+
+			RandomAccessFile rfile = new RandomAccessFile(output, "rw"); //$NON-NLS-1$
+			rfile.write(data);
+			rfile.close();
+		}
+
+		return (String[]) names_used.toArray(new String[0]);
+	}
+
+	private boolean stringInStrings(String str, String[] set) {
+		for (int i = 0; i < set.length; i++)
+			if (str.compareTo(set[i]) == 0)
+				return true;
+		return false;
+	}
+
+	/**
+	 * Remove the padding from the archive header strings.
+	 */
+	private String removeBlanks(String str) {
+		while (str.charAt(str.length() - 1) == ' ')
+			str = str.substring(0, str.length() - 1);
+		return str;
+	}
+
+	public String[] extractFiles(String outdir) throws IOException {
+		return extractFiles(outdir, null);
+	}
+
+	private RandomAccessFile getRandomAccessFile () throws IOException {
+		if (file == null) {
+			file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
+		}
+		return file;
+	}
+
+	public static void main(String[] args) {
+		try {
+			AR ar = new AR(args[0]);
+			ar.getHeaders();
+			ar.extractFiles(args[0]);
+			System.out.println(ar);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}
+
Index: utils/org/eclipse/cdt/utils/xcoff/XCoff32.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/xcoff/XCoff32.java
diff -N utils/org/eclipse/cdt/utils/xcoff/XCoff32.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/xcoff/XCoff32.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,828 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.utils.xcoff;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.utils.coff.ReadMemoryAccess;
+
+/**
+ * TODO Provide description
+ * 
+ * @author vhirsl
+ */
+public class XCoff32 {
+	public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	
+	String filename;
+	FileHeader filehdr;
+	OptionalHeader opthdr;
+	RandomAccessFile rfile;
+	long startingOffset;
+	byte[] string_table;
+	SectionHeader[] scnhdrs;
+	Symbol[] symbols;
+	
+	public static class FileHeader {
+		public final static int FILHSZ = 20;
+		
+		// Consts
+		public final static int U802TOCMAGIC = 0x01df;	// XCOFF32
+		public final static int U803TOCMAGIC = 0x01e7;	// obsolete XCOFF64 - not used
+		public final static int U803XTOCMAGIC = 0x01ef;	// discontinued AIX XCOFF64
+		public final static int U64_TOCMAGIC = 0x01f7;	// XCOFF64
+
+		// Flags
+		public final static int F_RELFLG = 0x0001; // relocation info stripped from file
+		public final static int F_EXEC = 0x0002;   // file is executable
+							   //  (no unresolved external references)
+		public final static int F_LNNO = 0x0004;   // line numbers stripped from file
+		public final static int F_LSYMS = 0x0008;  // local symbols stripped from file
+		public final static int F_FDPR_PROF = 0x0010;	// file was profiled with fdpr command
+		public final static int F_FDPR_OPTI = 0x0020;	// file was reordered with fdpr command
+		public final static int F_DSA = 0x0040;	// file uses Very Large Program Support
+//		public final static int F_AR16WR = 0x0080; // file is 16-bit little-endian
+//		public final static int F_AR32WR = 0x0100; // file is 32-bit little-endian
+//		public final static int F_AR32W = 0x0200;  // file is 32-bit big-endian
+		public final static int F_DYNLOAD = 0x1000;	// rs/6000 aix: dynamically
+							   // loadable w/imports & exports
+		public final static int F_SHROBJ = 0x2000; 	// rs/6000 aix: file is a shared object
+		public final static int F_LOADONLY = 0x4000;// rs/6000 aix: if the object file is a member of an archive;
+							   // it can be loaded by the system loader but the member is ignored by the binder.
+
+		// Fields
+		public short f_magic;	/* 00-01 2 bytes: magic number                 */
+		public short f_nscns;	/* 02-03 2 bytes: number of sections: 2 bytes  */
+		public int f_timdat;	/* 04-07 4 bytes: time & date stamp            */
+		public int f_symptr;	/* 08-11 4 bytes: file pointer to symtab       */
+		public int f_nsyms;		/* 12-15 4 bytes: number of symtab entries     */
+		public short f_opthdr;	/* 16-17 2 bytes: sizeof(optional hdr)         */
+		public short f_flags;	/* 18-19 2 bytes: flags                        */
+
+		public FileHeader (RandomAccessFile file) throws IOException {
+			this(file, file.getFilePointer());
+		}
+
+		public FileHeader (RandomAccessFile file, long offset) throws IOException {
+			file.seek(offset);
+			byte[] hdr = new byte[FILHSZ];
+			file.readFully(hdr);
+			commonSetup(hdr, false);
+		}
+
+		public FileHeader (byte[] hdr, boolean little) throws IOException {
+			commonSetup(hdr, little);
+		}
+
+		public void commonSetup(byte[] hdr, boolean little) throws IOException {
+			if (hdr == null || hdr.length < FILHSZ) {
+				throw new EOFException(CCorePlugin.getResourceString("Util.exception.arrayToSmall")); //$NON-NLS-1$
+			}
+			if (!isXCOFF32Header(hdr)) {
+				throw new IOException(CCorePlugin.getResourceString("Util.exception.notXCOFF32")); //$NON-NLS-1$
+			}
+			ReadMemoryAccess memory = new ReadMemoryAccess(hdr, little);
+			f_magic = memory.getShort();
+			f_nscns = memory.getShort();
+			f_timdat = memory.getInt();
+			f_symptr = memory.getInt();
+			f_nsyms = memory.getInt();
+			f_opthdr = memory.getShort();
+			f_flags = memory.getShort();
+		}
+
+		public boolean isStrip() {
+			return (f_flags & F_RELFLG) == F_RELFLG;
+		}
+
+		public boolean isExec() {
+			return (f_flags & F_EXEC) == F_EXEC;
+		}
+
+		public boolean isDebug() {
+			return !((f_flags & F_LNNO) == F_LNNO);
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("FILE HEADER VALUES").append(NL); //$NON-NLS-1$
+
+			buffer.append("f_magic  = ").append(f_magic).append(NL); //$NON-NLS-1$
+			buffer.append("f_nscns  = ").append(f_nscns).append(NL); //$NON-NLS-1$
+
+			buffer.append("f_timdat = "); //$NON-NLS-1$
+			buffer.append(DateFormat.getDateInstance().format(new Date(f_timdat)));
+			buffer.append(NL);
+
+			buffer.append("f_symptr = ").append(f_symptr).append(NL); //$NON-NLS-1$
+			buffer.append("f_nsyms  = ").append(f_nsyms).append(NL); //$NON-NLS-1$
+			buffer.append("f_opthdr = ").append(f_opthdr).append(NL); //$NON-NLS-1$
+			buffer.append("f_flags  = ").append(f_flags).append(NL); //$NON-NLS-1$
+			return buffer.toString();
+		}
+	}
+
+	public static class OptionalHeader {
+		public final static int AOUTHDRSZ = 72;	// First 28 bytes same as for COFF
+
+		// Fields (as in COFF)
+		public short magic;		/* 2 bytes: type of file (0x010B)               	*/
+		public short vstamp;	/* 2 bytes: version stamp (1)                   	*/
+		public int tsize;		/* 4 bytes: text size in bytes, padded to FW bdry	*/
+		public int dsize;		/* 4 bytes: initialized data "  "               	*/
+		public int bsize;		/* 4 bytes: uninitialized data "   "            	*/
+		public int entry;		/* 4 bytes: entry pt.                           	*/
+		public int text_start;	/* 4 bytes: base of text used for this file     	*/
+		public int data_start;	/* 4 bytes: base of data used for this file     	*/
+		// Additional fields
+		public int o_toc;	   	/* 4 bytes: Address of TOC anchor 					*/
+		public short o_snentry;	/* 2 bytes: Section number for entry point			*/
+		public short o_sntext; 	/* 2 bytes: Section number for .text				*/
+		public short o_sndata; 	/* 2 bytes: Section number for .data				*/
+		public short o_sntoc;	/* 2 bytes: Section number for TOC					*/
+		public short o_snloader;/* 2 bytes: Section number for loader data			*/
+		public short o_snbss;	/* 2 bytes: Section number for .bss					*/
+		public short o_algntext;/* 2 bytes: Maximum alignment for .text				*/
+		public short o_algndata;/* 2 bytes: Maximum alignment for .data				*/
+		public short o_modtype;	/* 2 bytes: Maximum alignment for .data				*/
+		public byte o_cpuflag;	/* 1 byte: Bit flags - cpu types of objects			*/		
+		public byte o_cputype;	/* 1 byte: Reserved for cpu type					*/
+		public int o_maxstack;	/* 4 bytes: Maximum stack size allowed (bytes)		*/
+		public int o_maxdata;	/* 4 bytes: Maximum data size allowed (bytes)		*/
+		public int o_debugger;	/* 4 bytes: Reserved for debuggers					*/
+//		public byte o_resv2[8];	/* 8 bytes: Reserved. Field must contain 0s			*/
+
+		public OptionalHeader(RandomAccessFile file) throws IOException {
+			this(file, file.getFilePointer() + FileHeader.FILHSZ);
+		}
+
+		public OptionalHeader(RandomAccessFile file, long offset) throws IOException {
+			file.seek(offset);
+			byte[] hdr = new byte[AOUTHDRSZ];
+			file.readFully(hdr);
+			ReadMemoryAccess memory = new ReadMemoryAccess(hdr, false);	// big endian
+			// COFF common
+			magic = memory.getShort();
+			vstamp = memory.getShort();
+			tsize = memory.getInt();
+			dsize = memory.getInt();
+			bsize = memory.getInt();
+			entry = memory.getInt();
+			text_start = memory.getInt();
+			data_start = memory.getInt();
+			// XCOFF32 specific
+			o_toc = memory.getInt();
+			o_snentry = memory.getShort();
+			o_sntext = memory.getShort();
+			o_sndata = memory.getShort();
+			o_sntoc = memory.getShort();
+			o_snloader = memory.getShort();
+			o_snbss = memory.getShort();
+			o_algntext = memory.getShort();
+			o_algndata = memory.getShort();
+			o_modtype = memory.getShort();
+			o_cpuflag = memory.getByte();
+			o_cputype = memory.getByte();
+			o_maxstack = memory.getInt();
+			o_maxdata = memory.getInt();
+			o_debugger = memory.getInt();
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("OPTIONAL HEADER VALUES").append(NL); //$NON-NLS-1$
+			buffer.append("magic      = ").append(magic).append(NL); //$NON-NLS-1$
+			buffer.append("vstamp     = ").append(vstamp).append(NL); //$NON-NLS-1$
+			buffer.append("tsize      = ").append(tsize).append(NL); //$NON-NLS-1$
+			buffer.append("dsize      = ").append(dsize).append(NL); //$NON-NLS-1$
+			buffer.append("bsize      = ").append(bsize).append(NL); //$NON-NLS-1$
+			buffer.append("entry      = ").append(entry).append(NL); //$NON-NLS-1$
+			buffer.append("text_start = ").append(text_start).append(NL); //$NON-NLS-1$
+			buffer.append("data_start = ").append(data_start).append(NL); //$NON-NLS-1$
+			buffer.append("o_toc      = ").append(o_toc).append(NL); //$NON-NLS-1$
+			buffer.append("o_snentry  = ").append(o_snentry).append(NL); //$NON-NLS-1$
+			buffer.append("o_sntext   = ").append(o_sntext).append(NL); //$NON-NLS-1$
+			buffer.append("o_sndata   = ").append(o_sndata).append(NL); //$NON-NLS-1$
+			buffer.append("o_sntoc    = ").append(o_sntoc).append(NL); //$NON-NLS-1$
+			buffer.append("o_snloader = ").append(o_snloader).append(NL); //$NON-NLS-1$
+			buffer.append("o_snbss    = ").append(o_snbss).append(NL); //$NON-NLS-1$
+			buffer.append("o_algntext = ").append(o_algntext).append(NL); //$NON-NLS-1$
+			buffer.append("o_algndata = ").append(o_algndata).append(NL); //$NON-NLS-1$
+			buffer.append("o_modtype  = ").append(o_modtype).append(NL); //$NON-NLS-1$
+			buffer.append("o_cpuflag  = ").append(o_cpuflag).append(NL); //$NON-NLS-1$
+			buffer.append("o_cputype  = ").append(o_cputype).append(NL); //$NON-NLS-1$
+			buffer.append("o_maxstack = ").append(o_maxstack).append(NL); //$NON-NLS-1$
+			buffer.append("o_maxdata  = ").append(o_maxdata).append(NL); //$NON-NLS-1$
+			buffer.append("o_debugger = ").append(o_debugger).append(NL); //$NON-NLS-1$
+			return buffer.toString();
+		}
+	}
+
+	public static class SectionHeader {
+		public final static int SCNHSZ = 40;
+
+		/* names of "special" sections */
+		public final static String _TEXT = ".text"; //$NON-NLS-1$
+		public final static String _DATA = ".data"; //$NON-NLS-1$
+		public final static String _BSS = ".bss"; //$NON-NLS-1$
+		public final static String _PAD = ".pad"; //$NON-NLS-1$
+		public final static String _LOADER = ".loader"; //$NON-NLS-1$
+		public final static String _DEBUG = ".debug"; //$NON-NLS-1$
+		public final static String _TYPCHK = ".typchk"; //$NON-NLS-1$
+		public final static String _EXCEPT = ".except"; //$NON-NLS-1$
+		public final static String _OVRFLO = ".ovrflo"; //$NON-NLS-1$
+		public final static String _INFO = ".info"; //$NON-NLS-1$
+
+		/* s_flags "type".  */
+//		public final static int STYP_REG = 0x0000;    /* "regular": allocated, relocated,
+//								loaded */
+//		public final static int STYP_DSECT = 0x0001;  /* "dummy":  relocated only */
+//		public final static int STYP_NOLOAD = 0x0002; /* "noload": allocated, relocated,
+//								not loaded */
+//		public final static int STYP_GROUP = 0x0004;  /* "grouped": formed of input
+//								sections */
+		public final static int STYP_PAD = 0x0008;    /* "padding": not allocated, not
+								relocated, loaded */
+//		public final static int STYP_COPY = 0x0010;   /* "copy": for decision function
+//								used by field update;
+//								not allocated, not relocated,
+//								loaded; reloc & lineno entries
+//								processed normally */
+		public final static int STYP_TEXT = 0x0020;   /* section contains text only.  */
+//		public final static int S_SHRSEG = 0x0020;    /* In 3b Update files (output of
+//								ogen), sections which appear in
+//								SHARED segments of the Pfile
+//								will have the S_SHRSEG flag set
+//								by ogen, to inform dufr that
+//								updating 1 copy of the proc. will
+//								update all process invocations. */
+		public final static int STYP_DATA = 0x0040;   /* section contains data only */
+		public final static int STYP_BSS = 0x0080;    /* section contains bss only */
+		public final static int STYP_EXCEPT = 0x0080;    /* section contains exceptions info only */
+//		public final static int S_NEWFCN = 0x0100;    /* In a minimal file or an update
+//								file, a new function (as
+//								compared with a replaced
+//								function) */
+		public final static int STYP_INFO = 0x0200;   /* comment: not allocated not
+								relocated, not loaded */
+//		public final static int STYP_OVER = 0x0400;   /* overlay: relocated not allocated
+//								or loaded */
+//		public final static int STYP_LIB = 0x0800;    /* for .lib: same as INFO */
+		public final static int STYP_LOADER = 0x1000;  /* loader section:
+								imported symbols,
+								exported symbols,
+								relocation data,
+								type-check information and
+								shared object names */
+//		public final static int STYP_MERGE = 0x2000;  /* merge section -- combines with
+//								text, data or bss sections only */
+		public final static int STYP_DEBUG = 0x2000;  /* debug section - su
+								information used by the symbolic debugger */
+//		public final static int STYP_REVERSE_PAD = 0x4000; /* section will be padded
+//								with no-op instructions
+//								wherever padding is necessary
+//								and there is a word of
+//								contiguous bytes beginning on a
+//								word boundary. */
+		public final static int STYP_TYPCHK = 0x4000; /* type-check section - contains
+								parameter/argument type-check strings used by the binder */
+		public final static int STYP_OVRFLO = 0x8000; /* overflow section:
+								Specifies a relocation or line-number field overflow section.
+								A section header of this type contains the count of relocation 
+								entries and line number entries for some other section. 
+								This section header is required when either of the counts
+								exceeds 65,534. */
+
+//		public final static int STYP_LIT = 0x8020;  /* Literal data (like STYP_TEXT) */
+
+
+		public byte[] s_name= new byte[8]; // 8 bytes: section name
+		public int s_paddr;    // 4 bytes: physical address, aliased s_nlib
+		public int s_vaddr;    // 4 bytes: virtual address
+		public int s_size;     // 4 bytes: section size
+		public int s_scnptr;   // 4 bytes: file ptr to raw data for section
+		public int s_relptr;   // 4 bytes: file ptr to relocation
+		public int s_lnnoptr;  // 4 bytes: file ptr to line numbers
+		public short s_nreloc;   // 2 bytes: number of relocation entries
+		public short s_nlnno;    // 2 bytes: number of line number entries
+		public int s_flags;    // 4 bytes: flags
+
+		RandomAccessFile sfile;
+
+		public SectionHeader(RandomAccessFile file, long offset) throws IOException {
+			sfile = file;
+			file.seek(offset);
+			byte[] hdr = new byte[SCNHSZ];
+			file.readFully(hdr);
+			ReadMemoryAccess memory = new ReadMemoryAccess(hdr, false);
+			memory.getBytes(s_name);
+			s_paddr = memory.getInt();
+			s_vaddr = memory.getInt();
+			s_size = memory.getInt();
+			s_scnptr = memory.getInt();
+			s_relptr = memory.getInt();
+			s_lnnoptr = memory.getInt();
+			s_nreloc = memory.getShort();
+			s_nlnno = memory.getShort();
+			s_flags = memory.getInt();
+		}
+
+		public byte[] getRawData() throws IOException {
+			byte[] data = new byte[s_size];
+			sfile.seek(s_scnptr);
+			sfile.readFully(data);
+			return data;
+		}
+
+//		public Reloc[] getRelocs() throws IOException {
+//			Reloc[] relocs = new Reloc[s_nreloc];
+//			sfile.seek(s_relptr);
+//			for (int i = 0; i < s_nreloc; i++) {
+//				relocs[i] = new Reloc(sfile);
+//			}
+//			return relocs;
+//		}
+//
+//		public Lineno[] getLinenos() throws IOException {
+//			Lineno[] lines = new Lineno[s_nlnno];
+//			sfile.seek(s_lnnoptr);
+//			for (int i = 0; i < s_nlnno; i++) {
+//				lines[i] = new Lineno(sfile);
+//			}
+//			return lines;
+//		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("SECTION HEADER VALUES").append(NL); //$NON-NLS-1$
+			buffer.append(new String(s_name)).append(NL);
+			buffer.append("s_paddr = ").append(s_paddr).append(NL); //$NON-NLS-1$
+			buffer.append("s_vaddr = ").append(s_vaddr).append(NL); //$NON-NLS-1$
+			buffer.append("s_size = ").append(s_size).append(NL); //$NON-NLS-1$
+			buffer.append("s_scnptr = ").append(s_scnptr).append(NL); //$NON-NLS-1$
+			buffer.append("s_relptr = ").append(s_relptr).append(NL); //$NON-NLS-1$
+			buffer.append("s_lnnoptr = ").append(s_lnnoptr).append(NL); //$NON-NLS-1$
+			buffer.append("s_nreloc = ").append(s_nreloc).append(NL); //$NON-NLS-1$
+			buffer.append("s_nlnno = ").append(s_nlnno).append(NL); //$NON-NLS-1$
+			buffer.append("s_flags = ").append(s_flags).append(NL); //$NON-NLS-1$
+/*
+			try {
+				Reloc[] rcs = getRelocs();
+				for (int i = 0; i < rcs.length; i++) {
+					buffer.append(rcs[i]);
+				}
+			} catch (IOException e) {
+			}
+			try {
+				Lineno[] nos = getLinenos();
+				for (int i = 0; i < nos.length; i++) { 
+					buffer.append(nos[i]);
+				}
+			} catch (IOException e) {
+			}
+*/
+			return buffer.toString();
+		}
+	}
+
+	public class Symbol {
+		public final static int SYMSZ = 18;
+		public final static int SYMNMLEN = 8;
+
+		/* section number, in n_scnum.  */
+		public final static int N_DEBUG = -2;
+		public final static int N_ABS   = -1;
+		public final static int N_UNDEF = 0;
+		
+		/* Storage class, in n_sclass.  */
+		public final static int C_BCOMM = 135;	/* beginning of the common block */
+		public final static int C_BINCL = 108;	/* beginning of include file */
+		public final static int C_BLOCK = 100;	/* beginning or end of inner block */
+		public final static int C_BSTAT = 143;	/* beginning of static block */
+		public final static int C_DECL  = 140;	/* declaration of object (type) */
+		public final static int C_ECOML = 136;	/* local member of common block */
+		public final static int C_ECOMM = 127;	/* end of common block */
+		public final static int C_EINCL = 109;	/* end of include file */
+		public final static int C_ENTRY = 141;	/* alternate entry */
+		public final static int C_ESTAT = 144;	/* end of static block */
+		public final static int C_EXT   = 2;	/* external symbol */
+		public final static int C_FCN   = 101;	/* beginning or end of function */
+		public final static int C_FILE  = 103;	/* source file name and compiler information */
+		public final static int C_FUN   = 142;	/* function or procedure */
+		public final static int C_GSYM  = 128;	/* global variable */
+		public final static int C_HIDEXT = 107;	/* unnamed external symbol */
+		public final static int C_INFO  = 100;	/* comment section reference */
+		public final static int C_LSYM  = 129;	/* automatic variable allocated on stack */
+		public final static int C_NULL  = 0;	/* symbol table entry marked for deletion */
+		public final static int C_PSYM  = 130;	/* argument to subroutine allocated on stack */
+		public final static int C_RPSYM = 132;	/* argument to function or procedure stored in register */
+		public final static int C_RSYM  = 131;	/* register variable */
+		public final static int C_STAT  = 3;	/* static symbol (unknown) */
+		public final static int C_STSYM = 133;	/* statically allocated symbol */
+		public final static int C_TCSYM = 134;	/* reserved */
+		public final static int C_WEAKEXT = 111;/* weak external symbol */ 
+
+		/* csect storage class, in x_smlas.  */
+		public final static int XMC_PR = 0;		/* program code */
+		public final static int XMC_RO = 1;		/* read only constant */
+		public final static int XMC_DB = 2;		/* debug dictionary table */
+		public final static int XMC_TC = 3;		/* general TOC entry */
+		public final static int XMC_UA = 4;		/* unclassified */
+		public final static int XMC_RW = 5;		/* read/write data */
+		public final static int XMC_GL = 6;		/* global linkage */
+		public final static int XMC_XO = 7;		/* extended operation */
+		public final static int XMC_SV = 8;		/* 32-bit supervisor call descriptor csect */
+		public final static int XMC_BS = 9;		/* BSS class (uninitialized static internal) */
+		public final static int XMC_DS = 10;	/* csect containing a function descriptor */
+		public final static int XMC_UC = 11;	/* unnamed FORTRAN common */
+		public final static int XMC_TI = 12;	/* reserved */
+		public final static int XMC_TB = 13;	/* reserved */
+		public final static int XMC_TC0 = 15;	/* TOC anchor for TOC addressability */
+		public final static int XMC_TD = 16;	/* scalar data entry in TOC */
+		public final static int XMC_SV64 = 17;	/* 64-bit supervisor call descriptor csect */
+		public final static int XMC_SV3264 = 18;/* supervisor call descriptor csect for both 32-bit and 64-bit */
+		
+
+		// fields
+		public byte[] _n_name = new byte[SYMNMLEN]; /* Symbol name, or pointer into
+								   string table if symbol name
+								   is greater than SYMNMLEN.  */
+		public int n_value; 	/* long. Symbol's value: dependent on section number,
+				       			   storage class and type.  */
+		public short n_scnum; 	/* short, Section number.  */
+		public short n_type;   	/* Unsigned short. Symbolic type. Obsolete in XCOFF */
+		public byte n_sclass; 	/* char, Storage class.  */
+		public byte n_numaux; 	/* char. Nuymber of auxiliary enties.  */
+		private byte[] aux;
+		public byte x_smclas;	/* storage mapping class in csect auxiliary entry */
+
+		public Symbol(RandomAccessFile file) throws IOException {
+			this(file, file.getFilePointer());
+		}
+
+		public Symbol(RandomAccessFile file, long offset) throws IOException {
+			file.seek(offset);
+			byte[] bytes = new byte[SYMSZ];
+			file.readFully(bytes);
+			ReadMemoryAccess memory = new ReadMemoryAccess(bytes, false); // big endian
+			memory.getBytes(_n_name);
+			n_value = memory.getInt();
+			n_scnum = memory.getShort();
+			n_type = memory.getShort();
+			n_sclass = memory.getByte();
+			n_numaux = memory.getByte();
+			aux = new byte[n_numaux * SYMSZ];
+			file.readFully(aux);
+			// 11th byte in the last auxiliary entry (csect)
+			x_smclas = (n_numaux > 0) ? aux[aux.length - 7] : 0;	
+		}
+
+		private boolean isLongName() {
+			return (_n_name[0] == 0 && 
+					_n_name[1] == 0 &&
+					_n_name[2] == 0 &&
+					_n_name[3] == 0);
+		}
+
+		private String getShortName() {
+			for (int i = 0; i < _n_name.length; i++) {
+				if (_n_name[i] == 0) {
+					return new String(_n_name, 0, i);
+				}
+			}
+			return ""; //$NON-NLS-1$
+		}
+
+		public String getName(byte[] table) {
+			if (table.length > 0 && isLongName()) {
+				ReadMemoryAccess memory = new ReadMemoryAccess(_n_name, false);
+				memory.getInt(); // pass over the first 4 bytes.
+				// The first for bytes of the string table represent the
+				// number of bytes in the string table.
+				int offset = memory.getInt() - 4;
+				if (offset >= 0) {
+					for (int i = offset; i < table.length; i++) {
+						if (table[i] == 0) {
+							return new String(table, offset, i - offset);
+						}
+					}
+				}
+			}
+			return getShortName();
+		}
+
+		public boolean isFunction() {
+			return ((n_sclass == C_EXT || n_sclass == C_HIDEXT || n_sclass == C_WEAKEXT) && 
+					n_scnum == opthdr.o_sntext &&
+					!getShortName().equals(SectionHeader._TEXT));
+		}
+
+		public boolean isVariable() {
+			return ((n_sclass == C_EXT || n_sclass == C_HIDEXT || n_sclass == C_WEAKEXT) &&
+					(n_scnum == opthdr.o_snbss || n_scnum == opthdr.o_sndata) &&
+					x_smclas != XMC_TC0 && x_smclas != XMC_TC && x_smclas != XMC_DS &&
+					!getShortName().equals(SectionHeader._BSS) &&
+					!getShortName().equals(SectionHeader._DATA));
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("SYMBOL TABLE ENTRY").append(NL); //$NON-NLS-1$
+			buffer.append("n_value = ").append(n_value).append(NL); //$NON-NLS-1$
+			buffer.append("n_scnum = ").append(n_scnum).append(NL); //$NON-NLS-1$
+			buffer.append("n_type = ").append(n_type).append(NL); //$NON-NLS-1$
+			buffer.append("n_sclass = ").append(n_sclass).append(NL); //$NON-NLS-1$
+			buffer.append("n_numaux = ").append(n_numaux).append(NL); //$NON-NLS-1$
+			return buffer.toString();
+		}
+
+	}
+
+	public static class Attribute {
+		public static final int XCOFF_TYPE_EXE   = 1;
+		public static final int XCOFF_TYPE_SHLIB = 2;
+		public static final int XCOFF_TYPE_OBJ   = 3;
+		public static final int XCOFF_TYPE_CORE  = 4;
+
+		String cpu;
+		int type;
+		boolean bDebug;
+		boolean isle;
+
+		public String getCPU() {
+			return cpu;
+		}
+                
+		public int getType() {
+			return type;
+		}
+                
+		public boolean hasDebug() {
+			return bDebug;
+		}
+
+		public boolean isLittleEndian() {
+			return isle;
+		}
+	}
+
+	public Attribute getAttributes() {
+		Attribute attrib = new Attribute();
+		// Machine type.
+		switch (filehdr.f_magic) {
+			case FileHeader.U802TOCMAGIC:
+				attrib.cpu = "xcoff32"; //$NON-NLS-1$
+			break;
+			case FileHeader.U64_TOCMAGIC:
+				attrib.cpu = "xcoff64"; //$NON-NLS-1$
+			break;
+			default:
+				attrib.cpu = "unknown"; //$NON-NLS-1$
+			break;
+		}
+
+		/* XCOFF characteristics, FileHeader.f_flags.  */
+		if ((filehdr.f_flags & FileHeader.F_SHROBJ) != 0) {
+			attrib.type = Attribute.XCOFF_TYPE_SHLIB;
+		} else if ((filehdr.f_flags & FileHeader.F_EXEC) != 0) {
+			attrib.type = Attribute.XCOFF_TYPE_EXE;
+		} else {
+			attrib.type = Attribute.XCOFF_TYPE_OBJ;
+		}
+
+		// For AIX XCOFF always assume big endian unless otherwise.
+		attrib.isle = false;
+
+		// No debug information.
+		if ((filehdr.f_flags & (FileHeader.F_LNNO & FileHeader.F_LSYMS & FileHeader.F_RELFLG)) != 0) {
+			attrib.bDebug = false;
+		} else {
+			attrib.bDebug = true;
+		}
+		
+		return attrib;
+	}
+
+	public FileHeader getFileHeader() throws IOException {
+		return filehdr;
+	}
+	
+	public OptionalHeader getOptionalHeader() throws IOException {
+		return opthdr;
+	}
+
+	public SectionHeader[] getSectionHeaders() throws IOException {
+		if (scnhdrs == null) {
+			getRandomAccessFile();
+			scnhdrs = new SectionHeader[getFileHeader().f_nscns];
+			long sec = startingOffset + FileHeader.FILHSZ + getFileHeader().f_opthdr;
+			for (int i = 0; i < scnhdrs.length; i++, sec += SectionHeader.SCNHSZ) {
+				scnhdrs[i] = new SectionHeader(rfile, sec);
+			}
+		}
+		return scnhdrs;
+	}
+
+	public Symbol[] getSymbols() throws IOException {
+		if (symbols == null) {
+			long offset = startingOffset + getFileHeader().f_symptr;
+			getRandomAccessFile();
+			rfile.seek(offset);
+			int numSymbols = getFileHeader().f_nsyms;
+			ArrayList symList = new ArrayList(numSymbols);
+			for (int i = 0; i < numSymbols; ++i) {
+				Symbol v = new Symbol(rfile);
+				symList.add(v);
+				i += v.n_numaux; // account for auxiliary entries
+			}
+			symbols = (Symbol[]) symList.toArray(new Symbol[symList.size()]);
+		}
+		return symbols;
+	}
+
+	public byte[] getStringTable() throws IOException {
+		if (string_table == null) {
+			if (filehdr.f_nsyms > 0) {
+				getRandomAccessFile();
+				long symbolsize = Symbol.SYMSZ * getFileHeader().f_nsyms;
+				long offset = startingOffset+ getFileHeader().f_symptr + symbolsize;
+				rfile.seek(offset);
+				byte[] bytes = new byte[4];
+				rfile.readFully(bytes);
+				int str_len = ReadMemoryAccess.getIntBE(bytes);
+				if (str_len > 4 && str_len < rfile.length()) {
+					str_len -= 4;
+					string_table = new byte[str_len];
+					rfile.seek(offset + 4);
+					rfile.readFully(string_table);
+				} else {
+					string_table = new byte[0];
+				}
+			}
+		}
+		return string_table;
+	}
+
+    // A hollow entry, to be used with caution in controlled situations
+	protected XCoff32() {
+	}
+	
+	public XCoff32(String filename) throws IOException {
+		this(filename, 0);
+	}
+
+	public XCoff32(String filename, long offset) throws IOException {
+		this.filename = filename;
+		commonSetup(new RandomAccessFile(filename, "r"), offset);
+	}
+
+	void commonSetup(RandomAccessFile file, long offset) throws IOException {
+		startingOffset = offset;
+		rfile = file;
+		try {
+			filehdr = new FileHeader(rfile, startingOffset);
+			if (filehdr.f_opthdr > 0) {
+				opthdr = new OptionalHeader(rfile, startingOffset + FileHeader.FILHSZ);
+			}
+			if (filehdr.f_opthdr < OptionalHeader.AOUTHDRSZ) {
+				// auxiliary header does not contain needed information, 
+				// must load section headers
+				getSectionHeaders();
+				for (int i = 0; i < filehdr.f_nscns; ++i) {
+					if ((scnhdrs[i].s_flags & SectionHeader.STYP_TEXT) != 0) {
+						opthdr.o_sntext = (short)(i+1);
+					}
+					else if ((scnhdrs[i].s_flags & SectionHeader.STYP_BSS) != 0) {
+						opthdr.o_snbss = (short)(i+1);
+					}
+					else if ((scnhdrs[i].s_flags & SectionHeader.STYP_DATA) != 0) {
+						opthdr.o_sndata = (short)(i+1);
+					}
+				}
+			}
+		} finally {
+			dispose();
+		}
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		try {
+			FileHeader header = null;
+			header = getFileHeader();
+			if (header != null) {
+				buffer.append(header);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		try {
+			OptionalHeader opt = null;
+			opt = getOptionalHeader();
+			if (opt != null) {
+				buffer.append(opt);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		try {
+			SectionHeader[] sections = getSectionHeaders();
+			for (int i = 0; i < sections.length; i++) {
+				buffer.append(sections[i]);
+			}
+		} catch (IOException e) {
+		}
+
+		try {
+			Symbol[] table = getSymbols();
+			for (int i = 0; i < table.length; i++) {
+				buffer.append(table[i]).append("n_name = "); //$NON-NLS-1$
+				buffer.append(table[i].getName(getStringTable())).append(NL);
+			}
+		} catch (IOException e) {
+		}
+
+//		try {
+//			String[] strings = getStringTable(getStringTable());
+//			for (int i = 0; i < strings.length; i++) {
+//				buffer.append(strings[i]);
+//			}
+//		} catch (IOException e) {
+//			e.printStackTrace();
+//		}
+		return buffer.toString();
+	}
+
+	public void dispose() throws IOException {
+		if (rfile != null) {
+			rfile.close();
+			rfile = null;
+		}
+	}
+
+	RandomAccessFile getRandomAccessFile () throws IOException {
+		if (rfile == null) {
+			rfile = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
+		}
+		return rfile;
+	}
+
+	public static void main(String[] args) {
+		try {
+			XCoff32 xcoff = new XCoff32(args[0]);
+			System.out.println(xcoff);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * @param hints
+	 * @return
+	 */
+	public static boolean isXCOFF32Header(byte[] hints) {
+		if (hints != null && hints[0] == 0x01 && (hints[1] == (byte)0xdf) ) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * @param hints
+	 * @return
+	 * @throws IOException
+	 */
+	public static Attribute getAttributes(byte[] hints) throws IOException {
+		XCoff32 emptyXCoff = new XCoff32();
+		emptyXCoff.filehdr = new XCoff32.FileHeader(hints, false); // big endian
+		Attribute attribute = emptyXCoff.getAttributes();
+		emptyXCoff.dispose();
+		return attribute;
+	}
+
+	/**
+	 * @param file
+	 * @return
+	 * @throws IOException
+	 */
+	public static Attribute getAttributes(String file) throws IOException {
+		XCoff32 xcoff = new XCoff32(file);
+		Attribute attribute = xcoff.getAttributes();
+		xcoff.dispose();
+		return attribute;
+	}
+}
Index: utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java
diff -N utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,111 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.utils.xcoff.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.core.IBinaryParser.ISymbol;
+import org.eclipse.cdt.utils.Addr2line;
+import org.eclipse.cdt.utils.CPPFilt;
+import org.eclipse.cdt.utils.CygPath;
+import org.eclipse.cdt.utils.Symbol;
+import org.eclipse.cdt.utils.xcoff.AR;
+import org.eclipse.cdt.utils.xcoff.XCoff32;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * A member of an XCOFF32 archive
+ * 
+ * @author vhirsl
+ */
+public class ARMember extends XCOFFBinaryObject {
+	AR.MemberHeader header;
+
+	/**
+	 * @param parser
+	 * @param path
+	 */
+	public ARMember(IBinaryParser parser, IPath path, AR.MemberHeader header) {
+		super(parser, path);
+		this.header = header;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
+	 */
+	public InputStream getContents() {
+		InputStream stream = null;
+		if (path != null && header != null) {
+			try {
+				stream = new ByteArrayInputStream(header.getObjectData());
+			} catch (IOException e) {
+			}
+		}
+		if (stream == null) {
+			stream = super.getContents();
+		}
+		return stream;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getShortName()
+	 */
+	public String getName() {
+		if (header != null) {
+			return header.getObjectName();
+		}
+		return ""; //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.xcoff.parser.XCOFFBinaryObject#addSymbols(org.eclipse.cdt.utils.xcoff.XCoff32.Symbol[], byte[], org.eclipse.cdt.utils.Addr2line, org.eclipse.cdt.utils.CPPFilt, org.eclipse.cdt.utils.CygPath, java.util.List)
+	 */
+	protected void addSymbols(XCoff32.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath, List list) {
+		for (int i = 0; i < peSyms.length; i++) {
+			if (peSyms[i].isFunction() || peSyms[i].isVariable()) {
+				String name = peSyms[i].getName(table);
+				if (name == null || name.trim().length() == 0 /*||
+					!Character.isJavaIdentifierStart(name.charAt(0))*/) {
+					continue;
+				}
+				Symbol sym = new Symbol(this);
+				sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
+				sym.addr = peSyms[i].n_value;
+
+				sym.name = name;
+				if (cppfilt != null) {
+					try {
+						sym.name = cppfilt.getFunction(sym.name);
+					} catch (IOException e1) {
+						cppfilt = null;
+					}
+				}
+
+				list.add(sym);
+			}
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.xcoff.parser.XCOFFBinaryObject#getXCoff32()
+	 */
+	protected XCoff32 getXCoff32() throws IOException {
+		if (header != null) {
+			return header.getXCoff();
+		}
+		throw new IOException(CCorePlugin.getResourceString("Util.exception.noFileAssociation")); //$NON-NLS-1$
+	}
+}
Index: utils/org/eclipse/cdt/utils/xcoff/parser/BinaryArchive.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/xcoff/parser/BinaryArchive.java
diff -N utils/org/eclipse/cdt/utils/xcoff/parser/BinaryArchive.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/xcoff/parser/BinaryArchive.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,75 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.utils.xcoff.parser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
+import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
+import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
+import org.eclipse.cdt.utils.BinaryFile;
+import org.eclipse.cdt.utils.xcoff.AR;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * XCOFF32 binary archive
+ * 
+ * @author vhirsl
+ */
+public class BinaryArchive extends BinaryFile implements IBinaryArchive {
+	private ArrayList children;
+
+	/**
+	 * @param parser
+	 * @param path
+	 * @throws IOException
+	 */
+	public BinaryArchive(IBinaryParser parser, IPath path) throws IOException {
+		super(parser, path);
+		new AR(path.toOSString()).dispose(); // check file type
+		children = new ArrayList(5);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
+	 */
+	public int getType() {
+		return IBinaryFile.ARCHIVE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects()
+	 */
+	public IBinaryObject[] getObjects() {
+		if (hasChanged()) {
+			children.clear();
+			AR ar = null;
+			try {
+				ar = new AR(getPath().toOSString());
+				AR.MemberHeader[] headers = ar.getHeaders();
+				for (int i = 0; i < headers.length; i++) {
+					IBinaryObject bin = new ARMember(getBinaryParser(), getPath(), headers[i]);
+					children.add(bin);
+				}
+			} catch (IOException e) {
+				//e.printStackTrace();
+			}
+			if (ar != null) {
+				ar.dispose();
+			}
+			children.trimToSize();
+		}
+		return (IBinaryObject[]) children.toArray(new IBinaryObject[0]);
+	}
+
+}
Index: utils/org/eclipse/cdt/utils/xcoff/parser/XCOFF32Parser.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/xcoff/parser/XCOFF32Parser.java
diff -N utils/org/eclipse/cdt/utils/xcoff/parser/XCOFF32Parser.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/xcoff/parser/XCOFF32Parser.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,171 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.utils.xcoff.parser;
+
+import java.io.EOFException;
+import java.io.IOException;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.utils.ToolsProvider;
+import org.eclipse.cdt.utils.xcoff.AR;
+import org.eclipse.cdt.utils.xcoff.XCoff32;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * XCOFF 32bit binary parser for AIX
+ * 
+ * @author vhirsl
+ */
+public class XCOFF32Parser extends ToolsProvider implements IBinaryParser {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser#getBinary(byte[], org.eclipse.core.runtime.IPath)
+	 */
+	public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException {
+		if (path == null) {
+			throw new IOException(CCorePlugin.getResourceString("Util.exception.nullPath")); //$NON-NLS-1$
+		}
+
+		IBinaryFile binary = null;
+		if (isBinary(hints, path)) {
+			try {
+				XCoff32.Attribute attribute = null;
+				if (hints != null && hints.length > 0) {
+					try {
+						attribute = XCoff32.getAttributes(hints);
+					} catch (EOFException eof) {
+						// continue, the array was to small.
+					}
+				}
+	
+				//Take a second run at it if the data array failed. 			
+	 			if(attribute == null) {
+					attribute = XCoff32.getAttributes(path.toOSString());
+	 			}
+	
+				if (attribute != null) {
+					switch (attribute.getType()) {
+						case XCoff32.Attribute.XCOFF_TYPE_EXE :
+							binary = createBinaryExecutable(path);
+							break;
+	
+						case XCoff32.Attribute.XCOFF_TYPE_SHLIB :
+							binary = createBinaryShared(path);
+							break;
+	
+						case XCoff32.Attribute.XCOFF_TYPE_OBJ :
+							binary = createBinaryObject(path);
+							break;
+	
+						case XCoff32.Attribute.XCOFF_TYPE_CORE :
+							binary = createBinaryCore(path);
+							break;
+					}
+				}
+			} catch (IOException e) {
+				binary = createBinaryArchive(path);
+			}
+		}
+		return binary;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath)
+	 */
+	public IBinaryFile getBinary(IPath path) throws IOException {
+		return getBinary(null, path);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser#getFormat()
+	 */
+	public String getFormat() {
+		return "XCOFF32"; //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
+	 */
+	public boolean isBinary(byte[] hints, IPath path) {
+		return XCoff32.isXCOFF32Header(hints) || AR.isARHeader(hints);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize()
+	 */
+	public int getHintBufferSize() {
+		return 512;
+	}
+
+	/**
+	 * @param path
+	 * @return
+	 */
+	private IBinaryFile createBinaryExecutable(IPath path) {
+		return new XCOFFBinaryObject(this, path) {
+			/* (non-Javadoc)
+			 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
+			 */
+			public int getType() {
+				return IBinaryFile.EXECUTABLE;
+			}
+		};
+	}
+
+	/**
+	 * @param path
+	 * @return
+	 */
+	private IBinaryFile createBinaryShared(IPath path) {
+		return new XCOFFBinaryObject(this, path) {
+			/* (non-Javadoc)
+			 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
+			 */
+			public int getType() {
+				return IBinaryFile.SHARED;
+			}
+		};
+	}
+
+	/**
+	 * @param path
+	 * @return
+	 */
+	private IBinaryFile createBinaryObject(IPath path) {
+		return new XCOFFBinaryObject(this, path);
+	}
+
+	/**
+	 * @param path
+	 * @return
+	 */
+	private IBinaryFile createBinaryCore(IPath path) {
+		return new XCOFFBinaryObject(this, path) {
+			/* (non-Javadoc)
+			 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
+			 */
+			public int getType() {
+				return IBinaryFile.CORE;
+			}
+		};
+	}
+
+	/**
+	 * @param path
+	 * @return
+	 * @throws IOException
+	 */
+	private IBinaryFile createBinaryArchive(IPath path) throws IOException {
+		return new BinaryArchive(this, path);
+	}
+
+}
Index: utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java
diff -N utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,221 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.utils.xcoff.parser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
+import org.eclipse.cdt.core.IBinaryParser.ISymbol;
+import org.eclipse.cdt.utils.Addr2line;
+import org.eclipse.cdt.utils.BinaryObjectAdapter;
+import org.eclipse.cdt.utils.CPPFilt;
+import org.eclipse.cdt.utils.CygPath;
+import org.eclipse.cdt.utils.Objdump;
+import org.eclipse.cdt.utils.Symbol;
+import org.eclipse.cdt.utils.xcoff.XCoff32;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * TODO Provide description
+ * 
+ * @author vhirsl
+ */
+public class XCOFFBinaryObject extends BinaryObjectAdapter {
+	BinaryObjectInfo info;
+	ISymbol[] symbols;
+
+	/**
+	 * @param parser
+	 * @param path
+	 */
+	public XCOFFBinaryObject(IBinaryParser parser, IPath path) {
+		super(parser, path);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols()
+	 */
+	public ISymbol[] getSymbols() {
+		if (hasChanged() || symbols == null) {
+			try {
+				loadAll();
+			} catch (IOException e) {
+				symbols = NO_SYMBOLS;
+			}
+		}
+		return symbols;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo()
+	 */
+	protected BinaryObjectInfo getBinaryObjectInfo() {
+		if (hasChanged() || info == null) {
+			try {
+				loadInfo();
+			} catch (IOException e) {
+				info = new BinaryObjectInfo();
+			}
+		}
+		return info;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
+	 */
+	public int getType() {
+		return IBinaryFile.OBJECT;
+	}
+
+	protected XCoff32 getXCoff32() throws IOException {
+		return new XCoff32(getPath().toOSString());
+	}
+
+	protected void loadAll() throws IOException {
+		XCoff32 xcoff = null;
+		try {
+			xcoff = getXCoff32();
+			loadInfo(xcoff);
+			loadSymbols(xcoff);
+		} finally {
+			if (xcoff != null) {
+				xcoff.dispose();
+			}
+		}
+	}
+
+	protected void loadInfo() throws IOException {
+		XCoff32 xcoff = null;
+		try {
+			xcoff = getXCoff32();
+			loadInfo(xcoff);
+		} finally {
+			if (xcoff != null) {
+				xcoff.dispose();
+			}
+		}
+	}
+
+	protected void loadInfo(XCoff32 xcoff) throws IOException {
+		info = new BinaryObjectInfo();
+		XCoff32.Attribute attribute = xcoff.getAttributes();
+		info.isLittleEndian = attribute.isLittleEndian();
+		info.hasDebug = attribute.hasDebug();
+		info.cpu = attribute.getCPU();
+	}
+
+	protected void loadSymbols(XCoff32 xcoff) throws IOException {
+		ArrayList list = new ArrayList();
+		Addr2line addr2line = getAddr2line();
+		CPPFilt cppfilt = getCPPFilt();
+		CygPath cygpath = getCygPath();
+
+		XCoff32.Symbol[] peSyms = xcoff.getSymbols();
+		byte[] table = xcoff.getStringTable();
+		addSymbols(peSyms, table, addr2line, cppfilt, cygpath, list);
+
+		if (addr2line != null) {
+			addr2line.dispose();
+		}
+		if (cppfilt != null) {
+			cppfilt.dispose();
+		}
+		if (cygpath != null) {
+			cygpath.dispose();
+		}
+
+		symbols = (ISymbol[])list.toArray(NO_SYMBOLS);
+		Arrays.sort(symbols);
+		list.clear();
+	}
+
+	protected void addSymbols(XCoff32.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath, List list) {
+		for (int i = 0; i < peSyms.length; i++) {
+			if (peSyms[i].isFunction() || peSyms[i].isVariable()) {
+				String name = peSyms[i].getName(table);
+				if (name == null || name.trim().length() == 0 /*|| 
+				    !Character.isJavaIdentifierStart(name.charAt(0))*/) {
+					continue;
+				}
+				Symbol sym = new Symbol(this);
+				sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
+				sym.addr = peSyms[i].n_value;
+
+				sym.name = name;
+				if (cppfilt != null) {
+					try {
+						sym.name = cppfilt.getFunction(sym.name);
+					} catch (IOException e1) {
+						cppfilt = null;
+					}
+				}
+
+				sym.filename = null;
+				sym.startLine = 0;
+				sym.endLine = 0;
+				if (addr2line != null) {
+					try {
+						String filename =  addr2line.getFileName(sym.addr);
+						// Addr2line returns the funny "??" when it can not find the file.
+						if (filename != null && filename.equals("??")) { //$NON-NLS-1$
+							filename = null;
+						}
+
+						if (filename != null) {
+							if (cygpath != null) {
+								sym.filename =  new Path(cygpath.getFileName(filename));
+							} else {
+								sym.filename = new Path(filename);
+							}
+						}
+						sym.startLine = addr2line.getLineNumber(sym.addr);
+					} catch (IOException e) {
+						addr2line = null;
+					}
+				}
+				list.add(sym);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddr2line()
+	 */
+	public Addr2line getAddr2line() {
+		XCOFF32Parser parser = (XCOFF32Parser)getBinaryParser();
+		return parser.getAddr2line(getPath());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getCPPFilt()
+	 */
+	public CPPFilt getCPPFilt() {
+		XCOFF32Parser parser = (XCOFF32Parser)getBinaryParser();
+		return parser.getCPPFilt();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getObjdump()
+	 */
+	public Objdump getObjdump() {
+		XCOFF32Parser parser = (XCOFF32Parser)getBinaryParser();
+		return parser.getObjdump(getPath());
+	}
+
+	private CygPath getCygPath() {
+		return null;
+	}
+}
Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/plugin.xml,v
retrieving revision 1.100
diff -u -r1.100 plugin.xml
--- plugin.xml	11 Jun 2004 18:38:39 -0000	1.100
+++ plugin.xml	21 Jun 2004 19:38:55 -0000
@@ -698,6 +698,11 @@
             parserID="org.eclipse.cdt.core.Cygwin_PE"
             id="PEBinaryParserPage">
       </parserPage>
+      <parserPage
+            class="org.eclipse.cdt.ui.dialogs.GNUXCoffBinaryParserPage"
+            parserID="org.eclipse.cdt.core.XCOFF32"
+            id="XcoffBinaryParserPage">
+      </parserPage>
    </extension>
    <extension
          point="org.eclipse.ui.workingSets">
Index: src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java,v
retrieving revision 1.6
diff -u -r1.6 GNUElfBinaryParserPage.java
--- src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java	8 Jun 2004 17:40:04 -0000	1.6
+++ src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java	21 Jun 2004 19:38:55 -0000
@@ -75,7 +75,7 @@
 				for (int i = 0; i < infos.length; i++) {
 					String id = infos[i].getAttribute("parserID"); //$NON-NLS-1$
 					String clazz = infos[i].getAttribute("class"); //$NON-NLS-1$
-					String ego = getClass().getName();
+					String ego = getRealBinaryParserPage().getClass().getName();
 					if (clazz != null && clazz.equals(ego)) {
 						parserID = id;
 						break;
@@ -102,6 +102,14 @@
 				store.setValue(PREF_CPPFILT_PATH, cppfilt);
 			}
 		}
+	}
+
+	/**
+	 * If this class is inherited from then this method MUST be implemented
+	 * in the derived class.
+	 */
+	protected Object getRealBinaryParserPage() {
+		return this;
 	}
 
 	/*
Index: src/org/eclipse/cdt/ui/dialogs/GNUXCoffBinaryParserPage.java
===================================================================
RCS file: src/org/eclipse/cdt/ui/dialogs/GNUXCoffBinaryParserPage.java
diff -N src/org/eclipse/cdt/ui/dialogs/GNUXCoffBinaryParserPage.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/ui/dialogs/GNUXCoffBinaryParserPage.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.ui.dialogs;
+
+/**
+ * Reusing GNUElfBinaryParserPage.
+ * New class is required for the algorithm in method performApply.
+ * Must implement getRealBinaryParserPage method. 
+ * 
+ * @author vhirsl
+ */
+public class GNUXCoffBinaryParserPage extends GNUElfBinaryParserPage {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.dialogs.GNUElfBinaryParserPage#getRealBinaryParserPage()
+	 */
+	protected Object getRealBinaryParserPage() {
+		return this;
+	}
+}

Attachment: xcoff32.tar.gz
Description: Binary data


Back to the top