Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrien Thierry2019-08-14 16:33:36 +0000
committerJonah Graham2019-09-03 14:44:02 +0000
commit975ff2f0cceb61467dad967589768610a081563a (patch)
treea0baacc2d35fbd9f8304a1b7900e42658503a098
parentfc46dc3304a117f3d1f5e0a6c2f7f0a963d09ee0 (diff)
downloadorg.eclipse.cdt-975ff2f0cceb61467dad967589768610a081563a.tar.gz
org.eclipse.cdt-975ff2f0cceb61467dad967589768610a081563a.tar.xz
org.eclipse.cdt-975ff2f0cceb61467dad967589768610a081563a.zip
Bug 550076 - Added new parser for PE executables
This new parser is compatible with both 32 bit and 64 bit executables. Change-Id: Ief9db7c6fcc10ea9e92d5ca58186eb50100d39f6 Signed-off-by: Adrien Thierry <adrien.thierry@spacecodesign.com>
-rwxr-xr-xcore/org.eclipse.cdt.core/plugin.properties6
-rw-r--r--core/org.eclipse.cdt.core/plugin.xml24
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff64.java819
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java6
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java1029
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive64.java46
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryExecutable64.java36
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject64.java320
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryShared64.java31
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser.java3
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser64.java81
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol64.java81
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive.java3
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive64.java74
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryExecutable64.java31
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java3
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java203
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared.java5
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryShared64.java31
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java3
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser64.java165
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java40
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java10
30 files changed, 3081 insertions, 4 deletions
diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties
index 4ba81d30227..39cddf9c21b 100755
--- a/core/org.eclipse.cdt.core/plugin.properties
+++ b/core/org.eclipse.cdt.core/plugin.properties
@@ -43,8 +43,10 @@ IndexerMarker=Indexer Marker
ElfParser.name=Elf Parser
GNUElfParser.name=GNU Elf Parser
-PEWindowsParser.name=PE Windows Parser
-CygwinPEParser.name=Cygwin PE Parser
+PEWindowsParser.name=PE Windows Parser (Deprecated)
+PE64WindowsParser.name=PE64 Windows Parser
+CygwinPEParser.name=Cygwin PE Parser (Deprecated)
+CygwinPE64Parser.name=Cygwin PE64 Parser
XCOFF32Parser.name=AIX XCOFF32 Parser
MachOParser.name=Mach-O Parser (Deprecated)
MachOParser64.name=Mach-O 64 Parser
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index a2c915f60c8..63f59d96ec8 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -72,6 +72,8 @@
</run>
</cextension>
</extension>
+ <!-- Deprecated as of CDT 6.9. Use 64 bit version PEParser64 instead.
+ This class is planned for removal in next major release. -->
<extension
id="PE"
name="%PEWindowsParser.name"
@@ -83,6 +85,18 @@
</cextension>
</extension>
<extension
+ id="PE64"
+ name="%PE64WindowsParser.name"
+ point="org.eclipse.cdt.core.BinaryParser">
+ <cextension>
+ <run
+ class="org.eclipse.cdt.utils.coff.parser.PEParser64">
+ </run>
+ </cextension>
+ </extension>
+ <!-- Deprecated as of CDT 6.9. Use 64 bit version CygwinPEParser64 instead.
+ This class is planned for removal in next major release. -->
+ <extension
id="Cygwin_PE"
name="%CygwinPEParser.name"
point="org.eclipse.cdt.core.BinaryParser">
@@ -93,6 +107,16 @@
</cextension>
</extension>
<extension
+ id="Cygwin_PE64"
+ name="%CygwinPE64Parser.name"
+ point="org.eclipse.cdt.core.BinaryParser">
+ <cextension>
+ <run
+ class="org.eclipse.cdt.utils.coff.parser.CygwinPEParser64">
+ </run>
+ </cextension>
+ </extension>
+ <extension
id="XCOFF32"
name="%XCOFF32Parser.name"
point="org.eclipse.cdt.core.BinaryParser">
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..28169a3e5db 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
@@ -26,6 +26,11 @@ 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..1530253c767
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff64.java
@@ -0,0 +1,819 @@
+/*******************************************************************************
+ * 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 Coff class
+ *******************************************************************************/
+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.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+
+import com.ibm.icu.text.DateFormat;
+
+/**
+ * @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/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java
index a19c36fc8d2..e8b55c744db 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,6 +67,12 @@ import org.eclipse.cdt.utils.debug.stabs.StabsReader;
* +-------------------+
* </pre>
*/
+
+/**
+ * @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 {
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/PE64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java
new file mode 100644
index 00000000000..6585605a7cf
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java
@@ -0,0 +1,1029 @@
+/*******************************************************************************
+ * 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 {
+
+ 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 {
+ PE64 pe = new PE64(file);
+ Attribute attrib = pe.getAttribute();
+ pe.dispose();
+ return attrib;
+ }
+
+ 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/parser/CygwinPEBinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryArchive.java
index f2c3fe73c98..b5bb34ffefe 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..3290f748a74 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..695bffeb5fe 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
@@ -41,6 +41,11 @@ 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..32d1748f311 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..04085df9239 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;
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..3cd81bd001b
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEParser64.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (adapter.isAssignableFrom(ICygwinToolsFactroy.class)) {
+ if (toolFactory == null) {
+ toolFactory = createToolFactory();
+ }
+ return 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..cbe080d2a9f 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
@@ -32,6 +32,11 @@ import org.eclipse.core.runtime.IPath;
* 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 {
/**
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..a279918ab2c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol64.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.utils.Symbol#getLineNumber(long)
+ */
+ @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..9040b0523ba 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,7 +25,10 @@ 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;
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..d4aa241357e
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryArchive64.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * 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);
+ new AR(path.toOSString()).dispose(); // 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..6bded3149a2 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..24446c71122 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;
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..699a49e9f89
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * 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);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getName()
+ */
+ @Override
+ public String getName() {
+ if (header != null) {
+ return header.getObjectName();
+ }
+ return super.getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents()
+ */
+ @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 {
+ PE64 pe = null;
+ try {
+ pe = getPE();
+ loadInfo(pe);
+ loadSymbols(pe);
+ } finally {
+ if (pe != null) {
+ pe.dispose();
+ }
+ }
+ }
+
+ protected void loadInfo() throws IOException {
+ PE64 pe = null;
+ try {
+ pe = getPE();
+ loadInfo(pe);
+ } finally {
+ if (pe != null) {
+ pe.dispose();
+ }
+ }
+ }
+
+ protected void loadInfo(PE64 pe) throws IOException {
+ info = new BinaryObjectInfo();
+ PE64.Attribute attribute = getPE().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()));
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddressFactory()
+ */
+ @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..ff0eb2d014d 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..697a3126e24 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,7 +27,10 @@ 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)
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..0071af23500
--- /dev/null
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser64.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * 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 {
+
+ /* (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) {
+ 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$
+ }
+
+ /* (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 = 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;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize()
+ */
+ @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/dwarf/Dwarf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java
index 4ec78e0367c..01a2f54ffe1 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;
@@ -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;
@@ -320,6 +329,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..16a390b96eb 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
@@ -35,6 +35,7 @@ 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 +80,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

Back to the top