mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-19 15:05:36 +02:00
Use the IBinaryParser
This commit is contained in:
parent
8b036e7766
commit
228076d41b
2 changed files with 211 additions and 219 deletions
|
@ -7,14 +7,17 @@ package org.eclipse.cdt.internal.core.model;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
|
||||
import org.eclipse.cdt.utils.elf.AR;
|
||||
import org.eclipse.cdt.utils.elf.ElfHelper;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.internal.core.model.parser.BinaryFileAdapter;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
||||
/**
|
||||
* Info for ICProject.
|
||||
|
@ -22,6 +25,8 @@ import org.eclipse.cdt.utils.elf.ElfHelper;
|
|||
|
||||
class ArchiveInfo extends CFileInfo {
|
||||
|
||||
IBinaryArchive archive;
|
||||
|
||||
/**
|
||||
*/
|
||||
public ArchiveInfo(CElement element) {
|
||||
|
@ -29,49 +34,59 @@ class ArchiveInfo extends CFileInfo {
|
|||
}
|
||||
|
||||
public ICElement[] getChildren() {
|
||||
init();
|
||||
return super.getChildren();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (hasChanged()) {
|
||||
removeChildren();
|
||||
loadInfo();
|
||||
IResource res = null;
|
||||
try {
|
||||
res = getElement().getResource();
|
||||
} catch (CModelException e) {
|
||||
}
|
||||
if (res != null && res instanceof IContainer) {
|
||||
IContainer container = (IContainer)res;
|
||||
IBinaryArchive ar = getBinaryArchive();
|
||||
IBinaryObject[] objects = ar.getObjects();
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
final IBinaryObject obj = objects[i];
|
||||
IFile file = new BinaryFileAdapter(container, obj);
|
||||
Binary binary = new Binary(getElement(), file) {
|
||||
public CElementInfo createElementInfo() {
|
||||
return new BinaryInfo(this) {
|
||||
/**
|
||||
* @see org.eclipse.cdt.internal.core.model.BinaryInfo#getBinaryObject()
|
||||
*/
|
||||
IBinaryObject getBinaryObject() {
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
addChild(binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getChildren();
|
||||
}
|
||||
|
||||
public boolean isArchive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void loadInfo() {
|
||||
IPath location = ((CFile)getElement()).getLocation();
|
||||
IFile file = ((CFile)getElement()).getFile();
|
||||
IBinaryArchive getBinaryArchive() {
|
||||
if (archive == null) {
|
||||
IProject project = getElement().getCProject().getProject();
|
||||
IBinaryParser parser = CModelManager.getBinaryParser(project);
|
||||
if (parser != null) {
|
||||
try {
|
||||
AR ar = new AR(location.toOSString());
|
||||
AR.ARHeader[] header = ar.getHeaders();
|
||||
for (int i = 0; i < header.length; i++) {
|
||||
ElfHelper helper = new ElfHelper(header[i].getElf());
|
||||
//IPath path = new Path(header[i].getObjectName());
|
||||
// FIXME: We should create a special IResource for this files
|
||||
// but for now, just bypass.
|
||||
Binary binary = new Binary(getElement(), file, header[i].getObjectName()) {
|
||||
public IResource getCorrespondingResource() {
|
||||
return null;
|
||||
IFile file = (IFile) getElement().getUnderlyingResource();
|
||||
IBinaryFile bfile = parser.getBinary(file);
|
||||
if (bfile instanceof IBinaryArchive) {
|
||||
archive = (IBinaryArchive) bfile;
|
||||
}
|
||||
};
|
||||
// Force the loading so we can dispose;
|
||||
((BinaryInfo)(binary.getElementInfo())).elfHelper = helper;
|
||||
// Force the loading of the chidren right away so we can
|
||||
// dispose of the elf Elper.
|
||||
binary.getChildren();
|
||||
((BinaryInfo)(binary.getElementInfo())).elfHelper = null;
|
||||
helper.dispose();
|
||||
addChild(binary);
|
||||
}
|
||||
ar.dispose();
|
||||
} catch (CModelException e) {
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,33 +6,30 @@ package org.eclipse.cdt.internal.core.model;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryExecutable;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryShared;
|
||||
import org.eclipse.cdt.core.model.IBinaryParser.ISymbol;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
|
||||
import org.eclipse.cdt.utils.elf.Elf;
|
||||
import org.eclipse.cdt.utils.elf.ElfHelper;
|
||||
|
||||
class BinaryInfo extends CFileInfo {
|
||||
|
||||
String [] needed;
|
||||
ElfHelper.Sizes sizes;
|
||||
Elf.Attribute attribute;
|
||||
String soname;
|
||||
IBinaryObject binary;
|
||||
Map hash;
|
||||
ElfHelper elfHelper = null;
|
||||
|
||||
public BinaryInfo(CElement element) {
|
||||
super(element);
|
||||
needed = new String[0];
|
||||
sizes = null;
|
||||
attribute = null;
|
||||
soname = "";
|
||||
hash = new HashMap();
|
||||
}
|
||||
|
||||
public boolean isBinary() {
|
||||
|
@ -40,97 +37,140 @@ class BinaryInfo extends CFileInfo {
|
|||
}
|
||||
|
||||
public ICElement[] getChildren() {
|
||||
initChildren();
|
||||
if (hasChanged()) {
|
||||
if (hash == null) {
|
||||
hash = new HashMap();
|
||||
}
|
||||
hash.clear();
|
||||
removeChildren();
|
||||
setIsStructureKnown(true);
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
ISymbol[] symbols = bin.getSymbols();
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
switch (symbols[i].getType()) {
|
||||
case ISymbol.FUNCTION :
|
||||
addFunction(symbols[i]);
|
||||
break;
|
||||
|
||||
case ISymbol.VARIABLE :
|
||||
addVariable(symbols[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getChildren();
|
||||
}
|
||||
|
||||
public String getCPU() {
|
||||
init();
|
||||
String cpu = null;
|
||||
if (attribute != null)
|
||||
cpu = attribute.getCPU();
|
||||
return (cpu == null) ? "" : cpu;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getCPU();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean isSharedLib() {
|
||||
init();
|
||||
if (attribute != null)
|
||||
return attribute.getType() == attribute.ELF_TYPE_SHLIB;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getType() == IBinaryObject.SHARED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isExecutable() {
|
||||
init();
|
||||
if (attribute != null)
|
||||
return attribute.getType() == attribute.ELF_TYPE_EXE;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getType() == IBinaryObject.EXECUTABLE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isObject() {
|
||||
init();
|
||||
if (attribute != null)
|
||||
return attribute.getType() == attribute.ELF_TYPE_OBJ;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getType() == IBinaryObject.OBJECT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasDebug() {
|
||||
init();
|
||||
if (attribute != null)
|
||||
return attribute.hasDebug();
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.hasDebug();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String[] getNeededSharedLibs() {
|
||||
init();
|
||||
return needed;
|
||||
if (isExecutable()) {
|
||||
IBinaryExecutable exec = (IBinaryExecutable) getBinaryObject();
|
||||
return exec.getNeededSharedLibs();
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public long getText() {
|
||||
init();
|
||||
if (sizes != null) {
|
||||
return sizes.text;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getText();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getData() {
|
||||
init();
|
||||
if (sizes != null) {
|
||||
return sizes.data;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getData();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getBSS() {
|
||||
init();
|
||||
if (sizes != null) {
|
||||
return sizes.bss;
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.getBSS();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getSoname() {
|
||||
init();
|
||||
return soname;
|
||||
if (isSharedLib()) {
|
||||
IBinaryShared shared = (IBinaryShared) getBinaryObject();
|
||||
return shared.getSoName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean isLittleEndian() {
|
||||
init();
|
||||
if (attribute != null) {
|
||||
return attribute.isLittleEndian();
|
||||
IBinaryObject bin = getBinaryObject();
|
||||
if (bin != null) {
|
||||
return bin.isLittleEndian();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addFunction(Elf.Symbol [] symbol, boolean external) {
|
||||
for (int i = 0; i < symbol.length; i++) {
|
||||
ICElement parent = getElement();
|
||||
String filename = null;
|
||||
IBinaryObject getBinaryObject() {
|
||||
if (binary == null) {
|
||||
IProject project = getElement().getCProject().getProject();
|
||||
IBinaryParser parser = CModelManager.getBinaryParser(project);
|
||||
if (parser != null) {
|
||||
try {
|
||||
filename = symbol[i].getFilename();
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
IFile file = (IFile) getElement().getUnderlyingResource();
|
||||
IBinaryFile bfile = parser.getBinary(file);
|
||||
if (bfile instanceof IBinaryObject) {
|
||||
binary = (IBinaryObject) bfile;
|
||||
}
|
||||
} catch (CModelException e) {
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
private void addFunction(ISymbol symbol) {
|
||||
ICElement parent = getElement();
|
||||
String filename = filename = symbol.getFilename();
|
||||
Function function = null;
|
||||
|
||||
// Addr2line returns the funny "??" when it can find the file.
|
||||
|
@ -140,30 +180,36 @@ class BinaryInfo extends CFileInfo {
|
|||
if (hash.containsKey(path)) {
|
||||
tu = (TranslationUnit) hash.get(path);
|
||||
} else {
|
||||
tu = new TranslationUnit(parent, path);
|
||||
// A special ITranslationUnit we do not want the file to be parse.
|
||||
tu = new TranslationUnit(parent, path) {
|
||||
ArrayList array = new ArrayList(5);
|
||||
public void addChild(ICElement e) {
|
||||
array.add(e);
|
||||
array.trimToSize();
|
||||
}
|
||||
|
||||
public ICElement [] getChildren() {
|
||||
return (ICElement[])array.toArray(new ICElement[0]);
|
||||
}
|
||||
};
|
||||
hash.put(path, tu);
|
||||
addChild(tu);
|
||||
}
|
||||
function = new Function(tu, symbol[i].toString());
|
||||
function = new Function(tu, symbol.getName());
|
||||
tu.addChild(function);
|
||||
} else {
|
||||
function = new Function(parent, symbol[i].toString());
|
||||
function = new Function(parent, symbol.getName());
|
||||
addChild(function);
|
||||
}
|
||||
if (function != null)
|
||||
if (!external)
|
||||
function.getFunctionInfo().setAccessControl(IConstants.AccStatic);
|
||||
}
|
||||
// if (function != null) {
|
||||
// if (!external) {
|
||||
// function.getFunctionInfo().setAccessControl(IConstants.AccStatic);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private void addVariable(Elf.Symbol[] symbol, boolean external) {
|
||||
for (int i = 0; i < symbol.length; i++) {
|
||||
String filename = null;
|
||||
try {
|
||||
filename = symbol[i].getFilename();
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
private void addVariable(ISymbol symbol) {
|
||||
String filename = filename = symbol.getFilename();
|
||||
ICElement parent = getElement();
|
||||
Variable variable = null;
|
||||
// Addr2line returns the funny "??" when it can not find the file.
|
||||
|
@ -177,86 +223,17 @@ class BinaryInfo extends CFileInfo {
|
|||
hash.put(path, tu);
|
||||
addChild(tu);
|
||||
}
|
||||
variable = new Variable(tu, symbol[i].toString());
|
||||
variable = new Variable(tu, symbol.getName());
|
||||
tu.addChild(variable);
|
||||
} else {
|
||||
variable = new Variable(parent, symbol[i].toString());
|
||||
variable = new Variable(parent, symbol.getName());
|
||||
addChild(variable);
|
||||
}
|
||||
if (variable != null)
|
||||
if (!external)
|
||||
variable.getVariableInfo().setAccessControl(IConstants.AccStatic);
|
||||
}
|
||||
//if (variable != null) {
|
||||
// if (!external) {
|
||||
// variable.getVariableInfo().setAccessControl(IConstants.AccStatic);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
if (hasChanged()) {
|
||||
loadInfo();
|
||||
}
|
||||
}
|
||||
|
||||
protected void initChildren() {
|
||||
if (hasChanged() || !isStructureKnown()) {
|
||||
removeChildren();
|
||||
loadInfoChildren();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected ElfHelper getElfHelper() throws IOException {
|
||||
if (elfHelper != null) {
|
||||
return elfHelper;
|
||||
}
|
||||
CFile file = (CFile)getElement();
|
||||
if (file != null) {
|
||||
IPath path = ((CFile)getElement()).getLocation();
|
||||
if (path == null)
|
||||
path = new Path("");
|
||||
return new ElfHelper(path.toOSString());
|
||||
}
|
||||
throw new IOException("No file assiocated with Binary");
|
||||
}
|
||||
|
||||
protected void loadInfo() {
|
||||
try {
|
||||
ElfHelper helper = this.getElfHelper();
|
||||
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();
|
||||
helper.dispose();
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadInfoChildren() {
|
||||
try {
|
||||
setIsStructureKnown(true);
|
||||
ElfHelper helper = this.getElfHelper();
|
||||
addFunction(helper.getExternalFunctions(), true);
|
||||
addFunction(helper.getLocalFunctions(), false);
|
||||
addVariable(helper.getExternalObjects(), true);
|
||||
addVariable(helper.getLocalObjects(), false);
|
||||
|
||||
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();
|
||||
helper.dispose();
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue