Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Framework for the binary parsers.

  Not currently UI Enabled.

Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/ChangeLog,v
retrieving revision 1.41
diff -u -r1.41 ChangeLog
--- ChangeLog	24 Nov 2002 16:08:35 -0000	1.41
+++ ChangeLog	25 Nov 2002 05:49:27 -0000
@@ -1,3 +1,37 @@
+2002-11-23 Alain Magloire
+
+	* model/.../cdt/core/model/CoreModel.java (getBinaryParser):
+	New methods to retrieve the parser for a project.
+	* model/.../cdt/core/model/IBinaryParser.java (getFormat):
+	New method return the format supported.
+	* model/.../internal/core/model/CModelManager.java (getBinaryParser):
+	New methods to retrieve the parser for a project.
+	* model/.../internal/core/model/parser/ElfBinaryFile.java:
+	Move the Symbol class out so it can be shared.
+	* model/.../internal/core/model/parser/ElfParser.java (getFormat):
+	New method.
+	* model/.../internal/core/model/parser/PEBinaryArchive.java: New file.
+	* model/.../internal/core/model/parser/PEBinaryFile.java: New file.
+	* model/.../internal/core/model/parser/PEParser.java: New file.
+	* model/.../internal/core/model/parser/Symbol.java: New file.
+
+	* src/.../cdt/core/CCorePlugin.java (getBinaryParser):
+	New Methods to retrieve the extension-point.
+
+	* utils/.../cdt/utils/coff/Coff.java :
+	Parse the symbols.
+	* utils/.../cdt/utils/coff/PE.java (getAttribute):
+	New helper method/class Attribute.
+	* utils/.../cdt/utils/coff/PEArchive.java :
+	New File.
+	* utils/.../cdt/utils/elf/AR.java (finalize): 
+	Make sure we do not leak fds.
+	* utils/.../cdt/utils/elf/Elf.java (finalize): 
+	Make sure we do not leak fds.
+
+	* plugin.xml: Define two "parser" extension-point.
+
+
 2002-11-22 Alain Magloire
 
 	* src/.../cdt/core/CommandLauncher.java (waitAndRead):
Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/plugin.xml,v
retrieving revision 1.14
diff -u -r1.14 plugin.xml
--- plugin.xml	20 Nov 2002 14:31:35 -0000	1.14
+++ plugin.xml	25 Nov 2002 05:49:28 -0000
@@ -29,7 +29,13 @@
    <extension-point id="CProject" name="%CProject.name"/>
    <extension-point id="CBuildModel" name="%CBuilder.name"/>
    <extension-point id="ProcessList" name="%ProcessList.name" schema="schema/ProcessList.exsd"/>
+   <extension-point id="BinaryParser" name="BinaryParser"/>
 
+   <extension id="parser" name="C Parser" point="org.eclipse.cdt.core.BinaryParser">
+      <parser format="ELF" class="org.eclipse.cdt.internal.core.model.parser.ElfParser"/>
+      <parser format="PE"  class="org.eclipse.cdt.internal.core.model.parser.PEParser"/>
+   </extension>
+   
    <extension
          id="cbuilder"
          name="C Builder"
Index: model/org/eclipse/cdt/core/model/CoreModel.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java,v
retrieving revision 1.4
diff -u -r1.4 CoreModel.java
--- model/org/eclipse/cdt/core/model/CoreModel.java	15 Oct 2002 17:47:49 -0000	1.4
+++ model/org/eclipse/cdt/core/model/CoreModel.java	25 Nov 2002 05:49:35 -0000
@@ -5,6 +5,7 @@
  * All Rights Reserved.
  */
  
+import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.internal.core.model.CModelManager;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
@@ -18,6 +19,8 @@
 
 	private static CoreModel cmodel = null;
 	private static CModelManager manager = null;
+	
+	public final static String CORE_MODEL_ID = CCorePlugin.PLUGIN_ID + ".coremodel";
 
 	/**
 	 * Creates an ICElement form and IPath.
@@ -126,6 +129,34 @@
 		return manager.hasCCNature(project);
 	}
 
+	/**
+	 * Return the the binaryParser of the Project.
+	 */
+	public static IBinaryParser getBinaryParser(IProject project) {
+		return manager.getBinaryParser(project);
+	}
+	
+	/**
+	 * Return all the known binaryParsers formats.
+	 */
+	public static String[] getBinaryParserFormats() {
+		return CCorePlugin.getDefault().getBinaryParserFormats();
+	}
+
+	/**
+	 * Save the binary parser for the project.
+	 */
+	public static void setBinaryParser(IProject project, String format) {
+		manager.setBinaryParser(project, format);
+	}
+	
+	/**
+	 * Return the BinaryParser corresponding to this format.
+	 */
+	public static IBinaryParser getBinaryParser(String format) {
+		return CCorePlugin.getDefault().getBinaryParser(format);
+	}
+	
 	/**
 	 * Return the singleton.
 	 */
Index: model/org/eclipse/cdt/core/model/IBinaryParser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinaryParser.java,v
retrieving revision 1.2
diff -u -r1.2 IBinaryParser.java
--- model/org/eclipse/cdt/core/model/IBinaryParser.java	22 Nov 2002 16:31:36 -0000	1.2
+++ model/org/eclipse/cdt/core/model/IBinaryParser.java	25 Nov 2002 05:49:34 -0000
@@ -85,4 +85,6 @@
 	}
 
 	public IBinaryFile getBinary(IFile file) throws IOException;
+	
+	public String getFormat();
 }
Index: model/org/eclipse/cdt/internal/core/model/CModelManager.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java,v
retrieving revision 1.10
diff -u -r1.10 CModelManager.java
--- model/org/eclipse/cdt/internal/core/model/CModelManager.java	22 Nov 2002 16:32:36 -0000	1.10
+++ model/org/eclipse/cdt/internal/core/model/CModelManager.java	25 Nov 2002 05:49:31 -0000
@@ -13,6 +13,7 @@
 import org.eclipse.cdt.core.CCProjectNature;
 import org.eclipse.cdt.core.CProjectNature;
 import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.model.ElementChangedEvent;
 import org.eclipse.cdt.core.model.IArchive;
 import org.eclipse.cdt.core.model.IBinary;
@@ -41,12 +42,19 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.QualifiedName;
 
 public class CModelManager implements IResourceChangeListener {
 
 	private HashMap fParsedResources =  new HashMap();	
 
+	final static String BINARY_PARSER= "binaryparser";
+
+	static QualifiedName binaryParserKey = new QualifiedName(CoreModel.CORE_MODEL_ID, BINARY_PARSER);
+	
+	private static HashMap fParsers = new HashMap();
 	private static IBinaryParser defaultBinaryParser = new ElfParser();
+	//private static IBinaryParser defaultBinaryParser = new PEParser();
 
 	/**
 	 * Used to convert <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s.
@@ -341,11 +349,39 @@
 	}
 
 	public static IBinaryParser getBinaryParser(IProject project) {
+		// It is in the property of the project of the cdtproject
 		// For now the default is Elf.
-		// It is in the porperty of the project of the cdtproject
-		return defaultBinaryParser;
+		IBinaryParser parser = (IBinaryParser)fParsers.get(project);
+		if (parser == null) {
+			String format = null;
+			// FIXME: Ask the .cdtproject second.
+			try {
+				if (project != null) {
+					format = project.getPersistentProperty(binaryParserKey);
+				}
+			} catch (CoreException e) {
+			}
+			if (format != null && format.length() > 0) {
+				parser = CoreModel.getDefault().getBinaryParser(format);
+			}
+			if (parser == null) {
+				parser = defaultBinaryParser;
+			}
+			fParsers.put(project, parser);
+		}
+		return parser;
 	}
 
+	public static void setBinaryParser(IProject project, String format) {
+		try {
+			if (project != null) {
+				project.setPersistentProperty(binaryParserKey, format);
+				fParsers.remove(project);
+			}
+		} catch (CoreException e) {
+		}
+	}
+	
 	public static boolean isSharedLib(IFile file) {
 		try {
 			IBinaryParser parser = getBinaryParser(file.getProject());
Index: model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java,v
retrieving revision 1.1
diff -u -r1.1 ElfBinaryArchive.java
--- model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java	18 Nov 2002 15:43:53 -0000	1.1
+++ model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java	25 Nov 2002 05:49:32 -0000
@@ -91,4 +91,16 @@
 		timestamp = modif;
 		return changed;
 	}
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[])
+	 */
+	public void add(IBinaryObject[] objs) throws IOException {
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[])
+	 */
+	public void delete(IBinaryObject[] objs) throws IOException {
+	}
+
 }
Index: model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java,v
retrieving revision 1.2
diff -u -r1.2 ElfBinaryFile.java
--- model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java	22 Nov 2002 16:32:00 -0000	1.2
+++ model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java	25 Nov 2002 05:49:34 -0000
@@ -40,66 +40,15 @@
 	Attribute attribute;
 	ArrayList symbols;
 	
-	public class ElfSymbol implements ISymbol {
-	
-		String filename;
-		int lineno;
-		String name;
-		int type;
-
-		public ElfSymbol (Elf.Symbol symbol, int t) throws IOException {
-			filename = symbol.getFilename();
-			name = symbol.toString();
-			lineno = symbol.getFuncLineNumber();
-			type = t;
-		}
-		
-		/**
-		 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename()
-		 */
-		public String getFilename() {
-			return filename;
-		}
-
-		/**
-		 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getLineNumber()
-		 */
-		public int getLineNumber() {
-			return lineno;
-		}
-
-		/**
-		 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getName()
-		 */
-		public String getName() {
-			return name;
-		}
-
-		/**
-		 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getType()
-		 */
-		public int getType() {
-			return type;
-		}
-
-	}
-	
 	public ElfBinaryFile(IFile f) throws IOException {
-		this(f, null, null);
+		this(f, null);
 	}
 
 	public ElfBinaryFile(IFile f, String n) throws IOException {
-		this(f, n, null);
-	}
-
-	public ElfBinaryFile(IFile f, String n, Elf elf) throws IOException {
 		file = f;
 		objectName = n;
-		if (elf != null) {
-			loadAttributes(new ElfHelper(elf));
-		} else {
-			loadAttributes();
-		}
+		loadInformation();
+		hasChanged();
 	}
 
 	/**
@@ -292,7 +241,13 @@
 	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
 	 */
 	public String getName() {
-		return objectName;
+		if (objectName != null) {
+			return objectName;
+		}
+		if (file != null) {
+			return file.getName();
+		}
+		return "";
 	}
 
 	public String toString() {
@@ -328,24 +283,30 @@
 
 	protected ElfHelper getElfHelper() throws IOException {
 		// Archive ?
-		if (file != null && file.exists() && objectName != null) {
-			ElfHelper helper = null;
-			AR ar = null;
-			try {	
-				ar = new AR(file.getLocation().toOSString());
-				AR.ARHeader[] headers = ar.getHeaders();
-				for (int i = 0; i < headers.length; i++) {
-					if (objectName.equals(headers[i].getObjectName())) {
-						helper = new ElfHelper(headers[i].getElf());
-						break;
+		if (file != null && objectName != null) {
+			IPath location = file.getLocation();
+			if (location != null) {
+				ElfHelper helper = null;
+				AR ar = null;
+				try {	
+					ar = new AR(file.getLocation().toOSString());
+					AR.ARHeader[] headers = ar.getHeaders();
+					for (int i = 0; i < headers.length; i++) {
+						AR.ARHeader hdr = headers[i];
+						if (objectName.equals(hdr.getObjectName())) {
+							helper = new ElfHelper(hdr.getElf());
+							break;
+						}
+					}
+				} finally {
+					if (ar != null) {
+						ar.dispose();
 					}
 				}
-			} finally {
-				if (ar != null) {
-					ar.dispose();
+				if (helper != null) {
+					return helper;
 				}
 			}
-			return helper;
 		} else if (file != null && file.exists()) {
 			IPath path = file.getLocation();
 			if (path == null) {
@@ -357,21 +318,21 @@
 	}
 
 	protected void loadInformation() throws IOException {
-		loadAttributes();
+		ElfHelper helper = getElfHelper();
+		loadInformation(helper);
+		helper.dispose();
+	}
+
+	private void loadInformation(ElfHelper helper) throws IOException {
+		loadAttributes(helper);
 		if (symbols != null) {
 			symbols.clear();
-			loadSymbols();
+			loadSymbols(helper);
 			symbols.trimToSize();
 		}
 	}
 	
-	protected void loadAttributes() throws IOException {
-		ElfHelper helper = getElfHelper();
-		loadAttributes(helper);
-		helper.dispose();
-	}
-
-	protected void loadAttributes(ElfHelper helper) throws IOException {
+	private void loadAttributes(ElfHelper helper) throws IOException {
 		Elf.Dynamic[] sharedlibs = helper.getNeeded();
 		needed = new String[sharedlibs.length];
 		for (int i = 0; i < sharedlibs.length; i++) {
@@ -382,13 +343,7 @@
 		attribute = helper.getElf().getAttributes();
 	}
 
-	protected void loadSymbols() throws IOException {
-		ElfHelper helper = getElfHelper();
-		loadSymbols(helper);
-		helper.dispose();
-	}
-
-	protected void loadSymbols(ElfHelper helper) throws IOException {
+	private void loadSymbols(ElfHelper helper) throws IOException {
 		Elf.Dynamic[] sharedlibs = helper.getNeeded();
 		needed = new String[sharedlibs.length];
 		for (int i = 0; i < sharedlibs.length; i++) {
@@ -405,10 +360,14 @@
 		symbols.trimToSize();
 	}
 
-	protected void addSymbols(Elf.Symbol[] array, int type) {
+	private void addSymbols(Elf.Symbol[] array, int type) {
 		for (int i = 0; i < array.length; i++) {
 			try {
-				ISymbol sym = new ElfSymbol(array[i], type);
+				Symbol sym = new Symbol();
+				sym.filename = array[i].getFilename();
+				sym.name = array[i].toString();
+				sym.lineno = array[i].getFuncLineNumber();
+				sym.type = type;
 				symbols.add(sym);
 			} catch (IOException e) {
 			}
Index: model/org/eclipse/cdt/internal/core/model/parser/ElfParser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfParser.java,v
retrieving revision 1.1
diff -u -r1.1 ElfParser.java
--- model/org/eclipse/cdt/internal/core/model/parser/ElfParser.java	18 Nov 2002 15:43:53 -0000	1.1
+++ model/org/eclipse/cdt/internal/core/model/parser/ElfParser.java	25 Nov 2002 05:49:33 -0000
@@ -32,4 +32,11 @@
 		return new ElfBinaryArchive(file);
 	}
 
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat()
+	 */
+	public String getFormat() {
+		return "ELF";
+	}
+
 }
Index: model/org/eclipse/cdt/internal/core/model/parser/PEBinaryArchive.java
===================================================================
RCS file: model/org/eclipse/cdt/internal/core/model/parser/PEBinaryArchive.java
diff -N model/org/eclipse/cdt/internal/core/model/parser/PEBinaryArchive.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ model/org/eclipse/cdt/internal/core/model/parser/PEBinaryArchive.java	25 Nov 2002 05:49:32 -0000
@@ -0,0 +1,106 @@
+package org.eclipse.cdt.internal.core.model.parser;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+ 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive;
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile;
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject;
+import org.eclipse.cdt.utils.coff.PEArchive;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ */
+public class PEBinaryArchive extends PlatformObject implements IBinaryArchive {
+
+	IFile file;
+	ArrayList children;
+	long timestamp;
+	
+	public PEBinaryArchive(IFile f) {
+		file = f;
+		children = new ArrayList(5);
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#getObjects()
+	 */
+	public IBinaryObject[] getObjects() {
+		if (hasChanged()) {
+			children.clear();
+			IPath location = file.getLocation();
+			if (location != null) {
+				PEArchive ar = null;
+				try {
+					ar = new PEArchive(location.toOSString());
+					PEArchive.ARHeader[] headers = ar.getHeaders();
+					for (int i = 0; i < headers.length; i++) {
+						IBinaryObject bin = new PEBinaryFile(file, headers[i].getObjectName());
+						children.add(bin);
+					}
+				} catch (IOException e) {
+					//e.printStackTrace();
+				}
+				if (ar != null) {
+					ar.dispose();
+				}
+			}
+			children.trimToSize();
+		}
+		return (IBinaryObject[])children.toArray(new IBinaryObject[0]);
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
+	 */
+	public IFile getFile() {
+		return file;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
+	 */
+	public int getType() {
+		return IBinaryFile.ARCHIVE;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
+	 */
+	public InputStream getContents() {
+		try {
+			return file.getContents();
+		} catch (CoreException e) {
+		}
+		return new ByteArrayInputStream(new byte[0]);
+	}
+
+	boolean hasChanged() {
+		long modif = file.getModificationStamp();
+		boolean changed = modif != timestamp;
+		timestamp = modif;
+		return changed;
+	}
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[])
+	 */
+	public void add(IBinaryObject[] objs) throws IOException {
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[])
+	 */
+	public void delete(IBinaryObject[] objs) throws IOException {
+	}
+
+}
Index: model/org/eclipse/cdt/internal/core/model/parser/PEBinaryFile.java
===================================================================
RCS file: model/org/eclipse/cdt/internal/core/model/parser/PEBinaryFile.java
diff -N model/org/eclipse/cdt/internal/core/model/parser/PEBinaryFile.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ model/org/eclipse/cdt/internal/core/model/parser/PEBinaryFile.java	25 Nov 2002 05:49:33 -0000
@@ -0,0 +1,308 @@
+package org.eclipse.cdt.internal.core.model.parser;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryExecutable;
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile;
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject;
+import org.eclipse.cdt.core.model.IBinaryParser.IBinaryShared;
+import org.eclipse.cdt.core.model.IBinaryParser.ISymbol;
+import org.eclipse.cdt.utils.coff.Coff;
+import org.eclipse.cdt.utils.coff.PE;
+import org.eclipse.cdt.utils.coff.PEArchive;
+import org.eclipse.cdt.utils.coff.PE.Attribute;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ */
+public class PEBinaryFile extends PlatformObject implements IBinaryFile, 
+	IBinaryObject, IBinaryExecutable, IBinaryShared {
+
+	IFile file;
+	long timestamp;
+	PE.Attribute attribute;
+	String objectName;
+	ArrayList symbols;
+
+	public PEBinaryFile(IFile file) throws IOException {
+		this(file, null);
+	}
+	
+	public PEBinaryFile(IFile file, String o) throws IOException {
+		this.file = file;
+		objectName = o;
+		loadInformation();
+		hasChanged();
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
+	 */
+	public InputStream getContents() {
+		InputStream stream = null;
+		if (file != null && objectName != null) {
+			IPath location = file.getLocation();
+			if (location != null) {
+				PEArchive ar = null;
+				try {   
+					ar = new PEArchive(file.getLocation().toOSString());
+					PEArchive.ARHeader[] headers = ar.getHeaders();
+					for (int i = 0; i < headers.length; i++) {
+						PEArchive.ARHeader hdr = headers[i];
+						if (objectName.equals(hdr.getObjectName())) {
+							stream = new ByteArrayInputStream(hdr.getObjectData());
+							break;
+						}
+					}
+				} catch (IOException e) {
+				}
+				if (ar != null) {
+					ar.dispose();
+				}
+			}
+		} else if (file != null && file.exists()) {
+			try {
+				stream = file.getContents();
+			} catch (CoreException e) {
+			}
+		}
+		if (stream == null) {
+			stream = new ByteArrayInputStream(new byte[0]);
+		}
+		return stream;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
+	 */
+	public IFile getFile() {
+		return file;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
+	 */
+	public int getType() {
+		int type = 0;
+		Attribute attr = getAttribute();
+		if (attr != null) {
+			switch (attribute.getType()) {
+				case Attribute.PE_TYPE_EXE:
+					type = IBinaryFile.EXECUTABLE;
+				break;
+
+				case Attribute.PE_TYPE_SHLIB:
+					type = IBinaryFile.SHARED;
+				break;
+
+				case Attribute.PE_TYPE_OBJ:
+					type = IBinaryFile.OBJECT;
+				break;
+
+				case Attribute.PE_TYPE_CORE:
+					type = IBinaryFile.CORE;
+				break;
+			}
+		}
+		return type;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getBSS()
+	 */
+	public long getBSS() {
+		return 0;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getCPU()
+	 */
+	public String getCPU() {
+		Attribute attr = getAttribute();
+		if (attr != null) {
+			return attribute.getCPU();
+		}
+		return "";
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getData()
+	 */
+	public long getData() {
+		return 0;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
+	 */
+	public String getName() {
+		if (objectName != null) {
+			return objectName;
+		} else if (file != null) {
+			return file.getName();
+		}
+		return "";
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getSymbols()
+	 */
+	public ISymbol[] getSymbols() {
+		if (hasChanged() || symbols == null) {
+			if (symbols == null) {
+				symbols = new ArrayList(5);
+			}
+			try {
+				loadInformation();
+			} catch (IOException e) {
+			}
+		}
+		return (ISymbol[])symbols.toArray(new ISymbol[0]);
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getText()
+	 */
+	public long getText() {
+		return 0;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#hasDebug()
+	 */
+	public boolean hasDebug() {
+		Attribute attr = getAttribute();
+		if (attr != null) {
+			return attr.hasDebug();
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#isLittleEndian()
+	 */
+	public boolean isLittleEndian() {
+		Attribute attr = getAttribute();
+		if (attr != null) {
+			return attr.isLittleEndian();
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryExecutable#getNeededSharedLibs()
+	 */
+	public String[] getNeededSharedLibs() {
+		return new String[0];
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryShared#getSoName()
+	 */
+	public String getSoName() {
+		return "";
+	}
+
+	protected PE getPE() throws IOException {
+		if (file != null && objectName != null) {
+			IPath location = file.getLocation();
+			if (location != null) { 
+				PE pe = null;
+				PEArchive ar = null;
+				try {
+					ar = new PEArchive(file.getLocation().toOSString());
+					PEArchive.ARHeader[] headers = ar.getHeaders();
+					for (int i = 0; i < headers.length; i++) {
+						PEArchive.ARHeader hdr = headers[i];
+						if (objectName.equals(hdr.getObjectName())) {
+							pe = hdr.getPE();
+							break;
+						}
+					}
+				} finally {
+					if (ar != null) {
+						ar.dispose();
+					}
+				}
+				if (pe != null) {
+					return pe; 
+				}
+			}
+		} else if (file != null && file.exists()) {
+			IPath path = file.getLocation();
+			if (path == null) {
+				path = new Path("");
+			}
+			return new PE(path.toOSString());
+		}
+		throw new IOException("No file assiocated with Binary");
+	}
+
+	protected PE.Attribute getAttribute() {
+		if (hasChanged()) {
+			try {
+				loadInformation(); 
+			} catch (IOException e) {
+			}
+		}
+		return attribute;
+	}
+
+	protected void loadInformation() throws IOException {
+		PE pe = getPE();
+		loadInformation(pe);
+		pe.dispose();
+	}
+
+	private void loadInformation(PE pe) throws IOException {
+		loadAttribute(pe);
+		if (symbols != null) {
+			symbols.clear();
+			loadSymbols(pe);
+			symbols.trimToSize();
+		}
+	}
+
+	private void loadAttribute(PE pe) throws IOException {
+		attribute = pe.getAttribute();
+	}
+
+	private void loadSymbols(PE pe) throws IOException {
+		Coff.Symbol[] peSyms = pe.getSymbols();
+		byte[] table = pe.getStringTable();
+		for (int i = 0; i < peSyms.length; i++) {
+			if (peSyms[i].isFunction() || peSyms[i].isPointer() ||peSyms[i].isArray()) {
+				String name = peSyms[i].getName(table);
+				if (name == null || name.trim().length() == 0 ||
+				    !Character.isJavaIdentifierStart(name.charAt(0))) {
+					continue;
+				}
+				Symbol sym = new Symbol();
+				sym.filename = null;
+				sym.name = name;
+				sym.lineno = 0;
+				sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
+				symbols.add(sym);
+			}
+		}
+	}
+
+	boolean hasChanged() {
+		long modification = file.getModificationStamp();
+		boolean changed = modification != timestamp;
+		timestamp = modification;
+		return changed;
+	}
+
+}
Index: model/org/eclipse/cdt/internal/core/model/parser/PEParser.java
===================================================================
RCS file: model/org/eclipse/cdt/internal/core/model/parser/PEParser.java
diff -N model/org/eclipse/cdt/internal/core/model/parser/PEParser.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ model/org/eclipse/cdt/internal/core/model/parser/PEParser.java	25 Nov 2002 05:49:33 -0000
@@ -0,0 +1,42 @@
+package org.eclipse.cdt.internal.core.model.parser;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+
+import org.eclipse.cdt.core.model.IBinaryParser;
+import org.eclipse.cdt.utils.coff.PE;
+import org.eclipse.cdt.utils.coff.PEArchive;
+import org.eclipse.core.resources.IFile;
+
+/**
+ */
+public class PEParser implements IBinaryParser {
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IFile)
+	 */
+	public IBinaryFile getBinary(IFile file) throws IOException {
+		try {
+			PE pe = new PE(file.getLocation().toOSString());
+			pe.dispose();
+			return new PEBinaryFile(file);
+		} catch (IOException e) {
+		}
+		// Is it an Archive.
+		PEArchive ar = new PEArchive(file.getLocation().toOSString());
+		ar.dispose();
+		return new PEBinaryArchive(file);
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat()
+	 */
+	public String getFormat() {
+		return "PE";
+	}
+
+}
Index: model/org/eclipse/cdt/internal/core/model/parser/Symbol.java
===================================================================
RCS file: model/org/eclipse/cdt/internal/core/model/parser/Symbol.java
diff -N model/org/eclipse/cdt/internal/core/model/parser/Symbol.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ model/org/eclipse/cdt/internal/core/model/parser/Symbol.java	25 Nov 2002 05:49:33 -0000
@@ -0,0 +1,45 @@
+package org.eclipse.cdt.internal.core.model.parser;
+
+import org.eclipse.cdt.core.model.IBinaryParser.ISymbol;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public class Symbol implements ISymbol {
+
+	public String filename;
+	public int lineno;
+	public String name;
+	public int type;
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename()
+	 */
+	public String getFilename() {
+		return filename;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getLineNumber()
+	 */
+	public int getLineNumber() {
+		return lineno;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getName()
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getType()
+	 */
+	public int getType() {
+		return type;
+	}
+
+}
Index: src/org/eclipse/cdt/core/CCorePlugin.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java,v
retrieving revision 1.7
diff -u -r1.7 CCorePlugin.java
--- src/org/eclipse/cdt/core/CCorePlugin.java	13 Nov 2002 20:39:27 -0000	1.7
+++ src/org/eclipse/cdt/core/CCorePlugin.java	25 Nov 2002 05:49:37 -0000
@@ -6,12 +6,14 @@
  */
 
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
 import org.eclipse.cdt.core.builder.ICBuilder;
 import org.eclipse.cdt.core.index.IndexModel;
 import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.IBinaryParser;
 import org.eclipse.cdt.core.resources.IConsole;
 import org.eclipse.cdt.internal.core.CDescriptorManager;
 import org.eclipse.core.resources.IProject;
@@ -152,11 +154,49 @@
 			}
 		};
 	}
-	
+
 	public IConsole getConsole() throws CoreException {
 		return getConsole(null);
 	}
+
+	public String[] getBinaryParserFormats() {
+		ArrayList list = new ArrayList();
+		IExtensionPoint extensionPoint = getDescriptor().getExtensionPoint("BinaryParser");
+		if (extensionPoint != null) {
+			IExtension[] extensions =  extensionPoint.getExtensions();
+			for(int i = 0; i < extensions.length; i++){
+				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+				for( int j = 0; j < configElements.length; j++ ) {
+					String attr = configElements[j].getAttribute("format");
+					if (attr != null) {
+						list.add(attr);
+					}
+				}
+			}
+		}	
+		return (String[])list.toArray(new String[0]);
+	}
 	
+	public IBinaryParser getBinaryParser(String format) {
+		try {
+			IExtensionPoint extensionPoint = getDescriptor().getExtensionPoint("BinaryParser");
+			if (extensionPoint != null) {
+				IExtension[] extensions =  extensionPoint.getExtensions();
+				for(int i = 0; i < extensions.length; i++){
+					IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+					for( int j = 0; j < configElements.length; j++ ) {
+						String attr = configElements[j].getAttribute("format");
+						if (attr != null && attr.equalsIgnoreCase(format)) {
+							return (IBinaryParser)configElements[j].createExecutableExtension("class");
+						}
+					}
+				}
+			}	
+		} catch (CoreException e) {
+		} 
+		return null;
+	}	
+
 	public CoreModel getCoreModel() {
 		return CoreModel.getDefault();
 	}
Index: utils/org/eclipse/cdt/utils/coff/Coff.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java,v
retrieving revision 1.1
diff -u -r1.1 Coff.java
--- utils/org/eclipse/cdt/utils/coff/Coff.java	6 Nov 2002 01:05:54 -0000	1.1
+++ utils/org/eclipse/cdt/utils/coff/Coff.java	25 Nov 2002 05:49:40 -0000
@@ -351,6 +351,18 @@
 	public static class Symbol {
 		public final static int SYMSZ = 18;
 		public final static int SYMNMLEN = 8;
+
+		/* Derived types, in n_type.  */
+		public final static int DT_NON = 0;     /* no derived type */
+		public final static int DT_PTR = 1;     /* pointer */
+		public final static int DT_FCN = 2;     /* function */
+		public final static int DT_ARY = 3;     /* array */
+
+		public final static int N_TMASK  = 0x30;
+		public final static int N_BTSHFT = 4;
+		public final static int N_TSHIFT = 2;
+
+
 		public byte[] _n_name = new byte[SYMNMLEN]; /* Symbol name, or pointer into
 								string table if symbol name
 								is greater than SYMNMLEN.  */
@@ -378,11 +390,51 @@
 			n_numaux = memory.getByte();
 		}
 
+		public boolean isLongName() {
+			return (_n_name[0] == 0);
+		}
+
+		public String getName() {
+			for (int i = 0; i < _n_name.length; i++) {
+				if (_n_name[i] == 0) {
+					return new String(_n_name, 0, i);
+				}
+			}
+			return "";
+		}
+
+		public String getName(byte[] table) {
+			if (table.length > 0 && isLongName()) {
+				ReadMemoryAccess memory = new ReadMemoryAccess(_n_name, true);
+				memory.getInt();
+				int offset = memory.getInt();
+				if (offset > 0) {
+					for (int i = offset; i < table.length; i++) {
+						if (table[i] == 0) {
+							return new String(table, offset, i - offset);
+						}
+					}
+				}
+			}
+			return getName();
+		}
+
+		public boolean isPointer() {
+			return (n_type & N_TMASK) == (DT_PTR << N_BTSHFT);
+		}
+
+		public boolean isFunction() {
+			return (n_type & N_TMASK) == (DT_FCN << N_BTSHFT);
+		}
+
+		public boolean isArray() {
+			return (n_type & N_TMASK) == (DT_ARY << N_BTSHFT);
+		}
+
 		public String toString() {
-			StringBuffer buffer = new StringBuffer();
-			buffer.append("SYMBOL VALUES");
-			return buffer.toString();
+			return getName();
 		}
+
 	}
 
 	public FileHeader getFileHeader() throws IOException {
@@ -467,19 +519,19 @@
 		try {
 			Symbol[] table = getSymbols();
 			for (int i = 0; i < table.length; i++) {
-				buffer.append(table[i]);
+				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();
-		}
+//		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();
 	}
 
@@ -487,9 +539,9 @@
 		List aList = new ArrayList();
 		int offset = 0;
 		for (int i = 0; i < bytes.length; i++) {
-			if (bytes[i] == '\0') {
-				aList.add(new String(bytes, offset, (i + 1) - offset));
-				offset = i;
+			if (bytes[i] == 0) {
+				aList.add(new String(bytes, offset, i - offset));
+				offset = i + 1;
 			}
 		}
 		return (String[])aList.toArray(new String[0]);
Index: utils/org/eclipse/cdt/utils/coff/PE.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java,v
retrieving revision 1.1
diff -u -r1.1 PE.java
--- utils/org/eclipse/cdt/utils/coff/PE.java	6 Nov 2002 01:05:54 -0000	1.1
+++ utils/org/eclipse/cdt/utils/coff/PE.java	25 Nov 2002 05:49:43 -0000
@@ -55,6 +55,7 @@
 
 	public static final String NL = System.getProperty("line.separator", "\n");
 	RandomAccessFile rfile;
+	String filename;
 	ExeHeader exeHeader;
 	DOSHeader dosHeader;
 	FileHeader fileHeader;
@@ -65,6 +66,39 @@
 	Symbol[] symbolTable;
 	byte[] stringTable;
 
+	public class Attribute {
+		public static final int PE_TYPE_EXE   = 1;
+		public static final int PE_TYPE_SHLIB = 2;
+		public static final int PE_TYPE_OBJ   = 3;
+		public static final int PE_TYPE_CORE  = 4;
+
+		String cpu;
+		int type;
+		int word;
+		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 int getWord() {
+			return word;
+		}
+	}
+
 	/**
 	 */
 	public static class DOSHeader {
@@ -239,32 +273,186 @@
 		}
 	}
 
-
 	public PE (String filename) throws IOException {
+		this(filename, 0);
+	}
 
-		rfile = new RandomAccessFile(filename, "r");
-
-		exeHeader = new ExeHeader(rfile);
+	public PE(String filename, long pos) throws IOException {
+		this(filename, pos, true);
+	}
 
-		dosHeader = new DOSHeader(rfile);
+	public PE (String filename, long pos, boolean filter) throws IOException {
+		try {
+			rfile = new RandomAccessFile(filename, "r");
+			this.filename = filename;
+			rfile.seek(pos);
+		
+			// Object files do not have exe/dos header.
+			try {
+				exeHeader = new ExeHeader(rfile);
+				dosHeader = new DOSHeader(rfile);
+				// Jump the Coff header, and Check the sig.
+				rfile.seek(dosHeader.e_lfanew);
+				byte[] sig = new byte[4]; 
+				rfile.readFully(sig);
+				if (!((sig[0] == 'P') && (sig[1] == 'E')
+				   && (sig[2] == '\0') && (sig[3] == '\0'))) {
+					throw new IOException("Not a PE format");
+				}
+			} catch (IOException e) {
+				rfile.seek(pos);
+			}
 
-		// Jump the Coff header, and Check the sig.
-		rfile.seek(dosHeader.e_lfanew);
-		byte[] sig = new byte[4]; 
-		rfile.readFully(sig);
-		if (!((sig[0] == 'P') && (sig[1] == 'E')
-		   && (sig[2] == '\0') && (sig[3] == '\0'))) {
-			throw new IOException("Not a PE format");
-		}
+			fileHeader = new Coff.FileHeader(rfile, rfile.getFilePointer());
 
-		fileHeader = new Coff.FileHeader(rfile, rfile.getFilePointer());
+			// Check if this a valid machine.
+			switch (fileHeader.f_magic) {
+				case PEConstants.IMAGE_FILE_MACHINE_ALPHA:
+				case PEConstants.IMAGE_FILE_MACHINE_ARM:
+				case PEConstants.IMAGE_FILE_MACHINE_ALPHA64:
+				case PEConstants.IMAGE_FILE_MACHINE_I386:
+				case PEConstants.IMAGE_FILE_MACHINE_IA64:
+				case PEConstants.IMAGE_FILE_MACHINE_M68K:
+				case PEConstants.IMAGE_FILE_MACHINE_MIPS16:
+				case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU:
+				case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16:
+				case PEConstants.IMAGE_FILE_MACHINE_POWERPC:
+				case PEConstants.IMAGE_FILE_MACHINE_R3000:
+				case PEConstants.IMAGE_FILE_MACHINE_R4000:
+				case PEConstants.IMAGE_FILE_MACHINE_R10000:
+				case PEConstants.IMAGE_FILE_MACHINE_SH3:
+				case PEConstants.IMAGE_FILE_MACHINE_SH4:
+				case PEConstants.IMAGE_FILE_MACHINE_THUMB:
+					// Ok;
+				break;
 
-		optionalHeader = new Coff.OptionalHeader(rfile, rfile.getFilePointer());
+				default:
+					throw new IOException("Unknow machine/format");
+			}
 
-		ntHeader = new NTOptionalHeader(rfile, rfile.getFilePointer());
+			if (fileHeader.f_opthdr > 0) {
+				optionalHeader = new Coff.OptionalHeader(rfile, rfile.getFilePointer());
+				ntHeader = new NTOptionalHeader(rfile, rfile.getFilePointer());
+			}
+		} finally {
+			if (rfile != null) {
+				rfile.close();
+				rfile = null;
+			}
+		}
+	}
 
+	public Attribute getAttribute() {
+		Attribute attrib = new Attribute();
+		FileHeader filhdr = getFileHeader();
+
+		// Machine type.
+		switch (filhdr.f_magic) {
+			case PEConstants.IMAGE_FILE_MACHINE_UNKNOWN:
+				attrib.cpu = "none";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_ALPHA:
+				attrib.cpu = "alpha";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_ARM:
+				attrib.cpu = "arm";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_ALPHA64:
+				attrib.cpu = "arm64";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_I386:
+				attrib.cpu = "i386";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_IA64:
+				attrib.cpu = "ia64";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_M68K:
+				attrib.cpu = "m68k";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_MIPS16:
+				attrib.cpu = "mips16";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU:
+				attrib.cpu = "mipsfpu";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16:
+				attrib.cpu = "mipsfpu16";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_POWERPC:
+				attrib.cpu = "powerpc";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_R3000:
+				attrib.cpu = "r3000";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_R4000:
+				attrib.cpu = "r4000";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_R10000:
+				attrib.cpu = "r10000";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_SH3:
+				attrib.cpu = "sh3";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_SH4:
+				attrib.cpu = "sh4";
+			break;
+			case PEConstants.IMAGE_FILE_MACHINE_THUMB:
+				attrib.cpu = "thumb";
+			break;
+		}
+
+		/* PE characteristics, FileHeader.f_flags.  */
+		if ((filhdr.f_flags & PEConstants.IMAGE_FILE_DLL) != 0) {
+			attrib.type = attrib.PE_TYPE_SHLIB;
+		} else if ((filhdr.f_flags & PEConstants.IMAGE_FILE_EXECUTABLE_IMAGE) != 0) {
+			attrib.type = attrib.PE_TYPE_EXE;
+		} else {
+			attrib.type = attrib.PE_TYPE_OBJ;
+		}
+
+		// For PE always assume little endian unless otherwise.
+		attrib.isle = true;
+		// Little Endian.
+		if ((filhdr.f_flags & PEConstants.IMAGE_FILE_BYTES_REVERSED_LO) != 0) {
+			attrib.isle = true;
+		}
+		// Big Endian.
+		if ((filhdr.f_flags & PEConstants.IMAGE_FILE_BYTES_REVERSED_HI) != 0) {
+			attrib.isle = false;
+		}
+
+		// No debug information.
+		if ((filhdr.f_flags & PEConstants.IMAGE_FILE_DEBUG_STRIPPED) != 0) {
+			attrib.bDebug = false;
+		} else {
+			attrib.bDebug = true;
+		}
+		
+		// sizeof word.
+		if ((filhdr.f_flags & PEConstants.IMAGE_FILE_16BIT_MACHINE) != 0) {
+			attrib.word = 16;
+		}
+		if ((filhdr.f_flags & PEConstants.IMAGE_FILE_32BIT_MACHINE) != 0) {
+			attrib.word = 32;
+		}
+		return attrib;
+	}
+
+	public void dispose() throws IOException {
+		if (rfile != null) {
+			rfile.close();
+			rfile = null;
+		}
 	}
 
+	protected void finalize() throws Throwable {
+		try {
+			dispose();
+		} finally {
+			super.finalize();
+		}
+	}
+	
 	public ExeHeader getExeHeader() {
 		return exeHeader;
 	}
@@ -287,40 +475,52 @@
 
 	public ImageDataDirectory[] getImageDataDirectories() throws IOException {
 		if (dataDirectories == null) {
-			long offset = dosHeader.e_lfanew + FileHeader.FILHSZ +
-				OptionalHeader.AOUTHDRSZ + NTOptionalHeader.NTHDRSZ + 4/*NT SIG*/;
-			rfile.seek(offset);
+			RandomAccessFile accessFile = getRandomAccessFile();
+			long offset = 0;
+			if (dosHeader != null) {
+				offset = dosHeader.e_lfanew + 4/*NT SIG*/;
+			}
+			offset += FileHeader.FILHSZ + OptionalHeader.AOUTHDRSZ + NTOptionalHeader.NTHDRSZ;
+			accessFile.seek(offset);
 			dataDirectories = new ImageDataDirectory[PEConstants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
 			byte[] data = new byte[dataDirectories.length * (4 + 4)];
-			rfile.readFully(data);
+			accessFile.readFully(data);
 			ReadMemoryAccess memory = new ReadMemoryAccess(data, true);
 			for (int i = 0; i < dataDirectories.length; i++) {
 				int rva = memory.getInt();
 				int size = memory.getInt();
 				dataDirectories[i] = new ImageDataDirectory(rva, size);
 			}
+			dispose();
 		}
 		return dataDirectories;
 	}
 	public SectionHeader[] getSectionHeaders() throws IOException {
 		if (scnhdrs == null) {
+			RandomAccessFile accessFile = getRandomAccessFile();
 			scnhdrs = new SectionHeader[fileHeader.f_nscns];
-			long offset = dosHeader.e_lfanew +
-				FileHeader.FILHSZ + fileHeader.f_opthdr + 4 /* NT SIG */;
+			long offset = 0;
+			if (dosHeader != null) {
+				offset = dosHeader.e_lfanew + 4 /* NT SIG */;
+			}
+			offset += FileHeader.FILHSZ + fileHeader.f_opthdr;
 			for (int i = 0; i < scnhdrs.length; i++, offset += SectionHeader.SCNHSZ) {
-				scnhdrs[i] = new SectionHeader(rfile, offset);
+				scnhdrs[i] = new SectionHeader(accessFile, offset);
 			}
+			dispose();
 		}
 		return scnhdrs;
 	}
 
 	public Symbol[] getSymbols() throws IOException {
 		if (symbolTable == null) {
+			RandomAccessFile accessFile = getRandomAccessFile();
 			long offset = fileHeader.f_symptr;
 			symbolTable = new Symbol[fileHeader.f_nsyms];
 			for (int i = 0; i < symbolTable.length; i++, offset += Symbol.SYMSZ) {
-				symbolTable[i] = new Symbol(rfile, offset);
+				symbolTable[i] = new Symbol(accessFile, offset);
 			}
+			dispose();
 		}
 		return symbolTable;
 	}
@@ -328,20 +528,22 @@
 	public byte[] getStringTable() throws IOException {
 		if (stringTable == null) {
 			if (fileHeader.f_nsyms > 0) {
+				RandomAccessFile accessFile = getRandomAccessFile();
 				long symbolsize = Symbol.SYMSZ * fileHeader.f_nsyms;
 				long offset = fileHeader.f_symptr + symbolsize;
-				rfile.seek(offset);
+				accessFile.seek(offset);
 				byte[] bytes = new byte[4];
-				rfile.readFully(bytes);
+				accessFile.readFully(bytes);
 				int str_len = ReadMemoryAccess.getIntLE(bytes);
 				if (str_len > 4) {
 					str_len -= 4;
 					stringTable = new byte[str_len];
-					rfile.seek(offset + 4);
-					rfile.readFully(stringTable);
+					accessFile.seek(offset + 4);
+					accessFile.readFully(stringTable);
 				} else {
 					stringTable = new byte[0];
 				}
+				dispose();
 			} else {
 				stringTable = new byte[0];
 			}
@@ -351,11 +553,19 @@
 
 	public String toString() {
 		StringBuffer buffer = new StringBuffer();
-		buffer.append(exeHeader);
-		buffer.append(dosHeader);
+		if (exeHeader != null) {
+			buffer.append(exeHeader);
+		}
+		if (dosHeader != null) {
+			buffer.append(dosHeader);
+		}
 		buffer.append(fileHeader);
-		buffer.append(optionalHeader);
-		buffer.append(ntHeader);
+		if (optionalHeader != null) {
+			buffer.append(optionalHeader);
+		}
+		if (ntHeader != null) {
+			buffer.append(ntHeader);
+		}
 		try {
 			ImageDataDirectory[] dirs = getImageDataDirectories();
 			for (int i = 0; i < dirs.length; i++) {
@@ -396,6 +606,12 @@
 		return buffer.toString();
 	}
 
+	RandomAccessFile getRandomAccessFile () throws IOException {
+		if (rfile == null) {
+			rfile = new RandomAccessFile(filename, "r");
+		}
+		return rfile;
+	}
 	public static void main(String[] args) {
 		try {
 			PE pe = new PE(args[0]);
Index: utils/org/eclipse/cdt/utils/coff/PEArchive.java
===================================================================
RCS file: utils/org/eclipse/cdt/utils/coff/PEArchive.java
diff -N utils/org/eclipse/cdt/utils/coff/PEArchive.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ utils/org/eclipse/cdt/utils/coff/PEArchive.java	25 Nov 2002 05:49:44 -0000
@@ -0,0 +1,315 @@
+package org.eclipse.cdt.utils.coff;
+
+/*
+ * (c) Copyright QNX Software Systems Ltd. 2002.
+ * All Rights Reserved.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Vector;
+
+/**
+ *  The <code>AR</code> class is used for parsing standard ELF 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 PE object for performing PE
+ *  class operations.
+ *  @see ARHeader
+ */
+public class PEArchive {
+
+	protected String filename;
+	protected RandomAccessFile rfile;
+	protected long strtbl_pos = -1;
+	private ARHeader[] headers;
+
+	public void dispose() {
+		try {
+			if (rfile != null) {
+				rfile.close();
+				rfile = null;
+			}
+		} catch (IOException e) {
+		}
+	}
+
+	/**
+	 * Do not leak fds.
+	 */
+	protected void finalize() throws Throwable {
+		try {
+			dispose();
+		} finally {
+			super.finalize();
+		}
+	}
+
+	/**
+	 * The <code>ARHeader</code> class is used to store the per-object file 
+	 *  archive headers.  It can also create an PE object for inspecting
+	 *  the object file data.
+	 */
+	public class ARHeader {
+
+		private String object_name;
+		private String modification_time;
+		private String uid;
+		private String gid;
+		private String mode;
+		private long size;
+		private long elf_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>rfile</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 = rfile.getFilePointer();
+
+			try {
+				if (strtbl_pos != -1) {
+					byte temp;
+					rfile.seek(strtbl_pos + offset);
+					while ((temp = rfile.readByte()) != '\n')
+						name.append((char) temp);
+				}
+			} finally {
+				rfile.seek(pos);
+			}
+
+			return name.toString();
+		}
+
+		/**
+		 * Creates a new archive header object.  
+		 *
+		 * Assumes that rfile is already at the correct location in the file.
+		 *
+		 * @throws IOException 
+		 *    There was an error processing the header data from the file.
+		 */
+		public ARHeader() throws IOException {
+			byte[] object_name = new byte[16];
+			byte[] modification_time = new byte[12];
+			byte[] uid = new byte[6];
+			byte[] gid = new byte[6];
+			byte[] mode = new byte[8];
+			byte[] size = new byte[10];
+			byte[] trailer = new byte[2];
+
+			//
+			// Read in the archive header data. Fixed sizes.
+			//
+			rfile.read(object_name);
+			rfile.read(modification_time);
+			rfile.read(uid);
+			rfile.read(gid);
+			rfile.read(mode);
+			rfile.read(size);
+			rfile.read(trailer);
+
+			//
+			// Save this location so we can create the PE object later.
+			//
+			elf_offset = rfile.getFilePointer();
+
+			//
+			// Convert the raw bytes into strings and numbers.
+			//
+			this.object_name = removeBlanks(new String(object_name));
+			this.modification_time = new String(modification_time);
+			this.uid = new String(uid);
+			this.gid = new String(gid);
+			this.mode = new String(mode);
+			this.size = Long.parseLong(removeBlanks(new String(size)));
+
+			//
+			// If the name is of the format "/<number>", get name from the
+			// string table.
+			//
+			if (strtbl_pos != -1
+				&& this.object_name.length() > 1
+				&& this.object_name.charAt(0) == '/') {
+				try {
+					long offset = Long.parseLong(this.object_name.substring(1));
+					this.object_name = nameFromStringTable(offset);
+				} catch (java.lang.Exception e) {
+				}
+			}
+
+			//
+			// Strip the trailing / from the object name.
+			//
+			int len = this.object_name.length();
+			if (len > 2 && this.object_name.charAt(len - 1) == '/') {
+				this.object_name = this.object_name.substring(0, len - 1);
+			}
+
+		}
+
+		/** Get the name of the object file */
+		public String getObjectName() {
+			return object_name;
+		}
+
+		/** Get the size of the object file . */
+		public long getSize() {
+			return size;
+		}
+
+		/**
+		 *  Create an new PE object for the object file.
+		 *
+		 * @throws IOException 
+		 *    Not a valid PE object file.
+		 * @return A new PE object.  
+		 * @see PE#PE( String, long )
+		 */
+		public PE getPE() throws IOException {
+			return new PE(filename, elf_offset);
+		}
+
+		public PE getPE(boolean filter_on) throws IOException {
+			return new PE(filename, elf_offset, filter_on);
+		}
+
+		public byte[] getObjectData() throws IOException {
+			byte[] temp = new byte[(int) size];
+			rfile.seek(elf_offset);
+			rfile.read(temp);
+			return temp;
+		}
+	}
+
+	/**
+	 *  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 PEArchive(String filename) throws IOException {
+		this.filename = filename;
+		rfile = new RandomAccessFile(filename, "r");
+		String hdr = rfile.readLine();
+		if (hdr == null || hdr.compareTo("!<arch>") != 0) {
+			rfile.close();
+			throw new IOException("Not a valid archive file.");
+		}
+	}
+
+	/** Load the headers from the file (if required).  */
+	private void loadHeaders() throws IOException {
+		if (headers != null)
+			return;
+
+		Vector v = new Vector();
+		try {
+			//
+			// Check for EOF condition
+			//
+			while (rfile.getFilePointer() < rfile.length()) {
+				ARHeader header = new ARHeader();
+				String name = header.getObjectName();
+
+				long pos = rfile.getFilePointer();
+
+				//
+				// If the name starts with a / it is specical.
+				//
+				if (name.charAt(0) != '/')
+					v.add(header);
+
+				//
+				// If the name is "//" then this is the string table section.
+				//
+				if (name.compareTo("//") == 0)
+					strtbl_pos = pos;
+
+				//
+				// Compute the location of the next header in the archive.
+				//
+				pos += header.getSize();
+				if ((pos % 2) != 0)
+					pos++;
+
+				rfile.seek(pos);
+			}
+		} catch (IOException e) {
+		}
+		headers = (ARHeader[]) v.toArray(new ARHeader[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 ARHeader[] getHeaders() throws IOException {
+		loadHeaders();
+		return headers;
+	}
+
+	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;
+	}
+
+	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 < headers.length; i++) {
+			object_name = headers[i].getObjectName();
+			if (names != null && !stringInStrings(object_name, names))
+				continue;
+
+			object_name = "" + count + "_" + object_name;
+			count++;
+
+			byte[] data = headers[i].getObjectData();
+			File output = new File(outdir, object_name);
+			names_used.add(object_name);
+
+			RandomAccessFile rfile = new RandomAccessFile(output, "rw");
+			rfile.write(data);
+			rfile.close();
+		}
+
+		return (String[]) names_used.toArray(new String[0]);
+	}
+
+	public String[] extractFiles(String outdir) throws IOException {
+		return extractFiles(outdir, null);
+	}
+
+}
Index: utils/org/eclipse/cdt/utils/elf/AR.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java,v
retrieving revision 1.2
diff -u -r1.2 AR.java
--- utils/org/eclipse/cdt/utils/elf/AR.java	9 Oct 2002 12:40:43 -0000	1.2
+++ utils/org/eclipse/cdt/utils/elf/AR.java	25 Nov 2002 05:49:48 -0000
@@ -30,11 +30,26 @@
     public void dispose() {
         try 
         {
-            efile.close();
+            if (efile != null)
+            {
+               efile.close();
+               efile = null;
+            }
         }
         catch( IOException e )
         {}
     }
+
+   protected void finalize() throws Throwable {
+        try
+        {
+            dispose();
+        }
+        finally
+        {
+           super.finalize();
+        }
+   }
 
     /**
      * The <code>ARHeader</code> class is used to store the per-object file 
Index: utils/org/eclipse/cdt/utils/elf/Elf.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java,v
retrieving revision 1.7
diff -u -r1.7 Elf.java
--- utils/org/eclipse/cdt/utils/elf/Elf.java	22 Nov 2002 16:32:43 -0000	1.7
+++ utils/org/eclipse/cdt/utils/elf/Elf.java	25 Nov 2002 05:49:46 -0000
@@ -687,15 +687,30 @@
 	}
 	
 	public void dispose() {
-		if ( addr2line != null ) {
+		if (addr2line != null) {
 			addr2line.dispose();
 		}
-		if ( cppFilt != null ) {
+		if (cppFilt != null) {
 			cppFilt.dispose();
 		}
 		try {
-			efile.close();
-		} catch (IOException e) {}
+			if (efile != null) {
+				efile.close();
+				efile = null;
+			}
+		} catch (IOException e) {
+		}
+	}
+
+	/**
+	 * Make sure we do not leak the fds.
+	 */
+	protected void finalize() throws Throwable {
+		try {
+			dispose();
+		} finally {
+			super.finalize();
+		}
 	}
 	
 	public Section[] getSections(int type) throws IOException {		



Back to the top