1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

new Binary Parser to add flexibilit to change

commands like addr2line. Still work in progress
This commit is contained in:
Alain Magloire 2003-09-17 02:11:24 +00:00
parent f3d847d96a
commit 2c1ef469c6
10 changed files with 772 additions and 0 deletions

View file

@ -1,3 +1,17 @@
2003-09-16 Alain Magloire
Putting the draft work to do a special binary parser
that the addr2line and c++filt command could be set
via extension in the ui.
* utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java
* utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java
* utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java
* utils/org/eclipse/cdt/utils/elf/parser/BinaryExecutable.java
* utils/org/eclipse/cdt/utils/elf/parser/BinaryShared.java
* utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java
* utils/org/eclipse/cdt/utils/elf/parser/ARMember.java
2003-09-16 David Inglis 2003-09-16 David Inglis
Deprecate old make builder Deprecate old make builder

View file

@ -129,6 +129,18 @@
</run> </run>
</cextension> </cextension>
</extension> </extension>
<!-- extension
id="GNU_ELF"
name="GNU Elf Parser"
point="org.eclipse.cdt.core.BinaryParser">
<cextension>
<run
class="org.eclipse.cdt.utils.elf.parser.GNUElfParser">
</run>
</cextension>
</extension -->
<extension <extension
id="PE" id="PE"
name="PE Windows Parser" name="PE Windows Parser"

View file

@ -0,0 +1,73 @@
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 org.eclipse.cdt.utils.elf.AR;
import org.eclipse.cdt.utils.elf.Elf;
import org.eclipse.cdt.utils.elf.ElfHelper;
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);
header = h;
}
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
*/
public InputStream getContents() {
InputStream stream = null;
if (path != null && header != null) {
try {
stream = new ByteArrayInputStream(header.getObjectData());
} catch (IOException e) {
}
}
if (stream == null) {
stream = super.getContents();
}
return stream;
}
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
*/
public String getName() {
if (header != null) {
return header.getObjectName();
}
return "";
}
protected ElfHelper getElfHelper() throws IOException {
if (header != null) {
return new ElfHelper(header.getElf());
}
throw new IOException("No file assiocated with Binary");
}
protected 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;
addSymbol(sym);
// This can fail if we use addr2line
// but we can safely ignore the error.
}
}
}

View file

@ -0,0 +1,105 @@
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.core.runtime.IPath;
import org.eclipse.core.runtime.PlatformObject;
/**
*/
public class BinaryArchive extends PlatformObject implements IBinaryArchive {
IPath path;
ArrayList children;
long timestamp;
public BinaryArchive(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 ARMember(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 {
}
}

View file

@ -0,0 +1,54 @@
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);
}
/**
* @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() {
return IBinaryFile.EXECUTABLE;
}
}

View file

@ -0,0 +1,62 @@
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.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;
public BinaryFile(IPath p) {
path = p;
}
/**
* @return
*/
protected abstract Attribute getAttribute();
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
*/
public IPath getPath() {
return path;
}
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
*/
public abstract int getType();
/**
* @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 (stream == null) {
stream = new ByteArrayInputStream(new byte[0]);
}
return stream;
}
}

View file

@ -0,0 +1,268 @@
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package org.eclipse.cdt.utils.elf.parser;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
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.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;
/**
*/
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;
public BinaryObject(IPath path) throws IOException {
super(path);
loadInformation();
hasChanged();
}
/**
* @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.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.IBinaryFile#getType()
*/
public int getType() {
return type;
}
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 (stream == null) {
stream = super.getContents();
}
return stream;
}
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
*/
public String getName() {
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 {
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();
}
protected 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.
sym.filename = array[i].getFilename();
sym.startLine = array[i].getFuncLineNumber();
sym.endLine = sym.startLine;
} catch (IOException e) {
//e.printStackTrace();
}
addSymbol(sym);
}
}
protected void addSymbol(Symbol sym) {
symbols.add(sym);
}
}

View file

@ -0,0 +1,46 @@
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;
import org.eclipse.cdt.core.IBinaryParser.IBinaryShared;
import org.eclipse.core.runtime.IPath;
/**
*/
public class BinaryShared extends BinaryExecutable implements IBinaryShared {
String soname;
public BinaryShared(IPath path) throws IOException {
super(path);
}
/**
* @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.IBinaryFile#getType()
*/
public int getType() {
return IBinaryFile.SHARED;
}
}

View file

@ -0,0 +1,76 @@
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.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
*/
public class GNUElfParser 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 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);
}
return binary;
}
/**
* @see org.eclipse.cdt.core.model.IBinaryParser#getFormat()
*/
public String getFormat() {
return "ELF";
}
String getAddr2LinePath() {
ICExtensionReference ref = getExtensionReference();
return ref.getExtensionData("addr2line");
}
String getCPPFiltPath() {
ICExtensionReference ref = getExtensionReference();
return ref.getExtensionData("c++filt");
}
}

View file

@ -0,0 +1,62 @@
package org.eclipse.cdt.utils.elf.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;
}
}