Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlain Magloire2003-11-18 16:20:49 +0000
committerAlain Magloire2003-11-18 16:20:49 +0000
commit7a446b027c273ed0c639bed513fe1b2a60b1960c (patch)
tree0def0c34dbfe4d0055e600a83a092352377abeb6
parent8b5836e8301a472c68d2f7929fb3f6670b7355a3 (diff)
downloadorg.eclipse.cdt-7a446b027c273ed0c639bed513fe1b2a60b1960c.tar.gz
org.eclipse.cdt-7a446b027c273ed0c639bed513fe1b2a60b1960c.tar.xz
org.eclipse.cdt-7a446b027c273ed0c639bed513fe1b2a60b1960c.zip
Attempt to address performance problem in the IBinaryParser
To many open()s a new method was create isBinary(byte[] ..) So the file could be open only one time.
-rw-r--r--core/org.eclipse.cdt.core/ChangeLog28
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java22
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelInfo.java2
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java34
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/NullBinaryParser.java7
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java2
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java10
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java6
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java13
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java10
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java2
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java81
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java8
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java23
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java13
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java7
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java10
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java2
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java72
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java8
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java26
21 files changed, 287 insertions, 99 deletions
diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog
index d683c8947ba..4d1e5027d33 100644
--- a/core/org.eclipse.cdt.core/ChangeLog
+++ b/core/org.eclipse.cdt.core/ChangeLog
@@ -1,3 +1,31 @@
+2003-11-18 Alain Magloire
+
+ Attempt to address performance problems from the binary parser
+ on big projects. The problem is that files are open multiple
+ times to detect if they are binaries or archives. We can
+ not really rely on the filename or extension. A new method
+ as been added to the IBinaryParser interface, isBinary()
+ taken an intial byte[].
+
+ * model/org/eclipse/cdt/internal/core/model/Binary.java
+ * model/org/eclipse/cdt/internal/core/model/CModelManager.java
+ * model/org/eclipse/cdt/internal/core/model/NullBinaryParser.java
+ * src/org/eclipse/cdt/core/CCorePlugin.java
+ * src/org/eclipse/cdt/core/IBinaryParser.java
+ * utils/org/eclipse/cdt/utils/coff/PE.java
+ * utils/org/eclipse/cdt/utils/coff/PEArchive.java
+ * utils/org/eclipse/cdt/utils/coff/parser/ARMember.java
+ * utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java
+ * utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java
+ * utils/org/eclipse/cdt/utils/coff/parser/PEParser.java
+ * utils/org/eclipse/cdt/utils/coff/parser/Symbol.java
+ * utils/org/eclipse/cdt/utils/elf/AR.java
+ * utils/org/eclipse/cdt/utils/elf/parser/ARMember.java
+ * utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java
+ * utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java
+ * utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
+ * utils/org/eclipse/cdt/utils/elf/parser/Symbol.java
+
2003-11-17 Doug Schaefer
Nothing just testing the commit logs
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java
index 37ecafe5e44..0b99b357bb6 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java
@@ -174,19 +174,18 @@ public class Binary extends Openable implements IBinary {
}
private void addFunction(OpenableInfo info, ISymbol symbol, Map hash) {
- String filename = filename = symbol.getFilename();
+ IPath filename = filename = symbol.getFilename();
BinaryFunction function = null;
// Addr2line returns the funny "??" when it can find the file.
if (filename != null && !filename.equals("??")) {
BinaryModule module = null;
- IPath path = new Path(filename);
- if (hash.containsKey(path)) {
- module = (BinaryModule)hash.get(path);
+ if (hash.containsKey(filename)) {
+ module = (BinaryModule)hash.get(filename);
} else {
// A special container we do not want the file to be parse.
- module = new BinaryModule(this, path);
- hash.put(path, module);
+ module = new BinaryModule(this, filename);
+ hash.put(filename, module);
info.addChild(module);
}
function = new BinaryFunction(module, symbol.getName(), symbol.getAddress());
@@ -206,17 +205,16 @@ public class Binary extends Openable implements IBinary {
}
private void addVariable(OpenableInfo info, ISymbol symbol, Map hash) {
- String filename = filename = symbol.getFilename();
+ IPath filename = filename = symbol.getFilename();
BinaryVariable variable = null;
// Addr2line returns the funny "??" when it can not find the file.
if (filename != null && !filename.equals("??")) {
BinaryModule module = null;
- IPath path = new Path(filename);
- if (hash.containsKey(path)) {
- module = (BinaryModule)hash.get(path);
+ if (hash.containsKey(filename)) {
+ module = (BinaryModule)hash.get(filename);
} else {
- module = new BinaryModule(this, path);
- hash.put(path, module);
+ module = new BinaryModule(this, filename);
+ hash.put(filename, module);
info.addChild(module);
}
variable = new BinaryVariable(module, symbol.getName(), symbol.getAddress());
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelInfo.java
index 8b54b5d6581..f2cac585ec8 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelInfo.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelInfo.java
@@ -21,7 +21,7 @@ public class CModelInfo extends CContainerInfo {
}
/**
- * Compute the non-java resources contained in this java project.
+ * Compute the non-C resources contained in this C project.
*/
private Object[] computeNonCResources() {
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java
index ec5aa277b44..1b20fe0c268 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java
@@ -6,6 +6,7 @@ package org.eclipse.cdt.internal.core.model;
*/
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -97,6 +98,11 @@ public class CModelManager implements IResourceChangeListener {
* The list of started BinaryRunners on projects.
*/
private HashMap binaryRunners = new HashMap();
+
+ /**
+ * Map of the binary parser for each project.
+ */
+ private HashMap binaryParsersMap = new HashMap();
/**
* The lis of the SourceMappers on projects.
@@ -345,7 +351,14 @@ public class CModelManager implements IResourceChangeListener {
public IBinaryParser getBinaryParser(IProject project) {
try {
- return CCorePlugin.getDefault().getBinaryParser(project);
+ IBinaryParser parser = (IBinaryParser)binaryParsersMap.get(project);
+ if (parser == null) {
+ parser = CCorePlugin.getDefault().getBinaryParser(project);
+ }
+ if (parser != null) {
+ binaryParsersMap.put(project, parser);
+ return parser;
+ }
} catch (CoreException e) {
}
return new NullBinaryParser();
@@ -354,8 +367,22 @@ public class CModelManager implements IResourceChangeListener {
public IBinaryFile createBinaryFile(IFile file) {
try {
IBinaryParser parser = getBinaryParser(file.getProject());
- return parser.getBinary(file.getLocation());
+ InputStream is = file.getContents();
+ byte[] bytes = new byte[128];
+ int count = is.read(bytes);
+ is.close();
+ if (count > 0 && count < bytes.length) {
+ byte[] array = new byte[count];
+ System.arraycopy(bytes, 0, array, 0, count);
+ bytes = array;
+ }
+ IPath location = file.getLocation();
+ if (parser.isBinary(bytes, location)) {
+ return parser.getBinary(location);
+ }
} catch (IOException e) {
+ } catch (CoreException e) {
+ //e.printStackTrace();
}
return null;
}
@@ -372,6 +399,7 @@ public class CModelManager implements IResourceChangeListener {
// but it has the side of effect of removing the CProject also
// so we have to recall create again.
releaseCElement(celement);
+ binaryParsersMap.remove(project);
celement = create(project);
Parent parent = (Parent)celement.getParent();
CElementInfo info = (CElementInfo)parent.getElementInfo();
@@ -750,6 +778,7 @@ public class CModelManager implements IResourceChangeListener {
break;
}
}
+
/**
* Returns the set of elements which are out of synch with their buffers.
*/
@@ -820,5 +849,6 @@ public class CModelManager implements IResourceChangeListener {
if (runner != null) {
runner.stop();
}
+ binaryParsersMap.remove(project);
}
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/NullBinaryParser.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/NullBinaryParser.java
index 148604d8a86..cf4c4586f09 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/NullBinaryParser.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/NullBinaryParser.java
@@ -28,4 +28,11 @@ public class NullBinaryParser implements IBinaryParser {
return "Null Format";
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
+ */
+ public boolean isBinary(byte[] array, IPath path) {
+ return false;
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index a9ed936d214..ee5e8c52939 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -471,7 +471,7 @@ public class CCorePlugin extends Plugin {
if (project != null) {
try {
ICDescriptor cdesc = (ICDescriptor) getCProjectDescription(project);
- ICExtensionReference[] cextensions = cdesc.get(BINARY_PARSER_UNIQ_ID);
+ ICExtensionReference[] cextensions = cdesc.get(BINARY_PARSER_UNIQ_ID, true);
if (cextensions.length > 0)
parser = (IBinaryParser) cextensions[0].createExtension();
} catch (CoreException e) {
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java
index 04abf78a16f..3f7e3a78898 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java
@@ -55,7 +55,9 @@ public interface IBinaryParser {
boolean isLittleEndian();
ISymbol[] getSymbols();
-
+
+ ISymbol getSymbol(long addr);
+
String getName();
}
@@ -74,7 +76,7 @@ public interface IBinaryParser {
String getSoName();
}
- interface ISymbol {
+ interface ISymbol extends Comparable {
static final int FUNCTION = 0x01;
static final int VARIABLE = 0x02;
@@ -82,11 +84,13 @@ public interface IBinaryParser {
long getAddress();
int getStartLine();
int getEndLine();
- String getFilename();
+ IPath getFilename();
int getType();
}
IBinaryFile getBinary(IPath path) throws IOException;
+
+ boolean isBinary(byte[] array, IPath path);
String getFormat();
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java
index ba7d1949452..d95e27ab4f0 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java
@@ -438,6 +438,12 @@ public class PE {
return attrib;
}
+ public static boolean isExeHeader(byte[] e_signature) {
+ if (e_signature.length < 2 || e_signature[0] != 'M' || e_signature[1] != 'Z')
+ return false;
+ return true;
+ }
+
public static Attribute getAttributes(String file) throws IOException {
PE pe = new PE(file);
Attribute attrib = pe.getAttribute();
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java
index 37b1e21bb99..35cb63c392f 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java
@@ -200,6 +200,19 @@ public class PEArchive {
}
}
+ public static boolean isARHeader(byte[] ident) {
+ if (ident.length < 7
+ || ident[0] != '!'
+ || ident[1] != '<'
+ || ident[2] != 'a'
+ || ident[3] != 'r'
+ || ident[4] != 'c'
+ || ident[5] != 'h'
+ || ident[6] != '>')
+ return false;
+ return true;
+ }
+
/**
* Creates a new <code>AR</code> object from the contents of
* the given file.
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java
index d213ecab810..73ec760ad76 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java
@@ -13,11 +13,13 @@ package org.eclipse.cdt.utils.coff.parser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.CygPath;
+import org.eclipse.cdt.utils.ICygwinToolsProvider;
import org.eclipse.cdt.utils.coff.Coff;
import org.eclipse.cdt.utils.coff.PE;
import org.eclipse.cdt.utils.coff.PEArchive;
@@ -28,8 +30,8 @@ import org.eclipse.core.runtime.IPath;
public class ARMember extends BinaryObject {
PEArchive.ARHeader header;
- public ARMember(IPath p, PEArchive.ARHeader h) throws IOException {
- super(p, h.getPE());
+ public ARMember(IPath p, PEArchive.ARHeader h, ICygwinToolsProvider provider) throws IOException {
+ super(p, h.getPE(), provider);
header = h;
}
@@ -67,7 +69,7 @@ public class ARMember extends BinaryObject {
throw new IOException("No file assiocated with Binary");
}
- protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cypath) {
+ protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cypath, List list) {
for (int i = 0; i < peSyms.length; i++) {
if (peSyms[i].isFunction() || peSyms[i].isPointer() ||peSyms[i].isArray()) {
String name = peSyms[i].getName(table);
@@ -80,7 +82,7 @@ public class ARMember extends BinaryObject {
sym.name = name;
sym.addr = peSyms[i].n_value;
- addSymbol(sym);
+ list.add(sym);
}
}
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java
index a29aeaf8be9..d32d6e22dfb 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java
@@ -38,7 +38,7 @@ public class BinaryArchive extends BinaryFile implements IBinaryArchive {
ar = new PEArchive(getPath().toOSString());
PEArchive.ARHeader[] headers = ar.getHeaders();
for (int i = 0; i < headers.length; i++) {
- IBinaryObject bin = new ARMember(path, headers[i]);
+ IBinaryObject bin = new ARMember(path, headers[i], toolsProvider);
children.add(bin);
}
} catch (IOException e) {
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java
index f71ef98628e..1ea7e6d2b93 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java
@@ -1,11 +1,19 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+***********************************************************************/
package org.eclipse.cdt.utils.coff.parser;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
@@ -13,27 +21,29 @@ import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.CygPath;
+import org.eclipse.cdt.utils.ICygwinToolsProvider;
import org.eclipse.cdt.utils.coff.Coff;
import org.eclipse.cdt.utils.coff.PE;
import org.eclipse.cdt.utils.coff.PE.Attribute;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
/**
*/
public class BinaryObject extends BinaryFile implements IBinaryObject {
PE.Attribute attribute;
- ArrayList symbols;
+ ISymbol[] symbols;
int type = IBinaryFile.OBJECT;
-
+ private ISymbol[] NO_SYMBOLS = new ISymbol[0];
+
public BinaryObject(IPath p) throws IOException {
super(p);
- loadInformation();
- hasChanged();
}
- public BinaryObject(IPath p, PE pe) throws IOException {
+ public BinaryObject(IPath p, PE pe, ICygwinToolsProvider provider) throws IOException {
super(p);
+ setToolsProvider(provider);
loadInformation(pe);
pe.dispose();
hasChanged();
@@ -43,6 +53,18 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
type = t;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbol(long)
+ */
+ public ISymbol getSymbol(long addr) {
+ ISymbol[] syms = getSymbols();
+ int i = Arrays.binarySearch(syms, new Long(addr));
+ if (i < 0 || i >= syms.length) {
+ return null;
+ }
+ return syms[i];
+ }
+
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
*/
@@ -87,15 +109,15 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
*/
public ISymbol[] getSymbols() {
if (hasChanged() || symbols == null) {
- if (symbols == null) {
- symbols = new ArrayList(5);
- }
try {
loadInformation();
} catch (IOException e) {
}
+ if (symbols == null) {
+ symbols = NO_SYMBOLS;
+ }
}
- return (ISymbol[])symbols.toArray(new ISymbol[0]);
+ return symbols;
}
/**
@@ -163,11 +185,7 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
private void loadInformation(PE pe) throws IOException {
loadAttribute(pe);
- if (symbols != null) {
- symbols.clear();
- loadSymbols(pe);
- symbols.trimToSize();
- }
+ loadSymbols(pe);
}
private void loadAttribute(PE pe) throws IOException {
@@ -175,13 +193,14 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
}
private void loadSymbols(PE pe) throws IOException {
+ ArrayList list = new ArrayList();
Addr2line addr2line = getAddr2Line();
CPPFilt cppfilt = getCPPFilt();
CygPath cygpath = getCygPath();
Coff.Symbol[] peSyms = pe.getSymbols();
byte[] table = pe.getStringTable();
- addSymbols(peSyms, table, addr2line, cppfilt, cygpath);
+ addSymbols(peSyms, table, addr2line, cppfilt, cygpath, list);
if (addr2line != null) {
addr2line.dispose();
@@ -192,10 +211,13 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
if (cygpath != null) {
cygpath.dispose();
}
- symbols.trimToSize();
+
+ symbols = (ISymbol[])list.toArray(NO_SYMBOLS);
+ Arrays.sort(symbols);
+ list.clear();
}
- protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath) {
+ protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath, List list) {
for (int i = 0; i < peSyms.length; i++) {
if (peSyms[i].isFunction() || peSyms[i].isPointer() ||peSyms[i].isArray()) {
String name = peSyms[i].getName(table);
@@ -220,20 +242,21 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
sym.endLine = 0;
if (addr2line != null) {
try {
- sym.filename = addr2line.getFileName(sym.addr);
- if (cygpath != null)
- sym.filename = cygpath.getFileName(sym.filename);
+ String filename = addr2line.getFileName(sym.addr);
+ if (filename != null) {
+ if (cygpath != null) {
+ sym.filename = new Path(cygpath.getFileName(filename));
+ } else {
+ sym.filename = new Path(filename);
+ }
+ }
sym.startLine = addr2line.getLineNumber(sym.addr);
} catch (IOException e) {
}
}
- addSymbol(sym);
+ list.add(sym);
}
}
}
- protected void addSymbol(Symbol sym) {
- symbols.add(sym);
- }
-
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java
index 4b7eeeafb22..1043a4a21e9 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java
@@ -16,6 +16,7 @@ import java.io.IOException;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.IBinaryParser;
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.runtime.IPath;
@@ -70,4 +71,11 @@ public class PEParser extends AbstractCExtension implements IBinaryParser {
return "PE";
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
+ */
+ public boolean isBinary(byte[] array, IPath path) {
+ return PE.isExeHeader(array) || PEArchive.isARHeader(array);
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java
index 14b84430b29..e0535a68416 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java
@@ -14,12 +14,13 @@ import java.io.IOException;
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
+import org.eclipse.core.runtime.IPath;
public class Symbol implements ISymbol {
BinaryObject binary;
- public String filename;
+ public IPath filename;
public int startLine;
public int endLine;
public long addr;
@@ -32,7 +33,7 @@ public class Symbol implements ISymbol {
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename()
*/
- public String getFilename() {
+ public IPath getFilename() {
return filename;
}
@@ -88,4 +89,22 @@ public class Symbol implements ISymbol {
return line;
}
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Object obj) {
+ long thisVal = 0;
+ long anotherVal = 0;
+ if (obj instanceof Symbol) {
+ Symbol sym = (Symbol) obj;
+ thisVal = this.addr;
+ anotherVal = sym.addr;
+ } else if (obj instanceof Long) {
+ Long val = (Long) obj;
+ anotherVal = val.longValue();
+ thisVal = (long) this.addr;
+ }
+ return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java
index 98df6c982a2..fcb9e7d6e9d 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java
@@ -207,6 +207,19 @@ public class AR {
}
}
+ public static boolean isARHeader(byte[] ident) {
+ if (ident.length < 7
+ || ident[0] != '!'
+ || ident[1] != '<'
+ || ident[2] != 'a'
+ || ident[3] != 'r'
+ || ident[4] != 'c'
+ || ident[5] != 'h'
+ || ident[6] != '>')
+ return false;
+ return true;
+ }
+
/**
* Creates a new <code>AR</code> object from the contents of
* the given file.
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java
index 1ef4640e788..76285236294 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java
@@ -707,6 +707,13 @@ public class Elf {
return attrib;
}
+ public static boolean isElfHeader(byte[] e_ident) {
+ if (e_ident.length < 4 || e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' ||
+ e_ident[ELFhdr.EI_MAG2] != 'L' || e_ident[ELFhdr.EI_MAG3] != 'F')
+ return false;
+ return true;
+ }
+
public void dispose() {
if (addr2line != null) {
addr2line.dispose();
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java
index 417c369625c..a9162ef000f 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java
@@ -13,9 +13,11 @@ package org.eclipse.cdt.utils.elf.parser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
+import org.eclipse.cdt.utils.IToolsProvider;
import org.eclipse.cdt.utils.elf.AR;
import org.eclipse.cdt.utils.elf.Elf;
import org.eclipse.cdt.utils.elf.ElfHelper;
@@ -26,8 +28,8 @@ import org.eclipse.core.runtime.IPath;
public class ARMember extends BinaryObject {
AR.ARHeader header;
- public ARMember(IPath p, AR.ARHeader h) throws IOException {
- super(p, new ElfHelper(h.getElf()));
+ public ARMember(IPath p, AR.ARHeader h, IToolsProvider provider) throws IOException {
+ super(p, new ElfHelper(h.getElf()), provider);
header = h;
}
@@ -65,13 +67,13 @@ public class ARMember extends BinaryObject {
throw new IOException("No file assiocated with Binary");
}
- protected void addSymbols(Elf.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt) {
+ protected void addSymbols(Elf.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt, List list) {
for (int i = 0; i < array.length; i++) {
Symbol sym = new Symbol(this);
sym.type = type;
sym.name = array[i].toString();
sym.addr = array[i].st_value;
- addSymbol(sym);
+ list.add(sym);
}
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java
index ba4a8b78fa5..d91f4190974 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java
@@ -44,7 +44,7 @@ public class BinaryArchive extends BinaryFile implements IBinaryArchive {
ar = new AR(getPath().toOSString());
AR.ARHeader[] headers = ar.getHeaders();
for (int i = 0; i < headers.length; i++) {
- IBinaryObject bin = new ARMember(getPath(), headers[i]);
+ IBinaryObject bin = new ARMember(getPath(), headers[i], toolsProvider);
children.add(bin);
}
} catch (IOException e) {
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java
index fdf3d56a95a..d454d9c6e15 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java
@@ -12,17 +12,21 @@ package org.eclipse.cdt.utils.elf.parser;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
+import org.eclipse.cdt.utils.IToolsProvider;
import org.eclipse.cdt.utils.elf.Elf;
import org.eclipse.cdt.utils.elf.ElfHelper;
import org.eclipse.cdt.utils.elf.Elf.Attribute;
import org.eclipse.cdt.utils.elf.ElfHelper.Sizes;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
/**
*/
@@ -32,21 +36,33 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
protected int type = IBinaryFile.OBJECT;
private Sizes sizes;
private Attribute attribute;
- private ArrayList symbols;
+ private ISymbol[] symbols;
+ private ISymbol[] NO_SYMBOLS = new ISymbol[0];
public BinaryObject(IPath path) throws IOException {
super(path);
- loadInformation();
- hasChanged();
}
- public BinaryObject(IPath path, ElfHelper helper) throws IOException {
+ public BinaryObject(IPath path, ElfHelper helper, IToolsProvider provider) throws IOException {
super(path);
+ setToolsProvider(provider);
loadInformation(helper);
helper.dispose();
hasChanged();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbol(long)
+ */
+ public ISymbol getSymbol(long addr) {
+ ISymbol[] syms = getSymbols();
+ int i = Arrays.binarySearch(syms, new Long(addr));
+ if (i < 0 || i >= syms.length) {
+ return null;
+ }
+ return syms[i];
+ }
+
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getBSS()
*/
@@ -129,15 +145,15 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
*/
public ISymbol[] getSymbols() {
if (hasChanged() || symbols == null) {
- if (symbols == null) {
- symbols = new ArrayList(5);
- }
try {
loadInformation();
} catch (IOException e) {
}
+ if (symbols == null) {
+ symbols = NO_SYMBOLS;
+ }
}
- return (ISymbol[]) symbols.toArray(new ISymbol[0]);
+ return symbols;
}
/**
@@ -189,11 +205,7 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
private void loadInformation(ElfHelper helper) throws IOException {
loadAttributes(helper);
- if (symbols != null) {
- symbols.clear();
- loadSymbols(helper);
- symbols.trimToSize();
- }
+ loadSymbols(helper);
}
private void loadAttributes(ElfHelper helper) throws IOException {
@@ -208,25 +220,18 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
}
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++) {
- needed[i] = sharedlibs[i].toString();
- }
- sizes = helper.getSizes();
- soname = helper.getSoname();
- attribute = helper.getElf().getAttributes();
+ ArrayList list = new ArrayList();
// Hack should be remove when Elf is clean
helper.getElf().setCppFilter(false);
Addr2line addr2line = getAddr2Line();
CPPFilt cppfilt = getCPPFilt();
- addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION, addr2line, cppfilt);
- addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION, addr2line, cppfilt);
- addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE, addr2line, cppfilt);
- addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE, addr2line, cppfilt);
- symbols.trimToSize();
+ addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION, addr2line, cppfilt, list);
+ addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION, addr2line, cppfilt, list);
+ addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE, addr2line, cppfilt, list);
+ addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE, addr2line, cppfilt, list);
+ list.trimToSize();
if (addr2line != null) {
addr2line.dispose();
@@ -234,9 +239,13 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
if (cppfilt != null) {
cppfilt.dispose();
}
+
+ symbols = (ISymbol[])list.toArray(NO_SYMBOLS);
+ Arrays.sort(symbols);
+ list.clear();
}
- protected void addSymbols(Elf.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt) {
+ protected void addSymbols(Elf.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt, List list) {
for (int i = 0; i < array.length; i++) {
Symbol sym = new Symbol(this);
sym.type = type;
@@ -253,18 +262,15 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
sym.endLine = sym.startLine;
if (addr2line != null) {
try {
- sym.filename = addr2line.getFileName(sym.addr);
+ String filename = addr2line.getFileName(sym.addr);
+ sym.filename = (filename != null) ? new Path(filename) : null;
sym.startLine = addr2line.getLineNumber(sym.addr);
sym.endLine = addr2line.getLineNumber(sym.addr + array[i].st_size - 1);
} catch (IOException e) {
}
}
- addSymbol(sym);
+ list.add(sym);
}
}
- protected void addSymbol(Symbol sym) {
- symbols.add(sym);
- }
-
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
index 348ff6d22cf..b3c4679ab65 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
@@ -14,6 +14,7 @@ import java.io.IOException;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.utils.elf.AR;
import org.eclipse.cdt.utils.elf.Elf;
import org.eclipse.cdt.utils.elf.Elf.Attribute;
import org.eclipse.core.runtime.IPath;
@@ -67,4 +68,11 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
return "ELF";
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
+ */
+ public boolean isBinary(byte[] array, IPath path) {
+ return Elf.isElfHeader(array) || AR.isARHeader(array);
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java
index 263b0d1d98f..f05e274ab4e 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java
@@ -14,12 +14,13 @@ import java.io.IOException;
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
+import org.eclipse.core.runtime.IPath;
-public class Symbol implements ISymbol {
+public class Symbol implements ISymbol, Comparable {
BinaryObject binary;
- public String filename;
+ public IPath filename;
public int startLine;
public int endLine;
public long addr;
@@ -27,16 +28,15 @@ public class Symbol implements ISymbol {
public int type;
public Symbol(BinaryObject bin) {
- binary = bin;
+ binary = bin;
}
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename()
*/
- public String getFilename() {
+ public IPath getFilename() {
return filename;
}
-
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getName()
*/
@@ -83,9 +83,23 @@ public class Symbol implements ISymbol {
line = addr2line.getLineNumber(addr + offset);
addr2line.dispose();
}
- } catch (IOException e) {
+ } catch (IOException e) {
}
return line;
}
+ public int compareTo(Object obj) {
+ long thisVal = 0;
+ long anotherVal = 0;
+ if (obj instanceof Symbol) {
+ Symbol sym = (Symbol) obj;
+ thisVal = this.addr;
+ anotherVal = sym.addr;
+ } else if (obj instanceof Long) {
+ Long val = (Long) obj;
+ anotherVal = val.longValue();
+ thisVal = (long) this.addr;
+ }
+ return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
+ }
}

Back to the top