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

Enable the GNU Elf Parser.

This commit is contained in:
Alain Magloire 2003-10-06 20:16:38 +00:00
parent 4882849b8c
commit 994d18c7ab
8 changed files with 174 additions and 45 deletions

View file

@ -1,3 +1,15 @@
2003-10-06 Alain Magloire
Implementation of the GNU Elf parser, where you can
change the path of the external commands: addr2line and cppfilt.
* plugin.xml: Enable the GNU Elf Parser.
* utils/org/eclipse/cdt/utils/elf/BinaryFile.java
* utils/org/eclipse/cdt/utils/elf/BinaryObject.java
* utils/org/eclipse/cdt/utils/elf/BinaryArchive.java
* utils/org/eclipse/cdt/utils/Addr2line.java
* utils/org/eclipse/cdt/utils/elf/CPPFilt.java
2003-10-01 Bogdan Gheorghe 2003-10-01 Bogdan Gheorghe
Changed DeltaProcessor.updateDependencies to use the CModelManager Changed DeltaProcessor.updateDependencies to use the CModelManager

View file

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

View file

@ -19,13 +19,17 @@ public class Addr2line {
private BufferedWriter stdin; private BufferedWriter stdin;
private String lastaddr, lastsymbol, lastline; private String lastaddr, lastsymbol, lastline;
public Addr2line(String file) throws IOException { public Addr2line(String command, String file) throws IOException {
String[] args = {"addr2line", "-C", "-f", "-e", file}; String[] args = {command, "-C", "-f", "-e", file};
addr2line = ProcessFactory.getFactory().exec(args); addr2line = ProcessFactory.getFactory().exec(args);
stdin = new BufferedWriter(new OutputStreamWriter(addr2line.getOutputStream())); 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 { private void getOutput(String address) throws IOException {
if ( address.equals(lastaddr) == false ) { if ( address.equals(lastaddr) == false ) {
stdin.write(address + "\n"); stdin.write(address + "\n");

View file

@ -18,14 +18,18 @@ public class CPPFilt {
private BufferedReader stdout; private BufferedReader stdout;
private BufferedWriter stdin; private BufferedWriter stdin;
public CPPFilt() throws IOException { public CPPFilt(String command) throws IOException {
String[] args = {"c++filt"}; String[] args = {command};
cppfilt = ProcessFactory.getFactory().exec(args); cppfilt = ProcessFactory.getFactory().exec(args);
//cppfilt = new Spawner(args); //cppfilt = new Spawner(args);
stdin = new BufferedWriter(new OutputStreamWriter(cppfilt.getOutputStream())); stdin = new BufferedWriter(new OutputStreamWriter(cppfilt.getOutputStream()));
stdout = new BufferedReader(new InputStreamReader(cppfilt.getInputStream())); stdout = new BufferedReader(new InputStreamReader(cppfilt.getInputStream()));
} }
public CPPFilt() throws IOException {
this("c++filt");
}
public String getFunction(String symbol) throws IOException { public String getFunction(String symbol) throws IOException {
stdin.write(symbol + "\n"); stdin.write(symbol + "\n");
stdin.flush(); stdin.flush();

View file

@ -15,20 +15,19 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.utils.elf.AR; 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.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; ArrayList children;
long timestamp; long timestamp;
public BinaryArchive(IPath p) throws IOException { public BinaryArchive(IPath p) throws IOException {
path = p; super(p);
new AR(path.toOSString()).dispose(); // check file type new AR(p.toOSString()).dispose(); // check file type
children = new ArrayList(5); children = new ArrayList(5);
} }
@ -41,10 +40,10 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
if (path != null) { if (path != null) {
AR ar = null; AR ar = null;
try { try {
ar = new AR(path.toOSString()); ar = new AR(getPath().toOSString());
AR.ARHeader[] headers = ar.getHeaders(); AR.ARHeader[] headers = ar.getHeaders();
for (int i = 0; i < headers.length; i++) { for (int i = 0; i < headers.length; i++) {
IBinaryObject bin = new ARMember(path, headers[i]); IBinaryObject bin = new ARMember(getPath(), headers[i]);
children.add(bin); children.add(bin);
} }
} catch (IOException e) { } catch (IOException e) {
@ -59,13 +58,6 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
return (IBinaryObject[]) children.toArray(new IBinaryObject[0]); 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() * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
*/ */
@ -78,14 +70,14 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
*/ */
public InputStream getContents() { public InputStream getContents() {
try { try {
return new FileInputStream(path.toFile()); return new FileInputStream(getPath().toFile());
} catch (IOException e) { } catch (IOException e) {
} }
return new ByteArrayInputStream(new byte[0]); return new ByteArrayInputStream(new byte[0]);
} }
boolean hasChanged() { boolean hasChanged() {
long modif = path.toFile().lastModified(); long modif = getPath().toFile().lastModified();
boolean changed = modif != timestamp; boolean changed = modif != timestamp;
timestamp = modif; timestamp = modif;
return changed; return changed;
@ -102,4 +94,11 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
public void delete(IBinaryObject[] objs) throws IOException { public void delete(IBinaryObject[] objs) throws IOException {
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.elf.parser.BinaryFile#getAttribute()
*/
protected Attribute getAttribute() {
return null;
}
} }

View file

@ -16,15 +16,34 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
/** /**
*
*/ */
public abstract class BinaryFile extends PlatformObject implements IBinaryFile { public abstract class BinaryFile extends PlatformObject implements IBinaryFile {
protected IPath path; protected IPath path;
protected IPath addr2linePath;
protected IPath cppfiltPath;
public BinaryFile(IPath p) { public BinaryFile(IPath p) {
path = p; path = p;
} }
public void setAddr2LinePath(IPath p) {
addr2linePath = p;
}
public IPath getAddr2LinePath() {
return addr2linePath;
}
public void setCPPFiltPath(IPath p) {
cppfiltPath = p;
}
public IPath getCPPFiltPath() {
return cppfiltPath;
}
/** /**
* @return * @return
*/ */

View file

@ -12,6 +12,8 @@ import java.util.ArrayList;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.core.IBinaryParser.ISymbol; import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.elf.Elf; import org.eclipse.cdt.utils.elf.Elf;
import org.eclipse.cdt.utils.elf.ElfHelper; import org.eclipse.cdt.utils.elf.ElfHelper;
import org.eclipse.cdt.utils.elf.Elf.Attribute; import org.eclipse.cdt.utils.elf.Elf.Attribute;
@ -234,25 +236,84 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
sizes = helper.getSizes(); sizes = helper.getSizes();
soname = helper.getSoname(); soname = helper.getSoname();
attribute = helper.getElf().getAttributes(); attribute = helper.getElf().getAttributes();
// Hack should be remove when Elf is clean
helper.getElf().setCppFilter(false);
addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION); Addr2line addr2line = getAddr2Line();
addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION); CPPFilt cppfilt = getCPPFilt();
addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE);
addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE); addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION, addr2line, cppfilt);
addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION, addr2line, cppfilt);
addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE, addr2line, cppfilt);
addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE, addr2line, cppfilt);
symbols.trimToSize(); symbols.trimToSize();
if (addr2line != null) {
addr2line.dispose();
}
if (cppfilt != null) {
cppfilt.dispose();
}
} }
protected void addSymbols(Elf.Symbol[] array, int type) { protected void addSymbols(Elf.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt) {
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
Symbol sym = new Symbol(); Symbol sym = new Symbol();
sym.type = type; sym.type = type;
sym.name = array[i].toString(); sym.name = array[i].toString();
if (cppfilt != null) {
try {
sym.name = cppfilt.getFunction(sym.name);
} catch (IOException e1) {
}
}
sym.addr = array[i].st_value; sym.addr = array[i].st_value;
try { try {
// This can fail if we use addr2line // This can fail if we use addr2line
// but we can safely ignore the error. // but we can safely ignore the error.
sym.filename = array[i].getFilename(); long value = sym.addr;
sym.startLine = array[i].getFuncLineNumber(); int lineno = -1;
String filename = null;
if (addr2line != null) {
// 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.
String line = null;
for (int j = 0; j <= 20; j += 4, value += j) {
line = addr2line.getLine(value);
if (line != null) {
int colon = line.lastIndexOf(':');
if (colon != -1) {
String number = line.substring(colon + 1);
if (!number.startsWith("0")) {
break; // potential candidate bail out
}
}
}
}
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);
try {
lineno = Integer.parseInt(line.substring(index1 + 1));
lineno = (lineno == 0) ? -1 : lineno;
} catch(Exception e) {
lineno = -1;
}
}
}
sym.filename = filename;
sym.startLine = lineno;
sym.endLine = sym.startLine; sym.endLine = sym.startLine;
} catch (IOException e) { } catch (IOException e) {
//e.printStackTrace(); //e.printStackTrace();
@ -265,4 +326,24 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
symbols.add(sym); symbols.add(sym);
} }
protected Addr2line getAddr2Line() {
IPath addr2LinePath = getAddr2LinePath();
Addr2line addr2line = null;
try {
addr2line = new Addr2line(addr2LinePath.toOSString(), getPath().toOSString());
} catch (IOException e1) {
}
return addr2line;
}
protected CPPFilt getCPPFilt() {
IPath cppFiltPath = getCPPFiltPath();
CPPFilt cppfilt = null;
try {
cppfilt = new CPPFilt(cppFiltPath.toOSString());
} catch (IOException e2) {
}
return cppfilt;
}
} }

View file

@ -10,7 +10,6 @@ import java.io.IOException;
import org.eclipse.cdt.core.AbstractCExtension; import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.ICExtensionReference; 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;
import org.eclipse.cdt.utils.elf.Elf.Attribute; import org.eclipse.cdt.utils.elf.Elf.Attribute;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -25,9 +24,10 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
*/ */
public IBinaryFile getBinary(IPath path) throws IOException { public IBinaryFile getBinary(IPath path) throws IOException {
if (path == null) { if (path == null) {
path = new Path(""); throw new IOException("path is null");
} }
IBinaryFile binary = null;
BinaryFile binary = null;
try { try {
Elf.Attribute attribute = Elf.getAttributes(path.toOSString()); Elf.Attribute attribute = Elf.getAttributes(path.toOSString());
if (attribute != null) { if (attribute != null) {
@ -52,8 +52,10 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
} }
} }
} catch (IOException e) { } catch (IOException e) {
binary = new ElfBinaryArchive(path); binary = new BinaryArchive(path);
} }
binary.setAddr2LinePath(getAddr2LinePath());
binary.setCPPFiltPath(getCPPFiltPath());
return binary; return binary;
} }
@ -64,13 +66,21 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
return "ELF"; return "ELF";
} }
String getAddr2LinePath() { public IPath getAddr2LinePath() {
ICExtensionReference ref = getExtensionReference(); ICExtensionReference ref = getExtensionReference();
return ref.getExtensionData("addr2line"); String value = ref.getExtensionData("addr2line");
if (value == null || value.length() == 0) {
value = "addr2line";
}
return new Path(value);
} }
String getCPPFiltPath() { public IPath getCPPFiltPath() {
ICExtensionReference ref = getExtensionReference(); ICExtensionReference ref = getExtensionReference();
return ref.getExtensionData("c++filt"); String value = ref.getExtensionData("c++filt");
if (value == null || value.length() == 0) {
value = "c++filt";
}
return new Path(value);
} }
} }