mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-21 15:23:59 +02:00
Those are heavy changes concerning the Binary Parser.
The problem was that binaryParser scheme was a perfomance problem affecting a lot of people when projects were medium/big size. The IBinaryParser was extended to allow one more method isbinary() so that will let the BinaryParser open() the file only once instead of multiple time like it did before.
This commit is contained in:
parent
52ecc62130
commit
29026f5fb0
31 changed files with 707 additions and 1365 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-13 David Inglis
|
||||
Fixed #46431
|
||||
* utils/org/eclipse/cdt/utils/spawner/EnvironmentReader.java
|
||||
|
|
|
@ -69,7 +69,7 @@ public class Archive extends Openable implements IArchive {
|
|||
IBinaryObject[] objects = ar.getObjects();
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
final IBinaryObject obj = objects[i];
|
||||
Binary binary = new Binary(this, res.getLocation().append(obj.getName()), obj);
|
||||
Binary binary = new Binary(this, ar.getPath().append(obj.getName()), obj);
|
||||
info.addChild(binary);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -40,6 +40,10 @@ public class Binary extends Openable implements IBinary {
|
|||
binaryFile = bin;
|
||||
}
|
||||
|
||||
protected IBinaryFile getBinaryFile() {
|
||||
return binaryFile;
|
||||
}
|
||||
|
||||
public boolean isSharedLib() {
|
||||
return getType() == IBinaryObject.SHARED;
|
||||
}
|
||||
|
@ -58,65 +62,71 @@ public class Binary extends Openable implements IBinary {
|
|||
|
||||
public boolean hasDebug() {
|
||||
if (isObject() || isExecutable() || isSharedLib()) {
|
||||
return ((IBinaryObject)binaryFile).hasDebug();
|
||||
return ((IBinaryObject)getBinaryFile()).hasDebug();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getCPU() {
|
||||
if (isObject() || isExecutable() || isSharedLib() || isCore()) {
|
||||
return ((IBinaryObject)binaryFile).getCPU();
|
||||
return ((IBinaryObject)getBinaryFile()).getCPU();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String[] getNeededSharedLibs() {
|
||||
if (isExecutable() || isSharedLib()) {
|
||||
return ((IBinaryExecutable)binaryFile).getNeededSharedLibs();
|
||||
return ((IBinaryExecutable)getBinaryFile()).getNeededSharedLibs();
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
protected int getType() {
|
||||
IResource res = getResource();
|
||||
if (binaryFile != null && (fBinType == 0 || res.getModificationStamp() != fLastModification )) {
|
||||
fLastModification = res.getModificationStamp();
|
||||
fBinType = binaryFile.getType();
|
||||
if (getBinaryFile() != null && (fBinType == 0 || getModificationStamp() != fLastModification )) {
|
||||
fLastModification = getModificationStamp();
|
||||
fBinType = getBinaryFile().getType();
|
||||
}
|
||||
return fBinType;
|
||||
}
|
||||
|
||||
protected long getModificationStamp() {
|
||||
IResource res = getResource();
|
||||
if (res != null)
|
||||
return res.getModificationStamp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getText() {
|
||||
if (isObject() || isExecutable() || isSharedLib()) {
|
||||
return ((IBinaryObject)binaryFile).getText();
|
||||
return ((IBinaryObject)getBinaryFile()).getText();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getData() {
|
||||
if (isObject() || isExecutable() || isSharedLib()) {
|
||||
return ((IBinaryObject)binaryFile).getData();
|
||||
return ((IBinaryObject)getBinaryFile()).getData();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getBSS() {
|
||||
if (isObject() || isExecutable() || isSharedLib()) {
|
||||
return ((IBinaryObject)binaryFile).getBSS();
|
||||
return ((IBinaryObject)getBinaryFile()).getBSS();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getSoname() {
|
||||
if (isSharedLib()) {
|
||||
return ((IBinaryShared)binaryFile).getSoName();
|
||||
return ((IBinaryShared)getBinaryFile()).getSoName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean isLittleEndian() {
|
||||
if (isObject() || isExecutable() || isSharedLib() || isCore()) {
|
||||
return ((IBinaryObject)binaryFile).isLittleEndian();
|
||||
return ((IBinaryObject)getBinaryFile()).isLittleEndian();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -145,7 +155,7 @@ public class Binary extends Openable implements IBinary {
|
|||
boolean computeChildren(OpenableInfo info, IResource res) {
|
||||
if (isObject() || isExecutable() || isSharedLib()) {
|
||||
Map hash = new HashMap();
|
||||
ISymbol[] symbols = ((IBinaryObject)binaryFile).getSymbols();
|
||||
ISymbol[] symbols = ((IBinaryObject)getBinaryFile()).getSymbols();
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
switch (symbols[i].getType()) {
|
||||
case ISymbol.FUNCTION :
|
||||
|
@ -164,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());
|
||||
|
@ -196,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());
|
||||
|
|
|
@ -10,59 +10,72 @@ import org.eclipse.cdt.core.model.ICElement;
|
|||
import org.eclipse.cdt.core.model.ICModel;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IResourceVisitor;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class BinaryRunner extends Thread {
|
||||
ArchiveContainer clib;
|
||||
BinaryContainer cbin;
|
||||
ICProject cproject;
|
||||
CModelManager factory;
|
||||
public class BinaryRunner {
|
||||
IProject project;
|
||||
Thread runner;
|
||||
|
||||
public BinaryRunner(IProject prj) {
|
||||
project = prj;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
runner = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
ICProject cproject = CModelManager.getDefault().create(project);
|
||||
ArchiveContainer clib;
|
||||
BinaryContainer cbin;
|
||||
cbin = (BinaryContainer)cproject.getBinaryContainer();
|
||||
clib = (ArchiveContainer)cproject.getArchiveContainer();
|
||||
clib.removeChildren();
|
||||
cbin.removeChildren();
|
||||
try {
|
||||
cproject.getProject().accept(new Visitor(BinaryRunner.this));
|
||||
} catch (CoreException e) {
|
||||
//e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
// What is wrong ?
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!Thread.currentThread().isInterrupted()) {
|
||||
fireEvents(cproject, cbin);
|
||||
fireEvents(cproject, clib);
|
||||
}
|
||||
// Tell the listeners we are done.
|
||||
synchronized(BinaryRunner.this) {
|
||||
BinaryRunner.this.notifyAll();
|
||||
runner = null;
|
||||
}
|
||||
}
|
||||
|
||||
public BinaryRunner(ICProject cprj) {
|
||||
super("Binary Search Thread");
|
||||
cproject = cprj;
|
||||
cbin = (BinaryContainer)cprj.getBinaryContainer();
|
||||
clib = (ArchiveContainer)cprj.getArchiveContainer();
|
||||
factory = CModelManager.getDefault();
|
||||
start();
|
||||
}, "Binary Search Thread");
|
||||
runner.start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
clib.removeChildren();
|
||||
cbin.removeChildren();
|
||||
try {
|
||||
cproject.getProject().accept(new Visitor(this));
|
||||
} catch (CoreException e) {
|
||||
//e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
// What is wrong ?
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!isInterrupted()) {
|
||||
fireEvents(cbin);
|
||||
fireEvents(clib);
|
||||
}
|
||||
// Tell the listeners we are done.
|
||||
synchronized(this) {
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrap the wait call and the interrupteException.
|
||||
*/
|
||||
public synchronized void waitIfRunning() {
|
||||
while (isAlive()) {
|
||||
while (runner != null && runner.isAlive()) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if ( runner != null && runner.isAlive()) {
|
||||
runner.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void fireEvents(Parent container) {
|
||||
void fireEvents(ICProject cproject, Parent container) {
|
||||
// Fired the event.
|
||||
ICElement[] children = container.getChildren();
|
||||
if (children.length > 0) {
|
||||
|
@ -80,6 +93,7 @@ public class BinaryRunner extends Thread {
|
|||
}
|
||||
|
||||
void addChildIfBinary(IFile file) {
|
||||
CModelManager factory = CModelManager.getDefault();
|
||||
// Attempt to speed things up by rejecting up front
|
||||
// Things we know should not be Binary files.
|
||||
if (!factory.isTranslationUnit(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();
|
||||
|
|
|
@ -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;
|
||||
|
@ -46,12 +47,12 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
|
||||
public class CModelManager implements IResourceChangeListener {
|
||||
|
||||
/**
|
||||
* Unique handle onto the CModel
|
||||
*/
|
||||
final CModel cModel = new CModel();
|
||||
/**
|
||||
* Unique handle onto the CModel
|
||||
*/
|
||||
final CModel cModel = new CModel();
|
||||
|
||||
public static HashSet OptionNames = new HashSet(20);
|
||||
public static HashSet OptionNames = new HashSet(20);
|
||||
|
||||
/**
|
||||
* Used to convert <code>IResourceDelta</code>s into <code>ICElementDelta</code>s.
|
||||
|
@ -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.
|
||||
|
@ -188,7 +194,7 @@ public class CModelManager implements IResourceChangeListener {
|
|||
case IResource.FOLDER :
|
||||
return create(parent, (IFolder)resource);
|
||||
case IResource.ROOT :
|
||||
return create(parent, (IWorkspaceRoot)resource);
|
||||
return create((IWorkspaceRoot)resource);
|
||||
default :
|
||||
return null;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -504,13 +532,14 @@ public class CModelManager implements IResourceChangeListener {
|
|||
return ok;
|
||||
}
|
||||
|
||||
public BinaryRunner getBinaryRunner(ICProject cProject) {
|
||||
public BinaryRunner getBinaryRunner(ICProject project) {
|
||||
BinaryRunner runner = null;
|
||||
synchronized(binaryRunners) {
|
||||
runner = (BinaryRunner)binaryRunners.get(cProject);
|
||||
runner = (BinaryRunner)binaryRunners.get(project.getProject());
|
||||
if (runner == null) {
|
||||
runner = new BinaryRunner(cProject);
|
||||
binaryRunners.put(cProject, runner);
|
||||
runner = new BinaryRunner(project.getProject());
|
||||
binaryRunners.put(project.getProject(), runner);
|
||||
runner.start();
|
||||
}
|
||||
}
|
||||
return runner;
|
||||
|
@ -574,8 +603,8 @@ public class CModelManager implements IResourceChangeListener {
|
|||
case IResourceChangeEvent.PRE_DELETE :
|
||||
try{
|
||||
if (resource.getType() == IResource.PROJECT &&
|
||||
( ((IProject)resource).hasNature(CProjectNature.C_NATURE_ID) ||
|
||||
((IProject)resource).hasNature(CCProjectNature.CC_NATURE_ID) )){
|
||||
( ((IProject)resource).hasNature(CProjectNature.C_NATURE_ID) ||
|
||||
((IProject)resource).hasNature(CCProjectNature.CC_NATURE_ID) )){
|
||||
this.deleting((IProject) resource);}
|
||||
}catch (CoreException e){
|
||||
}
|
||||
|
@ -729,10 +758,27 @@ public class CModelManager implements IResourceChangeListener {
|
|||
}
|
||||
break;
|
||||
case IResource.PROJECT :
|
||||
// TO BE COMPLETED ...
|
||||
break;
|
||||
if (0 != (delta.getFlags() & IResourceDelta.OPEN)) {
|
||||
IProject project = (IProject) resource;
|
||||
if (!project.isOpen()) {
|
||||
// project closing... stop the runner.
|
||||
BinaryRunner runner = (BinaryRunner)binaryRunners.get(project);
|
||||
if (runner != null ) {
|
||||
runner.stop();
|
||||
}
|
||||
} else {
|
||||
if ( binaryRunners.get(project) == null ) {
|
||||
// project opening... lets add the runner to the
|
||||
// map but no need to start it since the deltas
|
||||
// will populate containers
|
||||
binaryRunners.put(project, new BinaryRunner(project));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of elements which are out of synch with their buffers.
|
||||
*/
|
||||
|
@ -788,9 +834,7 @@ public class CModelManager implements IResourceChangeListener {
|
|||
|
||||
BinaryRunner[] runners = (BinaryRunner[])binaryRunners.values().toArray(new BinaryRunner[0]);
|
||||
for (int i = 0; i < runners.length; i++) {
|
||||
if (runners[i].isAlive()) {
|
||||
runners[i].interrupt();
|
||||
}
|
||||
runners[i].stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -801,5 +845,10 @@ public class CModelManager implements IResourceChangeListener {
|
|||
public void deleting(IProject project){
|
||||
// discard all indexing jobs for this project
|
||||
this.getIndexManager().discardJobs(project.getName());
|
||||
BinaryRunner runner = (BinaryRunner) binaryRunners.remove(project);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
package org.eclipse.cdt.internal.core.model.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.utils.elf.AR;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ElfBinaryArchive extends PlatformObject implements IBinaryArchive {
|
||||
|
||||
IPath path;
|
||||
ArrayList children;
|
||||
long timestamp;
|
||||
|
||||
public ElfBinaryArchive(IPath p) throws IOException {
|
||||
path = p;
|
||||
new AR(path.toOSString()).dispose(); // check file type
|
||||
children = new ArrayList(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#getObjects()
|
||||
*/
|
||||
public IBinaryObject[] getObjects() {
|
||||
if (hasChanged()) {
|
||||
children.clear();
|
||||
if (path != null) {
|
||||
AR ar = null;
|
||||
try {
|
||||
ar = new AR(path.toOSString());
|
||||
AR.ARHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
IBinaryObject bin = new ElfBinaryFile(path, headers[i]);
|
||||
children.add(bin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
}
|
||||
children.trimToSize();
|
||||
}
|
||||
return (IBinaryObject[])children.toArray(new IBinaryObject[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
|
||||
*/
|
||||
public IPath getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.ARCHIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
try {
|
||||
return new FileInputStream(path.toFile());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
|
||||
boolean hasChanged() {
|
||||
long modif = path.toFile().lastModified();
|
||||
boolean changed = modif != timestamp;
|
||||
timestamp = modif;
|
||||
return changed;
|
||||
}
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[])
|
||||
*/
|
||||
public void add(IBinaryObject[] objs) throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[])
|
||||
*/
|
||||
public void delete(IBinaryObject[] objs) throws IOException {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,346 +0,0 @@
|
|||
package org.eclipse.cdt.internal.core.model.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryShared;
|
||||
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||
import org.eclipse.cdt.utils.elf.AR;
|
||||
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.PlatformObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ElfBinaryFile extends PlatformObject implements IBinaryFile, IBinaryObject, IBinaryExecutable, IBinaryShared {
|
||||
IPath path;
|
||||
AR.ARHeader header;
|
||||
long timestamp;
|
||||
String soname;
|
||||
String[] needed;
|
||||
Sizes sizes;
|
||||
Attribute attribute;
|
||||
ArrayList symbols;
|
||||
|
||||
public ElfBinaryFile(IPath p) throws IOException {
|
||||
this(p, null);
|
||||
}
|
||||
|
||||
public ElfBinaryFile(IPath p, AR.ARHeader h) throws IOException {
|
||||
header = h;
|
||||
path = p;
|
||||
loadInformation();
|
||||
hasChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
|
||||
*/
|
||||
public IPath getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getBSS()
|
||||
*/
|
||||
public long getBSS() {
|
||||
Sizes sz = getSizes();
|
||||
if (sz != null) {
|
||||
return sizes.bss;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getCPU()
|
||||
*/
|
||||
public String getCPU() {
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
return attribute.getCPU();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getData()
|
||||
*/
|
||||
public long getData() {
|
||||
Sizes sz = getSizes();
|
||||
if (sz != null) {
|
||||
return sizes.data;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getText()
|
||||
*/
|
||||
public long getText() {
|
||||
Sizes sz = getSizes();
|
||||
if (sz != null) {
|
||||
return sizes.text;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryShared#getSoName()
|
||||
*/
|
||||
public String getSoName() {
|
||||
if (hasChanged()) {
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (soname != null) {
|
||||
return soname;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#hasDebug()
|
||||
*/
|
||||
public boolean hasDebug() {
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
return attribute.hasDebug();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#isLittleEndian()
|
||||
*/
|
||||
public boolean isLittleEndian() {
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
return attribute.isLittleEndian();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryExecutable#getNeededSharedLibs()
|
||||
*/
|
||||
public String[] getNeededSharedLibs() {
|
||||
if (hasChanged()) {
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (needed != null) {
|
||||
return needed;
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
int type = 0;
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
switch (attribute.getType()) {
|
||||
case Attribute.ELF_TYPE_EXE :
|
||||
type = IBinaryFile.EXECUTABLE;
|
||||
break;
|
||||
|
||||
case Attribute.ELF_TYPE_SHLIB :
|
||||
type = IBinaryFile.SHARED;
|
||||
break;
|
||||
|
||||
case Attribute.ELF_TYPE_OBJ :
|
||||
type = IBinaryFile.OBJECT;
|
||||
break;
|
||||
|
||||
case Attribute.ELF_TYPE_CORE :
|
||||
type = IBinaryFile.CORE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getSymbols()
|
||||
*/
|
||||
public ISymbol[] getSymbols() {
|
||||
if (hasChanged() || symbols == null) {
|
||||
if (symbols == null) {
|
||||
symbols = new ArrayList(5);
|
||||
}
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return (ISymbol[]) symbols.toArray(new ISymbol[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
InputStream stream = null;
|
||||
// Archive ?
|
||||
if (path != null && header != null) {
|
||||
try {
|
||||
stream = new ByteArrayInputStream(header.getObjectData());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
} else if (path != null) {
|
||||
try {
|
||||
stream = new FileInputStream(path.toFile());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (stream == null) {
|
||||
stream = new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
if (header != null) {
|
||||
return header.getObjectName();
|
||||
}
|
||||
if (path != null) {
|
||||
return path.lastSegment().toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
protected Attribute getAttribute() {
|
||||
if (hasChanged()) {
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
|
||||
protected Sizes getSizes() {
|
||||
if (hasChanged()) {
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return sizes;
|
||||
}
|
||||
|
||||
boolean hasChanged() {
|
||||
long modification = path.toFile().lastModified();
|
||||
boolean changed = modification != timestamp;
|
||||
timestamp = modification;
|
||||
return changed;
|
||||
}
|
||||
|
||||
protected ElfHelper getElfHelper() throws IOException {
|
||||
// Archive ?
|
||||
if (header != null) {
|
||||
return new ElfHelper(header.getElf());
|
||||
} else if (path != null) {
|
||||
return new ElfHelper(path.toOSString());
|
||||
}
|
||||
throw new IOException("No file assiocated with Binary");
|
||||
}
|
||||
|
||||
protected void loadInformation() throws IOException {
|
||||
ElfHelper helper = null;
|
||||
try {
|
||||
helper = getElfHelper();
|
||||
loadInformation(helper);
|
||||
} finally {
|
||||
if (helper != null) {
|
||||
helper.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadInformation(ElfHelper helper) throws IOException {
|
||||
loadAttributes(helper);
|
||||
if (symbols != null) {
|
||||
symbols.clear();
|
||||
loadSymbols(helper);
|
||||
symbols.trimToSize();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAttributes(ElfHelper helper) throws IOException {
|
||||
Elf.Dynamic[] sharedlibs = helper.getNeeded();
|
||||
needed = new String[sharedlibs.length];
|
||||
for (int i = 0; i < sharedlibs.length; i++) {
|
||||
needed[i] = sharedlibs[i].toString();
|
||||
}
|
||||
sizes = helper.getSizes();
|
||||
soname = helper.getSoname();
|
||||
attribute = helper.getElf().getAttributes();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION);
|
||||
addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION);
|
||||
addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE);
|
||||
addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE);
|
||||
symbols.trimToSize();
|
||||
}
|
||||
|
||||
private void addSymbols(Elf.Symbol[] array, int type) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
Symbol sym = new Symbol();
|
||||
sym.type = type;
|
||||
sym.name = array[i].toString();
|
||||
sym.addr = array[i].st_value;
|
||||
try {
|
||||
// This can fail if we use addr2line
|
||||
// but we can safely ignore the error.
|
||||
if (header == null) {
|
||||
sym.filename = array[i].getFilename();
|
||||
sym.startLine = array[i].getFuncLineNumber();
|
||||
sym.endLine = sym.startLine;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
symbols.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +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.internal.core.model.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.AbstractCExtension;
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* Implementation moved to org.eclipse.cdt.utils.elf.parser.ElfParser
|
||||
* But this class is still provided for backward compatibility.
|
||||
*/
|
||||
public class ElfParser extends AbstractCExtension implements IBinaryParser {
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath)
|
||||
*/
|
||||
public IBinaryFile getBinary(IPath path) throws IOException {
|
||||
if (path == null ) {
|
||||
path = new Path("");
|
||||
}
|
||||
IBinaryFile bFile;
|
||||
try {
|
||||
bFile = new ElfBinaryFile(path);
|
||||
} catch (IOException e) {
|
||||
bFile = new ElfBinaryArchive(path);
|
||||
}
|
||||
return bFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser#getFormat()
|
||||
*/
|
||||
public String getFormat() {
|
||||
return "ELF";
|
||||
}
|
||||
|
||||
public class ElfParser extends org.eclipse.cdt.utils.elf.parser.ElfParser {
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
package org.eclipse.cdt.internal.core.model.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.utils.coff.PEArchive;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PEBinaryArchive extends PlatformObject implements IBinaryArchive {
|
||||
|
||||
IPath path;
|
||||
ArrayList children;
|
||||
long timestamp;
|
||||
|
||||
public PEBinaryArchive(IPath p) {
|
||||
path = p;
|
||||
children = new ArrayList(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#getObjects()
|
||||
*/
|
||||
public IBinaryObject[] getObjects() {
|
||||
if (hasChanged()) {
|
||||
children.clear();
|
||||
if (path != null) {
|
||||
PEArchive ar = null;
|
||||
try {
|
||||
ar = new PEArchive(path.toOSString());
|
||||
PEArchive.ARHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
IBinaryObject bin = new PEBinaryFile(path, headers[i].getObjectName());
|
||||
children.add(bin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
}
|
||||
children.trimToSize();
|
||||
}
|
||||
return (IBinaryObject[])children.toArray(new IBinaryObject[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
|
||||
*/
|
||||
public IPath getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.ARCHIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
try {
|
||||
return new FileInputStream(path.toFile());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
|
||||
boolean hasChanged() {
|
||||
File file = path.toFile();
|
||||
if (file != null && file.exists()) {
|
||||
long modification = file.lastModified();
|
||||
boolean changed = modification != timestamp;
|
||||
timestamp = modification;
|
||||
return changed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[])
|
||||
*/
|
||||
public void add(IBinaryObject[] objs) throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[])
|
||||
*/
|
||||
public void delete(IBinaryObject[] objs) throws IOException {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,304 +0,0 @@
|
|||
package org.eclipse.cdt.internal.core.model.parser;
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryShared;
|
||||
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||
import org.eclipse.cdt.utils.coff.Coff;
|
||||
import org.eclipse.cdt.utils.coff.PE;
|
||||
import org.eclipse.cdt.utils.coff.PEArchive;
|
||||
import org.eclipse.cdt.utils.coff.PE.Attribute;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PEBinaryFile extends PlatformObject implements IBinaryFile,
|
||||
IBinaryObject, IBinaryExecutable, IBinaryShared {
|
||||
|
||||
IPath path;
|
||||
long timestamp;
|
||||
PE.Attribute attribute;
|
||||
String objectName;
|
||||
ArrayList symbols;
|
||||
|
||||
public PEBinaryFile(IPath p) throws IOException {
|
||||
this(p, null);
|
||||
}
|
||||
|
||||
public PEBinaryFile(IPath p, String o) throws IOException {
|
||||
path = p;
|
||||
objectName = o;
|
||||
loadInformation();
|
||||
hasChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
InputStream stream = null;
|
||||
if (path != null && objectName != null) {
|
||||
PEArchive ar = null;
|
||||
try {
|
||||
ar = new PEArchive(path.toOSString());
|
||||
PEArchive.ARHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
PEArchive.ARHeader hdr = headers[i];
|
||||
if (objectName.equals(hdr.getObjectName())) {
|
||||
stream = new ByteArrayInputStream(hdr.getObjectData());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
}
|
||||
} else if (path != null) {
|
||||
try {
|
||||
stream = new FileInputStream (path.toFile());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (stream == null) {
|
||||
stream = new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
|
||||
*/
|
||||
public IPath getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
int type = 0;
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
switch (attribute.getType()) {
|
||||
case Attribute.PE_TYPE_EXE:
|
||||
type = IBinaryFile.EXECUTABLE;
|
||||
break;
|
||||
|
||||
case Attribute.PE_TYPE_SHLIB:
|
||||
type = IBinaryFile.SHARED;
|
||||
break;
|
||||
|
||||
case Attribute.PE_TYPE_OBJ:
|
||||
type = IBinaryFile.OBJECT;
|
||||
break;
|
||||
|
||||
case Attribute.PE_TYPE_CORE:
|
||||
type = IBinaryFile.CORE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getBSS()
|
||||
*/
|
||||
public long getBSS() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getCPU()
|
||||
*/
|
||||
public String getCPU() {
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
return attribute.getCPU();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getData()
|
||||
*/
|
||||
public long getData() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
if (objectName != null) {
|
||||
return objectName;
|
||||
} else if (path != null) {
|
||||
return path.lastSegment().toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getSymbols()
|
||||
*/
|
||||
public ISymbol[] getSymbols() {
|
||||
if (hasChanged() || symbols == null) {
|
||||
if (symbols == null) {
|
||||
symbols = new ArrayList(5);
|
||||
}
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return (ISymbol[])symbols.toArray(new ISymbol[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getText()
|
||||
*/
|
||||
public long getText() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#hasDebug()
|
||||
*/
|
||||
public boolean hasDebug() {
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
return attr.hasDebug();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#isLittleEndian()
|
||||
*/
|
||||
public boolean isLittleEndian() {
|
||||
Attribute attr = getAttribute();
|
||||
if (attr != null) {
|
||||
return attr.isLittleEndian();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryExecutable#getNeededSharedLibs()
|
||||
*/
|
||||
public String[] getNeededSharedLibs() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryShared#getSoName()
|
||||
*/
|
||||
public String getSoName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
protected PE getPE() throws IOException {
|
||||
if (path != null && objectName != null) {
|
||||
PE pe = null;
|
||||
PEArchive ar = null;
|
||||
try {
|
||||
ar = new PEArchive(path.toOSString());
|
||||
PEArchive.ARHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
PEArchive.ARHeader hdr = headers[i];
|
||||
if (objectName.equals(hdr.getObjectName())) {
|
||||
pe = hdr.getPE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
}
|
||||
if (pe != null) {
|
||||
return pe;
|
||||
}
|
||||
} else if (path != null) {
|
||||
return new PE(path.toOSString());
|
||||
}
|
||||
throw new IOException("No file assiocated with Binary");
|
||||
}
|
||||
|
||||
protected PE.Attribute getAttribute() {
|
||||
if (hasChanged()) {
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
|
||||
protected void loadInformation() throws IOException {
|
||||
PE pe = getPE();
|
||||
loadInformation(pe);
|
||||
pe.dispose();
|
||||
}
|
||||
|
||||
private void loadInformation(PE pe) throws IOException {
|
||||
loadAttribute(pe);
|
||||
if (symbols != null) {
|
||||
symbols.clear();
|
||||
loadSymbols(pe);
|
||||
symbols.trimToSize();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAttribute(PE pe) throws IOException {
|
||||
attribute = pe.getAttribute();
|
||||
}
|
||||
|
||||
private void loadSymbols(PE pe) throws IOException {
|
||||
Coff.Symbol[] peSyms = pe.getSymbols();
|
||||
byte[] table = pe.getStringTable();
|
||||
for (int i = 0; i < peSyms.length; i++) {
|
||||
if (peSyms[i].isFunction() || peSyms[i].isPointer() ||peSyms[i].isArray()) {
|
||||
String name = peSyms[i].getName(table);
|
||||
if (name == null || name.trim().length() == 0 ||
|
||||
!Character.isJavaIdentifierStart(name.charAt(0))) {
|
||||
continue;
|
||||
}
|
||||
Symbol sym = new Symbol();
|
||||
sym.filename = null;
|
||||
sym.name = name;
|
||||
sym.addr = peSyms[i].n_value;
|
||||
sym.startLine = 0;
|
||||
sym.endLine = 0;
|
||||
sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
|
||||
symbols.add(sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasChanged() {
|
||||
File file = path.toFile();
|
||||
if (file != null && file.exists()) {
|
||||
long modification = file.lastModified();
|
||||
boolean changed = modification != timestamp;
|
||||
timestamp = modification;
|
||||
return changed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,43 +5,10 @@ package org.eclipse.cdt.internal.core.model.parser;
|
|||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
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.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* Implementation moved to org.eclipse.cdt.utils.coff.parser.PEParser
|
||||
* But this class is still provided for backward compatibility.
|
||||
*/
|
||||
public class PEParser extends AbstractCExtension implements IBinaryParser {
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IFile)
|
||||
*/
|
||||
public IBinaryFile getBinary(IPath path) throws IOException {
|
||||
if (path == null) {
|
||||
path = new Path("");
|
||||
}
|
||||
try {
|
||||
PE pe = new PE(path.toOSString());
|
||||
pe.dispose();
|
||||
return new PEBinaryFile(path);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
// Is it an Archive.
|
||||
PEArchive ar = new PEArchive(path.toOSString());
|
||||
ar.dispose();
|
||||
return new PEBinaryArchive(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser#getFormat()
|
||||
*/
|
||||
public String getFormat() {
|
||||
return "PE";
|
||||
}
|
||||
|
||||
public class PEParser extends org.eclipse.cdt.utils.coff.parser.PEParser {
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package org.eclipse.cdt.internal.core.model.parser;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
public class Symbol implements ISymbol {
|
||||
|
||||
public String filename;
|
||||
public int startLine;
|
||||
public int endLine;
|
||||
public long addr;
|
||||
public String name;
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename()
|
||||
*/
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getAdress()
|
||||
*/
|
||||
public long getAddress() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getEndLine()
|
||||
*/
|
||||
public int getEndLine() {
|
||||
return endLine;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getStartLine()
|
||||
*/
|
||||
public int getStartLine() {
|
||||
return startLine;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -54,38 +54,41 @@ public class GCCErrorParser implements IErrorParser {
|
|||
|
||||
if (firstColon != -1) {
|
||||
try {
|
||||
int secondColon= line.indexOf(':', firstColon + 1);
|
||||
if (secondColon != -1) {
|
||||
String fileName = line.substring(0, firstColon);
|
||||
String lineNumber = line.substring(firstColon + 1, secondColon);
|
||||
String varName = null;
|
||||
String desc = line.substring(secondColon + 1).trim();
|
||||
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
|
||||
int num = -1;
|
||||
int col = -1;
|
||||
int secondColon = -1;
|
||||
int num = -1;
|
||||
|
||||
while ((secondColon = line.indexOf(':', firstColon + 1)) != -1) {
|
||||
String lineNumber = line.substring(firstColon + 1, secondColon);
|
||||
try {
|
||||
num = Integer.parseInt(lineNumber);
|
||||
} catch (NumberFormatException e) {
|
||||
// Failed.
|
||||
}
|
||||
if (num != -1) {
|
||||
break; // Find possible match.
|
||||
}
|
||||
firstColon = secondColon;
|
||||
}
|
||||
|
||||
if (num == -1) {
|
||||
// Bail out not recognizable format. i.e. no line numbers
|
||||
return false;
|
||||
} else {
|
||||
/* Then check for the column */
|
||||
int thirdColon= line.indexOf(':', secondColon + 1);
|
||||
if (thirdColon != -1) {
|
||||
String columnNumber = line.substring(secondColon + 1, thirdColon);
|
||||
try {
|
||||
col = Integer.parseInt(columnNumber);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
if (col != -1) {
|
||||
desc = line.substring(thirdColon + 1).trim();
|
||||
if (secondColon != -1) {
|
||||
int col = -1;
|
||||
|
||||
String fileName = line.substring(0, firstColon);
|
||||
String varName = null;
|
||||
String desc = line.substring(secondColon + 1).trim();
|
||||
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
|
||||
/* Then check for the column */
|
||||
int thirdColon= line.indexOf(':', secondColon + 1);
|
||||
if (thirdColon != -1) {
|
||||
String columnNumber = line.substring(secondColon + 1, thirdColon);
|
||||
try {
|
||||
col = Integer.parseInt(columnNumber);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
if (col != -1) {
|
||||
desc = line.substring(thirdColon + 1).trim();
|
||||
}
|
||||
|
||||
// gnu c: filename:no: (Each undeclared identifier is reported
|
||||
// only once. filename:no: for each function it appears in.)
|
||||
|
@ -103,9 +106,11 @@ public class GCCErrorParser implements IErrorParser {
|
|||
|
||||
/* See if we can get a var name
|
||||
* Look for:
|
||||
* 'foo' undeclared
|
||||
* 'foo' defined but not used
|
||||
* conflicting types for 'foo'
|
||||
* `foo' undeclared
|
||||
* `foo' defined but not used
|
||||
* conflicting types for `foo'
|
||||
* previous declaration of `foo'
|
||||
* parse error before `foo'
|
||||
*
|
||||
*/
|
||||
int s;
|
||||
|
@ -141,26 +146,43 @@ public class GCCErrorParser implements IErrorParser {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In file included from b.h:2,
|
||||
* from a.h:3,
|
||||
* from hello.c:3:
|
||||
* c.h:2:15: missing ')' in macro parameter list
|
||||
*
|
||||
* We reconstruct the multiline gcc errors to multiple errors:
|
||||
* c.h:3:15: missing ')' in macro parameter list
|
||||
* b.h:2: in inclusion c.h:3:15
|
||||
* a.h:3: in inclusion b.h:2
|
||||
* hello.c:3: in inclusion a.h:3
|
||||
*
|
||||
*/
|
||||
if (eoParser.getScratchBuffer().startsWith("In file included from ")) {
|
||||
if (line.startsWith("from ")) {
|
||||
// We want the last error in the chain, so continue.
|
||||
eoParser.appendToScratchBuffer(line);
|
||||
return false;
|
||||
}
|
||||
String buffer = eoParser.getScratchBuffer();
|
||||
eoParser.clearScratchBuffer();
|
||||
int from = -1;
|
||||
while ((from = buffer.lastIndexOf("from ")) != -1) {
|
||||
String buf = buffer.substring(from + 5);
|
||||
buffer = buffer.substring(0, from);
|
||||
if (buf.endsWith(",")) {
|
||||
int coma = buf.lastIndexOf(',');
|
||||
StringBuffer b = new StringBuffer(buf);
|
||||
b.setCharAt(coma, ':');
|
||||
b.append(' ').append(buffer).append(" from ").append(line);
|
||||
buf = b.toString();
|
||||
String inclusionError = fileName + ":" + num;
|
||||
while ((from = buffer.indexOf("from ")) != -1) {
|
||||
int coma = buffer.indexOf(',', from);
|
||||
String buf;
|
||||
if (coma != -1) {
|
||||
buf = buffer.substring(from + 5, coma) + ':';
|
||||
buffer = buffer.substring(coma);
|
||||
} else {
|
||||
buf = buf + ' ' + buffer + " from " + line;
|
||||
buf = buffer.substring(from + 5);
|
||||
buffer = "";
|
||||
}
|
||||
String t = buf;
|
||||
buf += " in inclusion " + inclusionError;
|
||||
inclusionError = t;
|
||||
// Call the parsing process again.
|
||||
processLine(buf, eoParser);
|
||||
}
|
||||
}
|
||||
|
@ -196,6 +218,7 @@ public class GCCErrorParser implements IErrorParser {
|
|||
if (file == null) {
|
||||
desc = desc +"[" + fileName + "]";
|
||||
}
|
||||
|
||||
eoParser.generateMarker(file, num, desc, severity, varName);
|
||||
} else {
|
||||
if (line.startsWith("In file included from ")) {
|
||||
|
|
|
@ -18,21 +18,25 @@ public class Addr2line {
|
|||
private BufferedReader stdout;
|
||||
private BufferedWriter stdin;
|
||||
private String lastaddr, lastsymbol, lastline;
|
||||
|
||||
public Addr2line(String file) throws IOException {
|
||||
String[] args = {"addr2line", "-C", "-f", "-e", file};
|
||||
|
||||
public Addr2line(String command, String file) throws IOException {
|
||||
String[] args = {command, "-C", "-f", "-e", file};
|
||||
addr2line = ProcessFactory.getFactory().exec(args);
|
||||
stdin = new BufferedWriter(new OutputStreamWriter(addr2line.getOutputStream()));
|
||||
stdout = new BufferedReader(new InputStreamReader(addr2line.getInputStream()));
|
||||
stdout = new BufferedReader(new InputStreamReader(addr2line.getInputStream()));
|
||||
}
|
||||
|
||||
public Addr2line(String file) throws IOException {
|
||||
this("addr2line", file);
|
||||
}
|
||||
|
||||
private void getOutput(String address) throws IOException {
|
||||
if ( address.equals(lastaddr) == false ) {
|
||||
stdin.write(address + "\n");
|
||||
stdin.flush();
|
||||
lastsymbol = stdout.readLine();
|
||||
lastline = stdout.readLine();
|
||||
lastaddr = address;
|
||||
stdin.write(address + "\n");
|
||||
stdin.flush();
|
||||
lastsymbol = stdout.readLine();
|
||||
lastline = stdout.readLine();
|
||||
lastaddr = address;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,14 +50,62 @@ public class Addr2line {
|
|||
return lastsymbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* The format of the output:
|
||||
* addr2line -C -f -e hello
|
||||
* 08048442
|
||||
* main
|
||||
* hello.c:39
|
||||
*/
|
||||
public String getFileName(long address) throws IOException {
|
||||
String filename = null;
|
||||
String line = getLine(address);
|
||||
int index1, index2;
|
||||
if (line != null && (index1 = line.lastIndexOf(':')) != -1) {
|
||||
// we do this because addr2line on win produces
|
||||
// <cygdrive/pathtoexc/C:/pathtofile:##>
|
||||
index2 = line.indexOf(':');
|
||||
if (index1 == index2) {
|
||||
index2 = 0;
|
||||
} else {
|
||||
index2--;
|
||||
}
|
||||
filename = line.substring(index2, index1);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* The format of the output:
|
||||
* addr2line -C -f -e hello
|
||||
* 08048442
|
||||
* main
|
||||
* hello.c:39
|
||||
*/
|
||||
public int getLineNumber(long address) throws IOException {
|
||||
// We try to get the nearest match
|
||||
// since the symbol may not exactly align with debug info.
|
||||
// In C line number 0 is invalid, line starts at 1 for file, we use
|
||||
// this for validation.
|
||||
for (int i = 0; i <= 20; i += 4, address += i) {
|
||||
String line = getLine(address);
|
||||
if (line != null) {
|
||||
int colon = line.lastIndexOf(':');
|
||||
String number = line.substring(colon + 1);
|
||||
if (!number.startsWith("0")) {
|
||||
return Integer.parseInt(number);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
//stdin.write(-1);
|
||||
stdout.close();
|
||||
stdin.close();
|
||||
addr2line.getErrorStream().close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
}
|
||||
addr2line.destroy();
|
||||
}
|
||||
|
|
|
@ -17,15 +17,19 @@ public class CPPFilt {
|
|||
private Process cppfilt;
|
||||
private BufferedReader stdout;
|
||||
private BufferedWriter stdin;
|
||||
|
||||
public CPPFilt() throws IOException {
|
||||
String[] args = {"c++filt"};
|
||||
|
||||
public CPPFilt(String command) throws IOException {
|
||||
String[] args = {command};
|
||||
cppfilt = ProcessFactory.getFactory().exec(args);
|
||||
//cppfilt = new Spawner(args);
|
||||
stdin = new BufferedWriter(new OutputStreamWriter(cppfilt.getOutputStream()));
|
||||
stdout = new BufferedReader(new InputStreamReader(cppfilt.getInputStream()));
|
||||
}
|
||||
|
||||
public CPPFilt() throws IOException {
|
||||
this("c++filt");
|
||||
}
|
||||
|
||||
public String getFunction(String symbol) throws IOException {
|
||||
stdin.write(symbol + "\n");
|
||||
stdin.flush();
|
||||
|
|
|
@ -267,7 +267,7 @@ public class Coff {
|
|||
buffer.append("s_nreloc = ").append(s_nreloc).append(NL);
|
||||
buffer.append("s_nlnno = ").append(s_nlnno).append(NL);
|
||||
buffer.append("s_flags = ").append(s_flags).append(NL);
|
||||
/*
|
||||
///*
|
||||
try {
|
||||
Reloc[] rcs = getRelocs();
|
||||
for (int i = 0; i < rcs.length; i++) {
|
||||
|
@ -282,7 +282,7 @@ public class Coff {
|
|||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
*/
|
||||
//*/
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
@ -406,8 +406,10 @@ public class Coff {
|
|||
public String getName(byte[] table) {
|
||||
if (table.length > 0 && isLongName()) {
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(_n_name, true);
|
||||
memory.getInt();
|
||||
int offset = memory.getInt();
|
||||
memory.getInt(); // pass over the first 4 bytes.
|
||||
// The first for bytes of the string table represent the
|
||||
// number of bytes in the string table.
|
||||
int offset = memory.getInt() - 4;
|
||||
if (offset > 0) {
|
||||
for (int i = offset; i < table.length; i++) {
|
||||
if (table[i] == 0) {
|
||||
|
|
|
@ -438,6 +438,20 @@ 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();
|
||||
pe.dispose();
|
||||
return attrib;
|
||||
}
|
||||
|
||||
|
||||
public void dispose() throws IOException {
|
||||
if (rfile != null) {
|
||||
rfile.close();
|
||||
|
@ -491,7 +505,6 @@ public class PE {
|
|||
int size = memory.getInt();
|
||||
dataDirectories[i] = new ImageDataDirectory(rva, size);
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
return dataDirectories;
|
||||
}
|
||||
|
@ -507,7 +520,6 @@ public class PE {
|
|||
for (int i = 0; i < scnhdrs.length; i++, offset += SectionHeader.SCNHSZ) {
|
||||
scnhdrs[i] = new SectionHeader(accessFile, offset);
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
return scnhdrs;
|
||||
}
|
||||
|
@ -519,8 +531,11 @@ public class PE {
|
|||
symbolTable = new Symbol[fileHeader.f_nsyms];
|
||||
for (int i = 0; i < symbolTable.length; i++, offset += Symbol.SYMSZ) {
|
||||
symbolTable[i] = new Symbol(accessFile, offset);
|
||||
NTOptionalHeader ntHeader = getNTOptionalHeader();
|
||||
// FIXME: What is this again ?
|
||||
if (ntHeader != null)
|
||||
symbolTable[i].n_value += ntHeader.ImageBase + ntHeader.FileAlignment;
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
return symbolTable;
|
||||
}
|
||||
|
@ -543,7 +558,6 @@ public class PE {
|
|||
} else {
|
||||
stringTable = new byte[0];
|
||||
}
|
||||
dispose();
|
||||
} else {
|
||||
stringTable = new byte[0];
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.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;
|
||||
|
@ -19,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);
|
||||
public ARMember(IPath p, AR.ARHeader h, IToolsProvider provider) throws IOException {
|
||||
super(p, new ElfHelper(h.getElf()), provider);
|
||||
header = h;
|
||||
}
|
||||
|
||||
|
@ -58,15 +67,13 @@ public class ARMember extends BinaryObject {
|
|||
throw new IOException("No file assiocated with Binary");
|
||||
}
|
||||
|
||||
protected void addSymbols(Elf.Symbol[] array, int type) {
|
||||
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();
|
||||
Symbol sym = new Symbol(this);
|
||||
sym.type = type;
|
||||
sym.name = array[i].toString();
|
||||
sym.addr = array[i].st_value;
|
||||
addSymbol(sym);
|
||||
// This can fail if we use addr2line
|
||||
// but we can safely ignore the error.
|
||||
list.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,34 +1,35 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.utils.elf.AR;
|
||||
import org.eclipse.cdt.utils.elf.Elf.Attribute;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class BinaryArchive extends PlatformObject implements IBinaryArchive {
|
||||
public class BinaryArchive extends BinaryFile implements IBinaryArchive {
|
||||
|
||||
IPath path;
|
||||
ArrayList children;
|
||||
long timestamp;
|
||||
|
||||
public BinaryArchive(IPath p) throws IOException {
|
||||
path = p;
|
||||
new AR(path.toOSString()).dispose(); // check file type
|
||||
super(p);
|
||||
new AR(p.toOSString()).dispose(); // check file type
|
||||
children = new ArrayList(5);
|
||||
}
|
||||
|
||||
|
@ -38,34 +39,25 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
|
|||
public IBinaryObject[] getObjects() {
|
||||
if (hasChanged()) {
|
||||
children.clear();
|
||||
if (path != null) {
|
||||
AR ar = null;
|
||||
try {
|
||||
ar = new AR(path.toOSString());
|
||||
AR.ARHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
IBinaryObject bin = new ARMember(path, headers[i]);
|
||||
children.add(bin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
AR ar = null;
|
||||
try {
|
||||
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], toolsProvider);
|
||||
children.add(bin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
children.trimToSize();
|
||||
}
|
||||
return (IBinaryObject[]) children.toArray(new IBinaryObject[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
|
||||
*/
|
||||
public IPath getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
|
@ -73,23 +65,6 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
|
|||
return IBinaryFile.ARCHIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
try {
|
||||
return new FileInputStream(path.toFile());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
|
||||
boolean hasChanged() {
|
||||
long modif = path.toFile().lastModified();
|
||||
boolean changed = modif != timestamp;
|
||||
timestamp = modif;
|
||||
return changed;
|
||||
}
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[])
|
||||
*/
|
||||
|
@ -102,4 +77,11 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
|
|||
public void delete(IBinaryObject[] objs) throws IOException {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.elf.parser.BinaryFile#getAttribute()
|
||||
*/
|
||||
protected Attribute getAttribute() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,28 +1,24 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.utils.elf.Elf.Attribute;
|
||||
import org.eclipse.cdt.utils.elf.ElfHelper.Sizes;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class BinaryExecutable extends BinaryObject implements IBinaryExecutable {
|
||||
long timestamp;
|
||||
String soname;
|
||||
String[] needed;
|
||||
Sizes sizes;
|
||||
Attribute attribute;
|
||||
ArrayList symbols;
|
||||
|
||||
public BinaryExecutable(IPath path) throws IOException {
|
||||
super(path);
|
||||
|
|
|
@ -1,34 +1,57 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.utils.*;
|
||||
import org.eclipse.cdt.utils.Addr2line;
|
||||
import org.eclipse.cdt.utils.CPPFilt;
|
||||
import org.eclipse.cdt.utils.elf.Elf.Attribute;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class BinaryFile extends PlatformObject implements IBinaryFile {
|
||||
|
||||
protected IPath path;
|
||||
protected IToolsProvider toolsProvider;
|
||||
protected long timestamp;
|
||||
|
||||
public BinaryFile(IPath p) {
|
||||
path = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
protected abstract Attribute getAttribute();
|
||||
public void setToolsProvider(IToolsProvider p) {
|
||||
toolsProvider = p;
|
||||
}
|
||||
|
||||
public Addr2line getAddr2Line() {
|
||||
if (toolsProvider != null)
|
||||
return toolsProvider.getAddr2Line(path);
|
||||
return null;
|
||||
}
|
||||
|
||||
public CPPFilt getCPPFilt() {
|
||||
if (toolsProvider != null)
|
||||
return toolsProvider.getCPPFilt();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
|
||||
|
@ -59,4 +82,16 @@ public abstract class BinaryFile extends PlatformObject implements IBinaryFile {
|
|||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
protected abstract Attribute getAttribute();
|
||||
|
||||
protected boolean hasChanged() {
|
||||
long modification = getPath().toFile().lastModified();
|
||||
boolean changed = modification != timestamp;
|
||||
timestamp = modification;
|
||||
return changed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,32 @@
|
|||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
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;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -24,18 +34,35 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
|
|||
protected String soname;
|
||||
protected String[] needed;
|
||||
protected int type = IBinaryFile.OBJECT;
|
||||
|
||||
private long timestamp;
|
||||
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();
|
||||
}
|
||||
|
||||
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()
|
||||
*/
|
||||
|
@ -112,47 +139,28 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
|
|||
public void setType(int t) {
|
||||
type = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getSymbols()
|
||||
*/
|
||||
public ISymbol[] getSymbols() {
|
||||
if (hasChanged() || symbols == null) {
|
||||
if (symbols == null) {
|
||||
symbols = new ArrayList(5);
|
||||
}
|
||||
try {
|
||||
loadInformation();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return (ISymbol[]) symbols.toArray(new ISymbol[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
InputStream stream = null;
|
||||
if (path != null) {
|
||||
try {
|
||||
stream = new FileInputStream(path.toFile());
|
||||
} catch (IOException e) {
|
||||
if (symbols == null) {
|
||||
symbols = NO_SYMBOLS;
|
||||
}
|
||||
}
|
||||
if (stream == null) {
|
||||
stream = super.getContents();
|
||||
}
|
||||
return stream;
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
if (path != null) {
|
||||
return path.lastSegment().toString();
|
||||
}
|
||||
return "";
|
||||
return getPath().lastSegment().toString();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -179,18 +187,8 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
|
|||
return sizes;
|
||||
}
|
||||
|
||||
boolean hasChanged() {
|
||||
long modification = path.toFile().lastModified();
|
||||
boolean changed = modification != timestamp;
|
||||
timestamp = modification;
|
||||
return changed;
|
||||
}
|
||||
|
||||
protected ElfHelper getElfHelper() throws IOException {
|
||||
if (path != null) {
|
||||
return new ElfHelper(path.toOSString());
|
||||
}
|
||||
throw new IOException("No file assiocated with Binary");
|
||||
return new ElfHelper(getPath().toOSString());
|
||||
}
|
||||
|
||||
protected void loadInformation() throws IOException {
|
||||
|
@ -207,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 {
|
||||
|
@ -226,43 +220,57 @@ 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);
|
||||
|
||||
addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION);
|
||||
addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION);
|
||||
addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE);
|
||||
addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE);
|
||||
symbols.trimToSize();
|
||||
Addr2line addr2line = getAddr2Line();
|
||||
CPPFilt cppfilt = getCPPFilt();
|
||||
|
||||
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();
|
||||
}
|
||||
if (cppfilt != null) {
|
||||
cppfilt.dispose();
|
||||
}
|
||||
|
||||
symbols = (ISymbol[])list.toArray(NO_SYMBOLS);
|
||||
Arrays.sort(symbols);
|
||||
list.clear();
|
||||
}
|
||||
|
||||
protected void addSymbols(Elf.Symbol[] array, int type) {
|
||||
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();
|
||||
Symbol sym = new Symbol(this);
|
||||
sym.type = type;
|
||||
sym.name = array[i].toString();
|
||||
sym.addr = array[i].st_value;
|
||||
try {
|
||||
// This can fail if we use addr2line
|
||||
// but we can safely ignore the error.
|
||||
sym.filename = array[i].getFilename();
|
||||
sym.startLine = array[i].getFuncLineNumber();
|
||||
sym.endLine = sym.startLine;
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
if (cppfilt != null) {
|
||||
try {
|
||||
sym.name = cppfilt.getFunction(sym.name);
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
}
|
||||
addSymbol(sym);
|
||||
sym.addr = array[i].st_value;
|
||||
sym.filename = null;
|
||||
sym.startLine = 0;
|
||||
sym.endLine = sym.startLine;
|
||||
if (addr2line != null) {
|
||||
try {
|
||||
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) {
|
||||
}
|
||||
}
|
||||
list.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addSymbol(Symbol sym) {
|
||||
symbols.add(sym);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
|
@ -14,7 +19,6 @@ import org.eclipse.core.runtime.IPath;
|
|||
/**
|
||||
*/
|
||||
public class BinaryShared extends BinaryExecutable implements IBinaryShared {
|
||||
String soname;
|
||||
|
||||
public BinaryShared(IPath path) throws IOException {
|
||||
super(path);
|
||||
|
|
|
@ -1,58 +1,36 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.AbstractCExtension;
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.core.ICExtensionReference;
|
||||
import org.eclipse.cdt.internal.core.model.parser.ElfBinaryArchive;
|
||||
import org.eclipse.cdt.utils.elf.Elf;
|
||||
import org.eclipse.cdt.utils.elf.Elf.Attribute;
|
||||
import org.eclipse.cdt.utils.*;
|
||||
import org.eclipse.cdt.utils.Addr2line;
|
||||
import org.eclipse.cdt.utils.CPPFilt;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
|
||||
public class GNUElfParser extends ElfParser implements IBinaryParser, IToolsProvider {
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath)
|
||||
*/
|
||||
public IBinaryFile getBinary(IPath path) throws IOException {
|
||||
if (path == null) {
|
||||
path = new Path("");
|
||||
}
|
||||
IBinaryFile binary = null;
|
||||
try {
|
||||
Elf.Attribute attribute = Elf.getAttributes(path.toOSString());
|
||||
if (attribute != null) {
|
||||
switch (attribute.getType()) {
|
||||
case Attribute.ELF_TYPE_EXE :
|
||||
binary = new BinaryExecutable(path);
|
||||
break;
|
||||
|
||||
case Attribute.ELF_TYPE_SHLIB :
|
||||
binary = new BinaryShared(path);
|
||||
break;
|
||||
|
||||
case Attribute.ELF_TYPE_OBJ :
|
||||
binary = new BinaryObject(path);
|
||||
break;
|
||||
|
||||
case Attribute.ELF_TYPE_CORE :
|
||||
BinaryObject obj = new BinaryObject(path);
|
||||
obj.setType(IBinaryFile.CORE);
|
||||
binary = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
binary = new ElfBinaryArchive(path);
|
||||
IBinaryFile binary = super.getBinary(path);
|
||||
if (binary instanceof BinaryFile) {
|
||||
((BinaryFile)binary).setToolsProvider(this);
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
@ -61,16 +39,49 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
|
|||
* @see org.eclipse.cdt.core.model.IBinaryParser#getFormat()
|
||||
*/
|
||||
public String getFormat() {
|
||||
return "ELF";
|
||||
return "GNU ELF";
|
||||
}
|
||||
|
||||
String getAddr2LinePath() {
|
||||
public IPath getAddr2LinePath() {
|
||||
ICExtensionReference ref = getExtensionReference();
|
||||
return ref.getExtensionData("addr2line");
|
||||
String value = ref.getExtensionData("addr2line"); //$NON-NLS-1
|
||||
if (value == null || value.length() == 0) {
|
||||
value = "addr2line"; //$NON-NLS-1
|
||||
}
|
||||
return new Path(value);
|
||||
}
|
||||
|
||||
String getCPPFiltPath() {
|
||||
public IPath getCPPFiltPath() {
|
||||
ICExtensionReference ref = getExtensionReference();
|
||||
return ref.getExtensionData("c++filt");
|
||||
String value = ref.getExtensionData("c++filt"); //$NON-NLS-1
|
||||
if (value == null || value.length() == 0) {
|
||||
value = "c++filt"; //$NON-NLS-1
|
||||
}
|
||||
return new Path(value);
|
||||
}
|
||||
|
||||
public Addr2line getAddr2Line(IPath path) {
|
||||
IPath addr2LinePath = getAddr2LinePath();
|
||||
Addr2line addr2line = null;
|
||||
if (addr2LinePath != null && !addr2LinePath.isEmpty()) {
|
||||
try {
|
||||
addr2line = new Addr2line(addr2LinePath.toOSString(), path.toOSString());
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
}
|
||||
return addr2line;
|
||||
}
|
||||
|
||||
public CPPFilt getCPPFilt() {
|
||||
IPath cppFiltPath = getCPPFiltPath();
|
||||
CPPFilt cppfilt = null;
|
||||
if (cppFiltPath != null && ! cppFiltPath.isEmpty()) {
|
||||
try {
|
||||
cppfilt = new CPPFilt(cppFiltPath.toOSString());
|
||||
} catch (IOException e2) {
|
||||
}
|
||||
}
|
||||
return cppfilt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +1,42 @@
|
|||
/**********************************************************************
|
||||
* 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.elf.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||
import org.eclipse.cdt.utils.Addr2line;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/*
|
||||
* (c) Copyright IBM Corp. 2000, 2001.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
public class Symbol implements ISymbol, Comparable {
|
||||
|
||||
public class Symbol implements ISymbol {
|
||||
BinaryObject binary;
|
||||
|
||||
public String filename;
|
||||
public IPath filename;
|
||||
public int startLine;
|
||||
public int endLine;
|
||||
public long addr;
|
||||
public String name;
|
||||
public int type;
|
||||
|
||||
public Symbol(BinaryObject 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()
|
||||
*/
|
||||
|
@ -59,4 +72,34 @@ public class Symbol implements ISymbol {
|
|||
return startLine;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getLineNumber(long)
|
||||
*/
|
||||
public int getLineNumber(long offset) {
|
||||
int line = -1;
|
||||
try {
|
||||
Addr2line addr2line = binary.getAddr2Line();
|
||||
if (addr2line != null) {
|
||||
line = addr2line.getLineNumber(addr + offset);
|
||||
addr2line.dispose();
|
||||
}
|
||||
} 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