1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 19:25:38 +02:00

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>
This commit is contained in:
Adrien Thierry 2019-08-14 12:33:36 -04:00 committed by Jonah Graham
parent fc46dc3304
commit 975ff2f0cc
30 changed files with 3081 additions and 4 deletions

View file

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

View file

@ -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"
@ -82,6 +84,18 @@
</run>
</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"
@ -92,6 +106,16 @@
</run>
</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"

View file

@ -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$

View file

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

View file

@ -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$

File diff suppressed because it is too large Load diff

View file

@ -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 {
/**

View file

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

View file

@ -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 {
/**

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

@ -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 {
/**

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

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

View file

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