mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
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.
This commit is contained in:
parent
8b5836e830
commit
7a446b027c
21 changed files with 287 additions and 99 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue