[
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 {