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
Changed DeltaProcessor.updateDependencies to use the CModelManager

View file

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

View file

@ -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;
}
}

View file

@ -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();

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.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);
}
@ -41,10 +40,10 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
if (path != null) {
AR ar = null;
try {
ar = new AR(path.toOSString());
ar = new AR(getPath().toOSString());
AR.ARHeader[] headers = ar.getHeaders();
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);
}
} catch (IOException e) {
@ -59,13 +58,6 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
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()
*/
@ -78,14 +70,14 @@ public class BinaryArchive extends PlatformObject implements IBinaryArchive {
*/
public InputStream getContents() {
try {
return new FileInputStream(path.toFile());
return new FileInputStream(getPath().toFile());
} catch (IOException e) {
}
return new ByteArrayInputStream(new byte[0]);
}
boolean hasChanged() {
long modif = path.toFile().lastModified();
long modif = getPath().toFile().lastModified();
boolean changed = modif != timestamp;
timestamp = modif;
return changed;
@ -102,4 +94,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;
}
}

View file

@ -16,15 +16,34 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.PlatformObject;
/**
*
*/
public abstract class BinaryFile extends PlatformObject implements IBinaryFile {
protected IPath path;
protected IPath addr2linePath;
protected IPath cppfiltPath;
public BinaryFile(IPath 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
*/

View file

@ -12,6 +12,8 @@ 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.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.elf.Elf;
import org.eclipse.cdt.utils.elf.ElfHelper;
import org.eclipse.cdt.utils.elf.Elf.Attribute;
@ -234,25 +236,84 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
sizes = helper.getSizes();
soname = helper.getSoname();
attribute = helper.getElf().getAttributes();
// 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);
Addr2line addr2line = getAddr2Line();
CPPFilt cppfilt = getCPPFilt();
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();
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++) {
Symbol sym = new Symbol();
sym.type = type;
sym.name = array[i].toString();
if (cppfilt != null) {
try {
sym.name = cppfilt.getFunction(sym.name);
} catch (IOException e1) {
}
}
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();
long value = sym.addr;
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;
} catch (IOException e) {
//e.printStackTrace();
@ -265,4 +326,24 @@ public class BinaryObject extends BinaryFile implements IBinaryObject {
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.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;
@ -25,9 +24,10 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
*/
public IBinaryFile getBinary(IPath path) throws IOException {
if (path == null) {
path = new Path("");
throw new IOException("path is null");
}
IBinaryFile binary = null;
BinaryFile binary = null;
try {
Elf.Attribute attribute = Elf.getAttributes(path.toOSString());
if (attribute != null) {
@ -52,8 +52,10 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
}
}
} catch (IOException e) {
binary = new ElfBinaryArchive(path);
binary = new BinaryArchive(path);
}
binary.setAddr2LinePath(getAddr2LinePath());
binary.setCPPFiltPath(getCPPFiltPath());
return binary;
}
@ -64,13 +66,21 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser {
return "ELF";
}
String getAddr2LinePath() {
public IPath getAddr2LinePath() {
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();
return ref.getExtensionData("c++filt");
String value = ref.getExtensionData("c++filt");
if (value == null || value.length() == 0) {
value = "c++filt";
}
return new Path(value);
}
}