[
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