1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-20 15:35:24 +02:00

Use the IBinaryParser

This commit is contained in:
Alain Magloire 2002-11-18 15:45:20 +00:00
parent 8b036e7766
commit 228076d41b
2 changed files with 211 additions and 219 deletions

View file

@ -7,14 +7,17 @@ package org.eclipse.cdt.internal.core.model;
import java.io.IOException; import java.io.IOException;
import org.eclipse.core.resources.IResource; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.core.resources.IFile; import org.eclipse.cdt.core.model.IBinaryParser;
import org.eclipse.core.runtime.IPath;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive;
import org.eclipse.cdt.utils.elf.AR; import org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.utils.elf.ElfHelper; 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. * Info for ICProject.
@ -22,56 +25,68 @@ import org.eclipse.cdt.utils.elf.ElfHelper;
class ArchiveInfo extends CFileInfo { class ArchiveInfo extends CFileInfo {
IBinaryArchive archive;
/** /**
*/ */
public ArchiveInfo(CElement element) { public ArchiveInfo(CElement element) {
super(element); super(element);
} }
public ICElement [] getChildren() { public ICElement[] getChildren() {
init();
return super.getChildren();
}
public void init() {
if (hasChanged()) { if (hasChanged()) {
removeChildren(); 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() { public boolean isArchive() {
return true; return true;
} }
protected void loadInfo() { IBinaryArchive getBinaryArchive() {
IPath location = ((CFile)getElement()).getLocation(); if (archive == null) {
IFile file = ((CFile)getElement()).getFile(); IProject project = getElement().getCProject().getProject();
IBinaryParser parser = CModelManager.getBinaryParser(project);
if (parser != null) {
try { try {
AR ar = new AR(location.toOSString()); IFile file = (IFile) getElement().getUnderlyingResource();
AR.ARHeader[] header = ar.getHeaders(); IBinaryFile bfile = parser.getBinary(file);
for (int i = 0; i < header.length; i++) { if (bfile instanceof IBinaryArchive) {
ElfHelper helper = new ElfHelper(header[i].getElf()); archive = (IBinaryArchive) bfile;
//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;
} }
}; } catch (CModelException e) {
// 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 (IOException e) { } catch (IOException e) {
//e.printStackTrace();
} }
} }
}
return archive;
}
} }

View file

@ -6,131 +6,171 @@ package org.eclipse.cdt.internal.core.model;
*/ */
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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.IPath;
import org.eclipse.core.runtime.Path; 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 { class BinaryInfo extends CFileInfo {
String [] needed; IBinaryObject binary;
ElfHelper.Sizes sizes;
Elf.Attribute attribute;
String soname;
Map hash; Map hash;
ElfHelper elfHelper = null;
public BinaryInfo(CElement element) { public BinaryInfo(CElement element) {
super(element); super(element);
needed = new String[0];
sizes = null;
attribute = null;
soname = "";
hash = new HashMap();
} }
public boolean isBinary() { public boolean isBinary() {
return true; return true;
} }
public ICElement [] getChildren() { 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(); return super.getChildren();
} }
public String getCPU() { public String getCPU() {
init(); IBinaryObject bin = getBinaryObject();
String cpu = null; if (bin != null) {
if (attribute != null) return bin.getCPU();
cpu = attribute.getCPU(); }
return (cpu == null) ? "" : cpu; return "";
} }
public boolean isSharedLib() { public boolean isSharedLib() {
init(); IBinaryObject bin = getBinaryObject();
if (attribute != null) if (bin != null) {
return attribute.getType() == attribute.ELF_TYPE_SHLIB; return bin.getType() == IBinaryObject.SHARED;
}
return false; return false;
} }
public boolean isExecutable() { public boolean isExecutable() {
init(); IBinaryObject bin = getBinaryObject();
if (attribute != null) if (bin != null) {
return attribute.getType() == attribute.ELF_TYPE_EXE; return bin.getType() == IBinaryObject.EXECUTABLE;
}
return false; return false;
} }
public boolean isObject() { public boolean isObject() {
init(); IBinaryObject bin = getBinaryObject();
if (attribute != null) if (bin != null) {
return attribute.getType() == attribute.ELF_TYPE_OBJ; return bin.getType() == IBinaryObject.OBJECT;
}
return false; return false;
} }
public boolean hasDebug () { public boolean hasDebug() {
init(); IBinaryObject bin = getBinaryObject();
if (attribute != null) if (bin != null) {
return attribute.hasDebug(); return bin.hasDebug();
}
return false; return false;
} }
public String [] getNeededSharedLibs() { public String[] getNeededSharedLibs() {
init(); if (isExecutable()) {
return needed; IBinaryExecutable exec = (IBinaryExecutable) getBinaryObject();
return exec.getNeededSharedLibs();
}
return new String[0];
} }
public long getText() { public long getText() {
init(); IBinaryObject bin = getBinaryObject();
if (sizes != null) { if (bin != null) {
return sizes.text; return bin.getText();
} }
return 0; return 0;
} }
public long getData() { public long getData() {
init(); IBinaryObject bin = getBinaryObject();
if (sizes != null) { if (bin != null) {
return sizes.data; return bin.getData();
} }
return 0; return 0;
} }
public long getBSS() { public long getBSS() {
init(); IBinaryObject bin = getBinaryObject();
if (sizes != null) { if (bin != null) {
return sizes.bss; return bin.getBSS();
} }
return 0; return 0;
} }
public String getSoname() { public String getSoname() {
init(); if (isSharedLib()) {
return soname; IBinaryShared shared = (IBinaryShared) getBinaryObject();
return shared.getSoName();
}
return "";
} }
public boolean isLittleEndian() { public boolean isLittleEndian() {
init(); IBinaryObject bin = getBinaryObject();
if (attribute != null) { if (bin != null) {
return attribute.isLittleEndian(); return bin.isLittleEndian();
} }
return false; return false;
} }
private void addFunction(Elf.Symbol [] symbol, boolean external) { IBinaryObject getBinaryObject() {
for (int i = 0; i < symbol.length; i++) { if (binary == null) {
ICElement parent = getElement(); IProject project = getElement().getCProject().getProject();
String filename = null; IBinaryParser parser = CModelManager.getBinaryParser(project);
if (parser != null) {
try { try {
filename = symbol[i].getFilename(); IFile file = (IFile) getElement().getUnderlyingResource();
} catch (IOException e) { IBinaryFile bfile = parser.getBinary(file);
//e.printStackTrace(); 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; Function function = null;
// Addr2line returns the funny "??" when it can find the file. // Addr2line returns the funny "??" when it can find the file.
@ -138,32 +178,38 @@ class BinaryInfo extends CFileInfo {
TranslationUnit tu = null; TranslationUnit tu = null;
IPath path = new Path(filename); IPath path = new Path(filename);
if (hash.containsKey(path)) { if (hash.containsKey(path)) {
tu = (TranslationUnit)hash.get(path); tu = (TranslationUnit) hash.get(path);
} else { } 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); hash.put(path, tu);
addChild(tu); addChild(tu);
} }
function = new Function(tu, symbol[i].toString()); function = new Function(tu, symbol.getName());
tu.addChild(function); tu.addChild(function);
} else { } else {
function = new Function(parent, symbol[i].toString()); function = new Function(parent, symbol.getName());
addChild(function); addChild(function);
} }
if (function != null) // if (function != null) {
if (!external) // if (!external) {
function.getFunctionInfo().setAccessControl(IConstants.AccStatic); // function.getFunctionInfo().setAccessControl(IConstants.AccStatic);
} // }
// }
} }
private void addVariable(Elf.Symbol[] symbol, boolean external) { private void addVariable(ISymbol symbol) {
for (int i = 0; i < symbol.length; i++) { String filename = filename = symbol.getFilename();
String filename = null;
try {
filename = symbol[i].getFilename();
} catch (IOException e) {
//e.printStackTrace();
}
ICElement parent = getElement(); ICElement parent = getElement();
Variable variable = null; Variable variable = null;
// Addr2line returns the funny "??" when it can not find the file. // Addr2line returns the funny "??" when it can not find the file.
@ -171,92 +217,23 @@ class BinaryInfo extends CFileInfo {
TranslationUnit tu = null; TranslationUnit tu = null;
IPath path = new Path(filename); IPath path = new Path(filename);
if (hash.containsKey(path)) { if (hash.containsKey(path)) {
tu = (TranslationUnit)hash.get(path); tu = (TranslationUnit) hash.get(path);
} else { } else {
tu = new TranslationUnit(parent, path); tu = new TranslationUnit(parent, path);
hash.put(path, tu); hash.put(path, tu);
addChild(tu); addChild(tu);
} }
variable = new Variable(tu, symbol[i].toString()); variable = new Variable(tu, symbol.getName());
tu.addChild(variable); tu.addChild(variable);
} else { } else {
variable = new Variable(parent, symbol[i].toString()); variable = new Variable(parent, symbol.getName());
addChild(variable); addChild(variable);
} }
if (variable != null) //if (variable != null) {
if (!external) // if (!external) {
variable.getVariableInfo().setAccessControl(IConstants.AccStatic); // 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();
}
}
} }