1
0
Fork 0
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:
Alain Magloire 2003-11-18 16:20:49 +00:00
parent 8b5836e830
commit 7a446b027c
21 changed files with 287 additions and 99 deletions

View file

@ -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

View file

@ -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());

View file

@ -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();

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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();
}

View file

@ -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();

View file

@ -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.

View 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);
}
}
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}

View file

@ -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.

View 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();

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}