From 4a143b03a833ed764258cb312684fda45b653e87 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Wed, 8 Oct 2003 18:58:15 +0000 Subject: [PATCH] More work done to clean the GNU Elf Binary Parser --- .../org/eclipse/cdt/utils/Addr2line.java | 50 ++++++++++++- .../cdt/utils/elf/parser/ARMember.java | 17 +++-- .../cdt/utils/elf/parser/BinaryArchive.java | 15 ++-- .../utils/elf/parser/BinaryExecutable.java | 15 ++-- .../cdt/utils/elf/parser/BinaryFile.java | 15 ++-- .../cdt/utils/elf/parser/BinaryObject.java | 73 +++++-------------- .../cdt/utils/elf/parser/BinaryShared.java | 15 ++-- .../cdt/utils/elf/parser/ElfParser.java | 70 ++++++++++++++++++ .../cdt/utils/elf/parser/GNUElfParser.java | 66 +++++------------ .../eclipse/cdt/utils/elf/parser/Symbol.java | 39 ++++++++-- 10 files changed, 242 insertions(+), 133 deletions(-) create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java index 4d705175018..588cdd79877 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java @@ -50,14 +50,58 @@ public class Addr2line { return lastsymbol; } + /** + * The format of the output: + * addr2line -C -f -e hello + * 08048442 + * main + * hello.c:39 + */ + public String getFileName(long address) throws IOException { + String filename = null; + String line = getLine(address); + int index1, index2; + if (line != null && (index1 = line.lastIndexOf(':')) != -1) { + // we do this because addr2line on win produces + // + index2 = line.indexOf(':'); + if (index1 == index2) { + index2 = 0; + } else { + index2--; + } + filename = line.substring(index2, index1); + } + return filename; + } + + /** + * The format of the output: + * addr2line -C -f -e hello + * 08048442 + * main + * hello.c:39 + */ + public int getLineNumber(long address) throws IOException { + int lineno = -1; + String line = getLine(address); + int colon; + if (line != null && (colon = line.lastIndexOf(':')) != -1) { + try { + lineno = Integer.parseInt(line.substring(colon + 1)); + lineno = (lineno == 0) ? -1 : lineno; + } catch(Exception e) { + } + } + return lineno; + } + public void dispose() { try { - //stdin.write(-1); stdout.close(); stdin.close(); addr2line.getErrorStream().close(); - } - catch (IOException e) { + } catch (IOException e) { } addr2line.destroy(); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java index c2e55f311d1..98a3ad40e7e 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ARMember.java @@ -1,10 +1,15 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ 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; @@ -60,7 +65,7 @@ public class ARMember extends BinaryObject { protected void addSymbols(Elf.Symbol[] array, int type) { for (int i = 0; i < array.length; i++) { - Symbol sym = new Symbol(); + Symbol sym = new Symbol(this); sym.type = type; sym.name = array[i].toString(); sym.addr = array[i].st_value; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java index 2c39d5cebda..9c766240684 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryArchive.java @@ -1,10 +1,15 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ 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; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryExecutable.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryExecutable.java index b443c0e70a5..ae64ee3d5a4 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryExecutable.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryExecutable.java @@ -1,10 +1,15 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ package org.eclipse.cdt.utils.elf.parser; -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ - import java.io.IOException; import java.util.ArrayList; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java index 42329f883c0..122537f5287 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryFile.java @@ -1,10 +1,15 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ 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; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java index ba2659e7c40..a0dc9f8d66d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryObject.java @@ -1,7 +1,13 @@ -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ package org.eclipse.cdt.utils.elf.parser; import java.io.FileInputStream; @@ -258,7 +264,7 @@ public class BinaryObject extends BinaryFile implements IBinaryObject { protected void addSymbols(Elf.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt) { for (int i = 0; i < array.length; i++) { - Symbol sym = new Symbol(); + Symbol sym = new Symbol(this); sym.type = type; sym.name = array[i].toString(); if (cppfilt != null) { @@ -268,55 +274,16 @@ public class BinaryObject extends BinaryFile implements IBinaryObject { } } sym.addr = array[i].st_value; - try { - // This can fail if we use addr2line - // but we can safely ignore the error. - 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 - // - 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 = null; + sym.startLine = -1; + sym.endLine = sym.startLine; + if (addr2line != null) { + try { + sym.filename = addr2line.getFileName(sym.addr); + sym.startLine = addr2line.getLineNumber(sym.addr); + sym.endLine = addr2line.getLineNumber(sym.addr + array[i].st_size - 1); + } catch (IOException e) { } - sym.filename = filename; - sym.startLine = lineno; - sym.endLine = sym.startLine; - } catch (IOException e) { - //e.printStackTrace(); } addSymbol(sym); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryShared.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryShared.java index cb8c0299448..66eba7e189f 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryShared.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/BinaryShared.java @@ -1,10 +1,15 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ 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; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java new file mode 100644 index 00000000000..348ff6d22cf --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java @@ -0,0 +1,70 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.elf.parser; + +import java.io.IOException; + +import org.eclipse.cdt.core.AbstractCExtension; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.utils.elf.Elf; +import org.eclipse.cdt.utils.elf.Elf.Attribute; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class ElfParser extends AbstractCExtension implements IBinaryParser { + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath) + */ + public IBinaryFile getBinary(IPath path) throws IOException { + if (path == null) { + throw new IOException("path is null"); + } + + BinaryFile 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 BinaryArchive(path); + } + return binary; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat() + */ + public String getFormat() { + return "ELF"; + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java index 5344b2e706d..4f4322a6ebe 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfParser.java @@ -1,61 +1,35 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ 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.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 { +public class GNUElfParser extends ElfParser implements IBinaryParser { /** * @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath) */ public IBinaryFile getBinary(IPath path) throws IOException { - if (path == null) { - throw new IOException("path is null"); + IBinaryFile binary = super.getBinary(path); + if (binary instanceof BinaryFile) { + ((BinaryFile)binary).setAddr2LinePath(getAddr2LinePath()); + ((BinaryFile)binary).setCPPFiltPath(getCPPFiltPath()); } - - BinaryFile 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 BinaryArchive(path); - } - binary.setAddr2LinePath(getAddr2LinePath()); - binary.setCPPFiltPath(getCPPFiltPath()); return binary; } @@ -63,23 +37,23 @@ public class GNUElfParser extends AbstractCExtension implements IBinaryParser { * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat() */ public String getFormat() { - return "ELF"; + return "GNU ELF"; } public IPath getAddr2LinePath() { ICExtensionReference ref = getExtensionReference(); - String value = ref.getExtensionData("addr2line"); + String value = ref.getExtensionData("addr2line"); //$NON-NLS-1 if (value == null || value.length() == 0) { - value = "addr2line"; + value = "addr2line"; //$NON-NLS-1 } return new Path(value); } public IPath getCPPFiltPath() { ICExtensionReference ref = getExtensionReference(); - String value = ref.getExtensionData("c++filt"); + String value = ref.getExtensionData("c++filt"); //$NON-NLS-1 if (value == null || value.length() == 0) { - value = "c++filt"; + value = "c++filt"; //$NON-NLS-1 } return new Path(value); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java index ad88072c4d7..263b0d1d98f 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/Symbol.java @@ -1,14 +1,24 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ package org.eclipse.cdt.utils.elf.parser; -import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import java.io.IOException; -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr2line; public class Symbol implements ISymbol { + BinaryObject binary; + public String filename; public int startLine; public int endLine; @@ -16,6 +26,9 @@ public class Symbol implements ISymbol { public String name; public int type; + public Symbol(BinaryObject bin) { + binary = bin; + } /** * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename() */ @@ -59,4 +72,20 @@ public class Symbol implements ISymbol { return startLine; } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getLineNumber(long) + */ + public int getLineNumber(long offset) { + int line = -1; + try { + Addr2line addr2line = binary.getAddr2Line(); + if (addr2line != null) { + line = addr2line.getLineNumber(addr + offset); + addr2line.dispose(); + } + } catch (IOException e) { + } + return line; + } + }