Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Enable the GNU Elf Binary Parser in the head.

Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/ChangeLog,v
retrieving revision 1.159
diff -u -r1.159 ChangeLog
--- ChangeLog	1 Oct 2003 22:15:34 -0000	1.159
+++ ChangeLog	6 Oct 2003 20:14:37 -0000
@@ -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
Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/plugin.xml,v
retrieving revision 1.34
diff -u -r1.34 plugin.xml
--- plugin.xml	1 Oct 2003 20:21:58 -0000	1.34
+++ plugin.xml	6 Oct 2003 20:14:37 -0000
@@ -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"
Index: utils/org/eclipse/cdt/utils/Addr2line.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java,v
retrieving revision 1.1
diff -u -r1.1 Addr2line.java
--- utils/org/eclipse/cdt/utils/Addr2line.java	26 Jun 2002 20:38:33 -0000	1.1
+++ utils/org/eclipse/cdt/utils/Addr2line.java	6 Oct 2003 20:14:38 -0000
@@ -18,21 +18,25 @@
 	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;
 		}
 	}
 
Index: utils/org/eclipse/cdt/utils/CPPFilt.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CPPFilt.java,v
retrieving revision 1.2
diff -u -r1.2 CPPFilt.java
--- utils/org/eclipse/cdt/utils/CPPFilt.java	11 Mar 2003 20:03:16 -0000	1.2
+++ utils/org/eclipse/cdt/utils/CPPFilt.java	6 Oct 2003 20:14:38 -0000
@@ -17,13 +17,17 @@
 	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 {
Index: utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java,v
retrieving revision 1.1
diff -u -r1.1 BinaryArchive.java
--- utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java	17 Sep 2003 02:11:05 -0000	1.1
+++ utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java	6 Oct 2003 20:14:38 -0000
@@ -15,20 +15,19 @@
 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 @@
 			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) {
@@ -60,13 +59,6 @@
 	}
 
 	/**
-	 * @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() {
@@ -78,14 +70,14 @@
 	 */
 	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;
@@ -100,6 +92,13 @@
 	 * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[])
 	 */
 	public void delete(IBinaryObject[] objs) throws IOException {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.utils.elf.parser.BinaryFile#getAttribute()
+	 */
+	protected Attribute getAttribute() {
+		return null;
 	}
 
 }
Index: utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java,v
retrieving revision 1.1
diff -u -r1.1 BinaryFile.java
--- utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java	17 Sep 2003 02:11:05 -0000	1.1
+++ utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java	6 Oct 2003 20:14:38 -0000
@@ -16,13 +16,32 @@
 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;
 	}
 
 	/**
Index: utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java,v
retrieving revision 1.1
diff -u -r1.1 BinaryObject.java
--- utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java	17 Sep 2003 02:11:05 -0000	1.1
+++ utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java	6 Oct 2003 20:14:39 -0000
@@ -12,6 +12,8 @@
 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 @@
 		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();
@@ -263,6 +324,26 @@
 
 	protected void addSymbol(Symbol 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;
 	}
 
 }
Index: utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java,v
retrieving revision 1.1
diff -u -r1.1 GNUElfParser.java
--- utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java	17 Sep 2003 02:11:05 -0000	1.1
+++ utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java	6 Oct 2003 20:14:39 -0000
@@ -10,7 +10,6 @@
 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 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 @@
 				}
 			}
 		} catch (IOException e) {
-			binary = new ElfBinaryArchive(path);
+			binary = new BinaryArchive(path);
 		}
+		binary.setAddr2LinePath(getAddr2LinePath());
+		binary.setCPPFiltPath(getCPPFiltPath());
 		return binary;
 	}
 
@@ -64,13 +66,21 @@
 		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);
 	}
 }



Back to the top