diff options
Diffstat (limited to 'core/org.eclipse.cdt.core/utils/org/eclipse/cdt')
82 files changed, 3687 insertions, 909 deletions
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java index 5b3c977af68..49f3da0bc47 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java @@ -19,11 +19,11 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.Collections; import java.util.Map; +import java.util.Objects; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; -import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.utils.WindowsRegistry; import org.eclipse.core.runtime.IPath; @@ -251,8 +251,8 @@ public class Cygwin { String envCygwinHomeValue = varCygwinHome != null ? varCygwinHome.getValue() : null; // isCygwinLocationCached is used to figure fact of caching when all cached objects are null - if (isCygwinLocationCached && CDataUtil.objectsEqual(envPathValue, envPathValueCached) - && CDataUtil.objectsEqual(envCygwinHomeValue, envCygwinHomeValueCached)) { + if (isCygwinLocationCached && Objects.equals(envPathValue, envPathValueCached) + && Objects.equals(envCygwinHomeValue, envCygwinHomeValueCached)) { return cygwinLocation; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/MinGW.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/MinGW.java index 6ac686ba6f0..5a2d1cd604a 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/MinGW.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/MinGW.java @@ -16,13 +16,13 @@ package org.eclipse.cdt.internal.core; import java.io.File; import java.util.Collections; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.WeakHashMap; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; -import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.utils.WindowsRegistry; import org.eclipse.core.runtime.IPath; @@ -298,8 +298,8 @@ public class MinGW { // isMinGWLocationCached is used to figure fact of caching when all // cached objects are null - if (isMinGWLocationCached && CDataUtil.objectsEqual(envPathValue, envPathValueCached) - && CDataUtil.objectsEqual(envMinGWHomeValue, envMinGWHomeValueCached)) { + if (isMinGWLocationCached && Objects.equals(envPathValue, envPathValueCached) + && Objects.equals(envMinGWHomeValue, envMinGWHomeValueCached)) { return minGWLocation; } @@ -337,7 +337,7 @@ public class MinGW { // isMSysLocationCached is used to figure whether it was cached when all // cached objects are null - if (isMSysLocationCached && CDataUtil.objectsEqual(envMinGWHomeValue, envMinGWHomeValueCached_msys)) { + if (isMSysLocationCached && Objects.equals(envMinGWHomeValue, envMinGWHomeValueCached_msys)) { return mSysLocation; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java index 691319fe9e6..5dda1e8c309 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java @@ -53,7 +53,7 @@ import org.w3c.dom.NodeList; public class XmlUtil { private static final String ENCODING_UTF_8 = "UTF-8"; //$NON-NLS-1$ private static final String EOL_XML = "\n"; //$NON-NLS-1$ - private static final String DEFAULT_IDENT = "\t"; //$NON-NLS-1$ + private static final String DEFAULT_INDENT = "\t"; //$NON-NLS-1$ private static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$ /** @@ -133,10 +133,15 @@ public class XmlUtil { * to pretty print XML. This method prepares DOM {@code Document} for the transformer * to be pretty printed, i.e. providing proper indentations for enclosed tags. * + * Note, while this was originally a workaround, the user community of CDT + * has come to expect the format of the .cproject file and others to be + * unchanging, therefore CDT always uses this and does not attempt + * to format with the Transformer. + * * @param doc - DOM document to be pretty printed */ public static void prettyFormat(Document doc) { - prettyFormat(doc, DEFAULT_IDENT); + prettyFormat(doc, DEFAULT_INDENT); } /** @@ -144,14 +149,19 @@ public class XmlUtil { * to pretty print XML. This method prepares DOM {@code Document} for the transformer * to be pretty printed, i.e. providing proper indentations for enclosed tags. * + * Note, while this was originally a workaround, the user community of CDT + * has come to expect the format of the .cproject file and others to be + * unchanging, therefore CDT always uses this and does not attempt + * to format with the Transformer. + * * @param doc - DOM document to be pretty printed - * @param ident - custom indentation as a string of white spaces + * @param indent - custom indentation as a string of white spaces */ - public static void prettyFormat(Document doc, String ident) { + public static void prettyFormat(Document doc, String indent) { doc.normalize(); Element documentElement = doc.getDocumentElement(); if (documentElement != null) { - prettyFormat(documentElement, "", ident); //$NON-NLS-1$ + prettyFormat(documentElement, "", indent); //$NON-NLS-1$ } } @@ -159,17 +169,17 @@ public class XmlUtil { * The method inserts end-of-line+indentation Text nodes where indentation is necessary. * * @param node - node to be pretty formatted - * @param identLevel - initial indentation level of the node - * @param ident - additional indentation inside the node + * @param indentLevel - initial indentation level of the node + * @param indent - additional indentation inside the node */ - private static void prettyFormat(Node node, String identLevel, String ident) { + private static void prettyFormat(Node node, String indentLevel, String indent) { NodeList nodelist = node.getChildNodes(); int iStart = 0; Node item = nodelist.item(0); if (item != null) { short type = item.getNodeType(); if (type == Node.ELEMENT_NODE || type == Node.COMMENT_NODE) { - Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + identLevel + ident); + Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + indentLevel + indent); node.insertBefore(newChild, item); iStart = 1; } @@ -180,25 +190,25 @@ public class XmlUtil { short type = item.getNodeType(); if (type == Node.TEXT_NODE && item.getNodeValue().trim().length() == 0) { if (i + 1 < nodelist.getLength()) { - item.setNodeValue(EOL_XML + identLevel + ident); + item.setNodeValue(EOL_XML + indentLevel + indent); } else { - item.setNodeValue(EOL_XML + identLevel); + item.setNodeValue(EOL_XML + indentLevel); } } else if (type == Node.ELEMENT_NODE) { - prettyFormat(item, identLevel + ident, ident); + prettyFormat(item, indentLevel + indent, indent); if (i + 1 < nodelist.getLength()) { Node nextItem = nodelist.item(i + 1); if (nextItem != null) { short nextType = nextItem.getNodeType(); if (nextType == Node.ELEMENT_NODE || nextType == Node.COMMENT_NODE) { - Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + identLevel + ident); + Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + indentLevel + indent); node.insertBefore(newChild, nextItem); i++; continue; } } } else { - Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + identLevel); + Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + indentLevel); node.appendChild(newChild); i++; continue; @@ -275,22 +285,40 @@ public class XmlUtil { * * @param doc - DOM Document to serialize. * @param uriLocation - URI of the file. + * + * @throws IOException in case of problems with file I/O + * @throws TransformerException in case of problems with XML output + */ + public static void serializeXml(Document doc, URI uriLocation) + throws IOException, TransformerException, CoreException { + serializeXmlInternal(doc, uriLocation, null); + } + + /** + * Serialize XML Document into a file.<br/> + * Note: clients should synchronize access to this method. + * + * @param doc - DOM Document to serialize. + * @param uriLocation - URI of the file. * @param lineSeparator - line separator. + * Note: This will serialize in pretty format * * @throws IOException in case of problems with file I/O * @throws TransformerException in case of problems with XML output */ public static void serializeXml(Document doc, URI uriLocation, String lineSeparator) throws IOException, TransformerException, CoreException { - XmlUtil.prettyFormat(doc); + serializeXmlInternal(doc, uriLocation, lineSeparator); + } + private static void serializeXmlInternal(Document doc, URI uriLocation, String lineSeparator) + throws IOException, TransformerException, CoreException { java.io.File storeFile = new java.io.File(uriLocation); if (!storeFile.exists()) { storeFile.createNewFile(); } - String utfString = new String(toByteArray(doc), ENCODING_UTF_8); - utfString = XmlUtil.replaceLineSeparatorInternal(utfString, lineSeparator); + String utfString = lineSeparator != null ? toString(doc, lineSeparator) : toString(doc); FileOutputStream output = getFileOutputStreamWorkaround(storeFile); output.write(utfString.getBytes(ENCODING_UTF_8)); @@ -340,14 +368,13 @@ public class XmlUtil { * @throws CoreException if something goes wrong. */ private static byte[] toByteArray(Document doc) throws CoreException { - XmlUtil.prettyFormat(doc); - try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ transformer.setOutputProperty(OutputKeys.ENCODING, ENCODING_UTF_8); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + // Indentation is done with XmlUtil.prettyFormat(doc). + transformer.setOutputProperty(OutputKeys.INDENT, "no"); //$NON-NLS-1$ DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(stream); transformer.transform(source, result); @@ -376,6 +403,30 @@ public class XmlUtil { } /** + * <b>Do not use outside of CDT.</b> + * + * This method is used to workaround changing implementations of {@link javax.xml.transform.Transformer} + * to maintain the same file content for CDT users. See {@link #prettyFormat(Document)} and Bug 565628 + * + * This method inserts a newline between the <?... xml ... ?> and first tag in the document + * + * @noreference This method is not intended to be referenced by clients. + * This is an internal method which ideally should be made private. + */ + public static String insertNewlineAfterXMLVersionTag(String string, String lineSeparator) { + if (string == null) { + return null; + } + + int indexOf = string.indexOf("?><"); //$NON-NLS-1$ + if (indexOf < 0 || string.length() < indexOf + 2) { + return string; + } + + return string.substring(0, indexOf + 2) + lineSeparator + string.substring(indexOf + 2); + } + + /** * Serialize XML Document into a workspace file.<br/> * Note: clients should synchronize access to this method. * @@ -384,12 +435,9 @@ public class XmlUtil { * @throws CoreException if something goes wrong. */ public static void serializeXml(Document doc, IFile file) throws CoreException { - XmlUtil.prettyFormat(doc); - try { - String utfString = new String(toByteArray(doc), ENCODING_UTF_8); String lineSeparator = Util.getLineSeparator(file); - utfString = XmlUtil.replaceLineSeparatorInternal(utfString, lineSeparator); + String utfString = toString(doc, lineSeparator); byte[] newContents = utfString.getBytes(ENCODING_UTF_8); InputStream input = new ByteArrayInputStream(newContents); @@ -429,12 +477,36 @@ public class XmlUtil { /** * Serialize XML Document into a string. + * Note: This will return a non-pretty formatted string * * @param doc - DOM Document to serialize. * @return XML as a String. * @throws CoreException if something goes wrong. */ public static String toString(Document doc) throws CoreException { - return new String(toByteArray(doc)); + try { + return new String(toByteArray(doc), ENCODING_UTF_8); + } catch (UnsupportedEncodingException e) { + throw new CoreException(CCorePlugin.createStatus(Messages.XmlUtil_InternalErrorSerializing, e)); + } + } + + /** + * Serialize XML Document into a pretty formatted string. + * Note: This will return a pretty formatted string + * + * @param doc - DOM Document to serialize. + * @param lineSeparator - line separator + * @return XML as a pretty formatted String. + * @throws CoreException if something goes wrong. + */ + public static String toString(Document doc, String lineSeparator) throws CoreException { + XmlUtil.prettyFormat(doc); + + String utfString = toString(doc); + utfString = XmlUtil.replaceLineSeparatorInternal(utfString, lineSeparator); + utfString = XmlUtil.insertNewlineAfterXMLVersionTag(utfString, lineSeparator); + + return utfString; } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/AR.java index b7ddf28feb8..5cdc825377d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/AR.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/AR.java @@ -30,13 +30,18 @@ import org.eclipse.cdt.core.CCorePlugin; * class operations. * @see ARHeader */ -public class AR { +public class AR implements AutoCloseable { protected String filename; protected ERandomAccessFile efile; protected long strtbl_pos = -1; private ARHeader[] headers; + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (efile != null) { @@ -197,11 +202,10 @@ public class AR { efile.seek(obj_offset); efile.read(temp); } else { - efile = new ERandomAccessFile(filename, "r"); //$NON-NLS-1$ - efile.seek(obj_offset); - efile.read(temp); - efile.close(); - efile = null; + try (ERandomAccessFile tempfile = new ERandomAccessFile(filename, "r")) { //$NON-NLS-1$ + tempfile.seek(obj_offset); + tempfile.read(temp); + } } return temp; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java index 41ae8f30745..5eb844b6ad3 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java @@ -20,65 +20,41 @@ import org.eclipse.cdt.core.IAddressFactory2; public class Addr32Factory implements IAddressFactory2 { - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#getZero() - */ @Override public IAddress getZero() { return Addr32.ZERO; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#getMax() - */ @Override public IAddress getMax() { return Addr32.MAX; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#createAddress(java.lang.String) - */ @Override public IAddress createAddress(String addr) { return createAddress(addr, true); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory2#createAddress(java.lang.String, boolean) - */ @Override public IAddress createAddress(String addr, boolean truncate) { return new Addr32(addr, truncate); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#createAddress(java.lang.String, int) - */ @Override public IAddress createAddress(String addr, int radix) { return createAddress(addr, radix, true); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory2#createAddress(java.lang.String, int, boolean) - */ @Override public IAddress createAddress(String addr, int radix, boolean truncate) { return new Addr32(addr, radix, truncate); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#createAddress(java.math.BigInteger) - */ @Override public IAddress createAddress(BigInteger addr) { return createAddress(addr, true); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory2#createAddress(java.math.BigInteger, boolean) - */ @Override public IAddress createAddress(BigInteger addr, boolean truncate) { return new Addr32(addr.longValue(), truncate); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java index 7477ade9b47..a03b91a3be4 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java @@ -20,65 +20,41 @@ import org.eclipse.cdt.core.IAddressFactory2; public class Addr64Factory implements IAddressFactory2 { - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#getZero() - */ @Override public IAddress getZero() { return Addr64.ZERO; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#getMax() - */ @Override public IAddress getMax() { return Addr64.MAX; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#createAddress(java.lang.String) - */ @Override public IAddress createAddress(String addr) { return createAddress(addr, true); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory2#createAddress(java.lang.String, boolean) - */ @Override public IAddress createAddress(String addr, boolean truncate) { return new Addr64(addr, truncate); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#createAddress(java.lang.String, int) - */ @Override public IAddress createAddress(String addr, int radix) { return createAddress(addr, radix, true); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory2#createAddress(java.lang.String, int, boolean) - */ @Override public IAddress createAddress(String addr, int radix, boolean truncate) { return new Addr64(addr, radix, truncate); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory#createAddress(java.math.BigInteger) - */ @Override public IAddress createAddress(BigInteger addr) { return createAddress(addr, true); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IAddressFactory2#createAddress(java.math.BigInteger, boolean) - */ @Override public IAddress createAddress(BigInteger addr, boolean truncate) { return new Addr64(addr, truncate); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java index fa8489d8a6d..8e6cfb4892d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java @@ -48,9 +48,6 @@ public abstract class BinaryObjectAdapter extends BinaryFile implements IBinaryO super(parser, path, type); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbol(long) - */ @Override public ISymbol getSymbol(IAddress addr) { ISymbol[] syms = getSymbols(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java index 7d481c5fb48..5d91d7faa10 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java @@ -16,6 +16,7 @@ package org.eclipse.cdt.utils; import java.util.ArrayList; +import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.service.environment.Constants; /** @@ -49,11 +50,11 @@ public class CommandLineUtil { * Parsing arguments in a shell style. i.e. * * <pre> - * ["a b c" d] -> [[a b c],[d]] - * [a d] -> [[a],[d]] - * ['"quoted"'] -> [["quoted"]] - * [\\ \" \a] -> [[\],["],[a]] - * ["str\\str\a"] -> [[str\str\a]] + * ["a b c" d] -> [[a b c],[d]] + * [a d] -> [[a],[d]] + * ['"quoted"'] -> [["quoted"]] + * [\\ \" \a] -> [[\],["],[a]] + * ["str\\str\a"] -> [[str\str\a]] * </pre> * * @param line @@ -165,11 +166,11 @@ public class CommandLineUtil { * Parsing arguments in a cmd style. i.e. * * <pre> - * ["a b c" d] -> [[a b c],[d]] - * [a d] -> [[a],[d]] - * ['"quoted"'] -> [['quoted']] - * [\\ \" \a] -> [[\\],["],[\a]] - * ["str\\str\a"] -> [[str\\str\a]] + * ["a b c" d] -> [[a b c],[d]] + * [a d] -> [[a],[d]] + * ['"quoted"'] -> [['quoted']] + * [\\ \" \a] -> [[\\],["],[\a]] + * ["str\\str\a"] -> [[str\\str\a]] * </pre> * * @param line diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java index 45f193cc385..ff46be844b3 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java @@ -23,16 +23,10 @@ import org.eclipse.core.runtime.Path; public class DefaultGnuToolFactory implements IGnuToolFactory { protected ICExtension fExtension; - /** - * - */ public DefaultGnuToolFactory(ICExtension ext) { fExtension = ext; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.IGnuToolProvider#getAddr2line(org.eclipse.core.runtime.IPath) - */ @Override public Addr2line getAddr2line(IPath path) { IPath addr2LinePath = getAddr2linePath(); @@ -46,9 +40,6 @@ public class DefaultGnuToolFactory implements IGnuToolFactory { return addr2line; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.IGnuToolProvider#getCPPFilt() - */ @Override public CPPFilt getCPPFilt() { IPath cppFiltPath = getCPPFiltPath(); @@ -62,9 +53,6 @@ public class DefaultGnuToolFactory implements IGnuToolFactory { return cppfilt; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.IGnuToolProvider#getObjdump(org.eclipse.core.runtime.IPath) - */ @Override public Objdump getObjdump(IPath path) { IPath objdumpPath = getObjdumpPath(); @@ -79,9 +67,6 @@ public class DefaultGnuToolFactory implements IGnuToolFactory { return objdump; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.IGnuToolProvider#getObjdump(org.eclipse.core.runtime.IPath) - */ @Override public NM getNM(IPath path) { IPath nmPath = getNMPath(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/ERandomAccessFile.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/ERandomAccessFile.java index c88dba345c9..24c53c89d69 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/ERandomAccessFile.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/ERandomAccessFile.java @@ -17,6 +17,7 @@ import java.io.EOFException; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.ByteOrder; /** * @noextend This class is not intended to be subclassed by clients. @@ -25,13 +26,15 @@ public class ERandomAccessFile extends RandomAccessFile { private boolean isle; private long ptr_offset; int val[] = new int[4]; + private final String path; public ERandomAccessFile(String file, String mode) throws IOException { super(file, mode); + path = file; } public ERandomAccessFile(File file, String mode) throws IOException { - super(file, mode); + this(file.getPath(), mode); } public void setEndian(boolean le) { @@ -100,6 +103,14 @@ public class ERandomAccessFile extends RandomAccessFile { super.seek(offset); } + /** + * Get the path of the file reader + * @since 7.0 + */ + public String getPath() { + return path; + } + @Override public long getFilePointer() throws IOException { long ptr = super.getFilePointer(); @@ -112,4 +123,13 @@ public class ERandomAccessFile extends RandomAccessFile { long real_pos = pos + ptr_offset; super.seek(real_pos); } + + /** + * Get the byte order of the file + * @return {@link ByteOrder#LITTLE_ENDIAN} or {@link ByteOrder#BIG_ENDIAN} + * @since 7.0 + */ + public ByteOrder order() { + return isle ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Platform.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Platform.java deleted file mode 100644 index cedac0fa86f..00000000000 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Platform.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2011 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - Initial API and implementation (Corey Ashford) - * Anton Leherbauer (Wind River Systems) - * Markus Schorn (Wind River Systems) - *******************************************************************************/ - -package org.eclipse.cdt.utils; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import org.eclipse.cdt.core.CCorePlugin; -import org.osgi.framework.Bundle; - -/** - * @noinstantiate This class is not intended to be instantiated by clients. - */ -public final class Platform { - - // This class duplicates all of the methods in org.eclipse.core.runtime.Platform - // that are used by the CDT. getOSArch() needs a few tweaks because the value returned - // by org.eclipse.core.runtime.Platform.getOSArch represents what the JVM thinks the - // architecture is. In some cases, we may actually be running on a 64-bit machine, - // but the JVM thinks it's running on a 32-bit machine. Without this change, the CDT - // will not handle 64-bit executables on some ppc64. This method could easily be - // extended to handle other platforms with similar issues. - // - // Unfortunately, the org.eclipse.core.runtime.Platform is final, so we cannot just - // extend it and and then override the getOSArch method, so getBundle and getOS just - // encapsulate calls to the same methods in org.eclipse.core.runtime.Platform. - - public static final String OS_LINUX = org.eclipse.core.runtime.Platform.OS_LINUX; - - private static String cachedArch = null; - - public static Bundle getBundle(String symbolicName) { - return org.eclipse.core.runtime.Platform.getBundle(symbolicName); - } - - public static String getOS() { - return org.eclipse.core.runtime.Platform.getOS(); - } - - public static String getOSArch() { - if (cachedArch == null) { - String arch = org.eclipse.core.runtime.Platform.getOSArch(); - if (arch.equals(org.eclipse.core.runtime.Platform.ARCH_PPC)) { - // Determine if the platform is actually a ppc64 machine - Process unameProcess; - String cmd[] = { "uname", "-p" }; //$NON-NLS-1$//$NON-NLS-2$ - - try { - unameProcess = Runtime.getRuntime().exec(cmd); - - InputStreamReader inputStreamReader = new InputStreamReader(unameProcess.getInputStream()); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - String unameOutput = bufferedReader.readLine(); - if (unameOutput != null) { - arch = unameOutput; - } - bufferedReader.close(); - unameProcess.waitFor(); // otherwise the process becomes a zombie - } catch (IOException e) { - CCorePlugin.log(e); - } catch (InterruptedException exc) { - // restore interrupted flag - Thread.currentThread().interrupt(); - } - } else if (arch.equals(org.eclipse.core.runtime.Platform.ARCH_X86)) { - // Determine if the platform is actually a x86_64 machine - Process unameProcess; - String cmd[]; - if (org.eclipse.core.runtime.Platform.OS_WIN32.equals(getOS())) { - cmd = new String[] { "cmd", "/d", "/c", "set", "PROCESSOR_ARCHITECTURE" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ - } else { - // We don't use "uname -p" since it returns "unknown" on some Linux systems. - cmd = new String[] { "uname", "-m" }; //$NON-NLS-1$//$NON-NLS-2$ - } - - try { - unameProcess = Runtime.getRuntime().exec(cmd); - unameProcess.getOutputStream().close(); - unameProcess.getErrorStream().close(); - InputStreamReader inputStreamReader = new InputStreamReader(unameProcess.getInputStream()); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - String unameOutput = bufferedReader.readLine(); - if (unameOutput != null && unameOutput.endsWith("64")) { //$NON-NLS-1$ - arch = org.eclipse.core.runtime.Platform.ARCH_X86_64; - } - bufferedReader.close(); - unameProcess.waitFor(); // otherwise the process becomes a zombie - } catch (IOException e) { - CCorePlugin.log(e); - } catch (InterruptedException exc) { - // restore interrupted flag - Thread.currentThread().interrupt(); - } - } - cachedArch = arch; - } - return cachedArch; - } -} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java index 29e603b099e..381365fcaf3 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java @@ -53,33 +53,21 @@ public class Symbol implements ISymbol { this.sourceFile = null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getBinarObject() - */ @Override public IBinaryObject getBinaryObject() { return binary; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getFilename() - */ @Override public IPath getFilename() { return sourceFile; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getName() - */ @Override public String getName() { return name; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getType() - */ @Override public int getType() { return type; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/CdtVariableResolver.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/CdtVariableResolver.java index 6c720512b5d..2138b69dfd1 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/CdtVariableResolver.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/CdtVariableResolver.java @@ -62,21 +62,14 @@ public class CdtVariableResolver { private static final String EMPTY_STRING = ""; //$NON-NLS-1$ public static final String VARIABLE_PREFIX = "${"; //$NON-NLS-1$ - private static final String VARIABLE_PREFIX_MASKED = "$\1"; //$NON-NLS-1$ public static final char VARIABLE_SUFFIX = '}'; - private static final char VARIABLE_SUFFIX_MASKED = '\2'; - public static final char VARIABLE_ESCAPE_CHAR = '\\'; - private static final char VARIABLE_ESCAPE_CHAR_MASKED = '\3'; - - // Regular expression fragments private static final String RE_VPREFIX = "\\$\\{"; //$NON-NLS-1$ private static final String RE_VSUFFIX = "\\}"; //$NON-NLS-1$ private static final String RE_VNAME = "[^${}]*"; //$NON-NLS-1$ - private static final String RE_BSLASH = "[\\\\]"; // *one* backslash //$NON-NLS-1$ /** * Converts list of strings to one string using given string as delimiter, - * i.e -> "string1:string2:string3" + * i.e -> "string1:string2:string3" * * @param value - list of strings to convert. * @param listDelimiter - delimiter. @@ -99,8 +92,11 @@ public class CdtVariableResolver { /** * Resolves macros of kind ${Macro} in the given string by calling the macro substitutor * for each macro reference found. Macros can be inside one another like - * ${workspace_loc:/${ProjName}/} but resolved just once. No recursive or concatenated - * macro names are allowed. It is possible to prevent macro from expanding using backslash \$. + * ${workspace_loc:/${ProjName}/} but resolved just once. No recursive + * macro names are allowed. + * It is not possible to prevent macros from expanding. + * For historical reasons (See Bug 571472), macros that are multi-line according to + * {@link Pattern}'s Line Terminators are not expanded. * * @param string - macro expression. * @param substitutor - macro resolution provider to retrieve macro values. @@ -112,44 +108,42 @@ public class CdtVariableResolver { if (string == null) { return EMPTY_STRING; } + // Bug 571472 to match historical behaviour, don't substitute multi-line strings + for (char ch : string.toCharArray()) { + if (ch == '\n' || ch == '\r' || (ch | 1) == '\u2029' || ch == '\u0085') { + return string; + } + } - final Pattern pattern = Pattern - .compile(".*?(" + RE_BSLASH + "*)(" + RE_VPREFIX + "(" + RE_VNAME + ")" + RE_VSUFFIX + ").*"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + final Pattern pattern = Pattern.compile("(\\$\\{([^${}]*)\\})"); //$NON-NLS-1$ + final String VARIABLE_PREFIX_MASKED = "$\1"; //$NON-NLS-1$ + final char VARIABLE_SUFFIX_MASKED = '\2'; StringBuilder buffer = new StringBuilder(string); int limit = string.length(); - for (Matcher matcher = pattern.matcher(buffer); matcher.matches(); matcher = pattern.matcher(buffer)) { - String bSlashes = matcher.group(1); - String macro = matcher.group(2); - String name = matcher.group(3); + Matcher matcher = pattern.matcher(buffer); + while (matcher.find()) { + String name = matcher.group(2); String resolved = name.length() > 0 ? substitutor.resolveToString(name) : EMPTY_STRING; if (resolved == null) { throw new CdtVariableException(ICdtVariableStatus.TYPE_MACRO_UNDEFINED, null, string, name); } - if (limit-- < 0) { - // to prevent incidental looping - throw new CdtVariableException(ICdtVariableStatus.TYPE_ERROR, name, matcher.group(0), resolved); - } - int nBSlashes = bSlashes.length(); - if ((nBSlashes & 1) == 1) { - // if odd number of backslashes in front of "${...}" do not expand macro - resolved = macro; + if (limit-- < 0) { + // to prevent incidental endless looping + throw new CdtVariableException(ICdtVariableStatus.TYPE_ERROR, name, string, resolved); } // Only one expansion is allowed, so hide any text interfering with macro syntax resolved = resolved.replace(VARIABLE_PREFIX, VARIABLE_PREFIX_MASKED); resolved = resolved.replace(VARIABLE_SUFFIX, VARIABLE_SUFFIX_MASKED); - buffer.replace(matcher.start(2), matcher.end(2), resolved); - // collapse and hide backslashes \\\\${Macro} -> \\MacroValue or \\\\\${Macro} -> \\${Macro} - buffer.replace(matcher.start(1), matcher.end(1), - bSlashes.substring(0, nBSlashes / 2).replace(VARIABLE_ESCAPE_CHAR, VARIABLE_ESCAPE_CHAR_MASKED)); + + buffer.replace(matcher.start(1), matcher.end(1), resolved); + matcher = pattern.matcher(buffer); } String result = buffer.toString(); - // take hidden data back result = result.replace(VARIABLE_PREFIX_MASKED, VARIABLE_PREFIX); result = result.replace(VARIABLE_SUFFIX_MASKED, VARIABLE_SUFFIX); - result = result.replace(VARIABLE_ESCAPE_CHAR_MASKED, VARIABLE_ESCAPE_CHAR); return result; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/SupplierBasedCdtVariableSubstitutor.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/SupplierBasedCdtVariableSubstitutor.java index c0aa1d2a457..a7966ebe148 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/SupplierBasedCdtVariableSubstitutor.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/cdtvariables/SupplierBasedCdtVariableSubstitutor.java @@ -62,9 +62,6 @@ public class SupplierBasedCdtVariableSubstitutor implements IVariableSubstitutor fIsList = true; } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringValue() - */ @Override public String getStringValue() throws CdtVariableException { // if(!fIsDefined) @@ -74,9 +71,6 @@ public class SupplierBasedCdtVariableSubstitutor implements IVariableSubstitutor return fStringValue; } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringListValue() - */ @Override public String[] getStringListValue() throws CdtVariableException { // if(!fIsDefined) @@ -235,9 +229,6 @@ public class SupplierBasedCdtVariableSubstitutor implements IVariableSubstitutor return result; } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#resolveToString(java.lang.String) - */ @Override public String resolveToString(String macroName) throws CdtVariableException { return resolveToString(new MacroDescriptor(macroName, fContextInfo)); @@ -274,9 +265,6 @@ public class SupplierBasedCdtVariableSubstitutor implements IVariableSubstitutor return des.fMacro != null ? resolveMacro(des.fMacro) : resolveMacro(des.fName); } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#resolveToStringList(java.lang.String) - */ @Override public String[] resolveToStringList(String macroName) throws CdtVariableException { return resolveToStringList(new MacroDescriptor(macroName, fContextInfo)); @@ -419,9 +407,6 @@ public class SupplierBasedCdtVariableSubstitutor implements IVariableSubstitutor return fResolvedMacros.remove(name); } - /* (non-Javadoc) - * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#getMacroContextInfo() - */ public IVariableContextInfo getMacroContextInfo() { return fContextInfo; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java index b418fb34fd4..9ad619ea61a 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 QNX Software Systems and others. + * Copyright (c) 2000, 2020 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.utils.coff; @@ -18,14 +19,18 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel.MapMode; +import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; -import com.ibm.icu.text.DateFormat; - +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link Coff64}. + * This class is planned for removal in next major release. + */ +@Deprecated public class Coff { public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff64.java new file mode 100644 index 00000000000..3cd29d76e47 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff64.java @@ -0,0 +1,819 @@ +/******************************************************************************* + * Copyright (c) 2000, 2020 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - Initial Coff class + * Alexander Fedorov (ArSysOp) - Bug 561992 + *******************************************************************************/ +package org.eclipse.cdt.utils.coff; + +import java.io.EOFException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel.MapMode; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; + +/** + * @since 6.9 + */ +public class Coff64 { + + public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + FileHeader filehdr; + OptionalHeader opthdr; + RandomAccessFile rfile; + long startingOffset; + byte[] string_table; + SectionHeader[] scnhdrs; + Symbol[] symbols; + + public static class FileHeader { + public final static int FILHSZ = 20; + + public final static int F_RELFLG = 0x0001; // relocation info stripped from file + public final static int F_EXEC = 0x0002; // file is executable + // (no unresolved external references) + public final static int F_LNNO = 0x0004; // line numbers stripped from file + public final static int F_LSYMS = 0x0008; // local symbols stripped from file + public final static int F_AR16WR = 0x0080; // file is 16-bit little-endian + public final static int F_AR32WR = 0x0100; // file is 32-bit little-endian + public final static int F_AR32W = 0x0200; // file is 32-bit big-endian + public final static int F_DYNLOAD = 0x1000;// rs/6000 aix: dynamically + // loadable w/imports & exports + public final static int F_SHROBJ = 0x2000; // rs/6000 aix: file is a shared object + public final static int F_DLL = 0x2000; // PE format DLL. + + public int f_magic; /* 00-01 2 bytes: magic number */ + public int f_nscns; /* 02-03 2 bytes: number of sections: 2 bytes */ + public int f_timdat; /* 04-07 4 bytes: time & date stamp */ + public int f_symptr; /* 08-11 4 bytes: file pointer to symtab */ + public int f_nsyms; /* 12-15 4 bytes: number of symtab entries */ + public int f_opthdr; /* 16-17 2 bytes: sizeof(optional hdr) */ + public int f_flags; /* 18-19 2 bytes: flags */ + + public FileHeader(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public FileHeader(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[FILHSZ]; + file.readFully(hdr); + commonSetup(hdr, true); + } + + public FileHeader(byte[] hdr, boolean little) throws EOFException { + commonSetup(hdr, little); + } + + public void commonSetup(byte[] hdr, boolean little) throws EOFException { + if (hdr == null || hdr.length < FILHSZ) { + throw new EOFException(CCorePlugin.getResourceString("Util.exception.arrayToSmall")); //$NON-NLS-1$ + } + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, little); + f_magic = memory.getUnsignedShort(); + f_nscns = memory.getUnsignedShort(); + f_timdat = memory.getInt(); + f_symptr = memory.getInt(); + f_nsyms = memory.getInt(); + f_opthdr = memory.getUnsignedShort(); + f_flags = memory.getUnsignedShort(); + } + + public boolean isStrip() { + return (f_flags & F_RELFLG) == F_RELFLG; + } + + public boolean isExec() { + return (f_flags & F_EXEC) == F_EXEC; + } + + public boolean isDebug() { + return !((f_flags & F_LNNO) == F_LNNO); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("FILE HEADER VALUES").append(NL); //$NON-NLS-1$ + + buffer.append("f_magic = ").append(f_magic).append(NL); //$NON-NLS-1$ + buffer.append("f_nscns = ").append(f_nscns).append(NL); //$NON-NLS-1$ + + buffer.append("f_timdat = "); //$NON-NLS-1$ + buffer.append(DateFormat.getDateInstance().format(new Date(f_timdat))); + buffer.append(NL); + + buffer.append("f_symptr = ").append(f_symptr).append(NL); //$NON-NLS-1$ + buffer.append("f_nsyms = ").append(f_nsyms).append(NL); //$NON-NLS-1$ + buffer.append("f_opthdr = ").append(f_opthdr).append(NL); //$NON-NLS-1$ + buffer.append("f_flags = ").append(f_flags).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public static class OptionalHeader { + public short magic; /* 2 bytes: type of file */ + public OptionalHeader64 optionalHeader64; + public OptionalHeader32 optionalHeader32; + + private final static int MAGICSZ = 2; + private boolean is64Bits; + + public static class OptionalHeader64 { + public final static int AOUTHDRSZ = 22; + + public short vstamp; /* 2 bytes: version stamp */ + public int tsize; /* 4 bytes: text size in bytes, padded to FW bdry*/ + public int dsize; /* 4 bytes: initialized data " " */ + public int bsize; /* 4 bytes: uninitialized data " " */ + public int entry; /* 4 bytes: entry pt. */ + public int text_start; /* 4 bytes: base of text used for this file */ + + public OptionalHeader64(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[AOUTHDRSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + vstamp = memory.getShort(); + tsize = memory.getInt(); + dsize = memory.getInt(); + bsize = memory.getInt(); + entry = memory.getInt(); + text_start = memory.getInt(); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("vstamp = ").append(vstamp).append(NL); //$NON-NLS-1$ + buffer.append("tsize = ").append(tsize).append(NL); //$NON-NLS-1$ + buffer.append("dsize = ").append(dsize).append(NL); //$NON-NLS-1$ + buffer.append("bsize = ").append(bsize).append(NL); //$NON-NLS-1$ + buffer.append("entry = ").append(entry).append(NL); //$NON-NLS-1$ + buffer.append("text_start = ").append(text_start).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public static class OptionalHeader32 { + public final static int AOUTHDRSZ = 26; + + public short vstamp; /* 2 bytes: version stamp */ + public int tsize; /* 4 bytes: text size in bytes, padded to FW bdry*/ + public int dsize; /* 4 bytes: initialized data " " */ + public int bsize; /* 4 bytes: uninitialized data " " */ + public int entry; /* 4 bytes: entry pt. */ + public int text_start; /* 4 bytes: base of text used for this file */ + public int data_start; /* 4 bytes: base of data used for this file */ + + public OptionalHeader32(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[AOUTHDRSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + vstamp = memory.getShort(); + tsize = memory.getInt(); + dsize = memory.getInt(); + bsize = memory.getInt(); + entry = memory.getInt(); + text_start = memory.getInt(); + data_start = memory.getInt(); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("vstamp = ").append(vstamp).append(NL); //$NON-NLS-1$ + buffer.append("tsize = ").append(tsize).append(NL); //$NON-NLS-1$ + buffer.append("dsize = ").append(dsize).append(NL); //$NON-NLS-1$ + buffer.append("bsize = ").append(bsize).append(NL); //$NON-NLS-1$ + buffer.append("entry = ").append(entry).append(NL); //$NON-NLS-1$ + buffer.append("text_start = ").append(text_start).append(NL); //$NON-NLS-1$ + buffer.append("data_start = ").append(data_start).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public OptionalHeader(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer() + FileHeader.FILHSZ); + } + + public OptionalHeader(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[MAGICSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + magic = memory.getShort(); + + if (magic == 523) { // 64 bit executable + optionalHeader64 = new OptionalHeader64(file, file.getFilePointer()); + is64Bits = true; + } else if (magic == 267) { // 32 bit executable + optionalHeader32 = new OptionalHeader32(file, file.getFilePointer()); + is64Bits = false; + } + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("OPTIONAL HEADER VALUES").append(NL); //$NON-NLS-1$ + buffer.append("magic = ").append(magic).append(NL); //$NON-NLS-1$ + + if (is64Bits()) + buffer.append(optionalHeader64.toString()); + else + buffer.append(optionalHeader32.toString()); + + return buffer.toString(); + } + + public boolean is64Bits() { + return is64Bits; + } + + public int getSize() { + if (is64Bits()) + return OptionalHeader64.AOUTHDRSZ; + else + return OptionalHeader32.AOUTHDRSZ; + } + } + + public static class SectionHeader { + + public final static int SCNHSZ = 40; + + /* names of "special" sections */ + public final static String _TEXT = ".text"; //$NON-NLS-1$ + public final static String _DATA = ".data"; //$NON-NLS-1$ + public final static String _BSS = ".bss"; //$NON-NLS-1$ + public final static String _COMMENT = ".comment"; //$NON-NLS-1$ + public final static String _LIB = ".lib"; //$NON-NLS-1$ + + /* s_flags "type". */ + public final static int STYP_REG = 0x0000; /* "regular": allocated, relocated, + loaded */ + public final static int STYP_DSECT = 0x0001; /* "dummy": relocated only */ + public final static int STYP_NOLOAD = 0x0002; /* "noload": allocated, relocated, + not loaded */ + public final static int STYP_GROUP = 0x0004; /* "grouped": formed of input + sections */ + public final static int STYP_PAD = 0x0008; /* "padding": not allocated, not + relocated, loaded */ + public final static int STYP_COPY = 0x0010; /* "copy": for decision function + used by field update; + not allocated, not relocated, + loaded; reloc & lineno entries + processed normally */ + public final static int STYP_TEXT = 0x0020; /* section contains text only. */ + public final static int S_SHRSEG = 0x0020; /* In 3b Update files (output of + ogen), sections which appear in + SHARED segments of the Pfile + will have the S_SHRSEG flag set + by ogen, to inform dufr that + updating 1 copy of the proc. will + update all process invocations. */ + public final static int STYP_DATA = 0x0040; /* section contains data only */ + public final static int STYP_BSS = 0x0080; /* section contains bss only */ + public final static int S_NEWFCN = 0x0100; /* In a minimal file or an update + file, a new function (as + compared with a replaced + function) */ + public final static int STYP_INFO = 0x0200; /* comment: not allocated not + relocated, not loaded */ + public final static int STYP_OVER = 0x0400; /* overlay: relocated not allocated + or loaded */ + public final static int STYP_LIB = 0x0800; /* for .lib: same as INFO */ + public final static int STYP_MERGE = 0x2000; /* merge section -- combines with + text, data or bss sections only */ + public final static int STYP_REVERSE_PAD = 0x4000; /* section will be padded + with no-op instructions + wherever padding is necessary + and there is a word of + contiguous bytes beginning on a + word boundary. */ + + public final static int STYP_LIT = 0x8020; /* Literal data (like STYP_TEXT) */ + + public byte[] s_name = new byte[8]; // 8 bytes: section name + public int s_paddr; // 4 bytes: physical address, aliased s_nlib + public int s_vaddr; // 4 bytes: virtual address + public int s_size; // 4 bytes: section size + public int s_scnptr; // 4 bytes: file ptr to raw data for section + public int s_relptr; // 4 bytes: file ptr to relocation + public int s_lnnoptr; // 4 bytes: file ptr to line numbers + public int s_nreloc; // 2 bytes: number of relocation entries + public int s_nlnno; // 2 bytes: number of line number entries + public int s_flags; // 4 bytes: flags + + RandomAccessFile sfile; + + public SectionHeader(RandomAccessFile file, long offset) throws IOException { + sfile = file; + file.seek(offset); + byte[] hdr = new byte[SCNHSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + memory.getBytes(s_name); + s_paddr = memory.getInt(); + s_vaddr = memory.getInt(); + s_size = memory.getInt(); + s_scnptr = memory.getInt(); + s_relptr = memory.getInt(); + s_lnnoptr = memory.getInt(); + s_nreloc = memory.getUnsignedShort(); + s_nlnno = memory.getUnsignedShort(); + s_flags = memory.getInt(); + } + + public byte[] getRawData() throws IOException { + byte[] data = new byte[s_size]; + sfile.seek(s_scnptr); + sfile.readFully(data); + return data; + } + + public Reloc[] getRelocs() throws IOException { + Reloc[] relocs = new Reloc[s_nreloc]; + sfile.seek(s_relptr); + for (int i = 0; i < s_nreloc; i++) { + relocs[i] = new Reloc(sfile); + } + return relocs; + } + + public Lineno[] getLinenos() throws IOException { + Lineno[] lines = new Lineno[s_nlnno]; + sfile.seek(s_lnnoptr); + for (int i = 0; i < s_nlnno; i++) { + lines[i] = new Lineno(sfile); + } + return lines; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("SECTION HEADER VALUES").append(NL); //$NON-NLS-1$ + buffer.append(new String(s_name)).append(NL); + buffer.append("s_paddr = ").append(s_paddr).append(NL); //$NON-NLS-1$ + buffer.append("s_vaddr = ").append(s_vaddr).append(NL); //$NON-NLS-1$ + buffer.append("s_size = ").append(s_size).append(NL); //$NON-NLS-1$ + buffer.append("s_scnptr = ").append(s_scnptr).append(NL); //$NON-NLS-1$ + buffer.append("s_relptr = ").append(s_relptr).append(NL); //$NON-NLS-1$ + buffer.append("s_lnnoptr = ").append(s_lnnoptr).append(NL); //$NON-NLS-1$ + buffer.append("s_nreloc = ").append(s_nreloc).append(NL); //$NON-NLS-1$ + buffer.append("s_nlnno = ").append(s_nlnno).append(NL); //$NON-NLS-1$ + buffer.append("s_flags = ").append(s_flags).append(NL); //$NON-NLS-1$ + ///* + try { + Reloc[] rcs = getRelocs(); + for (int i = 0; i < rcs.length; i++) { + buffer.append(rcs[i]); + } + } catch (IOException e) { + } + try { + Lineno[] nos = getLinenos(); + for (int i = 0; i < nos.length; i++) { + buffer.append(nos[i]); + } + } catch (IOException e) { + } + //*/ + return buffer.toString(); + } + + /** + * @since 5.1 + */ + public ByteBuffer mapSectionData() throws IOException { + return sfile.getChannel().map(MapMode.READ_ONLY, s_scnptr, s_paddr).load().asReadOnlyBuffer(); + } + } + + public static class Reloc { + public static final int RELSZ = 16; + public int r_vaddr; /* 4 byte: Pointer to an area in raw data that represents a + referenced address. */ + public int r_symndx; /* 4 byte: Index into symbol table. */ + public int r_type; /* 2 byte(unsigned short): Type of address reference. */ + + public Reloc(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public Reloc(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] bytes = new byte[RELSZ]; + file.readFully(bytes); + ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true); + r_vaddr = memory.getInt(); + r_symndx = memory.getInt(); + r_type = memory.getUnsignedShort(); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("RELOC VALUES").append(NL); //$NON-NLS-1$ + buffer.append("r_vaddr = ").append(r_vaddr); //$NON-NLS-1$ + buffer.append(" r_symndx = ").append(r_symndx).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public static class Lineno { + public final static int LINESZ = 6; + public int l_addr; /* long. Index into symbol table if l_linn0 == 0. + Break-pointable address if l_lnno > 0. */ + public int l_lnno; /* unsigned short. Line number */ + + public Lineno(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public Lineno(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] bytes = new byte[LINESZ]; + file.readFully(bytes); + ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true); + l_addr = memory.getInt(); + l_lnno = memory.getUnsignedShort(); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + if (l_lnno == 0) { + buffer.append("Function address = ").append(l_addr).append(NL); //$NON-NLS-1$ + } else { + buffer.append("line# ").append(l_lnno); //$NON-NLS-1$ + buffer.append(" at address = ").append(l_addr).append(NL); //$NON-NLS-1$ + } + return buffer.toString(); + } + } + + public static class Symbol { + public final static int SYMSZ = 18; + public final static int SYMNMLEN = 8; + + /* Derived types, in n_type. */ + public final static int DT_NON = 0; /* no derived type */ + public final static int DT_PTR = 1; /* pointer */ + public final static int DT_FCN = 2; /* function */ + public final static int DT_ARY = 3; /* array */ + + public final static int N_TMASK = 0x30; + public final static int N_BTSHFT = 4; + public final static int N_TSHIFT = 2; + + /** @since 5.3 */ + public final static int T_NULL = 0x00; /* No symbol */ + /** @since 5.3 */ + public final static int T_VOID = 0x01; /* -- 0001 void function argument (not used) */ + /** @since 5.3 */ + public final static int T_CHAR = 0x02; /* -- 0010 character */ + /** @since 5.3 */ + public final static int T_SHORT = 0x03; /* -- 0011 short integer */ + /** @since 5.3 */ + public final static int T_INT = 0x04; /* -- 0100 integer */ + /** @since 5.3 */ + public final static int T_LONG = 0x05; /* -- 0101 long integer */ + /** @since 5.3 */ + public final static int T_FLOAT = 0x06; /* -- 0110 floating point */ + /** @since 5.3 */ + public final static int T_DOUBLE = 0x07; /* -- 0111 double precision float */ + /** @since 5.3 */ + public final static int T_STRUCT = 0x08; /* -- 1000 structure */ + /** @since 5.3 */ + public final static int T_UNION = 0x09; /* -- 1001 union */ + /** @since 5.3 */ + public final static int T_ENUM = 0x10; /* -- 1010 enumeration */ + /** @since 5.3 */ + public final static int T_MOE = 0x11; /* -- 1011 member of enumeration */ + /** @since 5.3 */ + public final static int T_UCHAR = 0x12; /* -- 1100 unsigned character */ + /** @since 5.3 */ + public final static int T_USHORT = 0x13; /* -- 1101 unsigned short */ + /** @since 5.3 */ + public final static int T_UINT = 0x14; /* -- 1110 unsigned integer */ + /** @since 5.3 */ + public final static int T_ULONG = 0x15; /* -- 1111 unsigned long */ + /** @since 5.3 */ + public final static int T_LNGDBL = 0x16; /* -1 0000 long double (special case bit pattern) */ + + public byte[] _n_name = new byte[SYMNMLEN]; /* Symbol name, or pointer into + string table if symbol name + is greater than SYMNMLEN. */ + public int n_value; /* long. Symbol;s value: dependent on section number, + storage class and type. */ + public short n_scnum; /* short, Section number. */ + public int n_type; /* Unsigned short. Symbolic type. */ + public byte n_sclass; /* char, Storage class. */ + public byte n_numaux; /* char. Number of auxiliary enties. */ + /** @since 5.4 */ + public short n_aux_lnno; /* short, line number in auxiliary entry */ + /** @since 5.4 */ + public short n_aux_size; /* short, size in bytes in auxiliary entry */ + /** @since 5.4 */ + public int n_aux_fcn_size; /* long, size of function in bytes found in auxiliary entry */ + + private boolean is64Bit; + + public Symbol(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer(), false); + } + + public Symbol(RandomAccessFile file, long offset) throws IOException { + this(file, offset, false); + } + + /** + * @since 5.4 + */ + public Symbol(RandomAccessFile file, boolean is64Bit) throws IOException { + this(file, file.getFilePointer(), is64Bit); + } + + /** + * @since 5.4 + */ + public Symbol(RandomAccessFile file, long offset, boolean is64Bit) throws IOException { + this.is64Bit = is64Bit; + file.seek(offset); + byte[] bytes = new byte[SYMSZ]; + file.readFully(bytes); + ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true); + memory.getBytes(_n_name); + n_value = memory.getInt(); + n_scnum = memory.getShort(); + n_type = memory.getUnsignedShort(); + n_sclass = memory.getByte(); + n_numaux = memory.getByte(); + if (n_numaux > 0) { + // read auxiliary section + byte[] bytes2 = new byte[SYMSZ * n_numaux]; + file.readFully(bytes2); + memory = new ReadMemoryAccess(bytes2, true); + memory.getInt(); // ignore first 4 bytes - tag index + n_aux_lnno = memory.getShort(); + n_aux_size = memory.getShort(); + // function size is unioned with lnno and size so we must rewind and + // reread + memory = new ReadMemoryAccess(bytes2, true); + memory.getInt(); // ignore first 4 bytes - tag index + n_aux_fcn_size = memory.getInt(); + } + } + + public boolean isLongName() { + return (_n_name[0] == 0); + } + + public String getName() { + // For a long name, _n_name[0] == 0 and this would just return empty string. + for (int i = 0; i < _n_name.length; i++) { + if (_n_name[i] == 0) { + return new String(_n_name, 0, i); + } + } + // all eight bytes are filled + return new String(_n_name); + } + + public String getName(byte[] table) { + if (table.length > 0 && isLongName()) { + ReadMemoryAccess memory = new ReadMemoryAccess(_n_name, true); + memory.getInt(); // pass over the first 4 bytes. + // The first for bytes of the string table represent the + // number of bytes in the string table. + int offset = memory.getInt() - 4; + if (offset > 0) { + for (int i = offset; i < table.length; i++) { + if (table[i] == 0) { + return new String(table, offset, i - offset); + } + } + } + } + return getName(); + } + + /** @since 5.3 */ + public boolean isNoSymbol() { + return (n_type == T_NULL); + } + + public boolean isPointer() { + return (n_type & N_TMASK) == (DT_PTR << N_BTSHFT); + } + + public boolean isFunction() { + return (n_type & N_TMASK) == (DT_FCN << N_BTSHFT); + } + + public boolean isArray() { + return (n_type & N_TMASK) == (DT_ARY << N_BTSHFT); + } + + /** + * @since 5.4 + */ + public int getSize() { + if (n_type <= T_LNGDBL) { + switch (n_type) { + case T_CHAR: + case T_UCHAR: + return 1; + case T_SHORT: + case T_USHORT: + return 2; + case T_LONG: + case T_ULONG: + return 4; + case T_INT: + case T_UINT: + return 4; + case T_FLOAT: + return 4; + case T_DOUBLE: + return 8; + case T_MOE: + return 4; + case T_LNGDBL: + return 16; + case T_ENUM: + case T_STRUCT: + case T_UNION: + return n_aux_size; + } + } else if (isFunction()) { + return n_aux_fcn_size; + } else if (isArray()) { + return n_aux_size; + } else if (isPointer()) { + return is64Bit ? 8 : 4; + } + return 1; + } + + @Override + public String toString() { + return getName(); + } + + } + + public FileHeader getFileHeader() throws IOException { + return filehdr; + } + + public OptionalHeader getOptionalHeader() throws IOException { + return opthdr; + } + + public SectionHeader[] getSectionHeaders() throws IOException { + if (scnhdrs == null) { + scnhdrs = new SectionHeader[getFileHeader().f_nscns]; + long sec = FileHeader.FILHSZ + getFileHeader().f_opthdr; + for (int i = 0; i < scnhdrs.length; i++, sec += SectionHeader.SCNHSZ) { + scnhdrs[i] = new SectionHeader(rfile, sec); + } + } + return scnhdrs; + } + + public Symbol[] getSymbols() throws IOException { + if (symbols == null) { + long offset = getFileHeader().f_symptr; + rfile.seek(offset); + symbols = new Symbol[getFileHeader().f_nsyms]; + for (int i = 0; i < symbols.length; i++) { + symbols[i] = new Symbol(rfile, (getFileHeader().f_flags & FileHeader.F_AR32WR) == 0); + } + } + return symbols; + } + + public byte[] getStringTable() throws IOException { + if (string_table == null) { + long symbolsize = Symbol.SYMSZ * getFileHeader().f_nsyms; + long offset = getFileHeader().f_symptr + symbolsize; + rfile.seek(offset); + byte[] bytes = new byte[4]; + rfile.readFully(bytes); + int str_len = ReadMemoryAccess.getIntLE(bytes); + if (str_len > 4 && str_len < rfile.length()) { + str_len -= 4; + string_table = new byte[str_len]; + rfile.seek(offset + 4); + rfile.readFully(string_table); + } else { + string_table = new byte[0]; + } + } + return string_table; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + try { + FileHeader header = null; + header = getFileHeader(); + if (header != null) { + buffer.append(header); + } + } catch (IOException e) { + e.printStackTrace(); + } + try { + OptionalHeader opt = null; + opt = getOptionalHeader(); + if (opt != null) { + buffer.append(opt); + } + } catch (IOException e) { + e.printStackTrace(); + } + try { + SectionHeader[] sections = getSectionHeaders(); + for (int i = 0; i < sections.length; i++) { + buffer.append(sections[i]); + } + } catch (IOException e) { + } + + try { + Symbol[] table = getSymbols(); + for (int i = 0; i < table.length; i++) { + buffer.append(table[i].getName(getStringTable())).append(NL); + } + } catch (IOException e) { + } + + return buffer.toString(); + } + + public static String[] getStringTable(byte[] bytes) { + List<String> aList = new ArrayList<>(); + int offset = 0; + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] == 0) { + aList.add(new String(bytes, offset, i - offset)); + offset = i + 1; + } + } + return aList.toArray(new String[0]); + } + + public Coff64(String filename) throws IOException { + this(new RandomAccessFile(filename, "r"), 0); //$NON-NLS-1$ + } + + public Coff64(RandomAccessFile file, long offset) throws IOException { + commonSetup(file, offset); + } + + void commonSetup(RandomAccessFile file, long offset) throws IOException { + startingOffset = offset; + rfile = file; + try { + filehdr = new FileHeader(rfile, offset); + if (filehdr.f_opthdr > 0) { + opthdr = new OptionalHeader(rfile, startingOffset + 20); + } + } finally { + if (filehdr == null) { + rfile.close(); + } + } + } + + public static void main(String[] args) { + try { + Coff64 coff = new Coff64(args[0]); + System.out.println(coff); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java index 784128ee734..85205e19620 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java @@ -18,11 +18,12 @@ import java.io.RandomAccessFile; import org.eclipse.cdt.core.CCorePlugin; -public class Exe { +public class Exe implements AutoCloseable { public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ protected RandomAccessFile rfile; ExeHeader ehdr; + private String file; static public class ExeHeader { @@ -160,12 +161,13 @@ public class Exe { @Override public String toString() { StringBuilder buffer = new StringBuilder(); - buffer.append(rfile).append(NL); + buffer.append(file).append(NL); buffer.append(ehdr); return buffer.toString(); } public Exe(String file) throws IOException { + this.file = file; rfile = new RandomAccessFile(file, "r"); //$NON-NLS-1$ try { ehdr = new ExeHeader(rfile); @@ -176,6 +178,15 @@ public class Exe { } } + @Override + public void close() throws Exception { + if (rfile != null) { + rfile.close(); + rfile = null; + ehdr = null; + } + } + public static void main(String[] args) { try { Exe exe = new Exe(args[0]); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java index a19c36fc8d2..f9e3c00c689 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java @@ -67,7 +67,13 @@ import org.eclipse.cdt.utils.debug.stabs.StabsReader; * +-------------------+ * </pre> */ -public class PE { + +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PE64}. + * This class is planned for removal in next major release. + */ +@Deprecated +public class PE implements AutoCloseable { public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ RandomAccessFile rfile; @@ -567,10 +573,14 @@ public class PE { } public static Attribute getAttribute(String file) throws IOException { - PE pe = new PE(file); - Attribute attrib = pe.getAttribute(); - pe.dispose(); - return attrib; + try (PE pe = new PE(file)) { + return pe.getAttribute(); + } + } + + @Override + public void close() throws IOException { + dispose(); } public void dispose() throws IOException { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java new file mode 100644 index 00000000000..5e4d8a4ba17 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java @@ -0,0 +1,1033 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - Initial PE class + *******************************************************************************/ + +package org.eclipse.cdt.utils.coff; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IAddressFactory; +import org.eclipse.cdt.core.ISymbolReader; +import org.eclipse.cdt.utils.Addr32Factory; +import org.eclipse.cdt.utils.coff.Coff64.FileHeader; +import org.eclipse.cdt.utils.coff.Coff64.OptionalHeader; +import org.eclipse.cdt.utils.coff.Coff64.SectionHeader; +import org.eclipse.cdt.utils.coff.Coff64.Symbol; +import org.eclipse.cdt.utils.coff.Exe.ExeHeader; +import org.eclipse.cdt.utils.debug.dwarf.DwarfReader; +import org.eclipse.cdt.utils.debug.stabs.StabsReader; + +/** + * The PE file header consists of an MS-DOS stub, the PE signature, the COFF file Header + * and an Optional Header. + * <pre> + * +-------------------+ + * | DOS-stub | + * +-------------------+ + * | file-header | + * +-------------------+ + * | optional header | + * |- - - - - - - - - -| + * | | + * | data directories | + * | | + * +-------------------+ + * | | + * | section headers | + * | | + * +-------------------+ + * | | + * | section 1 | + * | | + * +-------------------+ + * | | + * | section 2 | + * | | + * +-------------------+ + * | | + * | ... | + * | | + * +-------------------+ + * | | + * | section n | + * | | + * +-------------------+ + * </pre> + * @since 6.9 + */ +public class PE64 implements AutoCloseable { + + public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + RandomAccessFile rfile; + String filename; + ExeHeader exeHeader; + DOSHeader dosHeader; + FileHeader fileHeader; + OptionalHeader optionalHeader; + NTOptionalHeader64 ntHeader64; + NTOptionalHeader32 ntHeader32; + ImageDataDirectory[] dataDirectories; + SectionHeader[] scnhdrs; + Symbol[] symbolTable; + byte[] stringTable; + + public static class Attribute { + public static final int PE_TYPE_EXE = 1; + public static final int PE_TYPE_SHLIB = 2; + public static final int PE_TYPE_OBJ = 3; + public static final int PE_TYPE_CORE = 4; + + String cpu; + int type; + int word; + boolean bDebug; + boolean isle; + IAddressFactory addrFactory; + + public String getCPU() { + return cpu; + } + + public int getType() { + return type; + } + + public boolean hasDebug() { + return bDebug; + } + + public boolean isLittleEndian() { + return isle; + } + + public int getWord() { + return word; + } + } + + /** + */ + public static class DOSHeader { + final static int DOSHDRSZ = 100; + byte[] e_res = new byte[8]; /* Reserved words, all 0x0. */ + byte[] e_oemid = new byte[2]; /* OEM identifier (for e_oeminfo), 0x0. */ + byte[] e_oeminfo = new byte[2]; /* OEM information; e_oemid specific, 0x0. */ + byte[] e_res2 = new byte[20]; /* Reserved words, all 0x0. */ + int e_lfanew; /* 4 byte File address of new exe header, offset 60(0x3c), 0x80. */ + byte[] dos_message = new byte[64]; /* Other stuff, always follow DOS header. */ + + public DOSHeader(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public DOSHeader(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[DOSHDRSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + commonSetup(memory); + } + + public DOSHeader(byte[] hdr, boolean little) throws IOException { + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, little); + commonSetup(memory); + } + + public DOSHeader(ReadMemoryAccess memory) throws IOException { + commonSetup(memory); + } + + public void commonSetup(ReadMemoryAccess memory) throws IOException { + if (memory.getSize() < DOSHDRSZ) { + throw new IOException("Not a Dos Header"); //$NON-NLS-1$ + } + memory.getBytes(e_res); + memory.getBytes(e_oemid); + memory.getBytes(e_oeminfo); + memory.getBytes(e_res2); + e_lfanew = memory.getInt(); + memory.getBytes(dos_message); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("DOS STUB VALUES").append(NL); //$NON-NLS-1$ + buffer.append("e_lfanew = ").append(e_lfanew).append(NL); //$NON-NLS-1$ + buffer.append(new String(dos_message)).append(NL); + return buffer.toString(); + } + } + + public static class IMAGE_DEBUG_DIRECTORY { + final int DEBUGDIRSZ = 28; + public int Characteristics; + public int TimeDateStamp; + public short MajorVersion; + public short MinorVersion; + public int Type; + public int SizeOfData; + public int AddressOfRawData; + public int PointerToRawData; + + public IMAGE_DEBUG_DIRECTORY(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] dir = new byte[DEBUGDIRSZ]; + file.readFully(dir); + ReadMemoryAccess memory = new ReadMemoryAccess(dir, true); + Characteristics = memory.getInt(); + TimeDateStamp = memory.getInt(); + MajorVersion = memory.getShort(); + MinorVersion = memory.getShort(); + Type = memory.getInt(); + SizeOfData = memory.getInt(); + AddressOfRawData = memory.getInt(); + PointerToRawData = memory.getInt(); + } + } + + public static class IMAGE_DATA_DIRECTORY { + + public int VirtualAddress; + public int Size; + } + + public static class NTOptionalHeader64 { + + public final static int NTHDRSZ = 216; + public long ImageBase; // 8 bytes. + public int SectionAlignment; // 4 bytes. + public int FileAlignment; // 4 bytes. + public short MajorOperatingSystemVersion; // 2 bytes. + public short MinorOperatingSystemVersion; // 2 bytes. + public short MajorImageVersion; // 2 bytes. + public short MinorImageVersion; // 2 bytes. + public short MajorSubsystemVersion; // 2 bytes. + public short MinorSubsystemVersion; // 2 bytes. + public byte[] Reserved = new byte[4]; // 4 bytes. + public int SizeOfImage; // 4 bytes. + public int SizeOfHeaders; // 4 bytes. + public int CheckSum; // 4 bytes. + public short Subsystem; // 2 bytes. + public short DLLCharacteristics; // 2 bytes. + public long SizeOfStackReserve; // 8 bytes. + public long SizeOfStackCommit; // 8 bytes. + public long SizeOfHeapReserve; // 8 bytes. + public long SizeOfHeapCommit; // 8 bytes. + public int LoaderFlags; // 4 bytes. + public int NumberOfRvaAndSizes; // 4 bytes. + public IMAGE_DATA_DIRECTORY DataDirectory[]; + + public NTOptionalHeader64(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public NTOptionalHeader64(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[NTHDRSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + ImageBase = memory.getLong(); + SectionAlignment = memory.getInt(); + FileAlignment = memory.getInt(); + MajorOperatingSystemVersion = memory.getShort(); + MinorOperatingSystemVersion = memory.getShort(); + MajorImageVersion = memory.getShort(); + MinorImageVersion = memory.getShort(); + MajorSubsystemVersion = memory.getShort(); + MinorSubsystemVersion = memory.getShort(); + memory.getBytes(Reserved); + SizeOfImage = memory.getInt(); + SizeOfHeaders = memory.getInt(); + CheckSum = memory.getInt(); + Subsystem = memory.getShort(); + DLLCharacteristics = memory.getShort(); + SizeOfStackReserve = memory.getLong(); + SizeOfStackCommit = memory.getLong(); + SizeOfHeapReserve = memory.getLong(); + SizeOfHeapCommit = memory.getLong(); + LoaderFlags = memory.getInt(); + NumberOfRvaAndSizes = memory.getInt(); + + DataDirectory = new IMAGE_DATA_DIRECTORY[NumberOfRvaAndSizes]; // 8*16=128 bytes + for (int i = 0; i < NumberOfRvaAndSizes; i++) { + DataDirectory[i] = new IMAGE_DATA_DIRECTORY(); + DataDirectory[i].VirtualAddress = memory.getInt(); + DataDirectory[i].Size = memory.getInt(); + } + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("NT OPTIONAL HEADER VALUES").append(NL); //$NON-NLS-1$ + buffer.append("ImageBase = ").append(ImageBase).append(NL); //$NON-NLS-1$ + buffer.append("SexctionAlignement = ").append(SectionAlignment).append(NL); //$NON-NLS-1$ + buffer.append("FileAlignment = ").append(FileAlignment).append(NL); //$NON-NLS-1$ + buffer.append("MajorOSVersion = ").append(MajorOperatingSystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("MinorOSVersion = ").append(MinorOperatingSystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("MajorImageVersion = ").append(MajorImageVersion).append(NL); //$NON-NLS-1$ + buffer.append("MinorImageVersion = ").append(MinorImageVersion).append(NL); //$NON-NLS-1$ + buffer.append("MajorSubVersion = ").append(MajorSubsystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("MinorSubVersion = ").append(MinorSubsystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("Reserved = ").append(Reserved).append(NL); //$NON-NLS-1$ + buffer.append("SizeOfImage = ").append(SizeOfImage).append(NL); //$NON-NLS-1$ + buffer.append("SizeOfHeaders = ").append(SizeOfHeaders).append(NL); //$NON-NLS-1$ + buffer.append("CheckSum = ").append(CheckSum).append(NL); //$NON-NLS-1$ + buffer.append("Subsystem = ").append(Subsystem).append(NL); //$NON-NLS-1$ + buffer.append("DLL = ").append(DLLCharacteristics).append(NL); //$NON-NLS-1$ + buffer.append("StackReserve = ").append(SizeOfStackReserve).append(NL); //$NON-NLS-1$ + buffer.append("StackCommit = ").append(SizeOfStackCommit).append(NL); //$NON-NLS-1$ + buffer.append("HeapReserve = ").append(SizeOfHeapReserve).append(NL); //$NON-NLS-1$ + buffer.append("HeapCommit = ").append(SizeOfHeapCommit).append(NL); //$NON-NLS-1$ + buffer.append("LoaderFlags = ").append(LoaderFlags).append(NL); //$NON-NLS-1$ + buffer.append("#Rva size = ").append(NumberOfRvaAndSizes).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public static class NTOptionalHeader32 { + + public final static int NTHDRSZ = 196; + public int ImageBase; // 4 bytes. + public int SectionAlignment; // 4 bytes. + public int FileAlignment; // 4 bytes. + public short MajorOperatingSystemVersion; // 2 bytes. + public short MinorOperatingSystemVersion; // 2 bytes. + public short MajorImageVersion; // 2 bytes. + public short MinorImageVersion; // 2 bytes. + public short MajorSubsystemVersion; // 2 bytes. + public short MinorSubsystemVersion; // 2 bytes. + public byte[] Reserved = new byte[4]; // 4 bytes. + public int SizeOfImage; // 4 bytes. + public int SizeOfHeaders; // 4 bytes. + public int CheckSum; // 4 bytes. + public short Subsystem; // 2 bytes. + public short DLLCharacteristics; // 2 bytes. + public int SizeOfStackReserve; // 4 bytes. + public int SizeOfStackCommit; // 4 bytes. + public int SizeOfHeapReserve; // 4 bytes. + public int SizeOfHeapCommit; // 4 bytes. + public int LoaderFlags; // 4 bytes. + public int NumberOfRvaAndSizes; // 4 bytes. + public IMAGE_DATA_DIRECTORY DataDirectory[]; + + public NTOptionalHeader32(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public NTOptionalHeader32(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] hdr = new byte[NTHDRSZ]; + file.readFully(hdr); + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + ImageBase = memory.getInt(); + SectionAlignment = memory.getInt(); + FileAlignment = memory.getInt(); + MajorOperatingSystemVersion = memory.getShort(); + MinorOperatingSystemVersion = memory.getShort(); + MajorImageVersion = memory.getShort(); + MinorImageVersion = memory.getShort(); + MajorSubsystemVersion = memory.getShort(); + MinorSubsystemVersion = memory.getShort(); + memory.getBytes(Reserved); + SizeOfImage = memory.getInt(); + SizeOfHeaders = memory.getInt(); + CheckSum = memory.getInt(); + Subsystem = memory.getShort(); + DLLCharacteristics = memory.getShort(); + SizeOfStackReserve = memory.getInt(); + SizeOfStackCommit = memory.getInt(); + SizeOfHeapReserve = memory.getInt(); + SizeOfHeapCommit = memory.getInt(); + LoaderFlags = memory.getInt(); + NumberOfRvaAndSizes = memory.getInt(); + + DataDirectory = new IMAGE_DATA_DIRECTORY[NumberOfRvaAndSizes]; // 8*16=128 bytes + for (int i = 0; i < NumberOfRvaAndSizes; i++) { + DataDirectory[i] = new IMAGE_DATA_DIRECTORY(); + DataDirectory[i].VirtualAddress = memory.getInt(); + DataDirectory[i].Size = memory.getInt(); + } + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("NT OPTIONAL HEADER VALUES").append(NL); //$NON-NLS-1$ + buffer.append("ImageBase = ").append(ImageBase).append(NL); //$NON-NLS-1$ + buffer.append("SexctionAlignement = ").append(SectionAlignment).append(NL); //$NON-NLS-1$ + buffer.append("FileAlignment = ").append(FileAlignment).append(NL); //$NON-NLS-1$ + buffer.append("MajorOSVersion = ").append(MajorOperatingSystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("MinorOSVersion = ").append(MinorOperatingSystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("MajorImageVersion = ").append(MajorImageVersion).append(NL); //$NON-NLS-1$ + buffer.append("MinorImageVersion = ").append(MinorImageVersion).append(NL); //$NON-NLS-1$ + buffer.append("MajorSubVersion = ").append(MajorSubsystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("MinorSubVersion = ").append(MinorSubsystemVersion).append(NL); //$NON-NLS-1$ + buffer.append("Reserved = ").append(Reserved).append(NL); //$NON-NLS-1$ + buffer.append("SizeOfImage = ").append(SizeOfImage).append(NL); //$NON-NLS-1$ + buffer.append("SizeOfHeaders = ").append(SizeOfHeaders).append(NL); //$NON-NLS-1$ + buffer.append("CheckSum = ").append(CheckSum).append(NL); //$NON-NLS-1$ + buffer.append("Subsystem = ").append(Subsystem).append(NL); //$NON-NLS-1$ + buffer.append("DLL = ").append(DLLCharacteristics).append(NL); //$NON-NLS-1$ + buffer.append("StackReserve = ").append(SizeOfStackReserve).append(NL); //$NON-NLS-1$ + buffer.append("StackCommit = ").append(SizeOfStackCommit).append(NL); //$NON-NLS-1$ + buffer.append("HeapReserve = ").append(SizeOfHeapReserve).append(NL); //$NON-NLS-1$ + buffer.append("HeapCommit = ").append(SizeOfHeapCommit).append(NL); //$NON-NLS-1$ + buffer.append("LoaderFlags = ").append(LoaderFlags).append(NL); //$NON-NLS-1$ + buffer.append("#Rva size = ").append(NumberOfRvaAndSizes).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public class ImageDataDirectory { + public int rva; + public int size; + + public ImageDataDirectory(int r, int s) { + rva = r; + size = s; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("rva = ").append(rva).append(" "); //$NON-NLS-1$ //$NON-NLS-2$ + buffer.append("size = ").append(size).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public class ImportDirectoryEntry { + public final static int ENTRYSZ = 20; + public int rva; + public int timestamp; + public int forwarder; + public int name; + public int thunk; + + public ImportDirectoryEntry(RandomAccessFile file) throws IOException { + this(file, file.getFilePointer()); + } + + public ImportDirectoryEntry(RandomAccessFile file, long offset) throws IOException { + file.seek(offset); + byte[] bytes = new byte[ENTRYSZ]; + file.readFully(bytes); + ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true); + rva = memory.getInt(); + timestamp = memory.getInt(); + forwarder = memory.getInt(); + name = memory.getInt(); + thunk = memory.getInt(); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("rva = ").append(rva); //$NON-NLS-1$ + buffer.append(" timestamp = ").append(timestamp); //$NON-NLS-1$ + buffer.append(" forwarder = ").append(forwarder); //$NON-NLS-1$ + buffer.append(" name = ").append(name); //$NON-NLS-1$ + buffer.append(" thunk = ").append(thunk).append(NL); //$NON-NLS-1$ + return buffer.toString(); + } + } + + public PE64(String filename) throws IOException { + this(filename, 0); + } + + public PE64(String filename, long pos) throws IOException { + this(filename, pos, true); + } + + public PE64(String filename, long pos, boolean filter) throws IOException { + try { + rfile = new RandomAccessFile(filename, "r"); //$NON-NLS-1$ + this.filename = filename; + rfile.seek(pos); + + // Object files do not have exe/dos header. + try { + exeHeader = new ExeHeader(rfile); + dosHeader = new DOSHeader(rfile); + // Jump the Coff header, and Check the sig. + rfile.seek(dosHeader.e_lfanew); + byte[] sig = new byte[4]; + rfile.readFully(sig); + if (!((sig[0] == 'P') && (sig[1] == 'E') && (sig[2] == '\0') && (sig[3] == '\0'))) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.notPE")); //$NON-NLS-1$ + } + } catch (IOException e) { + rfile.seek(pos); + } + + fileHeader = new Coff64.FileHeader(rfile, rfile.getFilePointer()); + + // Check if this a valid machine. + if (!isValidMachine(fileHeader.f_magic)) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.unknownFormat")); //$NON-NLS-1$ + } + + if (fileHeader.f_opthdr > 0) { + optionalHeader = new Coff64.OptionalHeader(rfile, rfile.getFilePointer()); + + if (optionalHeader.is64Bits()) + ntHeader64 = new NTOptionalHeader64(rfile, rfile.getFilePointer()); + else + ntHeader32 = new NTOptionalHeader32(rfile, rfile.getFilePointer()); + } + } finally { + if (rfile != null) { + rfile.close(); + rfile = null; + } + } + } + + public static boolean isValidMachine(int magic) { + // Check if this a valid machine. + switch (magic) { + case PEConstants.IMAGE_FILE_MACHINE_ALPHA: + case PEConstants.IMAGE_FILE_MACHINE_ARM: + case PEConstants.IMAGE_FILE_MACHINE_ARM2: + case PEConstants.IMAGE_FILE_MACHINE_ALPHA64: + case PEConstants.IMAGE_FILE_MACHINE_AMD64: + case PEConstants.IMAGE_FILE_MACHINE_I386: + case PEConstants.IMAGE_FILE_MACHINE_IA64: + case PEConstants.IMAGE_FILE_MACHINE_M68K: + case PEConstants.IMAGE_FILE_MACHINE_MIPS16: + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU: + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16: + case PEConstants.IMAGE_FILE_MACHINE_POWERPC: + case PEConstants.IMAGE_FILE_MACHINE_R3000: + case PEConstants.IMAGE_FILE_MACHINE_R4000: + case PEConstants.IMAGE_FILE_MACHINE_R10000: + case PEConstants.IMAGE_FILE_MACHINE_SH3: + case PEConstants.IMAGE_FILE_MACHINE_SH4: + case PEConstants.IMAGE_FILE_MACHINE_THUMB: + // Ok; + return true; + //throw new IOException("Unknow machine/format"); + } + return false; + } + + public static Attribute getAttributes(FileHeader filhdr) { + Attribute attrib = new Attribute(); + // Machine type. + switch (filhdr.f_magic) { + case PEConstants.IMAGE_FILE_MACHINE_UNKNOWN: + attrib.cpu = "none"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_ALPHA: + attrib.cpu = "alpha"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_ARM: + case PEConstants.IMAGE_FILE_MACHINE_ARM2: + attrib.cpu = "arm"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_ALPHA64: + attrib.cpu = "arm64"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_AMD64: + attrib.cpu = "amd64"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_I386: + attrib.cpu = "x86"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_IA64: + attrib.cpu = "ia64"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_M68K: + attrib.cpu = "m68k"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_MIPS16: + attrib.cpu = "mips16"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU: + attrib.cpu = "mipsfpu"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16: + attrib.cpu = "mipsfpu16"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_POWERPC: + attrib.cpu = "powerpc"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_R3000: + attrib.cpu = "r3000"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_R4000: + attrib.cpu = "r4000"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_R10000: + attrib.cpu = "r10000"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_SH3: + attrib.cpu = "sh3"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_SH4: + attrib.cpu = "sh4"; //$NON-NLS-1$ + break; + case PEConstants.IMAGE_FILE_MACHINE_THUMB: + attrib.cpu = "thumb"; //$NON-NLS-1$ + break; + } + + /* PE characteristics, FileHeader.f_flags. */ + if ((filhdr.f_flags & PEConstants.IMAGE_FILE_DLL) != 0) { + attrib.type = Attribute.PE_TYPE_SHLIB; + } else if ((filhdr.f_flags & PEConstants.IMAGE_FILE_EXECUTABLE_IMAGE) != 0) { + attrib.type = Attribute.PE_TYPE_EXE; + } else { + attrib.type = Attribute.PE_TYPE_OBJ; + } + + // For PE always assume little endian unless otherwise. + attrib.isle = true; + // Little Endian. + if ((filhdr.f_flags & PEConstants.IMAGE_FILE_BYTES_REVERSED_LO) != 0) { + attrib.isle = true; + } + // Big Endian. + if ((filhdr.f_flags & PEConstants.IMAGE_FILE_BYTES_REVERSED_HI) != 0) { + attrib.isle = false; + } + + // No debug information. + if ((filhdr.f_flags & PEConstants.IMAGE_FILE_DEBUG_STRIPPED) != 0) { + attrib.bDebug = false; + } else { + attrib.bDebug = true; + } + + // sizeof word. + if ((filhdr.f_flags & PEConstants.IMAGE_FILE_16BIT_MACHINE) != 0) { + attrib.word = 16; + } + if ((filhdr.f_flags & PEConstants.IMAGE_FILE_32BIT_MACHINE) != 0) { + attrib.word = 32; + } + + attrib.addrFactory = new Addr32Factory(); + return attrib; + } + + public static boolean isExeHeader(byte[] e_signature) { + if (e_signature == null || e_signature.length < 2 || e_signature[0] != 'M' || e_signature[1] != 'Z') + return false; + return true; + } + + public Attribute getAttribute() throws IOException { + return getAttributes(getFileHeader()); + } + + public static Attribute getAttribute(byte[] data) throws IOException { + ReadMemoryAccess memory = new ReadMemoryAccess(data, true); + int idx = 0; + try { + //Exe.ExeHeader exeHdr = new Exe.ExeHeader(memory); + new Exe.ExeHeader(memory); + DOSHeader dosHdr = new DOSHeader(memory); + // Jump the Coff header, and Check the sig. + idx = dosHdr.e_lfanew; + if (idx + 4 < data.length) { + if (!((data[idx + 0] == 'P') && (data[idx + 1] == 'E') && (data[idx + 2] == '\0') + && (data[idx + 3] == '\0'))) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.notPE")); //$NON-NLS-1$ + } + idx += 4; + } + } catch (IOException e) { + } + if (idx < data.length) { + byte[] bytes = new byte[data.length - idx]; + System.arraycopy(data, idx, bytes, 0, data.length - idx); + Coff64.FileHeader filehdr = new Coff64.FileHeader(bytes, true); + if (isValidMachine(filehdr.f_magic)) { + return getAttributes(filehdr); + } + } + throw new IOException(CCorePlugin.getResourceString("Util.exception.notPE")); //$NON-NLS-1$ + } + + public static Attribute getAttribute(String file) throws IOException { + try (PE64 pe = new PE64(file)) { + return pe.getAttribute(); + } + } + + @Override + public void close() throws IOException { + dispose(); + } + + public void dispose() throws IOException { + if (rfile != null) { + rfile.close(); + rfile = null; + } + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(); + } finally { + super.finalize(); + } + } + + public ExeHeader getExeHeader() { + return exeHeader; + } + + public DOSHeader getDOSHeader() { + return dosHeader; + } + + public FileHeader getFileHeader() { + return fileHeader; + } + + public OptionalHeader getOptionalHeader() { + return optionalHeader; + } + + public NTOptionalHeader64 getNTOptionalHeader64() { + return ntHeader64; + } + + public NTOptionalHeader32 getNTOptionalHeader32() { + return ntHeader32; + } + + public ImageDataDirectory[] getImageDataDirectories() throws IOException { + if (dataDirectories == null) { + RandomAccessFile accessFile = getRandomAccessFile(); + long offset = 0; + if (dosHeader != null) { + offset = dosHeader.e_lfanew + 4/*NT SIG*/; + } + + int ntHeaderSize = 0; + if (ntHeader64 != null) + ntHeaderSize = NTOptionalHeader64.NTHDRSZ; + else if (ntHeader32 != null) + ntHeaderSize = NTOptionalHeader32.NTHDRSZ; + + offset += FileHeader.FILHSZ + getOptionalHeader().getSize() + ntHeaderSize; + accessFile.seek(offset); + dataDirectories = new ImageDataDirectory[PEConstants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + byte[] data = new byte[dataDirectories.length * (4 + 4)]; + accessFile.readFully(data); + ReadMemoryAccess memory = new ReadMemoryAccess(data, true); + for (int i = 0; i < dataDirectories.length; i++) { + int rva = memory.getInt(); + int size = memory.getInt(); + dataDirectories[i] = new ImageDataDirectory(rva, size); + } + } + return dataDirectories; + } + + public SectionHeader[] getSectionHeaders() throws IOException { + if (scnhdrs == null) { + RandomAccessFile accessFile = getRandomAccessFile(); + scnhdrs = new SectionHeader[fileHeader.f_nscns]; + long offset = 0; + if (dosHeader != null) { + offset = dosHeader.e_lfanew + 4 /* NT SIG */; + } + offset += FileHeader.FILHSZ + fileHeader.f_opthdr; + for (int i = 0; i < scnhdrs.length; i++, offset += SectionHeader.SCNHSZ) { + scnhdrs[i] = new SectionHeader(accessFile, offset); + } + } + return scnhdrs; + } + + public Symbol[] getSymbols() throws IOException { + if (symbolTable == null) { + SectionHeader[] secHeaders = getSectionHeaders(); + NTOptionalHeader64 ntHeader64 = getNTOptionalHeader64(); + NTOptionalHeader32 ntHeader32 = getNTOptionalHeader32(); + + RandomAccessFile accessFile = getRandomAccessFile(); + long offset = fileHeader.f_symptr; + symbolTable = new Symbol[fileHeader.f_nsyms]; + for (int i = 0; i < symbolTable.length; i++, offset += Symbol.SYMSZ) { + Symbol newSym = new Symbol(accessFile, offset, (fileHeader.f_flags & FileHeader.F_AR32WR) == 0); + + // Now convert section offset of the symbol to image offset. + if (newSym.n_scnum >= 1 && newSym.n_scnum <= secHeaders.length) // valid section # + newSym.n_value += secHeaders[newSym.n_scnum - 1].s_vaddr; + + // convert to absolute address. + if (ntHeader64 != null) + newSym.n_value += ntHeader64.ImageBase; + else if (ntHeader32 != null) + newSym.n_value += ntHeader32.ImageBase; + + symbolTable[i] = newSym; + } + } + return symbolTable; + } + + public byte[] getStringTable() throws IOException { + if (stringTable == null) { + if (fileHeader.f_nsyms > 0) { + RandomAccessFile accessFile = getRandomAccessFile(); + long symbolsize = Symbol.SYMSZ * fileHeader.f_nsyms; + long offset = fileHeader.f_symptr + symbolsize; + accessFile.seek(offset); + byte[] bytes = new byte[4]; + accessFile.readFully(bytes); + int str_len = ReadMemoryAccess.getIntLE(bytes); + if (str_len > 4 && str_len < accessFile.length()) { + str_len -= 4; + stringTable = new byte[str_len]; + accessFile.seek(offset + 4); + accessFile.readFully(stringTable); + } else { + stringTable = new byte[0]; + } + } else { + stringTable = new byte[0]; + } + } + return stringTable; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + if (exeHeader != null) { + buffer.append(exeHeader); + } + if (dosHeader != null) { + buffer.append(dosHeader); + } + buffer.append(fileHeader); + if (optionalHeader != null) { + buffer.append(optionalHeader); + } + if (ntHeader64 != null) { + buffer.append(ntHeader64); + } else if (ntHeader32 != null) { + buffer.append(ntHeader32); + } + try { + ImageDataDirectory[] dirs = getImageDataDirectories(); + for (int i = 0; i < dirs.length; i++) { + buffer.append("Entry ").append(i); //$NON-NLS-1$ + buffer.append(" ").append(dirs[i]); //$NON-NLS-1$ + } + } catch (IOException e) { + e.printStackTrace(); + } + + try { + SectionHeader[] sections = getSectionHeaders(); + for (int i = 0; i < sections.length; i++) { + buffer.append(sections[i]); + } + } catch (IOException e) { + e.printStackTrace(); + } + + try { + Symbol[] symbols = getSymbols(); + for (int i = 0; i < symbols.length; i++) { + buffer.append(symbols[i]); + } + } catch (IOException e) { + e.printStackTrace(); + } + + try { + byte[] bytes = getStringTable(); + String[] strings = Coff64.getStringTable(bytes); + for (int i = 0; i < strings.length; i++) { + buffer.append(strings[i]); + } + } catch (IOException e) { + e.printStackTrace(); + } + return buffer.toString(); + } + + RandomAccessFile getRandomAccessFile() throws IOException { + if (rfile == null) { + rfile = new RandomAccessFile(filename, "r"); //$NON-NLS-1$ + } + return rfile; + } + + private ISymbolReader createCodeViewReader() { + ISymbolReader symReader = null; + final int IMAGE_DIRECTORY_ENTRY_DEBUG = 6; + + try { + // the debug directory is the 6th entry + NTOptionalHeader64 ntHeader64 = getNTOptionalHeader64(); + NTOptionalHeader32 ntHeader32 = getNTOptionalHeader32(); + if (ntHeader32 == null && ntHeader64 == null) + return null; + + int debugDir = 0, debugFormats = 0; + + if (ntHeader64 != null) { + if (ntHeader64.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_DEBUG) + return null; + + debugDir = ntHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + if (debugDir == 0) + return null; + + debugFormats = ntHeader64.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size / 28; + if (debugFormats == 0) + return null; + } else if (ntHeader32 != null) { + if (ntHeader32.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_DEBUG) + return null; + + debugDir = ntHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + if (debugDir == 0) + return null; + + debugFormats = ntHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size / 28; + if (debugFormats == 0) + return null; + } + + SectionHeader[] sections = getSectionHeaders(); + + // loop through the section headers to find the .rdata section + for (int i = 0; i < sections.length; i++) { + String name = new String(sections[i].s_name).trim(); + if (name.equals(".rdata")) { //$NON-NLS-1$ + // figure out the file offset of the debug ddirectory entries + int offsetInto_rdata = debugDir - sections[i].s_vaddr; + int fileOffset = sections[i].s_scnptr + offsetInto_rdata; + RandomAccessFile accessFile = getRandomAccessFile(); + + // loop through the debug directories looking for CodeView (type 2) + for (int j = 0; j < debugFormats; j++) { + PE64.IMAGE_DEBUG_DIRECTORY dir = new PE64.IMAGE_DEBUG_DIRECTORY(accessFile, fileOffset); + + if ((2 == dir.Type) && (dir.SizeOfData > 0)) { + // CodeView found, seek to actual data + int debugBase = dir.PointerToRawData; + accessFile.seek(debugBase); + + // sanity check. the first four bytes of the CodeView + // data should be "NB11" + String s2 = accessFile.readLine(); + if (s2.startsWith("NB11")) { //$NON-NLS-1$ + Attribute att = getAttribute(); + symReader = new CodeViewReader(accessFile, debugBase, att.isLittleEndian()); + return symReader; + } + } + fileOffset += dir.DEBUGDIRSZ; + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + + return symReader; + } + + private ISymbolReader createStabsReader() { + ISymbolReader symReader = null; + try { + SectionHeader[] sections = getSectionHeaders(); + byte[] stab = null; + byte[] stabstr = null; + + // loop through the section headers looking for stabs info + for (int i = 0; i < sections.length; i++) { + String name = new String(sections[i].s_name).trim(); + if (name.equals(".stab")) { //$NON-NLS-1$ + stab = sections[i].getRawData(); + } + if (name.equals(".stabstr")) { //$NON-NLS-1$ + stabstr = sections[i].getRawData(); + } + } + + // if we found both sections then proceed + if (stab != null && stabstr != null) { + Attribute att = getAttribute(); + symReader = new StabsReader(stab, stabstr, att.isLittleEndian()); + } + + } catch (IOException e) { + } + return symReader; + } + + public ISymbolReader getSymbolReader() { + ISymbolReader reader = null; + reader = createStabsReader(); + if (reader == null) { + reader = createCodeViewReader(); + } + if (reader == null) { + reader = createDwarfReader(); + } + return reader; + } + + private ISymbolReader createDwarfReader() { + DwarfReader reader = null; + // Check if Dwarf data exists + try { + reader = new DwarfReader(this); + } catch (IOException e) { + // No Dwarf data in the Elf. + } + return reader; + } + + /** + * @since 5.1 + */ + public String getStringTableEntry(int offset) throws IOException { + byte[] bytes = getStringTable(); + offset = offset - 4; + for (int i = offset; i < bytes.length; i++) { + if (bytes[i] == 0) { + return new String(bytes, offset, i - offset); + } + } + + return ""; //$NON-NLS-1$ + } + + /** + * @since 5.1 + */ + public String getFilename() { + return filename; + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java index 226ee4d8cd5..33a26f029ae 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PEArchive.java @@ -30,13 +30,18 @@ import org.eclipse.cdt.core.CCorePlugin; * @see ARHeader */ @Deprecated -public class PEArchive { +public class PEArchive implements AutoCloseable { protected String filename; protected RandomAccessFile rfile; protected long strtbl_pos = -1; private ARHeader[] headers; + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (rfile != null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive.java index f2c3fe73c98..5f90c00410d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive.java @@ -20,6 +20,11 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; import org.eclipse.cdt.utils.AR.ARHeader; import org.eclipse.core.runtime.IPath; +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link CygwinPEBinaryArchive64}. + * This class is planned for removal in next major release. + */ +@Deprecated public class CygwinPEBinaryArchive extends PEBinaryArchive { /** diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive64.java new file mode 100644 index 00000000000..1737b3401cd --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive64.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2004, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial CygwinPEBinaryArchive class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.utils.AR.ARHeader; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class CygwinPEBinaryArchive64 extends PEBinaryArchive64 { + + /** + * @param parser + * @param path + * @throws IOException + */ + public CygwinPEBinaryArchive64(PEParser64 parser, IPath path) throws IOException { + super(parser, path); + } + + @Override + protected void addArchiveMembers(ARHeader[] headers, ArrayList<IBinaryObject> children2) { + for (int i = 0; i < headers.length; i++) { + IBinaryObject bin = new CygwinPEBinaryObject64(getBinaryParser(), getPath(), headers[i]); + children.add(bin); + } + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable.java index 5051e409291..27853d19c1d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable.java @@ -18,6 +18,11 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.core.runtime.IPath; +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link CygwinPEBinaryExecutable64}. + * This class is planned for removal in next major release. + */ +@Deprecated public class CygwinPEBinaryExecutable extends CygwinPEBinaryObject implements IBinaryExecutable { /** diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable64.java new file mode 100644 index 00000000000..f95f032c6e4 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable64.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2004, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial CygwinPEBinaryExecutable class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class CygwinPEBinaryExecutable64 extends CygwinPEBinaryObject64 implements IBinaryExecutable { + + /** + * @param parser + * @param path + * @param executable + */ + public CygwinPEBinaryExecutable64(IBinaryParser parser, IPath path, int executable) { + super(parser, path, IBinaryFile.EXECUTABLE); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java index d74bed3ffcb..20c5de6ac8c 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java @@ -38,9 +38,11 @@ import org.eclipse.cdt.utils.coff.PE; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; -/* - * CygwinPEBinaryObject +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link CygwinPEBinaryObject64}. + * This class is planned for removal in next major release. */ +@Deprecated public class CygwinPEBinaryObject extends PEBinaryObject { private Addr2line autoDisposeAddr2line; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject64.java new file mode 100644 index 00000000000..1d93731a844 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject64.java @@ -0,0 +1,320 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial CygwinPEBinaryObject class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.CConventions; +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.AR.ARHeader; +import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.CPPFilt; +import org.eclipse.cdt.utils.CygPath; +import org.eclipse.cdt.utils.ICygwinToolsFactroy; +import org.eclipse.cdt.utils.NM; +import org.eclipse.cdt.utils.Objdump; +import org.eclipse.cdt.utils.Symbol; +import org.eclipse.cdt.utils.coff.Coff64; +import org.eclipse.cdt.utils.coff.PE64; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * @since 6.9 + */ +public class CygwinPEBinaryObject64 extends PEBinaryObject64 { + + private Addr2line autoDisposeAddr2line; + private Addr2line symbolLoadingAddr2line; + private CygPath symbolLoadingCygPath; + private CPPFilt symbolLoadingCPPFilt; + long starttime; + + /** + * @param parser + * @param path + * @param header + */ + public CygwinPEBinaryObject64(IBinaryParser parser, IPath path, ARHeader header) { + super(parser, path, header); + } + + public CygwinPEBinaryObject64(IBinaryParser parser, IPath path, int type) { + super(parser, path, type); + } + + public Addr2line getAddr2line(boolean autodisposing) { + if (!autodisposing) { + return getAddr2line(); + } + if (autoDisposeAddr2line == null) { + autoDisposeAddr2line = getAddr2line(); + if (autoDisposeAddr2line != null) { + starttime = System.currentTimeMillis(); + Runnable worker = () -> { + + long diff = System.currentTimeMillis() - starttime; + while (diff < 10000) { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + break; + } + diff = System.currentTimeMillis() - starttime; + } + stopAddr2Line(); + }; + new Thread(worker, "Addr2line Reaper").start(); //$NON-NLS-1$ + } + } else { + starttime = System.currentTimeMillis(); // reset autodispose timeout + } + return autoDisposeAddr2line; + } + + synchronized void stopAddr2Line() { + if (autoDisposeAddr2line != null) { + autoDisposeAddr2line.dispose(); + } + autoDisposeAddr2line = null; + } + + private Addr2line getAddr2line() { + ICygwinToolsFactroy factory = getBinaryParser().getAdapter(ICygwinToolsFactroy.class); + if (factory != null) { + return factory.getAddr2line(getPath()); + } + return null; + } + + protected CPPFilt getCPPFilt() { + ICygwinToolsFactroy factory = getBinaryParser().getAdapter(ICygwinToolsFactroy.class); + if (factory != null) { + return factory.getCPPFilt(); + } + return null; + } + + protected Objdump getObjdump() { + ICygwinToolsFactroy factory = getBinaryParser().getAdapter(ICygwinToolsFactroy.class); + if (factory != null) { + return factory.getObjdump(getPath()); + } + return null; + } + + protected CygPath getCygPath() { + ICygwinToolsFactroy factory = getBinaryParser().getAdapter(ICygwinToolsFactroy.class); + if (factory != null) { + return factory.getCygPath(); + } + return null; + } + + /** + */ + protected NM getNM() { + ICygwinToolsFactroy factory = getBinaryParser().getAdapter(ICygwinToolsFactroy.class); + if (factory != null) { + return factory.getNM(getPath()); + } + return null; + } + + /** + * @throws IOException + * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents() + */ + @Override + public InputStream getContents() throws IOException { + InputStream stream = null; + Objdump objdump = getObjdump(); + if (objdump != null) { + try { + byte[] contents = objdump.getOutput(); + stream = new ByteArrayInputStream(contents); + } catch (IOException e) { + // Nothing + } + } + if (stream == null) { + stream = super.getContents(); + } + return stream; + } + + @Override + protected void loadSymbols(PE64 pe) throws IOException { + symbolLoadingAddr2line = getAddr2line(false); + symbolLoadingCPPFilt = getCPPFilt(); + symbolLoadingCygPath = getCygPath(); + + ArrayList<Symbol> list = new ArrayList<>(); + super.loadSymbols(pe, list); + + // Add any global symbols + NM nm = getNM(); + if (nm != null) { + NM.AddressNamePair[] pairs = nm.getBSSSymbols(); + for (int i = 0; i < pairs.length; ++i) { + addSymbol(pairs[i], list, ISymbol.VARIABLE); + } + pairs = nm.getDataSymbols(); + for (int i = 0; i < pairs.length; ++i) { + addSymbol(pairs[i], list, ISymbol.VARIABLE); + } + } + // pairs = nm.getTextSymbols(); + // for (int i = 0; i < pairs.length; ++i) { + // addSymbol(pairs[i], list, ISymbol.FUNCTION); + // } + symbols = list.toArray(NO_SYMBOLS); + Arrays.sort(symbols); + list.clear(); + + if (symbolLoadingAddr2line != null) { + symbolLoadingAddr2line.dispose(); + symbolLoadingAddr2line = null; + } + if (symbolLoadingCPPFilt != null) { + symbolLoadingCPPFilt.dispose(); + symbolLoadingCPPFilt = null; + } + if (symbolLoadingCygPath != null) { + symbolLoadingCygPath.dispose(); + symbolLoadingCygPath = null; + } + } + + private void addSymbol(NM.AddressNamePair p, List<Symbol> list, int type) { + String name = p.name; + if (name != null && name.length() > 0 && CConventions.isValidIdentifier(name)) { + IAddress addr = new Addr32(p.address); + int size = 4; + if (symbolLoadingCPPFilt != null) { + try { + name = symbolLoadingCPPFilt.getFunction(name); + } catch (IOException e1) { + symbolLoadingCPPFilt.dispose(); + symbolLoadingCPPFilt = null; + } + } + if (symbolLoadingAddr2line != null) { + try { + String filename = symbolLoadingAddr2line.getFileName(addr); + // Addr2line returns the funny "??" when it can not find + // the file. + if (filename != null && filename.equals("??")) { //$NON-NLS-1$ + filename = null; + } + if (filename != null) { + try { + if (symbolLoadingCygPath != null) { + filename = symbolLoadingCygPath.getFileName(filename); + } + } catch (IOException e) { + symbolLoadingCygPath.dispose(); + symbolLoadingCygPath = null; + } + } + IPath file = filename != null ? new Path(filename) : Path.EMPTY; + int startLine = symbolLoadingAddr2line.getLineNumber(addr); + int endLine = symbolLoadingAddr2line.getLineNumber(addr.add(size - 1)); + list.add(new CygwinSymbol64(this, name, type, addr, size, file, startLine, endLine)); + } catch (IOException e) { + symbolLoadingAddr2line.dispose(); + symbolLoadingAddr2line = null; + } + } + } + } + + @Override + protected void addSymbols(Coff64.Symbol[] peSyms, byte[] table, List<Symbol> list) { + for (Coff64.Symbol peSym : peSyms) { + if (peSym.isFunction() || peSym.isPointer() || peSym.isArray()) { + String name = peSym.getName(table); + if (name == null || name.trim().length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) { + continue; + } + int type = peSym.isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; + IAddress addr = new Addr32(peSym.n_value); + int size = 4; + if (symbolLoadingCPPFilt != null) { + try { + name = symbolLoadingCPPFilt.getFunction(name); + } catch (IOException e1) { + symbolLoadingCPPFilt.dispose(); + symbolLoadingCPPFilt = null; + } + } + if (symbolLoadingAddr2line != null) { + try { + String filename = symbolLoadingAddr2line.getFileName(addr); + // Addr2line returns the funny "??" when it can not find + // the file. + if (filename != null && filename.equals("??")) { //$NON-NLS-1$ + filename = null; + } + + if (filename != null) { + try { + if (symbolLoadingCygPath != null) { + filename = symbolLoadingCygPath.getFileName(filename); + } + } catch (IOException e) { + symbolLoadingCygPath.dispose(); + symbolLoadingCygPath = null; + } + } + IPath file = filename != null ? new Path(filename) : Path.EMPTY; + int startLine = symbolLoadingAddr2line.getLineNumber(addr); + int endLine = symbolLoadingAddr2line.getLineNumber(addr.add(size - 1)); + list.add(new CygwinSymbol64(this, name, type, addr, size, file, startLine, endLine)); + } catch (IOException e) { + symbolLoadingAddr2line.dispose(); + symbolLoadingAddr2line = null; + // the symbol still needs to be added + list.add(new CygwinSymbol64(this, name, type, addr, size)); + } + } else { + list.add(new CygwinSymbol64(this, name, type, addr, size)); + } + + } + } + } + + @Override + @SuppressWarnings("unchecked") + public <T> T getAdapter(Class<T> adapter) { + if (adapter == Addr2line.class) { + return (T) getAddr2line(false); + } else if (adapter == CPPFilt.class) { + return (T) getCPPFilt(); + } else if (adapter == CygPath.class) { + return (T) getCygPath(); + } + return super.getAdapter(adapter); + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared.java index 323a576b1c8..8c0faeb0750 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared.java @@ -18,6 +18,11 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryShared; import org.eclipse.core.runtime.IPath; +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link CygwinPEBinaryShared64}. + * This class is planned for removal in next major release. + */ +@Deprecated public class CygwinPEBinaryShared extends CygwinPEBinaryObject implements IBinaryShared { protected CygwinPEBinaryShared(IBinaryParser parser, IPath path) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared64.java new file mode 100644 index 00000000000..2bbbeaac8df --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared64.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial CygwinPEBinaryShared class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.IBinaryShared; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class CygwinPEBinaryShared64 extends CygwinPEBinaryObject64 implements IBinaryShared { + + protected CygwinPEBinaryShared64(IBinaryParser parser, IPath path) { + super(parser, path, IBinaryFile.SHARED); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser.java index c0dd7d6defa..d44b19231c2 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser.java @@ -21,7 +21,10 @@ import org.eclipse.cdt.utils.ICygwinToolsFactroy; import org.eclipse.core.runtime.IPath; /** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link CygwinPEParser64}. + * This class is planned for removal in next major release. */ +@Deprecated public class CygwinPEParser extends PEParser { private DefaultCygwinToolFactory toolFactory; @@ -63,17 +66,13 @@ public class CygwinPEParser extends PEParser { return new DefaultCygwinToolFactory(this); } - /* (non-Javadoc) - * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public Object getAdapter(Class adapter) { + public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(ICygwinToolsFactroy.class)) { if (toolFactory == null) { toolFactory = createToolFactory(); } - return toolFactory; + return adapter.cast(toolFactory); } return super.getAdapter(adapter); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser64.java new file mode 100644 index 00000000000..2bfa013b3df --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser64.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - Initial CygwinPEParser class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; + +import org.eclipse.cdt.utils.DefaultCygwinToolFactory; +import org.eclipse.cdt.utils.ICygwinToolsFactroy; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class CygwinPEParser64 extends PEParser64 { + + private DefaultCygwinToolFactory toolFactory; + + /** + * @see org.eclipse.cdt.core.IBinaryParser#getFormat() + */ + @Override + public String getFormat() { + return "Cygwin PE"; //$NON-NLS-1$ + } + + @Override + protected IBinaryArchive createBinaryArchive(IPath path) throws IOException { + return new CygwinPEBinaryArchive64(this, path); + } + + @Override + protected IBinaryExecutable createBinaryExecutable(IPath path) { + return new CygwinPEBinaryExecutable64(this, path, IBinaryFile.EXECUTABLE); + } + + @Override + protected IBinaryObject createBinaryCore(IPath path) { + return new CygwinPEBinaryObject64(this, path, IBinaryFile.CORE); + } + + @Override + protected IBinaryObject createBinaryObject(IPath path) { + return new CygwinPEBinaryObject64(this, path, IBinaryFile.OBJECT); + } + + @Override + protected IBinaryShared createBinaryShared(IPath path) { + return new CygwinPEBinaryShared64(this, path); + } + + protected DefaultCygwinToolFactory createToolFactory() { + return new DefaultCygwinToolFactory(this); + } + + @Override + public <T> T getAdapter(Class<T> adapter) { + if (adapter.isAssignableFrom(ICygwinToolsFactroy.class)) { + if (toolFactory == null) { + toolFactory = createToolFactory(); + } + return adapter.cast(toolFactory); + } + return super.getAdapter(adapter); + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java index e88c2bade19..3aae202adda 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java @@ -27,11 +27,10 @@ import org.eclipse.cdt.utils.Symbol; import org.eclipse.core.runtime.IPath; /** - * @author DInglis - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link CygwinSymbol64}. + * This class is planned for removal in next major release. */ +@Deprecated class CygwinSymbol extends Symbol { /** @@ -60,9 +59,6 @@ class CygwinSymbol extends Symbol { super(binary, name, type, addr, size); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.Symbol#getLineNumber(long) - */ @Override public int getLineNumber(long offset) { int line = -1; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol64.java new file mode 100644 index 00000000000..e4bb287d347 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol64.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2005, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial CygwinSymbol class + *******************************************************************************/ +/* + * Created on Jul 6, 2004 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.Symbol; +import org.eclipse.core.runtime.IPath; + +/** + * @author DInglis + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +class CygwinSymbol64 extends Symbol { + + /** + * @param binary + * @param name + * @param type + * @param addr + * @param size + * @param sourceFile + * @param startLine + * @param endLine + */ + public CygwinSymbol64(CygwinPEBinaryObject64 binary, String name, int type, IAddress addr, long size, + IPath sourceFile, int startLine, int endLine) { + super(binary, name, type, addr, size, sourceFile, startLine, endLine); + } + + /** + * @param binary + * @param name + * @param type + * @param addr + * @param size + */ + public CygwinSymbol64(CygwinPEBinaryObject64 binary, String name, int type, IAddress addr, long size) { + super(binary, name, type, addr, size); + } + + @Override + public int getLineNumber(long offset) { + int line = -1; + Addr2line addr2line = ((CygwinPEBinaryObject64) binary).getAddr2line(true); + if (addr2line != null) { + try { + return addr2line.getLineNumber(getAddress().add(offset)); + } catch (IOException e) { + // ignore + } + } + return line; + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive.java index d5034aa9dfa..8d833997de2 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive.java @@ -25,14 +25,19 @@ import org.eclipse.cdt.utils.BinaryFile; import org.eclipse.core.runtime.IPath; /** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PEBinaryArchive64}. + * This class is planned for removal in next major release. */ +@Deprecated public class PEBinaryArchive extends BinaryFile implements IBinaryArchive { ArrayList<IBinaryObject> children; public PEBinaryArchive(PEParser parser, IPath path) throws IOException { super(parser, path, IBinaryFile.ARCHIVE); - new AR(path.toOSString()).dispose(); // check file type + try (AR ar = new AR(path.toOSString())) { + // create the object just to check file type + } children = new ArrayList<>(5); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive64.java new file mode 100644 index 00000000000..c37b4774506 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive64.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - Initial PEBinaryArchive class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; +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.AR; +import org.eclipse.cdt.utils.AR.ARHeader; +import org.eclipse.cdt.utils.BinaryFile; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class PEBinaryArchive64 extends BinaryFile implements IBinaryArchive { + + ArrayList<IBinaryObject> children; + + public PEBinaryArchive64(PEParser64 parser, IPath path) throws IOException { + super(parser, path, IBinaryFile.ARCHIVE); + try (AR ar = new AR(path.toOSString())) { + // create the object just to check file type + } + children = new ArrayList<>(5); + } + + /** + * @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects() + */ + @Override + public IBinaryObject[] getObjects() { + if (hasChanged()) { + children.clear(); + AR ar = null; + try { + ar = new AR(getPath().toOSString()); + AR.ARHeader[] headers = ar.getHeaders(); + addArchiveMembers(headers, children); + } catch (IOException e) { + //e.printStackTrace(); + } + if (ar != null) { + ar.dispose(); + } + children.trimToSize(); + } + return children.toArray(new IBinaryObject[0]); + } + + /** + * @param headers + * @param children2 + */ + protected void addArchiveMembers(ARHeader[] headers, ArrayList<IBinaryObject> children2) { + for (int i = 0; i < headers.length; i++) { + IBinaryObject bin = new PEBinaryObject64(getBinaryParser(), getPath(), headers[i]); + children.add(bin); + } + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable.java index 984d0f43f3c..7a79a6d1486 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable.java @@ -18,6 +18,11 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.core.runtime.IPath; +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PEBinaryExecutable64}. + * This class is planned for removal in next major release. + */ +@Deprecated public class PEBinaryExecutable extends PEBinaryObject implements IBinaryExecutable { public PEBinaryExecutable(IBinaryParser parser, IPath path) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable64.java new file mode 100644 index 00000000000..a50090109b6 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable64.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial PEBinaryExecutable class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class PEBinaryExecutable64 extends PEBinaryObject64 implements IBinaryExecutable { + + public PEBinaryExecutable64(IBinaryParser parser, IPath path) { + super(parser, path, IBinaryFile.EXECUTABLE); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java index 3add07a14af..9f7fd4e81fc 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java @@ -35,7 +35,10 @@ import org.eclipse.cdt.utils.coff.PE; import org.eclipse.core.runtime.IPath; /** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PEBinaryObject64}. + * This class is planned for removal in next major release. */ +@Deprecated public class PEBinaryObject extends BinaryObjectAdapter { BinaryObjectInfo info; @@ -51,9 +54,6 @@ public class PEBinaryObject extends BinaryObjectAdapter { super(parser, p, type); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getName() - */ @Override public String getName() { if (header != null) { @@ -62,9 +62,6 @@ public class PEBinaryObject extends BinaryObjectAdapter { return super.getName(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents() - */ @Override public InputStream getContents() throws IOException { if (getPath() != null && header != null) { @@ -73,9 +70,6 @@ public class PEBinaryObject extends BinaryObjectAdapter { return super.getContents(); } - /** - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols() - */ @Override public ISymbol[] getSymbols() { if (hasChanged() || symbols == null) { @@ -129,33 +123,21 @@ public class PEBinaryObject extends BinaryObjectAdapter { } protected void loadAll() throws IOException { - PE pe = null; - try { - pe = getPE(); + try (PE pe = getPE()) { loadInfo(pe); loadSymbols(pe); - } finally { - if (pe != null) { - pe.dispose(); - } } } protected void loadInfo() throws IOException { - PE pe = null; - try { - pe = getPE(); + try (PE pe = getPE()) { loadInfo(pe); - } finally { - if (pe != null) { - pe.dispose(); - } } } protected void loadInfo(PE pe) throws IOException { info = new BinaryObjectInfo(); - PE.Attribute attribute = getPE().getAttribute(); + PE.Attribute attribute = pe.getAttribute(); info.isLittleEndian = attribute.isLittleEndian(); info.hasDebug = attribute.hasDebug(); info.cpu = attribute.getCPU(); @@ -188,9 +170,6 @@ public class PEBinaryObject extends BinaryObjectAdapter { } } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory() - */ @Override public IAddressFactory getAddressFactory() { if (addressFactory == null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java new file mode 100644 index 00000000000..849f36e355b --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - Initial PEBinaryObject class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.IAddressFactory; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.core.ISymbolReader; +import org.eclipse.cdt.utils.AR; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr32Factory; +import org.eclipse.cdt.utils.BinaryObjectAdapter; +import org.eclipse.cdt.utils.Symbol; +import org.eclipse.cdt.utils.coff.Coff64; +import org.eclipse.cdt.utils.coff.PE64; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class PEBinaryObject64 extends BinaryObjectAdapter { + + BinaryObjectInfo info; + IAddressFactory addressFactory; + ISymbol[] symbols; + AR.ARHeader header; + + public PEBinaryObject64(IBinaryParser parser, IPath path, AR.ARHeader header) { + super(parser, path, IBinaryFile.OBJECT); + } + + public PEBinaryObject64(IBinaryParser parser, IPath p, int type) { + super(parser, p, type); + } + + @Override + public String getName() { + if (header != null) { + return header.getObjectName(); + } + return super.getName(); + } + + @Override + public InputStream getContents() throws IOException { + if (getPath() != null && header != null) { + return new ByteArrayInputStream(header.getObjectData()); + } + return super.getContents(); + } + + /** + * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols() + */ + @Override + public ISymbol[] getSymbols() { + if (hasChanged() || symbols == null) { + try { + loadAll(); + } catch (IOException e) { + symbols = NO_SYMBOLS; + } + } + return symbols; + } + + @Override + protected BinaryObjectInfo getBinaryObjectInfo() { + if (hasChanged() || info == null) { + try { + loadInfo(); + } catch (IOException e) { + info = new BinaryObjectInfo(); + } + } + return info; + } + + @Override + @SuppressWarnings("unchecked") + public <T> T getAdapter(Class<T> adapter) { + if (adapter.equals(PE64.class)) { + try { + if (header != null) { + return (T) new PE64(getPath().toOSString(), header.getObjectDataOffset()); + } + return (T) new PE64(getPath().toOSString()); + } catch (IOException e) { + } + } + if (adapter.equals(ISymbolReader.class)) { + PE64 pe = getAdapter(PE64.class); + if (pe != null) { + return (T) pe.getSymbolReader(); + } + } + return super.getAdapter(adapter); + } + + protected PE64 getPE() throws IOException { + if (header != null) { + return new PE64(getPath().toOSString(), header.getObjectDataOffset()); + } + return new PE64(getPath().toOSString()); + } + + protected void loadAll() throws IOException { + try (PE64 pe = getPE()) { + loadInfo(pe); + loadSymbols(pe); + } + } + + protected void loadInfo() throws IOException { + try (PE64 pe = getPE()) { + loadInfo(pe); + } + } + + protected void loadInfo(PE64 pe) throws IOException { + info = new BinaryObjectInfo(); + PE64.Attribute attribute = pe.getAttribute(); + info.isLittleEndian = attribute.isLittleEndian(); + info.hasDebug = attribute.hasDebug(); + info.cpu = attribute.getCPU(); + } + + protected void loadSymbols(PE64 pe) throws IOException { + ArrayList<Symbol> list = new ArrayList<>(); + loadSymbols(pe, list); + symbols = list.toArray(NO_SYMBOLS); + Arrays.sort(symbols); + list.clear(); + } + + protected void loadSymbols(PE64 pe, List<Symbol> list) throws IOException { + Coff64.Symbol[] peSyms = pe.getSymbols(); + byte[] table = pe.getStringTable(); + addSymbols(peSyms, table, list); + } + + protected void addSymbols(Coff64.Symbol[] peSyms, byte[] table, List<Symbol> list) { + for (org.eclipse.cdt.utils.coff.Coff64.Symbol peSym : peSyms) { + if (peSym.isFunction() || peSym.isPointer() || peSym.isArray()) { + String name = peSym.getName(table); + if (name == null || name.trim().length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) { + continue; + } + int type = peSym.isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; + list.add(new Symbol(this, name, type, new Addr32(peSym.n_value), peSym.getSize())); + } + } + } + + @Override + public IAddressFactory getAddressFactory() { + if (addressFactory == null) { + addressFactory = new Addr32Factory(); + } + return addressFactory; + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared.java index c083e9c5186..79f8a67d5b4 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared.java @@ -18,6 +18,11 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryShared; import org.eclipse.core.runtime.IPath; +/** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PEBinaryShared64}. + * This class is planned for removal in next major release. + */ +@Deprecated public class PEBinaryShared extends PEBinaryObject implements IBinaryShared { public PEBinaryShared(IBinaryParser parser, IPath p) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared64.java new file mode 100644 index 00000000000..041b2b39426 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared64.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - initial PEBinaryShared class + *******************************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.IBinaryShared; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class PEBinaryShared64 extends PEBinaryObject64 implements IBinaryShared { + + public PEBinaryShared64(IBinaryParser parser, IPath p) { + super(parser, p, IBinaryFile.SHARED); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java index ea691ae0c4d..d1550fa4486 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java @@ -27,20 +27,17 @@ import org.eclipse.cdt.utils.coff.PEConstants; import org.eclipse.core.runtime.IPath; /** + * @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PEParser64}. + * This class is planned for removal in next major release. */ +@Deprecated public class PEParser extends AbstractCExtension implements IBinaryParser { - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(IPath path) throws IOException { return getBinary(null, path); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException { if (path == null) { @@ -89,17 +86,11 @@ public class PEParser extends AbstractCExtension implements IBinaryParser { return binary; } - /** - * @see org.eclipse.cdt.core.IBinaryParser#getFormat() - */ @Override public String getFormat() { return "PE"; //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public boolean isBinary(byte[] array, IPath path) { boolean isBin = PE.isExeHeader(array) || AR.isARHeader(array); @@ -132,9 +123,6 @@ public class PEParser extends AbstractCExtension implements IBinaryParser { return isBin; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize() - */ @Override public int getHintBufferSize() { return 512; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser64.java new file mode 100644 index 00000000000..4497c6a68be --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser64.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 Space Codesign Systems and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Space Codesign Systems - Initial API and implementation + * QNX Software Systems - Initial PEParser class + *******************************************************************************/ + +package org.eclipse.cdt.utils.coff.parser; + +import java.io.EOFException; +import java.io.IOException; + +import org.eclipse.cdt.core.AbstractCExtension; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.utils.AR; +import org.eclipse.cdt.utils.coff.PE64; +import org.eclipse.cdt.utils.coff.PE64.Attribute; +import org.eclipse.cdt.utils.coff.PEConstants; +import org.eclipse.core.runtime.IPath; + +/** + * @since 6.9 + */ +public class PEParser64 extends AbstractCExtension implements IBinaryParser { + + @Override + public IBinaryFile getBinary(IPath path) throws IOException { + return getBinary(null, path); + } + + @Override + public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException { + if (path == null) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.nullPath")); //$NON-NLS-1$ + } + + IBinaryFile binary = null; + try { + PE64.Attribute attribute = null; + if (hints != null && hints.length > 0) { + try { + attribute = PE64.getAttribute(hints); + } catch (EOFException e) { + // continue to try + } + } + // the hints may have to small, keep on trying. + if (attribute == null) { + attribute = PE64.getAttribute(path.toOSString()); + } + + if (attribute != null) { + switch (attribute.getType()) { + case Attribute.PE_TYPE_EXE: + binary = createBinaryExecutable(path); + break; + + case Attribute.PE_TYPE_SHLIB: + binary = createBinaryShared(path); + break; + + case Attribute.PE_TYPE_OBJ: + binary = createBinaryObject(path); + break; + + case Attribute.PE_TYPE_CORE: + binary = createBinaryCore(path); + break; + } + } + } catch (IOException e) { + // Is it an Archive? + binary = createBinaryArchive(path); + } + + return binary; + } + + /** + * @see org.eclipse.cdt.core.IBinaryParser#getFormat() + */ + @Override + public String getFormat() { + return "PE"; //$NON-NLS-1$ + } + + @Override + public boolean isBinary(byte[] array, IPath path) { + boolean isBin = PE64.isExeHeader(array) || AR.isARHeader(array); + // It maybe an object file try the known machine types. + if (!isBin && array.length > 1) { + int f_magic = (((array[1] & 0xff) << 8) | (array[0] & 0xff)); + switch (f_magic) { + case PEConstants.IMAGE_FILE_MACHINE_ALPHA: + case PEConstants.IMAGE_FILE_MACHINE_ARM: + case PEConstants.IMAGE_FILE_MACHINE_ALPHA64: + case PEConstants.IMAGE_FILE_MACHINE_I386: + case PEConstants.IMAGE_FILE_MACHINE_IA64: + case PEConstants.IMAGE_FILE_MACHINE_M68K: + case PEConstants.IMAGE_FILE_MACHINE_MIPS16: + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU: + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16: + case PEConstants.IMAGE_FILE_MACHINE_POWERPC: + case PEConstants.IMAGE_FILE_MACHINE_R3000: + case PEConstants.IMAGE_FILE_MACHINE_R4000: + case PEConstants.IMAGE_FILE_MACHINE_R10000: + case PEConstants.IMAGE_FILE_MACHINE_SH3: + case PEConstants.IMAGE_FILE_MACHINE_SH4: + case PEConstants.IMAGE_FILE_MACHINE_THUMB: + case PEConstants.IMAGE_FILE_MACHINE_ARM2: + // Ok; + isBin = true; + break; + } + } + return isBin; + } + + @Override + public int getHintBufferSize() { + return 512; + } + + protected IBinaryExecutable createBinaryExecutable(IPath path) { + return new PEBinaryExecutable64(this, path); + } + + protected IBinaryObject createBinaryCore(IPath path) { + return new PEBinaryObject64(this, path, IBinaryFile.CORE); + } + + protected IBinaryObject createBinaryObject(IPath path) { + return new PEBinaryObject64(this, path, IBinaryFile.OBJECT); + } + + protected IBinaryShared createBinaryShared(IPath path) { + return new PEBinaryShared64(this, path); + } + + protected IBinaryArchive createBinaryArchive(IPath path) throws IOException { + return new PEBinaryArchive64(this, path); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/IDebugEntryRequestor.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/IDebugEntryRequestor.java index d0c89375953..025abfcd33c 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/IDebugEntryRequestor.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/IDebugEntryRequestor.java @@ -69,7 +69,7 @@ public interface IDebugEntryRequestor { /** * Statement in the compilation unit with a given address. * @param line lineno of the statement relative to the current compilation unit. - * @param offset addres of the statement relative to the current function. + * @param address address of the statement relative to the current function. */ void acceptStatement(int line, long address); @@ -80,23 +80,16 @@ public interface IDebugEntryRequestor { /** * floating point constant. - * @param name - * @param value */ void acceptFloatConst(String name, double value); /** * Type constant: "const b = 0", b is a type enum. - * @param name - * @param type - * @param address */ void acceptTypeConst(String name, DebugType type, int value); /** * Caught Exception. - * @param name - * @param value */ void acceptCaughtException(String name, DebugType type, long address); @@ -111,10 +104,6 @@ public interface IDebugEntryRequestor { /** * Record a variable. - * @param name - * @param type - * @param kind - * @param address */ void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java index 4ec78e0367c..132d8e026ca 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 QNX Software Systems and others. + * Copyright (c) 2000, 2019 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -27,7 +27,9 @@ import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.utils.coff.Coff.SectionHeader; +import org.eclipse.cdt.utils.coff.Coff64; import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.PE64; import org.eclipse.cdt.utils.debug.DebugUnknownType; import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; import org.eclipse.cdt.utils.debug.tools.DebugSym; @@ -184,9 +186,9 @@ public class Dwarf { boolean printEnabled = true; public Dwarf(String file) throws IOException { - Elf exe = new Elf(file); - init(exe); - exe.dispose(); + try (Elf exe = new Elf(file)) { + init(exe); + } } public Dwarf(Elf exe) throws IOException { @@ -200,6 +202,13 @@ public class Dwarf { init(exe); } + /** + * @since 6.9 + */ + public Dwarf(PE64 exe) throws IOException { + init(exe); + } + public void init(Elf exe) throws IOException { Elf.ELFhdr header = exe.getELFhdr(); isLE = header.e_ident[Elf.ELFhdr.EI_DATA] == Elf.ELFhdr.ELFDATA2LSB; @@ -229,8 +238,9 @@ public class Dwarf { } if (debugFile.exists()) { // if the debug file exists from above, open it and get the section info from it - Elf debugInfo = new Elf(debugFile.getCanonicalPath()); - sections = debugInfo.getSections(); + try (Elf debugInfo = new Elf(debugFile.getCanonicalPath())) { + sections = debugInfo.getSections(); + } debugInfoPath = new Path(debugFile.getCanonicalPath()); } } @@ -255,17 +265,17 @@ public class Dwarf { } File altFile = altPath.toFile(); if (altFile.exists()) { - Elf altInfo = new Elf(altFile.getCanonicalPath()); - Elf.Section[] altSections = altInfo.getSections(); - for (Section altSection : altSections) { - String altName = altSection.toString(); - for (String element : DWARF_ALT_SCNNAMES) { - if (altName.equals(element)) { - try { - dwarfAltSections.put(element, altSection.mapSectionData()); - } catch (Exception e) { - e.printStackTrace(); - CCorePlugin.log(e); + try (Elf altInfo = new Elf(altFile.getCanonicalPath())) { + Elf.Section[] altSections = altInfo.getSections(); + for (Section altSection : altSections) { + String altName = altSection.toString(); + for (String element : DWARF_ALT_SCNNAMES) { + if (altName.equals(element)) { + try { + dwarfAltSections.put(element, altSection.mapSectionData()); + } catch (Exception e) { + CCorePlugin.log(e); + } } } } @@ -320,6 +330,35 @@ public class Dwarf { } + /** + * @since 6.9 + */ + public void init(PE64 exe) throws IOException { + + isLE = true; + Coff64.SectionHeader[] sections = exe.getSectionHeaders(); + + for (int i = 0; i < sections.length; i++) { + String name = new String(sections[i].s_name).trim(); + if (name.startsWith("/")) //$NON-NLS-1$ + { + int stringTableOffset = Integer.parseInt(name.substring(1)); + name = exe.getStringTableEntry(stringTableOffset); + } + for (String element : Dwarf.DWARF_SCNNAMES) { + if (name.equals(element)) { + try { + dwarfSections.put(element, sections[i].mapSectionData()); + } catch (Exception e) { + e.printStackTrace(); + CCorePlugin.log(e); + } + } + } + } + + } + int read_4_bytes(ByteBuffer in) throws IOException { try { byte[] bytes = new byte[4]; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java index 624b27e59aa..20564a52723 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2016 Nokia and others. + * Copyright (c) 2007, 2019 Nokia and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -28,13 +28,12 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.xml.bind.DatatypeConverter; - import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ICompileOptionsFinder; import org.eclipse.cdt.core.ISymbolReader; import org.eclipse.cdt.utils.coff.Coff.SectionHeader; import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.PE64; import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; import org.eclipse.cdt.utils.elf.Elf; import org.eclipse.cdt.utils.elf.Elf.Section; @@ -79,6 +78,13 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions super(exe); } + /** + * @since 6.9 + */ + public DwarfReader(PE64 exe) throws IOException { + super(exe); + } + // Override parent. // @Override @@ -119,15 +125,16 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions } // The build-id location is taken by converting the binary bytes to hex string. // The first byte is used as a directory specifier (e.g. 51/a4578fe2). - String bName = DatatypeConverter.printHexBinary(byteArray).toLowerCase(); + String bName = printHexBinary(byteArray).toLowerCase(); buildId = bName.substring(0, 2) + "/" + bName.substring(2) + ".debug"; //$NON-NLS-1$ //$NON-NLS-2$ // The build-id file should be in the special directory /usr/lib/debug/.build-id IPath buildIdPath = new Path("/usr/lib/debug/.build-id").append(buildId); //$NON-NLS-1$ File buildIdFile = buildIdPath.toFile(); if (buildIdFile.exists()) { // if the debug file exists from above, open it and get the section info from it - Elf debugInfo = new Elf(buildIdFile.getCanonicalPath()); - sections = debugInfo.getSections(); + try (Elf debugInfo = new Elf(buildIdFile.getCanonicalPath())) { + sections = debugInfo.getSections(); + } have_build_id = true; debugInfoPath = new Path(buildIdFile.getCanonicalPath()).removeLastSegments(1); break; @@ -177,8 +184,9 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions } if (debugFile.exists()) { // if the debug file exists from above, open it and get the section info from it - Elf debugInfo = new Elf(debugFile.getCanonicalPath()); - sections = debugInfo.getSections(); + try (Elf debugInfo = new Elf(debugFile.getCanonicalPath())) { + sections = debugInfo.getSections(); + } debugInfoPath = new Path(debugFile.getCanonicalPath()).removeLastSegments(1); } } @@ -207,17 +215,17 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions } File altFile = altPath.toFile(); if (altFile.exists()) { - Elf altInfo = new Elf(altFile.getCanonicalPath()); - Elf.Section[] altSections = altInfo.getSections(); - for (Section altSection : altSections) { - String altName = altSection.toString(); - for (String element : DWARF_ALT_SectionsToParse) { - if (altName.equals(element)) { - try { - dwarfAltSections.put(element, altSection.mapSectionData()); - } catch (Exception e) { - e.printStackTrace(); - CCorePlugin.log(e); + try (Elf altInfo = new Elf(altFile.getCanonicalPath())) { + Elf.Section[] altSections = altInfo.getSections(); + for (Section altSection : altSections) { + String altName = altSection.toString(); + for (String element : DWARF_ALT_SectionsToParse) { + if (altName.equals(element)) { + try { + dwarfAltSections.put(element, altSection.mapSectionData()); + } catch (Exception e) { + CCorePlugin.log(e); + } } } } @@ -278,6 +286,13 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions m_parsed = false; } + private static String printHexBinary(byte[] byteArray) { + StringBuilder sb = new StringBuilder(byteArray.length * 2); + for (byte b : byteArray) + sb.append(String.format("%02x", b)); //$NON-NLS-1$ + return sb.toString(); + } + /* * Parse line table data of a compilation unit to get names of all source files * that contribute to the compilation unit. @@ -288,7 +303,11 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions ByteBuffer data = dwarfSections.get(DWARF_DEBUG_LINE); if (data != null) { try { - data.position(cuStmtList); + try { + data.position(cuStmtList); + } catch (IllegalArgumentException e) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.noData")); //$NON-NLS-1$ + } /* Read line table header: * @@ -374,7 +393,7 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions leb128 = read_unsigned_leb128(data); } } catch (IOException e) { - e.printStackTrace(); + CCorePlugin.log("Failed to parse part of dwarf header", e); //$NON-NLS-1$ } } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/Stabs.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/Stabs.java index c99897e1bb8..69ecba5cc61 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/Stabs.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/Stabs.java @@ -68,14 +68,12 @@ public class Stabs { // we support Elf and PE executable formats. try Elf // and then PE. - try { - Elf exe = new Elf(file); + try (Elf exe = new Elf(file)) { init(exe); - exe.dispose(); } catch (IOException e) { - PE exe = new PE(file); - init(exe); - exe.dispose(); + try (PE exe = new PE(file)) { + init(exe); + } } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/TypeNumber.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/TypeNumber.java index c37e6e9cbc9..7169856000f 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/TypeNumber.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/TypeNumber.java @@ -48,9 +48,6 @@ public class TypeNumber { return super.equals(obj); } - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { return fileno * 10 + typeno; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java index 3c24e1c8a7b..52dd8642b78 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java @@ -31,9 +31,9 @@ public class DebugAddr2line { DebugSymsRequestor symreq; public DebugAddr2line(String file) throws IOException { - Elf elf = new Elf(file); - init(elf); - elf.dispose(); + try (Elf elf = new Elf(file)) { + init(elf); + } } public DebugAddr2line(Elf elf) throws IOException { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java index 071f4073c94..7fae54ef2c8 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java @@ -46,9 +46,9 @@ public class DebugDump implements IDebugEntryRequestor { } void parse(String file) throws IOException { - Elf elf = new Elf(file); - parse(elf); - elf.dispose(); + try (Elf elf = new Elf(file)) { + parse(elf); + } } void parse(Elf elf) throws IOException { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java index 0a58348f5c6..b3aacd773cd 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java @@ -70,9 +70,6 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { return null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCompilationUnit(java.lang.String, long) - */ @Override public void enterCompilationUnit(String name, long address) { DebugSym sym = new DebugSym(); @@ -84,9 +81,6 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { list.add(sym); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCompilationUnit(long) - */ @Override public void exitCompilationUnit(long address) { if (currentCU != null) { @@ -95,23 +89,14 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { currentCU = null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterInclude(java.lang.String) - */ @Override public void enterInclude(String name) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitInclude() - */ @Override public void exitInclude() { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterFunction(java.lang.String, int, boolean, long) - */ @Override public void enterFunction(String name, DebugType type, boolean isGlobal, long address) { DebugSym sym = new DebugSym(); @@ -125,9 +110,6 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { list.add(sym); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitFunction(long) - */ @Override public void exitFunction(long address) { if (currentFunction != null) { @@ -136,23 +118,14 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { currentFunction = null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCodeBlock(long) - */ @Override public void enterCodeBlock(long offset) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCodeBlock(long) - */ @Override public void exitCodeBlock(long offset) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptStatement(int, long) - */ @Override public void acceptStatement(int line, long address) { DebugSym sym = new DebugSym(); @@ -172,30 +145,18 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { list.add(sym); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptIntegerConst(java.lang.String, long) - */ @Override public void acceptIntegerConst(String name, int value) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptFloatConst(java.lang.String, double) - */ @Override public void acceptFloatConst(String name, double value) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeConst(java.lang.String, org.eclipse.cdt.utils.debug.DebugType, int) - */ @Override public void acceptTypeConst(String name, DebugType type, int value) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptParameter(java.lang.String, int, int, long) - */ @Override public void acceptParameter(String name, DebugType type, DebugParameterKind kind, long offset) { DebugSym sym = new DebugSym(); @@ -208,9 +169,6 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { list.add(sym); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptVariable(java.lang.String, int, int, long) - */ @Override public void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address) { DebugSym sym = new DebugSym(); @@ -223,16 +181,10 @@ public class DebugSymsRequestor implements IDebugEntryRequestor { list.add(sym); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptCaughtException(java.lang.String, org.eclipse.cdt.utils.debug.DebugType, long) - */ @Override public void acceptCaughtException(String name, DebugType type, long address) { } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeDef(java.lang.String, org.eclipse.cdt.utils.debug.DebugType) - */ @Override public void acceptTypeDef(String name, DebugType type) { } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java index bb37c2db604..bb88792ac09 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java @@ -31,13 +31,18 @@ import org.eclipse.cdt.utils.ERandomAccessFile; * @see ARHeader */ @Deprecated -public class AR { +public class AR implements AutoCloseable { protected String filename; protected ERandomAccessFile efile; protected long strtbl_pos = -1; private ARHeader[] headers; + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (efile != null) { @@ -207,11 +212,10 @@ public class AR { efile.seek(elf_offset); efile.read(temp); } else { - efile = new ERandomAccessFile(filename, "r"); //$NON-NLS-1$ - efile.seek(elf_offset); - efile.read(temp); - efile.close(); - efile = null; + try (ERandomAccessFile tempfile = new ERandomAccessFile(filename, "r")) { //$NON-NLS-1$ + tempfile.seek(elf_offset); + tempfile.read(temp); + } } return temp; } @@ -237,6 +241,7 @@ public class AR { String hdr = efile.readLine(); if (hdr == null || hdr.compareTo("!<arch>") != 0) { //$NON-NLS-1$ efile.close(); + efile = null; throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$ } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java index ebd04b45671..9e3090e2a8d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java @@ -18,13 +18,17 @@ import static org.eclipse.cdt.internal.core.ByteUtils.makeInt; import static org.eclipse.cdt.internal.core.ByteUtils.makeLong; import static org.eclipse.cdt.internal.core.ByteUtils.makeShort; +import java.io.Closeable; import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.channels.FileChannel.MapMode; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.Iterator; +import java.util.NoSuchElementException; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IAddress; @@ -37,11 +41,11 @@ import org.eclipse.cdt.utils.Addr64Factory; import org.eclipse.cdt.utils.ERandomAccessFile; import org.eclipse.cdt.utils.debug.dwarf.DwarfReader; -public class Elf { - public final static int ELF32_ADDR_SIZE = 4; - public final static int ELF32_OFF_SIZE = 4; - public final static int ELF64_ADDR_SIZE = 8; - public final static int ELF64_OFF_SIZE = 8; +public class Elf implements AutoCloseable { + public static final int ELF32_ADDR_SIZE = 4; + public static final int ELF32_OFF_SIZE = 4; + public static final int ELF64_ADDR_SIZE = 8; + public static final int ELF64_OFF_SIZE = 8; protected ERandomAccessFile efile; @@ -50,120 +54,123 @@ public class Elf { protected String file; protected byte[] section_strtab; - private int syms = 0; private Symbol[] symbols; - private Symbol[] symtab_symbols; - private Section symtab_sym; - private Symbol[] dynsym_symbols; - private Section dynsym_sym; - private boolean sections_mapped; // Have sections been mapped? Used to clean up properly in Elf.Dispose. + /** .symtab section */ + private Symbol[] symbolsTable; + /** .dynSym section */ + private Symbol[] dynamicSymbols; + private boolean areSectionsMapped; // Have sections been mapped? Used to clean up properly in Elf.Dispose. protected String EMPTY_STRING = ""; //$NON-NLS-1$ + private long elfOffset; public class ELFhdr { /* e_ident offsets */ - public final static int EI_MAG0 = 0; - public final static int EI_MAG1 = 1; - public final static int EI_MAG2 = 2; - public final static int EI_MAG3 = 3; - public final static int EI_CLASS = 4; - public final static int EI_DATA = 5; - public final static int EI_VERSION = 6; - public final static int EI_PAD = 7; - public final static int EI_NDENT = 16; + public static final int EI_MAG0 = 0; + public static final int EI_MAG1 = 1; + public static final int EI_MAG2 = 2; + public static final int EI_MAG3 = 3; + public static final int EI_CLASS = 4; + public static final int EI_DATA = 5; + public static final int EI_VERSION = 6; + public static final int EI_PAD = 7; + public static final int EI_NDENT = 16; /* e_ident[EI_CLASS] */ - public final static int ELFCLASSNONE = 0; - public final static int ELFCLASS32 = 1; - public final static int ELFCLASS64 = 2; + public static final int ELFCLASSNONE = 0; + public static final int ELFCLASS32 = 1; + public static final int ELFCLASS64 = 2; /* e_ident[EI_DATA] */ - public final static int ELFDATANONE = 0; - public final static int ELFDATA2LSB = 1; - public final static int ELFDATA2MSB = 2; + public static final int ELFDATANONE = 0; + public static final int ELFDATA2LSB = 1; + public static final int ELFDATA2MSB = 2; /* values of e_type */ - public final static int ET_NONE = 0; - public final static int ET_REL = 1; - public final static int ET_EXEC = 2; - public final static int ET_DYN = 3; - public final static int ET_CORE = 4; - public final static int ET_LOPROC = 0xff00; - public final static int ET_HIPROC = 0xffff; + public static final int ET_NONE = 0; + public static final int ET_REL = 1; + public static final int ET_EXEC = 2; + public static final int ET_DYN = 3; + public static final int ET_CORE = 4; + public static final int ET_LOPROC = 0xff00; + public static final int ET_HIPROC = 0xffff; /* values of e_machine */ - public final static int EM_NONE = 0; - public final static int EM_M32 = 1; - public final static int EM_SPARC = 2; - public final static int EM_386 = 3; - public final static int EM_68K = 4; - public final static int EM_88K = 5; - public final static int EM_486 = 6; - public final static int EM_860 = 7; - public final static int EM_MIPS = 8; - public final static int EM_MIPS_RS3_LE = 10; - public final static int EM_RS6000 = 11; - public final static int EM_PARISC = 15; - public final static int EM_nCUBE = 16; - public final static int EM_VPP550 = 17; - public final static int EM_SPARC32PLUS = 18; - public final static int EM_PPC = 20; - public final static int EM_PPC64 = 21; - public final static int EM_ARM = 40; - public final static int EM_SH = 42; - public final static int EM_SPARCV9 = 43; - public final static int EM_TRICORE = 44; - public final static int EM_H8_300 = 46; - public final static int EM_H8_300H = 47; - public final static int EM_IA_64 = 50; - public final static int EM_COLDFIRE = 52; - public final static int EM_STARCORE = 58; - public final static int EM_X86_64 = 62; - public final static int EM_ST100 = 60; + public static final int EM_NONE = 0; + public static final int EM_M32 = 1; + public static final int EM_SPARC = 2; + public static final int EM_386 = 3; + public static final int EM_68K = 4; + public static final int EM_88K = 5; + public static final int EM_486 = 6; + public static final int EM_860 = 7; + public static final int EM_MIPS = 8; + public static final int EM_MIPS_RS3_LE = 10; + public static final int EM_RS6000 = 11; + public static final int EM_PARISC = 15; + public static final int EM_nCUBE = 16; + public static final int EM_VPP550 = 17; + public static final int EM_SPARC32PLUS = 18; + public static final int EM_PPC = 20; + public static final int EM_PPC64 = 21; + public static final int EM_ARM = 40; + public static final int EM_SH = 42; + public static final int EM_SPARCV9 = 43; + public static final int EM_TRICORE = 44; + public static final int EM_H8_300 = 46; + public static final int EM_H8_300H = 47; + public static final int EM_IA_64 = 50; + public static final int EM_COLDFIRE = 52; + public static final int EM_STARCORE = 58; + public static final int EM_X86_64 = 62; + public static final int EM_ST100 = 60; /** @since 5.2 */ - public final static int EM_68HC08 = 71; /* Freescale MC68HC08 Microcontroller */ - - public final static int EM_AVR = 83; - public final static int EM_FR30 = 84; /* Fujitsu FR30 */ - public final static int EM_V850 = 87; - public final static int EM_M32R = 88; - public final static int EM_MN10300 = 89; - public final static int EM_MN10200 = 90; - public final static int EM_XTENSA = 94; - public final static int EM_MSP430 = 105; - public final static int EM_BLACKFIN = 106; - public final static int EM_EXCESS = 111; + public static final int EM_68HC08 = 71; /* Freescale MC68HC08 Microcontroller */ + + public static final int EM_AVR = 83; + public static final int EM_FR30 = 84; /* Fujitsu FR30 */ + public static final int EM_V850 = 87; + public static final int EM_M32R = 88; + public static final int EM_MN10300 = 89; + public static final int EM_MN10200 = 90; + public static final int EM_XTENSA = 94; + public static final int EM_MSP430 = 105; + public static final int EM_BLACKFIN = 106; + public static final int EM_EXCESS = 111; /** @since 5.5 */ - public final static int EM_ESIRISC = 111; - public final static int EM_NIOSII = 113; - public final static int EM_C166 = 116; - public final static int EM_M16C = 117; + public static final int EM_ESIRISC = 111; + public static final int EM_NIOSII = 113; + public static final int EM_C166 = 116; + public static final int EM_M16C = 117; /** @since 5.2 */ - public final static int EM_RS08 = 132; /* Freescale RS08 embedded processor */ + public static final int EM_RS08 = 132; /* Freescale RS08 embedded processor */ - public final static int EM_MMDSP = 160; + public static final int EM_MMDSP = 160; /** @since 5.4 */ - public final static int EM_RX = 173; /* Renesas RX Microcontroller */ + public static final int EM_RX = 173; /* Renesas RX Microcontroller */ /** @since 5.4 */ - public final static int EM_RL78 = 197; /* Renesas RL78 Microcontroller */ + public static final int EM_RL78 = 197; /* Renesas RL78 Microcontroller */ /** @since 6.0 */ - public final static int EM_AARCH64 = 183; - - public final static int EM_NIOS = 0xFEBB; - public final static int EM_CYGNUS_POWERPC = 0x9025; - public final static int EM_CYGNUS_M32R = 0x9041; - public final static int EM_CYGNUS_V850 = 0x9080; - public final static int EM_CYGNUS_MN10200 = 0xdead; - public final static int EM_CYGNUS_MN10300 = 0xbeef; - public final static int EM_CYGNUS_FR30 = 0x3330; - public final static int EM_XSTORMY16 = 0xad45; - public final static int EM_CYGNUS_FRV = 0x5441; - public final static int EM_IQ2000 = 0xFEBA; + public static final int EM_AARCH64 = 183; + + /** @since 7.0 */ + public static final int EM_RISCV = 243; + + public static final int EM_NIOS = 0xFEBB; + public static final int EM_CYGNUS_POWERPC = 0x9025; + public static final int EM_CYGNUS_M32R = 0x9041; + public static final int EM_CYGNUS_V850 = 0x9080; + public static final int EM_CYGNUS_MN10200 = 0xdead; + public static final int EM_CYGNUS_MN10300 = 0xbeef; + public static final int EM_CYGNUS_FR30 = 0x3330; + public static final int EM_XSTORMY16 = 0xad45; + public static final int EM_CYGNUS_FRV = 0x5441; + public static final int EM_IQ2000 = 0xFEBA; public static final int EM_XILINX_MICROBLAZE = 0xbaab; public static final int EM_SDMA = 0xcafe; public static final int EM_CRADLE = 0x4d55; @@ -286,35 +293,35 @@ public class Elf { public class Section { /* sh_type */ - public final static int SHT_NULL = 0; - public final static int SHT_PROGBITS = 1; - public final static int SHT_SYMTAB = 2; - public final static int SHT_STRTAB = 3; - public final static int SHT_RELA = 4; - public final static int SHT_HASH = 5; - public final static int SHT_DYNAMIC = 6; - public final static int SHT_NOTE = 7; - public final static int SHT_NOBITS = 8; - public final static int SHT_REL = 9; - public final static int SHT_SHLIB = 10; - public final static int SHT_DYNSYM = 11; - - public final static int SHT_LOPROC = 0x70000000; + public static final int SHT_NULL = 0; + public static final int SHT_PROGBITS = 1; + public static final int SHT_SYMTAB = 2; + public static final int SHT_STRTAB = 3; + public static final int SHT_RELA = 4; + public static final int SHT_HASH = 5; + public static final int SHT_DYNAMIC = 6; + public static final int SHT_NOTE = 7; + public static final int SHT_NOBITS = 8; + public static final int SHT_REL = 9; + public static final int SHT_SHLIB = 10; + public static final int SHT_DYNSYM = 11; + + public static final int SHT_LOPROC = 0x70000000; /* sh_flags */ - public final static int SHF_WRITE = 1; - public final static int SHF_ALLOC = 2; - public final static int SHF_EXECINTR = 4; + public static final int SHF_WRITE = 1; + public static final int SHF_ALLOC = 2; + public static final int SHF_EXECINTR = 4; /** * @since 6.6 */ - public final static int SHF_COMPRESSED = 2048; + public static final int SHF_COMPRESSED = 2048; /* note_types */ /** * @since 5.7 */ - public final static int NT_GNU_BUILD_ID = 3; + public static final int NT_GNU_BUILD_ID = 3; public long sh_name; public long sh_type; @@ -332,7 +339,7 @@ public class Elf { */ public ByteBuffer mapSectionData() throws IOException { makeSureNotCompressed(); - sections_mapped = true; + areSectionsMapped = true; return efile.getChannel().map(MapMode.READ_ONLY, sh_offset, sh_size).load().asReadOnlyBuffer(); } @@ -409,26 +416,26 @@ public class Elf { public class Symbol implements Comparable<Object> { /* Symbol bindings */ - public final static int STB_LOCAL = 0; - public final static int STB_GLOBAL = 1; - public final static int STB_WEAK = 2; + public static final int STB_LOCAL = 0; + public static final int STB_GLOBAL = 1; + public static final int STB_WEAK = 2; /* Symbol type */ - public final static int STT_NOTYPE = 0; - public final static int STT_OBJECT = 1; - public final static int STT_FUNC = 2; - public final static int STT_SECTION = 3; - public final static int STT_FILE = 4; + public static final int STT_NOTYPE = 0; + public static final int STT_OBJECT = 1; + public static final int STT_FUNC = 2; + public static final int STT_SECTION = 3; + public static final int STT_FILE = 4; /* Special Indexes */ - public final static int SHN_UNDEF = 0; - public final static int SHN_LORESERVE = 0xffffff00; - public final static int SHN_LOPROC = 0xffffff00; - public final static int SHN_HIPROC = 0xffffff1f; - public final static int SHN_LOOS = 0xffffff20; - public final static int SHN_HIOS = 0xffffff3f; - public final static int SHN_ABS = 0xfffffff1; - public final static int SHN_COMMON = 0xfffffff2; - public final static int SHN_XINDEX = 0xffffffff; - public final static int SHN_HIRESERVE = 0xffffffff; + public static final int SHN_UNDEF = 0; + public static final int SHN_LORESERVE = 0xffffff00; + public static final int SHN_LOPROC = 0xffffff00; + public static final int SHN_HIPROC = 0xffffff1f; + public static final int SHN_LOOS = 0xffffff20; + public static final int SHN_HIOS = 0xffffff3f; + public static final int SHN_ABS = 0xfffffff1; + public static final int SHN_COMMON = 0xfffffff2; + public static final int SHN_XINDEX = 0xffffffff; + public static final int SHN_HIRESERVE = 0xffffffff; /* NOTE: 64 bit and 32 bit ELF sections has different order */ public long st_name; @@ -518,17 +525,17 @@ public class Elf { public class PHdr { - public final static int PT_NULL = 0; - public final static int PT_LOAD = 1; - public final static int PT_DYNAMIC = 2; - public final static int PT_INTERP = 3; - public final static int PT_NOTE = 4; - public final static int PT_SHLIB = 5; - public final static int PT_PHDR = 6; - - public final static int PF_X = 1; - public final static int PF_W = 2; - public final static int PF_R = 4; + public static final int PT_NULL = 0; + public static final int PT_LOAD = 1; + public static final int PT_DYNAMIC = 2; + public static final int PT_INTERP = 3; + public static final int PT_NOTE = 4; + public static final int PT_SHLIB = 5; + public static final int PT_PHDR = 6; + + public static final int PF_X = 1; + public static final int PF_W = 2; + public static final int PF_R = 4; /* NOTE: 64 bit and 32 bit ELF have different order and size of elements */ public long p_type; public long p_offset; @@ -591,25 +598,25 @@ public class Elf { public class Dynamic { - public final static int DYN_ENT_SIZE_32 = 8; - public final static int DYN_ENT_SIZE_64 = 16; - - public final static int DT_NULL = 0; - public final static int DT_NEEDED = 1; - public final static int DT_PLTRELSZ = 2; - public final static int DT_PLTGOT = 3; - public final static int DT_HASH = 4; - public final static int DT_STRTAB = 5; - public final static int DT_SYMTAB = 6; - public final static int DT_RELA = 7; - public final static int DT_RELASZ = 8; - public final static int DT_RELAENT = 9; - public final static int DT_STRSZ = 10; - public final static int DT_SYMENT = 11; - public final static int DT_INIT = 12; - public final static int DT_FINI = 13; - public final static int DT_SONAME = 14; - public final static int DT_RPATH = 15; + public static final int DYN_ENT_SIZE_32 = 8; + public static final int DYN_ENT_SIZE_64 = 16; + + public static final int DT_NULL = 0; + public static final int DT_NEEDED = 1; + public static final int DT_PLTRELSZ = 2; + public static final int DT_PLTGOT = 3; + public static final int DT_HASH = 4; + public static final int DT_STRTAB = 5; + public static final int DT_SYMTAB = 6; + public static final int DT_RELA = 7; + public static final int DT_RELASZ = 8; + public static final int DT_RELAENT = 9; + public static final int DT_STRSZ = 10; + public static final int DT_SYMENT = 11; + public static final int DT_INIT = 12; + public static final int DT_FINI = 13; + public static final int DT_SONAME = 14; + public static final int DT_RPATH = 15; public long d_tag; public long d_val; private final Section section; @@ -697,6 +704,7 @@ public class Elf { public Elf(String file, long offset) throws IOException { commonSetup(file, offset); + elfOffset = offset; } public Elf(String file) throws IOException { @@ -903,6 +911,9 @@ public class Elf { case Elf.ELFhdr.EM_RS08: attrib.cpu = "rs08"; //$NON-NLS-1$ break; + case Elf.ELFhdr.EM_RISCV: + attrib.cpu = "riscv"; //$NON-NLS-1$ + break; case Elf.ELFhdr.EM_NONE: default: attrib.cpu = "none"; //$NON-NLS-1$ @@ -945,21 +956,20 @@ public class Elf { } public static Attribute getAttributes(String file) throws IOException { - Elf elf = new Elf(file); - Attribute attrib = elf.getAttributes(); - elf.dispose(); - return attrib; + try (Elf elf = new Elf(file)) { + Attribute attrib = elf.getAttributes(); + return attrib; + } } public static Attribute getAttributes(byte[] array) throws IOException { + try (Elf emptyElf = new Elf()) { + emptyElf.ehdr = emptyElf.new ELFhdr(array); + emptyElf.sections = new Elf.Section[0]; + Attribute attrib = emptyElf.getAttributes(); - Elf emptyElf = new Elf(); - emptyElf.ehdr = emptyElf.new ELFhdr(array); - emptyElf.sections = new Elf.Section[0]; - Attribute attrib = emptyElf.getAttributes(); - emptyElf.dispose(); - - return attrib; + return attrib; + } } public static boolean isElfHeader(byte[] e_ident) { @@ -967,14 +977,18 @@ public class Elf { && e_ident[ELFhdr.EI_MAG1] == 'E' && e_ident[ELFhdr.EI_MAG2] == 'L' && e_ident[ELFhdr.EI_MAG3] == 'F'; } + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (efile != null) { efile.close(); efile = null; - // ensure the mappings get cleaned up - if (sections_mapped) + if (areSectionsMapped) System.gc(); } } catch (IOException e) { @@ -1015,6 +1029,9 @@ public class Elf { return slist.toArray(new Section[0]); } + /** + * @throws ElfClassNoneException if {@link ELFhdr#ELFCLASSNONE} header is read + */ public Section[] getSections() throws IOException { if (sections == null) { if (ehdr.e_shoff == 0) { @@ -1049,7 +1066,7 @@ public class Elf { break; case ELFhdr.ELFCLASSNONE: default: - throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + throw new ElfClassNoneException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ } sections[i].sh_link = efile.readIntE(); @@ -1067,17 +1084,100 @@ public class Elf { break; case ELFhdr.ELFCLASSNONE: default: - throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + throw new ElfClassNoneException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ } - if (sections[i].sh_type == Section.SHT_SYMTAB) - syms = i; - if (syms == 0 && sections[i].sh_type == Section.SHT_DYNSYM) - syms = i; } } return sections; } + /** + * Symbol iterator, iterates over an elf file. Note: the iterator must be closed at the end in order to avoid resource leaks. + * + * TODO: move to another file when @link {@Link Symbol} can be made static. + */ + private class ElfSectionIterator implements Iterator<Symbol>, Closeable { + + private final int nbSymbols; + private final ERandomAccessFile innerEfile; + private final Section section; + private final byte arch; + private int position = 0; + + public ElfSectionIterator(ERandomAccessFile eFile, byte b, Section sectionToRead, byte architecture) + throws IOException { + int numSyms = 1; + section = sectionToRead; + if (section.sh_entsize != 0) { + numSyms = (int) section.sh_size / (int) section.sh_entsize; + } + section.makeSureNotCompressed(); + nbSymbols = numSyms; + innerEfile = new ERandomAccessFile(eFile.getPath(), "r"); //$NON-NLS-1$ + innerEfile.setFileOffset(elfOffset); + innerEfile.setEndian(efile.order() == ByteOrder.LITTLE_ENDIAN); + arch = architecture; + } + + @Override + public boolean hasNext() { + return position < nbSymbols; + } + + @Override + public Symbol next() { + long innerOffset = section.sh_entsize * position + section.sh_offset; + position++; + try { + innerEfile.seek(innerOffset); + Symbol symbol = new Symbol(section); + + switch (arch) { + case ELFhdr.ELFCLASS32: { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + + symbol.st_name = innerEfile.readIntE(); + innerEfile.readFullyE(addrArray); + symbol.st_value = new Addr32(addrArray); + symbol.st_size = innerEfile.readIntE(); + symbol.st_info = innerEfile.readByte(); + symbol.st_other = innerEfile.readByte(); + symbol.st_shndx = innerEfile.readShortE(); + break; + } + case ELFhdr.ELFCLASS64: { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + + symbol.st_name = innerEfile.readIntE(); + symbol.st_info = innerEfile.readByte(); + symbol.st_other = innerEfile.readByte(); + symbol.st_shndx = innerEfile.readShortE(); + innerEfile.readFullyE(addrArray); + symbol.st_value = new Addr64(addrArray); + symbol.st_size = innerEfile.readLongE(); + if (symbol.st_size < 0) { + throw new NoSuchElementException("Maximal file offset is " + Long.toHexString(Long.MAX_VALUE) + //$NON-NLS-1$ + " given offset is " + Long.toHexString(symbol.st_size)); //$NON-NLS-1$ + } + break; + } + case ELFhdr.ELFCLASSNONE: + default: + throw new NoSuchElementException("Unknown ELF class " + arch); //$NON-NLS-1$ + } + return symbol; + } catch (IOException e) { + throw new NoSuchElementException(e.getMessage()); + } + } + + @Override + public void close() throws IOException { + innerEfile.close(); + } + + } + private Symbol[] loadSymbolsBySection(Section section) throws IOException { int numSyms = 1; if (section.sh_entsize != 0) { @@ -1085,74 +1185,54 @@ public class Elf { } section.makeSureNotCompressed(); ArrayList<Symbol> symList = new ArrayList<>(numSyms); - long offset = section.sh_offset; - for (int c = 0; c < numSyms; offset += section.sh_entsize, c++) { - efile.seek(offset); - Symbol symbol = new Symbol(section); - switch (ehdr.e_ident[ELFhdr.EI_CLASS]) { - case ELFhdr.ELFCLASS32: { - byte[] addrArray = new byte[ELF32_ADDR_SIZE]; - - symbol.st_name = efile.readIntE(); - efile.readFullyE(addrArray); - symbol.st_value = new Addr32(addrArray); - symbol.st_size = efile.readIntE(); - symbol.st_info = efile.readByte(); - symbol.st_other = efile.readByte(); - symbol.st_shndx = efile.readShortE(); - } - break; - case ELFhdr.ELFCLASS64: { - byte[] addrArray = new byte[ELF64_ADDR_SIZE]; - - symbol.st_name = efile.readIntE(); - symbol.st_info = efile.readByte(); - symbol.st_other = efile.readByte(); - symbol.st_shndx = efile.readShortE(); - efile.readFullyE(addrArray); - symbol.st_value = new Addr64(addrArray); - symbol.st_size = readUnsignedLong(efile); - } - break; - case ELFhdr.ELFCLASSNONE: - default: - throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$ + try (ElfSectionIterator elfIterator = symbolIterator(section)) { + while (elfIterator.hasNext()) { + Symbol symbol = elfIterator.next(); + if (symbol.st_info == 0) + continue; + symList.add(symbol); } - if (symbol.st_info == 0) - continue; - symList.add(symbol); } Symbol[] results = symList.toArray(new Symbol[0]); Arrays.sort(results); return results; } + /** + * Get a symbol iterator + * @param section the section to iterate over + * @return an iterator that returns symbols of a given section + * @throws IOException If the file is corrupt + * @since 7.0 + */ + public ElfSectionIterator symbolIterator(Section section) throws IOException { + return new ElfSectionIterator(efile, ehdr.e_ident[ELFhdr.EI_CLASS], section, ehdr.e_ident[ELFhdr.EI_CLASS]); + } + public void loadSymbols() throws IOException { + Section symbolsTableSection = null; + Section dynamicSymbolSection = null; if (symbols == null) { Section section[] = getSections(Section.SHT_SYMTAB); if (section.length > 0) { - symtab_sym = section[0]; - symtab_symbols = loadSymbolsBySection(section[0]); + symbolsTableSection = section[0]; + symbolsTable = loadSymbolsBySection(section[0]); } else { - symtab_sym = null; - symtab_symbols = new Symbol[0]; + symbolsTable = new Symbol[0]; } section = getSections(Section.SHT_DYNSYM); if (section.length > 0) { - dynsym_sym = section[0]; - dynsym_symbols = loadSymbolsBySection(section[0]); + dynamicSymbolSection = section[0]; + dynamicSymbols = loadSymbolsBySection(section[0]); } else { - dynsym_sym = null; - dynsym_symbols = new Symbol[0]; + dynamicSymbols = new Symbol[0]; } - if (symtab_sym != null) { - // sym = symtab_sym; - symbols = symtab_symbols; - } else if (dynsym_sym != null) { - // sym = dynsym_sym; - symbols = dynsym_symbols; + if (symbolsTableSection != null) { + symbols = symbolsTable; + } else if (dynamicSymbolSection != null) { + symbols = dynamicSymbols; } } } @@ -1162,11 +1242,11 @@ public class Elf { } public Symbol[] getDynamicSymbols() { - return dynsym_symbols; + return dynamicSymbols; } public Symbol[] getSymtabSymbols() { - return symtab_symbols; + return symbolsTable; } /* return the address of the function that address is in */ @@ -1239,4 +1319,16 @@ public class Elf { } return result; } + + /** + * Exception indicating that {@link ELFhdr#ELFCLASSNONE} header is read. + * + * @since 7.2 + */ + public static class ElfClassNoneException extends IOException { + + ElfClassNoneException(String message) { + super(message); + } + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java index b5063ff16df..7ce48e1f3bf 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java @@ -26,7 +26,7 @@ import org.eclipse.cdt.utils.elf.Elf.Symbol; * * @see Elf */ -public class ElfHelper { +public class ElfHelper implements AutoCloseable { private Elf elf; private Elf.Symbol[] dynsyms; @@ -34,6 +34,11 @@ public class ElfHelper { private Elf.Section[] sections; private Elf.Dynamic[] dynamics; + @Override + public void close() { + dispose(); + } + public void dispose() { if (elf != null) { elf.dispose(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryArchive.java index 413e7eb386a..a4affdd11c3 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryArchive.java @@ -32,15 +32,14 @@ public class ElfBinaryArchive extends BinaryFile implements IBinaryArchive { private ArrayList<IBinaryObject> children; - public ElfBinaryArchive(IBinaryParser parser, IPath p) throws IOException { - super(parser, p, IBinaryFile.ARCHIVE); - new AR(p.toOSString()).dispose(); // check file type + public ElfBinaryArchive(IBinaryParser parser, IPath path) throws IOException { + super(parser, path, IBinaryFile.ARCHIVE); + try (AR ar = new AR(path.toOSString())) { + // create the object just to check file type + } children = new ArrayList<>(5); } - /** - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects() - */ @Override public IBinaryObject[] getObjects() { if (hasChanged()) { @@ -71,7 +70,7 @@ public class ElfBinaryArchive extends BinaryFile implements IBinaryArchive { } /** - * @deprecated use {@link ElfBinaryArchive#createArchiveMembers(ARHeader[])} + * @deprecated use {@link #createArchiveMembers(ARHeader[])} */ @SuppressWarnings({ "unchecked", "rawtypes" }) @Deprecated diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java index 9f180c39e58..1edf66298ce 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java @@ -61,9 +61,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { fElfAttributes = elfAttributes; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getName() - */ @Override public String getName() { if (header != null) { @@ -72,9 +69,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { return super.getName(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents() - */ @Override public InputStream getContents() throws IOException { if (getPath() != null && header != null) { @@ -83,9 +77,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { return super.getContents(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols() - */ @Override public ISymbol[] getSymbols() { // Call the hasChanged first, to initialize the timestamp @@ -99,9 +90,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { return symbols; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo() - */ @Override protected BinaryObjectInfo getBinaryObjectInfo() { // Call the hasChanged first, to initialize the timestamp @@ -123,27 +111,15 @@ public class ElfBinaryObject extends BinaryObjectAdapter { } protected void loadAll() throws IOException { - ElfHelper helper = null; - try { - helper = getElfHelper(); + try (ElfHelper helper = getElfHelper()) { loadInfo(helper); loadSymbols(helper); - } finally { - if (helper != null) { - helper.dispose(); - } } } protected void loadInfo() throws IOException { - ElfHelper helper = null; - try { - helper = getElfHelper(); + try (ElfHelper helper = getElfHelper()) { loadInfo(helper); - } finally { - if (helper != null) { - helper.dispose(); - } } } @@ -219,9 +195,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { return super.getAdapter(adapter); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory() - */ @Override public IAddressFactory getAddressFactory() { if (addressFactory == null) { @@ -239,9 +212,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { return addressFactory; } - /* - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#isLittleEndian() - */ @Override public boolean isLittleEndian() { if (fElfAttributes != null) { @@ -250,9 +220,6 @@ public class ElfBinaryObject extends BinaryObjectAdapter { return super.isLittleEndian(); } - /* - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getCPU() - */ @Override public String getCPU() { if (fElfAttributes != null) { 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 index 413295e5b34..0e4da98b046 100644 --- 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 @@ -29,17 +29,13 @@ import org.eclipse.cdt.utils.AR; import org.eclipse.cdt.utils.elf.Elf; import org.eclipse.cdt.utils.elf.Elf.Attribute; import org.eclipse.cdt.utils.elf.Elf.ELFhdr; +import org.eclipse.cdt.utils.elf.Elf.ElfClassNoneException; import org.eclipse.cdt.utils.elf.Elf.PHdr; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; -/** - */ public class ElfParser extends AbstractCExtension implements IBinaryParser { - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(IPath path) throws IOException { return getBinary(null, path); @@ -95,25 +91,16 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser { return binary; } - /** - * @see org.eclipse.cdt.core.IBinaryParser#getFormat() - */ @Override public String getFormat() { return "ELF"; //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public boolean isBinary(byte[] array, IPath path) { return Elf.isElfHeader(array) || AR.isARHeader(array); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBufferSize() - */ @Override public int getHintBufferSize() { return 128; @@ -190,10 +177,16 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser { try { /* No PHdr.PT_INTERP found in the hints meaning we need to read the file itself */ - return Arrays.stream(new Elf(path.toOSString()).getPHdrs()).anyMatch(phdr -> phdr.p_type == PHdr.PT_INTERP); - } catch (IOException e) { + return Arrays.stream(getPHdrs(path)).anyMatch(phdr -> phdr.p_type == PHdr.PT_INTERP); + } catch (ElfClassNoneException e) { CCorePlugin.log(e); } return false; } + + private static PHdr[] getPHdrs(IPath path) throws IOException { + try (Elf elf = new Elf(path.toOSString())) { + return elf.getPHdrs(); + } + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java index d0c40e2022c..7f4d4e9c12a 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java @@ -142,9 +142,6 @@ public class GNUElfBinaryObject extends ElfBinaryObject { return stream; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.elf.parser.ElfBinaryObject#loadSymbols(org.eclipse.cdt.utils.elf.ElfHelper) - */ @Override protected void loadSymbols(ElfHelper helper) throws IOException { symbolLoadingAddr2line = getAddr2line(false); 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 3c1523847e7..fc64a18ec66 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 @@ -19,55 +19,34 @@ import org.eclipse.cdt.utils.DefaultGnuToolFactory; import org.eclipse.cdt.utils.IGnuToolFactory; import org.eclipse.core.runtime.IPath; -/** - * GNUElfParser - */ public class GNUElfParser extends ElfParser { private IGnuToolFactory toolFactory; - /** - * @see org.eclipse.cdt.core.IBinaryParser#getFormat() - */ @Override public String getFormat() { return "GNU ELF"; //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.elf.parser.ElfParser#createBinaryCore(org.eclipse.core.runtime.IPath) - */ @Override protected IBinaryObject createBinaryCore(IPath path) throws IOException { return new GNUElfBinaryObject(this, path, IBinaryFile.CORE); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.elf.parser.ElfParser#createBinaryExecutable(org.eclipse.core.runtime.IPath) - */ @Override protected IBinaryExecutable createBinaryExecutable(IPath path) throws IOException { return new GNUElfBinaryExecutable(this, path); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.elf.parser.ElfParser#createBinaryObject(org.eclipse.core.runtime.IPath) - */ @Override protected IBinaryObject createBinaryObject(IPath path) throws IOException { return new GNUElfBinaryObject(this, path, IBinaryFile.OBJECT); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.elf.parser.ElfParser#createBinaryShared(org.eclipse.core.runtime.IPath) - */ @Override protected IBinaryShared createBinaryShared(IPath path) throws IOException { return new GNUElfBinaryShared(this, path); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.elf.parser.ElfParser#createBinaryArchive(org.eclipse.core.runtime.IPath) - */ @Override protected IBinaryArchive createBinaryArchive(IPath path) throws IOException { return new GNUElfBinaryArchive(this, path); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java index 056fd1a0f00..e85425dd8b2 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java @@ -31,9 +31,6 @@ public class GNUSymbol extends Symbol { super(binary, name, type, addr, size); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.Symbol#getLineNumber(long) - */ @Override public int getLineNumber(long offset) { int line = -1; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/EnvVarOperationProcessor.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/EnvVarOperationProcessor.java index 1d283d5f299..bbeab8a042c 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/EnvVarOperationProcessor.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/EnvVarOperationProcessor.java @@ -19,7 +19,6 @@ import java.util.List; import org.eclipse.cdt.core.envvar.EnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; -import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; /** * This is an utility class that implements environment variable operations @@ -225,7 +224,6 @@ public class EnvVarOperationProcessor { /** * normalizes the variable name. That is: removes prepended and appended spaces - * and converts the name to upper-case for Win32 systems * @return the normalized name or <code>null</code> in case the name is not valid */ static public String normalizeName(String name) { @@ -233,8 +231,6 @@ public class EnvVarOperationProcessor { return null; if ("".equals(name = name.trim())) //$NON-NLS-1$ return null; - if (!EnvironmentVariableManager.getDefault().isVariableCaseSensitive()) - name = name.toUpperCase(); return name; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/StorableEnvironment.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/StorableEnvironment.java index ba45db85862..41f0c55a140 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/StorableEnvironment.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/StorableEnvironment.java @@ -20,7 +20,6 @@ import java.util.Map; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.settings.model.ICStorageElement; -import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; import org.eclipse.cdt.internal.core.settings.model.ExceptionFactory; import org.eclipse.cdt.utils.envvar.StorableEnvironmentLoader.ISerializeInfo; @@ -315,8 +314,6 @@ public class StorableEnvironment { String getNameForMap(String name) { if (name == null || (name = name.trim()).length() == 0) return null; - if (!EnvironmentVariableManager.getDefault().isVariableCaseSensitive()) - return name.toUpperCase(); return name; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java index cc7ebb714f8..9eb8dbc2cf7 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java @@ -29,13 +29,18 @@ import org.eclipse.cdt.core.CCorePlugin; * class operations. * @see ARHeader */ -public class AR { +public class AR implements AutoCloseable { protected String filename; protected ERandomAccessFile efile; protected long strtbl_pos = -1; private ARHeader[] headers; + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (efile != null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java index 4bd96f5bd2c..91b70fc5629 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java @@ -30,7 +30,7 @@ import org.eclipse.cdt.utils.debug.stabs.StabsReader; // test checkin /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachO64}. + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachO64}. * This class is planned for removal in next major release. */ @Deprecated diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java index 620d4c651cc..b95658d9790 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java @@ -23,11 +23,11 @@ import org.eclipse.cdt.utils.macho.MachO.Section; import org.eclipse.cdt.utils.macho.MachO.Symbol; /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachOHelper64}. + * <code>MachOHelper</code> is a wrapper class for the <code>MachO</code> class + * to provide higher level API for sorting/searching the MachO data. + * + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOHelper64}. * This class is planned for removal in next major release. - * <br> - * <code>MachOHelper</code> is a wrapper class for the <code>MachO</code> class - * to provide higher level API for sorting/searching the MachO data. * * @see MachO */ diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive.java index da20d640931..e06d73de0a4 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive.java @@ -25,7 +25,7 @@ import org.eclipse.cdt.utils.macho.AR; import org.eclipse.core.runtime.IPath; /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryArchive64}. + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryArchive64}. * This class is planned for removal in next major release. */ @Deprecated @@ -35,7 +35,9 @@ public class MachOBinaryArchive extends BinaryFile implements IBinaryArchive { public MachOBinaryArchive(IBinaryParser parser, IPath p) throws IOException { super(parser, p, IBinaryFile.ARCHIVE); - new AR(p.toOSString()).dispose(); // check file type + try (AR ar = new AR(p.toOSString())) { + // create the object just to check file type + } children = new ArrayList<>(5); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive64.java index 8de3bf3cec9..3a09e1b258f 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryArchive64.java @@ -33,7 +33,10 @@ public class MachOBinaryArchive64 extends BinaryFile implements IBinaryArchive { public MachOBinaryArchive64(IBinaryParser parser, IPath p) throws IOException { super(parser, p, IBinaryFile.ARCHIVE); - new AR(p.toOSString()).dispose(); // check file type + try (AR ar = new AR(p.toOSString())) { + // create the object just to check file type + + } children = new ArrayList<>(5); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryExecutable.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryExecutable.java index 060d284f3ff..bfb5de30f52 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryExecutable.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryExecutable.java @@ -19,7 +19,7 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.core.runtime.IPath; /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryExecutable64}. + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryExecutable64}. * This class is planned for removal in next major release. */ @Deprecated diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java index 37495287cf8..1bf78ab259a 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java @@ -40,7 +40,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryObject64}. + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryObject64}. * This class is planned for removal in next major release. */ @Deprecated @@ -75,9 +75,6 @@ public class MachOBinaryObject extends BinaryObjectAdapter { super(parser, path, type); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo() - */ @Override protected BinaryObjectInfo getBinaryObjectInfo() { // we don't use this method @@ -85,9 +82,6 @@ public class MachOBinaryObject extends BinaryObjectAdapter { return new BinaryObjectInfo(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents() - */ @Override public InputStream getContents() throws IOException { if (getPath() != null && header != null) { @@ -108,9 +102,6 @@ public class MachOBinaryObject extends BinaryObjectAdapter { return null; } - /** - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getName() - */ @Override public String getName() { if (header != null) { @@ -119,9 +110,6 @@ public class MachOBinaryObject extends BinaryObjectAdapter { return super.getName(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory() - */ @Override public IAddressFactory getAddressFactory() { if (addressFactory == null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java index e59087fae4c..342ec03a0c1 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java @@ -78,9 +78,6 @@ public class MachOBinaryObject64 extends BinaryObjectAdapter { super(parser, path, type); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo() - */ @Override protected BinaryObjectInfo getBinaryObjectInfo() { // we don't use this method @@ -88,9 +85,6 @@ public class MachOBinaryObject64 extends BinaryObjectAdapter { return new BinaryObjectInfo(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents() - */ @Override public InputStream getContents() throws IOException { if (getPath() != null && header != null) { @@ -111,9 +105,6 @@ public class MachOBinaryObject64 extends BinaryObjectAdapter { return null; } - /** - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getName() - */ @Override public String getName() { if (header != null) { @@ -122,9 +113,6 @@ public class MachOBinaryObject64 extends BinaryObjectAdapter { return super.getName(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory() - */ @Override public IAddressFactory getAddressFactory() { if (addressFactory == null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryShared.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryShared.java index a6141d31b77..9fb11695ab2 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryShared.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryShared.java @@ -19,7 +19,7 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryShared; import org.eclipse.core.runtime.IPath; /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryShared64}. + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryShared64}. * This class is planned for removal in next major release. */ @Deprecated diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java index f52c50204df..04b579eb31b 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java @@ -27,15 +27,12 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; /** - * @deprecated. Deprecated as of CDT 6.1. Use 64 bit version {@link MachOParser64}. + * @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOParser64}. * This class is planned for removal in next major release. */ @Deprecated public class MachOParser extends AbstractCExtension implements IBinaryParser { - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(IPath path) throws IOException { return getBinary(null, path); @@ -88,33 +85,21 @@ public class MachOParser extends AbstractCExtension implements IBinaryParser { return binary; } - /** - * @see org.eclipse.cdt.core.IBinaryParser#getFormat() - */ @Override public String getFormat() { return "MACHO"; //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public boolean isBinary(byte[] array, IPath path) { return MachO.isMachOHeader(array) || AR.isARHeader(array); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBufferSize() - */ @Override public int getHintBufferSize() { return 128; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.IGnuToolProvider#getCPPFilt() - */ public CPPFilt getCPPFilt() { IPath cppFiltPath = getCPPFiltPath(); CPPFilt cppfilt = null; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser64.java index 8e39552a16d..348813add1f 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser64.java @@ -31,9 +31,6 @@ import org.eclipse.core.runtime.Path; */ public class MachOParser64 extends AbstractCExtension implements IBinaryParser { - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(IPath path) throws IOException { return getBinary(null, path); @@ -86,33 +83,21 @@ public class MachOParser64 extends AbstractCExtension implements IBinaryParser { return binary; } - /** - * @see org.eclipse.cdt.core.IBinaryParser#getFormat() - */ @Override public String getFormat() { return "MACHO"; //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public boolean isBinary(byte[] array, IPath path) { return MachO64.isMachOHeader(array) || AR.isARHeader(array); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBufferSize() - */ @Override public int getHintBufferSize() { return 128; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.IGnuToolProvider#getCPPFilt() - */ public CPPFilt getCPPFilt() { IPath cppFiltPath = getCPPFiltPath(); CPPFilt cppfilt = null; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/AR.java index 4499a1c88fa..1bbe85f8ade 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/AR.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/AR.java @@ -26,7 +26,7 @@ import org.eclipse.cdt.utils.coff.ReadMemoryAccess; * * @author vhirsl */ -public class AR { +public class AR implements AutoCloseable { public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ protected String filename; @@ -190,6 +190,11 @@ public class AR { lstHeader = new LSTHeader(); } + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (file != null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryArchive.java index 53cee864579..18cebb87dfe 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryArchive.java @@ -39,13 +39,12 @@ public class SOMBinaryArchive extends BinaryFile implements IBinaryArchive { */ public SOMBinaryArchive(IBinaryParser parser, IPath path) throws IOException { super(parser, path, IBinaryFile.ARCHIVE); - new AR(path.toOSString()).dispose(); // check file type + try (AR ar = new AR(path.toOSString())) { + // create the object just to check file type + } children = new ArrayList<>(5); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects() - */ @Override public IBinaryObject[] getObjects() { if (hasChanged()) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java index f83cfe673d0..646b8f5679d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java @@ -300,9 +300,6 @@ public class SOMBinaryObject extends BinaryObjectAdapter { return super.getAdapter(adapter); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory() - */ @Override public IAddressFactory getAddressFactory() { if (addressFactory == null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMParser.java index ec5e913c386..15726fa12a5 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMParser.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMParser.java @@ -33,9 +33,6 @@ import org.eclipse.core.runtime.IPath; public class SOMParser extends AbstractCExtension implements IBinaryParser { private DefaultGnuToolFactory toolFactory; - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException { if (path == null) { @@ -83,33 +80,21 @@ public class SOMParser extends AbstractCExtension implements IBinaryParser { return binary; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath) - */ @Override public IBinaryFile getBinary(IPath path) throws IOException { return getBinary(null, path); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getFormat() - */ @Override public String getFormat() { return "SOM"; //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) - */ @Override public boolean isBinary(byte[] hints, IPath path) { return SOM.isSOMHeader(hints) || AR.isARHeader(hints); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize() - */ @Override public int getHintBufferSize() { return 512; // size of file header diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java index 9db0cd5e549..aa04d490ac1 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java @@ -54,9 +54,6 @@ public class SomSymbol extends Symbol { super(binary, name, type, addr, size); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getLineNumber(long) - */ @Override public int getLineNumber(long offset) { int line = -1; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/AR.java index aea7534e873..43abe364888 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/AR.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/AR.java @@ -30,7 +30,7 @@ import org.eclipse.cdt.core.CCorePlugin; * * @author vhirsl */ -public class AR { +public class AR implements AutoCloseable { protected String filename; private RandomAccessFile file; private ARHeader header; @@ -105,6 +105,11 @@ public class AR { } } + @Override + public void close() { + dispose(); + } + public void dispose() { try { if (file != null) { @@ -365,4 +370,5 @@ public class AR { e.printStackTrace(); } } + } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/XCoff32.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/XCoff32.java index 47f00173dcc..129d45cf232 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/XCoff32.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/XCoff32.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2016 IBM Corporation and others. + * Copyright (c) 2004, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -9,21 +9,21 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * IBM - Initial API and implementation + * IBM - Initial API and implementation + * Alexander Fedorov (ArSysOp) - Bug 561992 *******************************************************************************/ package org.eclipse.cdt.utils.xcoff; import java.io.EOFException; import java.io.IOException; import java.io.RandomAccessFile; +import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.utils.coff.ReadMemoryAccess; -import com.ibm.icu.text.DateFormat; - /** * Representation of AIX XCOFF32 binary format * diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryArchive.java index 38790d0050f..d0cdf5f7299 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryArchive.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryArchive.java @@ -39,13 +39,12 @@ public class XCOFFBinaryArchive extends BinaryFile implements IBinaryArchive { */ public XCOFFBinaryArchive(IBinaryParser parser, IPath path) throws IOException { super(parser, path, IBinaryFile.ARCHIVE); - new AR(path.toOSString()).dispose(); // check file type + try (AR ar = new AR(path.toOSString())) { + // create the object just to check file type + } children = new ArrayList<>(5); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects() - */ @Override public IBinaryObject[] getObjects() { if (hasChanged()) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java index 28022da9b01..da955ee9fbc 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java @@ -94,9 +94,6 @@ public class XCOFFBinaryObject extends BinaryObjectAdapter { return info; } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getName() - */ @Override public String getName() { if (header != null) { @@ -302,9 +299,6 @@ public class XCOFFBinaryObject extends BinaryObjectAdapter { return super.getAdapter(adapter); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory() - */ @Override public IAddressFactory getAddressFactory() { if (addressFactory == null) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java index a2e25985765..d1caf448b0f 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java @@ -61,9 +61,6 @@ public class XCoffSymbol extends Symbol { super(binary, name, type, addr, size); } - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.Symbol#getLineNumber(long) - */ @Override public int getLineNumber(long offset) { int line = -1; |