mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +02:00
Remove deprecated binary parsers and supporting code
These binary parsers have been slated for deleting for a while and are replaced with 64-bit compatible versions. Some methods still refereneced the 32-bit variants and have been updated to the fully functioning 64-bit variant. The older parser IDs are preserved (forever?) so that old projects can be opened without needing to do anything. The IDs now point at the new implementations. See also Bug 562495
This commit is contained in:
parent
14dfefddb5
commit
9026f53fd5
30 changed files with 68 additions and 6191 deletions
|
@ -15,6 +15,7 @@ This section describes API removals that occurred in past releases, and upcoming
|
|||
- [Rework of API to determine GDB command line in org.eclipse.cdt.dsf.gdb](#gdbBackendDebuggerCommandLine)
|
||||
- [Removal of Qt plug-ins and features](#qt-plugins)
|
||||
- [Removal of constructor org.eclipse.cdt.utils.coff.CodeViewReader(RandomAccessFile, int, boolean)](#CodeViewReader-constructor-removal)
|
||||
- [Removal of 32-bit Binary parsers with 64-bit replacements](#32bitbinaryparsers)
|
||||
|
||||
## API Changes in CDT 10.5.0
|
||||
|
||||
|
@ -172,6 +173,43 @@ accepts filename and opens a RandomAccessFile.
|
|||
|
||||
See https://github.com/eclipse-cdt/cdt/pull/132
|
||||
|
||||
### <span id="32bitbinaryparsers">Removal of 32-bit Binary parsers with 64-bit replacements</span>
|
||||
|
||||
The following binary parser classes have been removed, mostly due to these versions not supporting 64-bit variants of the binary files.
|
||||
The new 64-bit parsers support both 32 and 64 bit files and can be identified by the same name class followed by `64`.
|
||||
|
||||
- org.eclipse.cdt.utils.coff.Coff
|
||||
- org.eclipse.cdt.utils.coff.PE
|
||||
- org.eclipse.cdt.utils.coff.PEArchive
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryArchive
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryExecutable
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryObject
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryShared
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEParser
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinSymbol
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryArchive
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryExecutable
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryObject
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryShared
|
||||
- org.eclipse.cdt.utils.coff.parser.PEParser
|
||||
- org.eclipse.cdt.utils.macho.MachO
|
||||
- org.eclipse.cdt.utils.macho.MachOHelper
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryArchive
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryExecutable
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryObject
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryShared
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOParser
|
||||
|
||||
In addition the following methods have been removed due to there existing a 64-bit compatible version.
|
||||
|
||||
- org.eclipse.cdt.utils.debug.dwarf.Dwarf.Dwarf(PE), use Dwarf(PE64) constructor instead
|
||||
- org.eclipse.cdt.utils.debug.dwarf.Dwarf.init(PE), use init(PE64) method instead
|
||||
- org.eclipse.cdt.utils.debug.dwarf.DwarfReader.DwarfReader(PE), use DwarfReader(PE64) constructor instead
|
||||
- org.eclipse.cdt.utils.debug.dwarf.DwarfReader.init(PE), use init(PE64) method instead
|
||||
- org.eclipse.cdt.utils.debug.stabs.Stabs.init(PE), use init(PE64) method instead
|
||||
|
||||
See https://github.com/eclipse-cdt/cdt/pull/135
|
||||
|
||||
---
|
||||
|
||||
## API Changes in CDT 10.5.0.
|
||||
|
@ -481,31 +519,6 @@ See the [policy](../POLICY.md) for the details.
|
|||
|
||||
## API Removals after June 2022
|
||||
|
||||
### <span id="binaryparsers">32-bit Binary parsers with 64-bit replacements</span>
|
||||
|
||||
The following binary parser classes have replacements, mostly due to
|
||||
these versions not supporting 64-bit variants of the binary files. The
|
||||
new 64-bit parsers support both 32 and 64 bit files.
|
||||
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryArchive
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryExecutable
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryObject
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEBinaryShared
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinPEParser
|
||||
- org.eclipse.cdt.utils.coff.parser.CygwinSymbol
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryArchive
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryExecutable
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryObject
|
||||
- org.eclipse.cdt.utils.coff.parser.PEBinaryShared
|
||||
- org.eclipse.cdt.utils.coff.parser.PEParser
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryArchive
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryExecutable
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryObject
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOBinaryShared
|
||||
- org.eclipse.cdt.utils.macho.parser.MachOParser
|
||||
|
||||
See [Bug 562495](https://bugs.eclipse.org/bugs/show_bug.cgi?id=562495).
|
||||
|
||||
### <span id="baudrate">BaudRate enum in org.eclipse.cdt.serial</span>
|
||||
|
||||
The BaudRate enum in org.eclipse.cdt.serial package will be removed. The
|
||||
|
|
|
@ -393,7 +393,7 @@
|
|||
</tool>
|
||||
<targetPlatform
|
||||
archList="all"
|
||||
binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.PE;org.eclipse.cdt.core.Cygwin_PE"
|
||||
binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.PE64;org.eclipse.cdt.core.Cygwin_PE64"
|
||||
id="org.eclipse.linuxtools.cdt.autotools.core.targetPlatform"
|
||||
isAbstract="false"
|
||||
name="%Autotools.targetplatform.name"/>
|
||||
|
|
|
@ -40,20 +40,6 @@ public class BackwardCompatiblityTests extends BaseTestCase {
|
|||
public void test3xStdMakeProject() {
|
||||
String PROJ_NAME = "std_cpp_1";
|
||||
|
||||
// String[] BIN_PARSERS = new String[]{
|
||||
// "org.eclipse.cdt.core.ELF",
|
||||
// "org.eclipse.cdt.core.PE",
|
||||
// "org.eclipse.cdt.core.GNU_ELF",
|
||||
// "org.eclipse.cdt.core.MachO"
|
||||
// };
|
||||
//
|
||||
// String[] ERR_PARSERS = new String[]{
|
||||
// "org.eclipse.cdt.core.CWDLocator",
|
||||
// "org.eclipse.cdt.core.GASErrorParser",
|
||||
// "org.eclipse.cdt.core.VCErrorParser",
|
||||
// "org.eclipse.cdt.core.GmakeErrorParser",
|
||||
// };
|
||||
|
||||
IProject project = loadStdProject(PROJ_NAME);
|
||||
projList.add(project);
|
||||
|
||||
|
|
|
@ -73,14 +73,18 @@
|
|||
</cextension>
|
||||
</extension>
|
||||
<!-- Deprecated as of CDT 6.9. Use 64 bit version PEParser64 instead.
|
||||
This class is planned for removal in next major release. -->
|
||||
The class associated with this parser is now the 64-bit handling version. -->
|
||||
<extension
|
||||
id="PE"
|
||||
name="%PEWindowsParser.name"
|
||||
point="org.eclipse.cdt.core.BinaryParser">
|
||||
<cextension>
|
||||
<filter
|
||||
name = "visibility"
|
||||
value = "private">
|
||||
</filter>
|
||||
<run
|
||||
class="org.eclipse.cdt.utils.coff.parser.PEParser">
|
||||
class="org.eclipse.cdt.utils.coff.parser.PEParser64">
|
||||
</run>
|
||||
</cextension>
|
||||
</extension>
|
||||
|
@ -95,14 +99,18 @@
|
|||
</cextension>
|
||||
</extension>
|
||||
<!-- Deprecated as of CDT 6.9. Use 64 bit version CygwinPEParser64 instead.
|
||||
This class is planned for removal in next major release. -->
|
||||
The class associated with this parser is now the 64-bit handling version. -->
|
||||
<extension
|
||||
id="Cygwin_PE"
|
||||
name="%CygwinPEParser.name"
|
||||
point="org.eclipse.cdt.core.BinaryParser">
|
||||
<cextension>
|
||||
<filter
|
||||
name = "visibility"
|
||||
value = "private">
|
||||
</filter>
|
||||
<run
|
||||
class="org.eclipse.cdt.utils.coff.parser.CygwinPEParser">
|
||||
class="org.eclipse.cdt.utils.coff.parser.CygwinPEParser64">
|
||||
</run>
|
||||
</cextension>
|
||||
</extension>
|
||||
|
@ -152,13 +160,19 @@
|
|||
</run>
|
||||
</cextension>
|
||||
</extension>
|
||||
<!-- Deprecated. Use 64 bit version CygwinPEParser64 instead.
|
||||
The class associated with this parser is now the 64-bit handling version. -->
|
||||
<extension
|
||||
id="MachO"
|
||||
name="%MachOParser.name"
|
||||
point="org.eclipse.cdt.core.BinaryParser">
|
||||
<cextension>
|
||||
<filter
|
||||
name = "visibility"
|
||||
value = "private">
|
||||
</filter>
|
||||
<run
|
||||
class="org.eclipse.cdt.utils.macho.parser.MachOParser">
|
||||
class="org.eclipse.cdt.utils.macho.parser.MachOParser64">
|
||||
</run>
|
||||
</cextension>
|
||||
</extension>
|
||||
|
|
|
@ -1,746 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2020 QNX Software Systems and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
|
||||
/**
|
||||
* @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$
|
||||
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 final static int AOUTHDRSZ = 28;
|
||||
|
||||
public short magic; /* 2 bytes: type of file */
|
||||
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 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[AOUTHDRSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
magic = memory.getShort();
|
||||
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("OPTIONAL HEADER VALUES").append(NL); //$NON-NLS-1$
|
||||
buffer.append("magic = ").append(magic).append(NL); //$NON-NLS-1$
|
||||
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 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) {
|
||||
}
|
||||
|
||||
// try {
|
||||
// String[] strings = getStringTable(getStringTable());
|
||||
// for (int i = 0; i < strings.length; i++) {
|
||||
// buffer.append(strings[i]);
|
||||
// }
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
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 Coff(String filename) throws IOException {
|
||||
this(new RandomAccessFile(filename, "r"), 0); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public Coff(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 {
|
||||
Coff coff = new Coff(args[0]);
|
||||
System.out.println(coff);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,905 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2016 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
|
||||
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.Coff.FileHeader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.OptionalHeader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.SectionHeader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.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 signalture, 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PE64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class PE implements AutoCloseable {
|
||||
|
||||
public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
RandomAccessFile rfile;
|
||||
String filename;
|
||||
ExeHeader exeHeader;
|
||||
DOSHeader dosHeader;
|
||||
FileHeader fileHeader;
|
||||
OptionalHeader optionalHeader;
|
||||
NTOptionalHeader ntHeader;
|
||||
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 NTOptionalHeader {
|
||||
|
||||
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 NTOptionalHeader(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public NTOptionalHeader(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 PE(String filename) throws IOException {
|
||||
this(filename, 0);
|
||||
}
|
||||
|
||||
public PE(String filename, long pos) throws IOException {
|
||||
this(filename, pos, true);
|
||||
}
|
||||
|
||||
public PE(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 Coff.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 Coff.OptionalHeader(rfile, rfile.getFilePointer());
|
||||
ntHeader = new NTOptionalHeader(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);
|
||||
Coff.FileHeader filehdr = new Coff.FileHeader(bytes, true);
|
||||
if (isValidMachine(filehdr.f_magic)) {
|
||||
return getAttributes(filehdr);
|
||||
}
|
||||
}
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.notPE")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public static Attribute getAttribute(String file) throws IOException {
|
||||
try (PE pe = new PE(file)) {
|
||||
return pe.getAttribute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (rfile != null) {
|
||||
try {
|
||||
rfile.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
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 NTOptionalHeader getNTOptionalHeader() {
|
||||
return ntHeader;
|
||||
}
|
||||
|
||||
public ImageDataDirectory[] getImageDataDirectories() throws IOException {
|
||||
if (dataDirectories == null) {
|
||||
RandomAccessFile accessFile = getRandomAccessFile();
|
||||
long offset = 0;
|
||||
if (dosHeader != null) {
|
||||
offset = dosHeader.e_lfanew + 4/*NT SIG*/;
|
||||
}
|
||||
offset += FileHeader.FILHSZ + OptionalHeader.AOUTHDRSZ + NTOptionalHeader.NTHDRSZ;
|
||||
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();
|
||||
NTOptionalHeader ntHeader = getNTOptionalHeader();
|
||||
|
||||
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 (ntHeader != null)
|
||||
newSym.n_value += ntHeader.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 (ntHeader != null) {
|
||||
buffer.append(ntHeader);
|
||||
}
|
||||
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 = Coff.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() {
|
||||
final int IMAGE_DIRECTORY_ENTRY_DEBUG = 6;
|
||||
|
||||
try {
|
||||
// the debug directory is the 6th entry
|
||||
NTOptionalHeader ntHeader = getNTOptionalHeader();
|
||||
if (ntHeader == null || ntHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_DEBUG)
|
||||
return null;
|
||||
|
||||
int debugDir = ntHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
|
||||
if (debugDir == 0)
|
||||
return null;
|
||||
|
||||
int debugFormats = ntHeader.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++) {
|
||||
PE.IMAGE_DEBUG_DIRECTORY dir = new PE.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();
|
||||
return new CodeViewReader(filename, debugBase, att.isLittleEndian());
|
||||
}
|
||||
}
|
||||
fileOffset += dir.DEBUGDIRSZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -1,337 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2016 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
|
||||
/**
|
||||
* The <code>AR</code> class is used for parsing standard ELF archive (ar) files.
|
||||
*
|
||||
* Each object within the archive is represented by an ARHeader class. Each of
|
||||
* of these objects can then be turned into an PE object for performing PE
|
||||
* class operations.
|
||||
* @deprecated - use org.eclipse.cdt.ui.utils.AR
|
||||
* @see ARHeader
|
||||
*/
|
||||
@Deprecated
|
||||
public class PEArchive implements AutoCloseable {
|
||||
|
||||
protected String filename;
|
||||
protected RandomAccessFile rfile;
|
||||
protected long strtbl_pos = -1;
|
||||
private ARHeader[] headers;
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
if (rfile != null) {
|
||||
rfile.close();
|
||||
rfile = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not leak fds.
|
||||
*/
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
dispose();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>ARHeader</code> class is used to store the per-object file
|
||||
* archive headers. It can also create an PE object for inspecting
|
||||
* the object file data.
|
||||
*/
|
||||
public class ARHeader {
|
||||
|
||||
private String object_name;
|
||||
// private String modification_time;
|
||||
// private String uid;
|
||||
// private String gid;
|
||||
// private String mode;
|
||||
private long size;
|
||||
private long elf_offset;
|
||||
|
||||
/**
|
||||
* Remove the padding from the archive header strings.
|
||||
*/
|
||||
private String removeBlanks(String str) {
|
||||
while (str.charAt(str.length() - 1) == ' ')
|
||||
str = str.substring(0, str.length() - 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the name stored in the archive's string table based
|
||||
* on the offset given.
|
||||
*
|
||||
* Maintains <code>rfile</code> file location.
|
||||
*
|
||||
* @param offset
|
||||
* Offset into the string table for first character of the name.
|
||||
* @throws IOException
|
||||
* <code>offset</code> not in string table bounds.
|
||||
*/
|
||||
private String nameFromStringTable(long offset) throws IOException {
|
||||
StringBuilder name = new StringBuilder(0);
|
||||
long pos = rfile.getFilePointer();
|
||||
|
||||
try {
|
||||
if (strtbl_pos != -1) {
|
||||
byte temp;
|
||||
rfile.seek(strtbl_pos + offset);
|
||||
while ((temp = rfile.readByte()) != '\n')
|
||||
name.append((char) temp);
|
||||
}
|
||||
} finally {
|
||||
rfile.seek(pos);
|
||||
}
|
||||
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new archive header object.
|
||||
*
|
||||
* Assumes that rfile is already at the correct location in the file.
|
||||
*
|
||||
* @throws IOException
|
||||
* There was an error processing the header data from the file.
|
||||
*/
|
||||
public ARHeader() throws IOException {
|
||||
byte[] object_name = new byte[16];
|
||||
byte[] modification_time = new byte[12];
|
||||
byte[] uid = new byte[6];
|
||||
byte[] gid = new byte[6];
|
||||
byte[] mode = new byte[8];
|
||||
byte[] size = new byte[10];
|
||||
byte[] trailer = new byte[2];
|
||||
|
||||
//
|
||||
// Read in the archive header data. Fixed sizes.
|
||||
//
|
||||
rfile.read(object_name);
|
||||
rfile.read(modification_time);
|
||||
rfile.read(uid);
|
||||
rfile.read(gid);
|
||||
rfile.read(mode);
|
||||
rfile.read(size);
|
||||
rfile.read(trailer);
|
||||
|
||||
//
|
||||
// Save this location so we can create the PE object later.
|
||||
//
|
||||
elf_offset = rfile.getFilePointer();
|
||||
|
||||
//
|
||||
// Convert the raw bytes into strings and numbers.
|
||||
//
|
||||
this.object_name = removeBlanks(new String(object_name));
|
||||
// this.modification_time = new String(modification_time);
|
||||
// this.uid = new String(uid);
|
||||
// this.gid = new String(gid);
|
||||
// this.mode = new String(mode);
|
||||
this.size = Long.parseLong(removeBlanks(new String(size)));
|
||||
|
||||
//
|
||||
// If the name is of the format "/<number>", get name from the
|
||||
// string table.
|
||||
//
|
||||
if (strtbl_pos != -1 && this.object_name.length() > 1 && this.object_name.charAt(0) == '/') {
|
||||
try {
|
||||
long offset = Long.parseLong(this.object_name.substring(1));
|
||||
this.object_name = nameFromStringTable(offset);
|
||||
} catch (java.lang.Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Strip the trailing / from the object name.
|
||||
//
|
||||
int len = this.object_name.length();
|
||||
if (len > 2 && this.object_name.charAt(len - 1) == '/') {
|
||||
this.object_name = this.object_name.substring(0, len - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Get the name of the object file */
|
||||
public String getObjectName() {
|
||||
return object_name;
|
||||
}
|
||||
|
||||
/** Get the size of the object file . */
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an new PE object for the object file.
|
||||
*
|
||||
* @throws IOException
|
||||
* Not a valid PE object file.
|
||||
* @return A new PE object.
|
||||
* @see PE#PE( String, long )
|
||||
*/
|
||||
public PE getPE() throws IOException {
|
||||
return new PE(filename, elf_offset);
|
||||
}
|
||||
|
||||
public PE getPE(boolean filter_on) throws IOException {
|
||||
return new PE(filename, elf_offset, filter_on);
|
||||
}
|
||||
|
||||
public byte[] getObjectData() throws IOException {
|
||||
byte[] temp = new byte[(int) size];
|
||||
rfile.seek(elf_offset);
|
||||
rfile.read(temp);
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isARHeader(byte[] ident) {
|
||||
if (ident == null || ident.length < 7 || ident[0] != '!' || ident[1] != '<' || ident[2] != 'a'
|
||||
|| ident[3] != 'r' || ident[4] != 'c' || ident[5] != 'h' || ident[6] != '>')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>AR</code> object from the contents of
|
||||
* the given file.
|
||||
*
|
||||
* @param filename The file to process.
|
||||
* @throws IOException The file is not a valid archive.
|
||||
*/
|
||||
public PEArchive(String filename) throws IOException {
|
||||
this.filename = filename;
|
||||
rfile = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
|
||||
String hdr = rfile.readLine();
|
||||
if (hdr == null || hdr.compareTo("!<arch>") != 0) { //$NON-NLS-1$
|
||||
rfile.close();
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the headers from the file (if required). */
|
||||
private void loadHeaders() throws IOException {
|
||||
if (headers != null)
|
||||
return;
|
||||
|
||||
Vector<ARHeader> v = new Vector<>();
|
||||
try {
|
||||
//
|
||||
// Check for EOF condition
|
||||
//
|
||||
while (rfile.getFilePointer() < rfile.length()) {
|
||||
ARHeader header = new ARHeader();
|
||||
String name = header.getObjectName();
|
||||
|
||||
long pos = rfile.getFilePointer();
|
||||
|
||||
//
|
||||
// If the name starts with a / it is specical.
|
||||
//
|
||||
if (name.charAt(0) != '/')
|
||||
v.add(header);
|
||||
|
||||
//
|
||||
// If the name is "//" then this is the string table section.
|
||||
//
|
||||
if (name.compareTo("//") == 0) //$NON-NLS-1$
|
||||
strtbl_pos = pos;
|
||||
|
||||
//
|
||||
// Compute the location of the next header in the archive.
|
||||
//
|
||||
pos += header.getSize();
|
||||
if ((pos % 2) != 0)
|
||||
pos++;
|
||||
|
||||
rfile.seek(pos);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
headers = v.toArray(new ARHeader[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all the object file headers for this archive.
|
||||
*
|
||||
* @throws IOException
|
||||
* Unable to process the archive file.
|
||||
* @return An array of headers, one for each object within the archive.
|
||||
* @see ARHeader
|
||||
*/
|
||||
public ARHeader[] getHeaders() throws IOException {
|
||||
loadHeaders();
|
||||
return headers;
|
||||
}
|
||||
|
||||
private boolean stringInStrings(String str, String[] set) {
|
||||
for (String element : set)
|
||||
if (str.compareTo(element) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public String[] extractFiles(String outdir, String[] names) throws IOException {
|
||||
Vector<String> names_used = new Vector<>();
|
||||
String object_name;
|
||||
int count;
|
||||
|
||||
loadHeaders();
|
||||
|
||||
count = 0;
|
||||
for (ARHeader header : headers) {
|
||||
object_name = header.getObjectName();
|
||||
if (names != null && !stringInStrings(object_name, names))
|
||||
continue;
|
||||
|
||||
object_name = "" + count + "_" + object_name; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
count++;
|
||||
|
||||
byte[] data = header.getObjectData();
|
||||
File output = new File(outdir, object_name);
|
||||
names_used.add(object_name);
|
||||
|
||||
RandomAccessFile rfile = new RandomAccessFile(output, "rw"); //$NON-NLS-1$
|
||||
rfile.write(data);
|
||||
rfile.close();
|
||||
}
|
||||
|
||||
return names_used.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String[] extractFiles(String outdir) throws IOException {
|
||||
return extractFiles(outdir, null);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2008 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
* @throws IOException
|
||||
*/
|
||||
public CygwinPEBinaryArchive(PEParser 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 CygwinPEBinaryObject(getBinaryParser(), getPath(), headers[i]);
|
||||
children.add(bin);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2006 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
* @param executable
|
||||
*/
|
||||
public CygwinPEBinaryExecutable(IBinaryParser parser, IPath path, int executable) {
|
||||
super(parser, path, IBinaryFile.EXECUTABLE);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,321 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2015 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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.Coff;
|
||||
import org.eclipse.cdt.utils.coff.PE;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
private Addr2line symbolLoadingAddr2line;
|
||||
private CygPath symbolLoadingCygPath;
|
||||
private CPPFilt symbolLoadingCPPFilt;
|
||||
long starttime;
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
* @param header
|
||||
*/
|
||||
public CygwinPEBinaryObject(IBinaryParser parser, IPath path, ARHeader header) {
|
||||
super(parser, path, header);
|
||||
}
|
||||
|
||||
public CygwinPEBinaryObject(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(PE 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 CygwinSymbol(this, name, type, addr, size, file, startLine, endLine));
|
||||
} catch (IOException e) {
|
||||
symbolLoadingAddr2line.dispose();
|
||||
symbolLoadingAddr2line = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, List<Symbol> list) {
|
||||
for (Coff.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 CygwinSymbol(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 CygwinSymbol(this, name, type, addr, size));
|
||||
}
|
||||
} else {
|
||||
list.add(new CygwinSymbol(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);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2008 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
super(parser, path, IBinaryFile.SHARED);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @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 CygwinPEBinaryArchive(this, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBinaryExecutable createBinaryExecutable(IPath path) {
|
||||
return new CygwinPEBinaryExecutable(this, path, IBinaryFile.EXECUTABLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBinaryObject createBinaryCore(IPath path) {
|
||||
return new CygwinPEBinaryObject(this, path, IBinaryFile.CORE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBinaryObject createBinaryObject(IPath path) {
|
||||
return new CygwinPEBinaryObject(this, path, IBinaryFile.OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBinaryShared createBinaryShared(IPath path) {
|
||||
return new CygwinPEBinaryShared(this, path);
|
||||
}
|
||||
|
||||
protected DefaultCygwinToolFactory createToolFactory() {
|
||||
return new DefaultCygwinToolFactory(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getAdapter(Class<T> adapter) {
|
||||
if (adapter.isAssignableFrom(ICygwinToolsFactroy.class)) {
|
||||
if (toolFactory == null) {
|
||||
toolFactory = createToolFactory();
|
||||
}
|
||||
return adapter.cast(toolFactory);
|
||||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2008 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
|
||||
/**
|
||||
* @param binary
|
||||
* @param name
|
||||
* @param type
|
||||
* @param addr
|
||||
* @param size
|
||||
* @param sourceFile
|
||||
* @param startLine
|
||||
* @param endLine
|
||||
*/
|
||||
public CygwinSymbol(CygwinPEBinaryObject 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 CygwinSymbol(CygwinPEBinaryObject binary, String name, int type, IAddress addr, long size) {
|
||||
super(binary, name, type, addr, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineNumber(long offset) {
|
||||
int line = -1;
|
||||
Addr2line addr2line = ((CygwinPEBinaryObject) binary).getAddr2line(true);
|
||||
if (addr2line != null) {
|
||||
try {
|
||||
return addr2line.getLineNumber(getAddress().add(offset));
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2012 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.9. Use 64 bit version {@link PEBinaryArchive64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class PEBinaryArchive extends BinaryFile implements IBinaryArchive {
|
||||
|
||||
ArrayList<IBinaryObject> children;
|
||||
|
||||
public PEBinaryArchive(PEParser parser, IPath path) throws IOException {
|
||||
super(parser, path, IBinaryFile.ARCHIVE);
|
||||
try (AR ar = new AR(path.toOSString())) {
|
||||
// create the object just to check file type
|
||||
}
|
||||
children = new ArrayList<>(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects()
|
||||
*/
|
||||
@Override
|
||||
public IBinaryObject[] getObjects() {
|
||||
if (hasChanged()) {
|
||||
children.clear();
|
||||
AR ar = null;
|
||||
try {
|
||||
ar = new AR(getPath().toOSString());
|
||||
AR.ARHeader[] headers = ar.getHeaders();
|
||||
addArchiveMembers(headers, children);
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
children.trimToSize();
|
||||
}
|
||||
return children.toArray(new IBinaryObject[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param headers
|
||||
* @param children2
|
||||
*/
|
||||
protected void addArchiveMembers(ARHeader[] headers, ArrayList<IBinaryObject> children2) {
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
IBinaryObject bin = new PEBinaryObject(getBinaryParser(), getPath(), headers[i]);
|
||||
children.add(bin);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2008 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
super(parser, path, IBinaryFile.EXECUTABLE);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2015 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
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.Coff;
|
||||
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;
|
||||
IAddressFactory addressFactory;
|
||||
ISymbol[] symbols;
|
||||
AR.ARHeader header;
|
||||
|
||||
public PEBinaryObject(IBinaryParser parser, IPath path, AR.ARHeader header) {
|
||||
super(parser, path, IBinaryFile.OBJECT);
|
||||
}
|
||||
|
||||
public PEBinaryObject(IBinaryParser parser, IPath p, int type) {
|
||||
super(parser, p, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (header != null) {
|
||||
return header.getObjectName();
|
||||
}
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContents() throws IOException {
|
||||
if (getPath() != null && header != null) {
|
||||
return new ByteArrayInputStream(header.getObjectData());
|
||||
}
|
||||
return super.getContents();
|
||||
}
|
||||
|
||||
@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(PE.class)) {
|
||||
try {
|
||||
if (header != null) {
|
||||
return (T) new PE(getPath().toOSString(), header.getObjectDataOffset());
|
||||
}
|
||||
return (T) new PE(getPath().toOSString());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (adapter.equals(ISymbolReader.class)) {
|
||||
try (PE pe = getAdapter(PE.class)) {
|
||||
if (pe != null) {
|
||||
return (T) pe.getSymbolReader();
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
||||
protected PE getPE() throws IOException {
|
||||
if (header != null) {
|
||||
return new PE(getPath().toOSString(), header.getObjectDataOffset());
|
||||
}
|
||||
return new PE(getPath().toOSString());
|
||||
}
|
||||
|
||||
protected void loadAll() throws IOException {
|
||||
try (PE pe = getPE()) {
|
||||
loadInfo(pe);
|
||||
loadSymbols(pe);
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadInfo() throws IOException {
|
||||
try (PE pe = getPE()) {
|
||||
loadInfo(pe);
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadInfo(PE pe) throws IOException {
|
||||
info = new BinaryObjectInfo();
|
||||
PE.Attribute attribute = pe.getAttribute();
|
||||
info.isLittleEndian = attribute.isLittleEndian();
|
||||
info.hasDebug = attribute.hasDebug();
|
||||
info.cpu = attribute.getCPU();
|
||||
}
|
||||
|
||||
protected void loadSymbols(PE pe) throws IOException {
|
||||
ArrayList<Symbol> list = new ArrayList<>();
|
||||
loadSymbols(pe, list);
|
||||
symbols = list.toArray(NO_SYMBOLS);
|
||||
Arrays.sort(symbols);
|
||||
list.clear();
|
||||
}
|
||||
|
||||
protected void loadSymbols(PE pe, List<Symbol> list) throws IOException {
|
||||
Coff.Symbol[] peSyms = pe.getSymbols();
|
||||
byte[] table = pe.getStringTable();
|
||||
addSymbols(peSyms, table, list);
|
||||
}
|
||||
|
||||
protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, List<Symbol> list) {
|
||||
for (org.eclipse.cdt.utils.coff.Coff.Symbol peSym : peSyms) {
|
||||
if (peSym.isFunction() || peSym.isPointer() || peSym.isArray()) {
|
||||
String name = peSym.getName(table);
|
||||
if (name == null || name.trim().length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) {
|
||||
continue;
|
||||
}
|
||||
int type = peSym.isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
|
||||
list.add(new Symbol(this, name, type, new Addr32(peSym.n_value), peSym.getSize()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAddressFactory getAddressFactory() {
|
||||
if (addressFactory == null) {
|
||||
addressFactory = new Addr32Factory();
|
||||
}
|
||||
return addressFactory;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2008 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
super(parser, p, IBinaryFile.SHARED);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2012 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
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.PE;
|
||||
import org.eclipse.cdt.utils.coff.PE.Attribute;
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public IBinaryFile getBinary(IPath path) throws IOException {
|
||||
return getBinary(null, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException {
|
||||
if (path == null) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.nullPath")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
IBinaryFile binary = null;
|
||||
try {
|
||||
PE.Attribute attribute = null;
|
||||
if (hints != null && hints.length > 0) {
|
||||
try {
|
||||
attribute = PE.getAttribute(hints);
|
||||
} catch (EOFException e) {
|
||||
// continue to try
|
||||
}
|
||||
}
|
||||
// the hints may have to small, keep on trying.
|
||||
if (attribute == null) {
|
||||
attribute = PE.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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return "PE"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBinary(byte[] array, IPath path) {
|
||||
boolean isBin = PE.isExeHeader(array) || AR.isARHeader(array);
|
||||
// It maybe an object file try the known machine types.
|
||||
if (!isBin && array.length > 1) {
|
||||
int f_magic = (((array[1] & 0xff) << 8) | (array[0] & 0xff));
|
||||
switch (f_magic) {
|
||||
case PEConstants.IMAGE_FILE_MACHINE_ALPHA:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_ARM:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_ALPHA64:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_I386:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_IA64:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_M68K:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_MIPS16:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_POWERPC:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_R3000:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_R4000:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_R10000:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_SH3:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_SH4:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_THUMB:
|
||||
case PEConstants.IMAGE_FILE_MACHINE_ARM2:
|
||||
// Ok;
|
||||
isBin = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isBin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHintBufferSize() {
|
||||
return 512;
|
||||
}
|
||||
|
||||
protected IBinaryExecutable createBinaryExecutable(IPath path) {
|
||||
return new PEBinaryExecutable(this, path);
|
||||
}
|
||||
|
||||
protected IBinaryObject createBinaryCore(IPath path) {
|
||||
return new PEBinaryObject(this, path, IBinaryFile.CORE);
|
||||
}
|
||||
|
||||
protected IBinaryObject createBinaryObject(IPath path) {
|
||||
return new PEBinaryObject(this, path, IBinaryFile.OBJECT);
|
||||
}
|
||||
|
||||
protected IBinaryShared createBinaryShared(IPath path) {
|
||||
return new PEBinaryShared(this, path);
|
||||
}
|
||||
|
||||
protected IBinaryArchive createBinaryArchive(IPath path) throws IOException {
|
||||
return new PEBinaryArchive(this, path);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,9 +26,7 @@ import java.util.List;
|
|||
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;
|
||||
|
@ -195,13 +193,6 @@ public class Dwarf implements AutoCloseable {
|
|||
init(exe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public Dwarf(PE exe) throws IOException {
|
||||
init(exe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.9
|
||||
*/
|
||||
|
@ -301,35 +292,6 @@ public class Dwarf implements AutoCloseable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public void init(PE exe) throws IOException {
|
||||
|
||||
isLE = true;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.9
|
||||
*/
|
||||
|
|
|
@ -31,8 +31,7 @@ import java.util.Set;
|
|||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ICompileOptionsFinder;
|
||||
import org.eclipse.cdt.core.ISymbolReader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.SectionHeader;
|
||||
import org.eclipse.cdt.utils.coff.PE;
|
||||
import org.eclipse.cdt.utils.coff.Coff64.SectionHeader;
|
||||
import org.eclipse.cdt.utils.coff.PE64;
|
||||
import org.eclipse.cdt.utils.debug.IDebugEntryRequestor;
|
||||
import org.eclipse.cdt.utils.elf.Elf;
|
||||
|
@ -71,13 +70,6 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions
|
|||
super(exe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public DwarfReader(PE exe) throws IOException {
|
||||
super(exe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.9
|
||||
*/
|
||||
|
@ -259,7 +251,7 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions
|
|||
}
|
||||
|
||||
@Override
|
||||
public void init(PE exe) throws IOException {
|
||||
public void init(PE64 exe) throws IOException {
|
||||
|
||||
isLE = true;
|
||||
SectionHeader[] sections = exe.getSectionHeaders();
|
||||
|
|
|
@ -21,9 +21,9 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.utils.coff.Coff.SectionHeader;
|
||||
import org.eclipse.cdt.utils.coff.PE;
|
||||
import org.eclipse.cdt.utils.coff.PE.Attribute;
|
||||
import org.eclipse.cdt.utils.coff.Coff64.SectionHeader;
|
||||
import org.eclipse.cdt.utils.coff.PE64;
|
||||
import org.eclipse.cdt.utils.coff.PE64.Attribute;
|
||||
import org.eclipse.cdt.utils.debug.DebugArrayType;
|
||||
import org.eclipse.cdt.utils.debug.DebugBaseType;
|
||||
import org.eclipse.cdt.utils.debug.DebugCrossRefType;
|
||||
|
@ -71,7 +71,7 @@ public class Stabs {
|
|||
try (Elf exe = new Elf(file)) {
|
||||
init(exe);
|
||||
} catch (IOException e) {
|
||||
try (PE exe = new PE(file)) {
|
||||
try (PE64 exe = new PE64(file)) {
|
||||
init(exe);
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class Stabs {
|
|||
}
|
||||
}
|
||||
|
||||
void init(PE exe) throws IOException {
|
||||
void init(PE64 exe) throws IOException {
|
||||
byte[] data = null;
|
||||
byte[] stabstr = null;
|
||||
|
||||
|
|
|
@ -1,343 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2016 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.elf;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.utils.ERandomAccessFile;
|
||||
|
||||
/**
|
||||
* The <code>AR</code> class is used for parsing standard ELF archive (ar) files.
|
||||
*
|
||||
* Each object within the archive is represented by an ARHeader class. Each of
|
||||
* of these objects can then be turned into an Elf object for performing Elf
|
||||
* class operations.
|
||||
* @deprecated use org.eclipse.cdt.utils.AR
|
||||
* @see ARHeader
|
||||
*/
|
||||
@Deprecated
|
||||
public class AR implements AutoCloseable {
|
||||
|
||||
protected String filename;
|
||||
protected ERandomAccessFile efile;
|
||||
protected long strtbl_pos = -1;
|
||||
private ARHeader[] headers;
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
if (efile != null) {
|
||||
efile.close();
|
||||
efile = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
dispose();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>ARHeader</code> class is used to store the per-object file
|
||||
* archive headers. It can also create an Elf object for inspecting
|
||||
* the object file data.
|
||||
*/
|
||||
public class ARHeader {
|
||||
|
||||
private String object_name;
|
||||
// private String modification_time;
|
||||
// private String uid;
|
||||
// private String gid;
|
||||
// private String mode;
|
||||
private long size;
|
||||
private long elf_offset;
|
||||
|
||||
/**
|
||||
* Remove the padding from the archive header strings.
|
||||
*/
|
||||
private String removeBlanks(String str) {
|
||||
while (str.charAt(str.length() - 1) == ' ')
|
||||
str = str.substring(0, str.length() - 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the name stored in the archive's string table based
|
||||
* on the offset given.
|
||||
*
|
||||
* Maintains <code>efile</code> file location.
|
||||
*
|
||||
* @param offset
|
||||
* Offset into the string table for first character of the name.
|
||||
* @throws IOException
|
||||
* <code>offset</code> not in string table bounds.
|
||||
*/
|
||||
private String nameFromStringTable(long offset) throws IOException {
|
||||
StringBuilder name = new StringBuilder(0);
|
||||
long pos = efile.getFilePointer();
|
||||
|
||||
try {
|
||||
if (strtbl_pos != -1) {
|
||||
byte temp;
|
||||
efile.seek(strtbl_pos + offset);
|
||||
while ((temp = efile.readByte()) != '\n')
|
||||
name.append((char) temp);
|
||||
}
|
||||
} finally {
|
||||
efile.seek(pos);
|
||||
}
|
||||
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new archive header object.
|
||||
*
|
||||
* Assumes that efile is already at the correct location in the file.
|
||||
*
|
||||
* @throws IOException
|
||||
* There was an error processing the header data from the file.
|
||||
*/
|
||||
public ARHeader() throws IOException {
|
||||
byte[] object_name = new byte[16];
|
||||
byte[] modification_time = new byte[12];
|
||||
byte[] uid = new byte[6];
|
||||
byte[] gid = new byte[6];
|
||||
byte[] mode = new byte[8];
|
||||
byte[] size = new byte[10];
|
||||
byte[] trailer = new byte[2];
|
||||
|
||||
//
|
||||
// Read in the archive header data. Fixed sizes.
|
||||
//
|
||||
efile.read(object_name);
|
||||
efile.read(modification_time);
|
||||
efile.read(uid);
|
||||
efile.read(gid);
|
||||
efile.read(mode);
|
||||
efile.read(size);
|
||||
efile.read(trailer);
|
||||
|
||||
//
|
||||
// Save this location so we can create the Elf object later.
|
||||
//
|
||||
elf_offset = efile.getFilePointer();
|
||||
|
||||
//
|
||||
// Convert the raw bytes into strings and numbers.
|
||||
//
|
||||
this.object_name = removeBlanks(new String(object_name));
|
||||
// this.modification_time = new String(modification_time);
|
||||
// this.uid = new String(uid);
|
||||
// this.gid = new String(gid);
|
||||
// this.mode = new String(mode);
|
||||
this.size = Long.parseLong(removeBlanks(new String(size)));
|
||||
|
||||
//
|
||||
// If the name is of the format "/<number>", get name from the
|
||||
// string table.
|
||||
//
|
||||
if (strtbl_pos != -1 && this.object_name.length() > 1 && this.object_name.charAt(0) == '/') {
|
||||
try {
|
||||
long offset = Long.parseLong(this.object_name.substring(1));
|
||||
this.object_name = nameFromStringTable(offset);
|
||||
} catch (java.lang.Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Strip the trailing / from the object name.
|
||||
//
|
||||
int len = this.object_name.length();
|
||||
if (len > 2 && this.object_name.charAt(len - 1) == '/') {
|
||||
this.object_name = this.object_name.substring(0, len - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Get the name of the object file */
|
||||
public String getObjectName() {
|
||||
return object_name;
|
||||
}
|
||||
|
||||
/** Get the size of the object file . */
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getArchiveName() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an new Elf object for the object file.
|
||||
*
|
||||
* @throws IOException
|
||||
* Not a valid Elf object file.
|
||||
* @return A new Elf object.
|
||||
* @see Elf#Elf( String, long )
|
||||
*/
|
||||
public Elf getElf() throws IOException {
|
||||
return new Elf(filename, elf_offset);
|
||||
}
|
||||
|
||||
public byte[] getObjectData() throws IOException {
|
||||
byte[] temp = new byte[(int) size];
|
||||
if (efile != null) {
|
||||
efile.seek(elf_offset);
|
||||
efile.read(temp);
|
||||
} else {
|
||||
try (ERandomAccessFile tempfile = new ERandomAccessFile(filename, "r")) { //$NON-NLS-1$
|
||||
tempfile.seek(elf_offset);
|
||||
tempfile.read(temp);
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isARHeader(byte[] ident) {
|
||||
if (ident == null || ident.length < 7 || ident[0] != '!' || ident[1] != '<' || ident[2] != 'a'
|
||||
|| ident[3] != 'r' || ident[4] != 'c' || ident[5] != 'h' || ident[6] != '>')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>AR</code> object from the contents of
|
||||
* the given file.
|
||||
*
|
||||
* @param filename The file to process.
|
||||
* @throws IOException The file is not a valid archive.
|
||||
*/
|
||||
public AR(String filename) throws IOException {
|
||||
this.filename = filename;
|
||||
efile = new ERandomAccessFile(filename, "r"); //$NON-NLS-1$
|
||||
String hdr = efile.readLine();
|
||||
if (hdr == null || hdr.compareTo("!<arch>") != 0) { //$NON-NLS-1$
|
||||
efile.close();
|
||||
efile = null;
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the headers from the file (if required). */
|
||||
private void loadHeaders() throws IOException {
|
||||
if (headers != null)
|
||||
return;
|
||||
|
||||
Vector<ARHeader> v = new Vector<>();
|
||||
try {
|
||||
//
|
||||
// Check for EOF condition
|
||||
//
|
||||
while (efile.getFilePointer() < efile.length()) {
|
||||
ARHeader header = new ARHeader();
|
||||
String name = header.getObjectName();
|
||||
|
||||
long pos = efile.getFilePointer();
|
||||
|
||||
//
|
||||
// If the name starts with a / it is specical.
|
||||
//
|
||||
if (name.charAt(0) != '/')
|
||||
v.add(header);
|
||||
|
||||
//
|
||||
// If the name is "//" then this is the string table section.
|
||||
//
|
||||
if (name.compareTo("//") == 0) //$NON-NLS-1$
|
||||
strtbl_pos = pos;
|
||||
|
||||
//
|
||||
// Compute the location of the next header in the archive.
|
||||
//
|
||||
pos += header.getSize();
|
||||
if ((pos % 2) != 0)
|
||||
pos++;
|
||||
|
||||
efile.seek(pos);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
headers = v.toArray(new ARHeader[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all the object file headers for this archive.
|
||||
*
|
||||
* @throws IOException
|
||||
* Unable to process the archive file.
|
||||
* @return An array of headers, one for each object within the archive.
|
||||
* @see ARHeader
|
||||
*/
|
||||
public ARHeader[] getHeaders() throws IOException {
|
||||
loadHeaders();
|
||||
return headers;
|
||||
}
|
||||
|
||||
private boolean stringInStrings(String str, String[] set) {
|
||||
for (String element : set)
|
||||
if (str.compareTo(element) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public String[] extractFiles(String outdir, String[] names) throws IOException {
|
||||
Vector<String> names_used = new Vector<>();
|
||||
String object_name;
|
||||
int count;
|
||||
|
||||
loadHeaders();
|
||||
|
||||
count = 0;
|
||||
for (ARHeader header : headers) {
|
||||
object_name = header.getObjectName();
|
||||
if (names != null && !stringInStrings(object_name, names))
|
||||
continue;
|
||||
|
||||
object_name = "" + count + "_" + object_name; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
count++;
|
||||
|
||||
byte[] data = header.getObjectData();
|
||||
File output = new File(outdir, object_name);
|
||||
names_used.add(object_name);
|
||||
|
||||
RandomAccessFile rfile = new RandomAccessFile(output, "rw"); //$NON-NLS-1$
|
||||
rfile.write(data);
|
||||
rfile.close();
|
||||
}
|
||||
|
||||
return names_used.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String[] extractFiles(String outdir) throws IOException {
|
||||
return extractFiles(outdir, null);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,319 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2016 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Craig Watson
|
||||
* Apple Computer - work on performance optimizations
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.macho;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.utils.macho.MachO.DyLib;
|
||||
import org.eclipse.cdt.utils.macho.MachO.Section;
|
||||
import org.eclipse.cdt.utils.macho.MachO.Symbol;
|
||||
|
||||
/**
|
||||
* <code>MachOHelper</code> is a wrapper class for the <code>MachO</code> class
|
||||
* to provide higher level API for sorting/searching the MachO data.
|
||||
*
|
||||
* @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOHelper64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*
|
||||
* @see MachO
|
||||
*/
|
||||
@Deprecated
|
||||
public class MachOHelper {
|
||||
|
||||
private MachO macho;
|
||||
private MachO.Symbol[] dynsyms;
|
||||
private MachO.Symbol[] symbols;
|
||||
private MachO.Section[] sections;
|
||||
private MachO.DyLib[] needed;
|
||||
private MachO.DyLib[] sonames;
|
||||
|
||||
public void dispose() {
|
||||
if (macho != null) {
|
||||
macho.dispose();
|
||||
macho = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class Sizes {
|
||||
public long text;
|
||||
public long data;
|
||||
public long bss;
|
||||
public long total;
|
||||
|
||||
public Sizes(long t, long d, long b) {
|
||||
text = t;
|
||||
data = d;
|
||||
bss = b;
|
||||
total = text + data + bss;
|
||||
}
|
||||
}
|
||||
|
||||
private void loadBinary() throws IOException {
|
||||
if (symbols == null) {
|
||||
macho.loadBinary();
|
||||
symbols = macho.getSymtabSymbols();
|
||||
dynsyms = macho.getDynamicSymbols();
|
||||
sections = macho.getSections();
|
||||
needed = macho.getDyLibs(MachO.LoadCommand.LC_LOAD_DYLIB);
|
||||
sonames = macho.getDyLibs(MachO.LoadCommand.LC_ID_DYLIB);
|
||||
|
||||
if (dynsyms == null)
|
||||
dynsyms = symbols;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new <code>MachOHelper</code> using an existing <code>MachO</code>
|
||||
* object.
|
||||
* @param macho An existing MachO object to wrap.
|
||||
* @throws IOException Error processing the MachO file.
|
||||
*/
|
||||
public MachOHelper(MachO macho) throws IOException {
|
||||
this.macho = macho;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new <code>MachOHelper</code> based on the given filename.
|
||||
*
|
||||
* @param filename The file to use for creating a new MachO object.
|
||||
* @throws IOException Error processing the MachO file.
|
||||
* @see MachO#MachO( String )
|
||||
*/
|
||||
public MachOHelper(String filename) throws IOException {
|
||||
macho = new MachO(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new <code>MachOHelper</code> based on the given filename.
|
||||
*
|
||||
* @param filename The file to use for creating a new MachO object.
|
||||
* @throws IOException Error processing the MachO file.
|
||||
* @see MachO#MachO( String )
|
||||
*/
|
||||
public MachOHelper(String filename, long offset) throws IOException {
|
||||
macho = new MachO(filename, offset);
|
||||
}
|
||||
|
||||
public MachOHelper(String filename, boolean filton) throws IOException {
|
||||
macho = new MachO(filename, filton);
|
||||
}
|
||||
|
||||
/** Give back the MachO object that this helper is wrapping */
|
||||
public MachO getMachO() {
|
||||
return macho;
|
||||
}
|
||||
|
||||
public MachO.Symbol[] getExternalFunctions() throws IOException {
|
||||
Vector<Symbol> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (Symbol sym : dynsyms) {
|
||||
if ((sym.n_type_mask(MachO.Symbol.N_PEXT) || sym.n_type_mask(MachO.Symbol.N_EXT))
|
||||
&& sym.n_desc(MachO.Symbol.REFERENCE_FLAG_UNDEFINED_LAZY)) {
|
||||
String name = sym.toString();
|
||||
if (name != null && name.trim().length() > 0)
|
||||
v.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
MachO.Symbol[] ret = v.toArray(new MachO.Symbol[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MachO.Symbol[] getExternalObjects() throws IOException {
|
||||
Vector<Symbol> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (Symbol sym : dynsyms) {
|
||||
if ((sym.n_type_mask(MachO.Symbol.N_PEXT) || sym.n_type_mask(MachO.Symbol.N_EXT))
|
||||
&& sym.n_desc(MachO.Symbol.REFERENCE_FLAG_UNDEFINED_NON_LAZY)) {
|
||||
String name = sym.toString();
|
||||
if (name != null && name.trim().length() > 0)
|
||||
v.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
MachO.Symbol[] ret = v.toArray(new MachO.Symbol[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MachO.Symbol[] getUndefined() throws IOException {
|
||||
Vector<Symbol> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (Symbol dynsym : dynsyms) {
|
||||
if (dynsym.n_type(MachO.Symbol.N_UNDF))
|
||||
v.add(dynsym);
|
||||
}
|
||||
|
||||
MachO.Symbol[] ret = v.toArray(new MachO.Symbol[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: I'm not sure if this are correct. Need to check
|
||||
*/
|
||||
public MachO.Symbol[] getLocalFunctions() throws IOException {
|
||||
Vector<Symbol> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (Symbol sym : dynsyms) {
|
||||
if ((!sym.n_type_mask(MachO.Symbol.N_PEXT) && !sym.n_type_mask(MachO.Symbol.N_EXT))
|
||||
&& sym.n_desc(MachO.Symbol.REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY)) {
|
||||
String name = sym.toString();
|
||||
if (name != null && name.trim().length() > 0)
|
||||
v.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
MachO.Symbol[] ret = v.toArray(new MachO.Symbol[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: I'm not sure if this are correct. Need to check
|
||||
*/
|
||||
public MachO.Symbol[] getLocalObjects() throws IOException {
|
||||
Vector<Symbol> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (Symbol sym : dynsyms) {
|
||||
if ((!sym.n_type_mask(MachO.Symbol.N_PEXT) && !sym.n_type_mask(MachO.Symbol.N_EXT))
|
||||
&& sym.n_desc(MachO.Symbol.REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)) {
|
||||
String name = sym.toString();
|
||||
if (name != null && name.trim().length() > 0)
|
||||
v.add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
MachO.Symbol[] ret = v.toArray(new MachO.Symbol[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MachO.Symbol[] getCommonObjects() throws IOException {
|
||||
Vector<Symbol> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (int i = 0; i < dynsyms.length; i++) {
|
||||
MachO.Symbol sym = dynsyms[i];
|
||||
if (sym.n_type_mask(MachO.Symbol.N_EXT) && sym.n_type(MachO.Symbol.N_UNDF) && sym.n_value != 0) {
|
||||
v.add(symbols[i]);
|
||||
}
|
||||
}
|
||||
|
||||
MachO.Symbol[] ret = v.toArray(new MachO.Symbol[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String[] getNeeded() throws IOException {
|
||||
Vector<String> v = new Vector<>();
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (DyLib element : needed) {
|
||||
v.add(element.toString());
|
||||
}
|
||||
return v.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String getSoname() throws IOException {
|
||||
String soname = ""; //$NON-NLS-1$
|
||||
|
||||
loadBinary();
|
||||
|
||||
for (DyLib soname2 : sonames) {
|
||||
soname = soname2.toString();
|
||||
}
|
||||
return soname;
|
||||
}
|
||||
|
||||
// private String getSubUsage(String full, String name) {
|
||||
// int start, end;
|
||||
// //boolean has_names = false;
|
||||
// //boolean has_languages = false;
|
||||
// start = 0;
|
||||
// end = 0;
|
||||
//
|
||||
// for (int i = 0; i < full.length(); i++) {
|
||||
// if (full.charAt(i) == '%') {
|
||||
// if (full.charAt(i + 1) == '-') {
|
||||
// if (start == 0) {
|
||||
// int eol = full.indexOf('\n', i + 2);
|
||||
// String temp = full.substring(i + 2, eol);
|
||||
// if (temp.compareTo(name) == 0)
|
||||
// start = eol;
|
||||
//
|
||||
// //has_names = true;
|
||||
// } else if (end == 0) {
|
||||
// end = i - 1;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //if( full.charAt( i+1 ) == '=' )
|
||||
// //has_languages = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (end == 0)
|
||||
// end = full.length();
|
||||
//
|
||||
// if (start == 0)
|
||||
// return full;
|
||||
//
|
||||
// return full.substring(start, end);
|
||||
// }
|
||||
|
||||
public String getQnxUsage() throws IOException {
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public Sizes getSizes() throws IOException {
|
||||
long text, data, bss;
|
||||
|
||||
text = 0;
|
||||
data = 0;
|
||||
bss = 0;
|
||||
|
||||
// TODO further optimization
|
||||
// TODO we only need to load the sections, not the whole shebang
|
||||
loadBinary();
|
||||
|
||||
for (Section section : sections) {
|
||||
MachO.SegmentCommand seg = section.segment;
|
||||
if (section.flags(MachO.Section.SECTION_TYP) != MachO.Section.S_ZEROFILL) {
|
||||
if (seg.prot(MachO.SegmentCommand.VM_PROT_EXECUTE)) {
|
||||
text += section.size;
|
||||
} else if (!seg.prot(MachO.SegmentCommand.VM_PROT_WRITE)) {
|
||||
data += section.size;
|
||||
}
|
||||
} else {
|
||||
if (seg.prot(MachO.SegmentCommand.VM_PROT_WRITE)) {
|
||||
bss += section.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Sizes(text, data, bss);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2012 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.macho.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
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.BinaryFile;
|
||||
import org.eclipse.cdt.utils.macho.AR;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryArchive64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MachOBinaryArchive extends BinaryFile implements IBinaryArchive {
|
||||
|
||||
ArrayList<IBinaryObject> children;
|
||||
|
||||
public MachOBinaryArchive(IBinaryParser parser, IPath p) throws IOException {
|
||||
super(parser, p, IBinaryFile.ARCHIVE);
|
||||
try (AR ar = new AR(p.toOSString())) {
|
||||
// create the object just to check file type
|
||||
}
|
||||
children = new ArrayList<>(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects()
|
||||
*/
|
||||
@Override
|
||||
public IBinaryObject[] getObjects() {
|
||||
if (hasChanged()) {
|
||||
children.clear();
|
||||
AR ar = null;
|
||||
try {
|
||||
ar = new AR(getPath().toOSString());
|
||||
AR.ARHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
IBinaryObject bin = new MachOBinaryObject(getBinaryParser(), getPath(), headers[i]);
|
||||
children.add(bin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
children.trimToSize();
|
||||
}
|
||||
return children.toArray(new IBinaryObject[0]);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2009 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.macho.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;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryExecutable64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MachOBinaryExecutable extends MachOBinaryObject implements IBinaryExecutable {
|
||||
|
||||
public MachOBinaryExecutable(IBinaryParser parser, IPath path) {
|
||||
super(parser, path, IBinaryFile.EXECUTABLE);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,407 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2015 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Apple Computer - work on performance optimizations
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.macho.parser;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
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.IAddress;
|
||||
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.Addr32;
|
||||
import org.eclipse.cdt.utils.Addr32Factory;
|
||||
import org.eclipse.cdt.utils.BinaryObjectAdapter;
|
||||
import org.eclipse.cdt.utils.CPPFilt;
|
||||
import org.eclipse.cdt.utils.Symbol;
|
||||
import org.eclipse.cdt.utils.macho.AR;
|
||||
import org.eclipse.cdt.utils.macho.MachO;
|
||||
import org.eclipse.cdt.utils.macho.MachOHelper;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryObject64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MachOBinaryObject extends BinaryObjectAdapter {
|
||||
|
||||
protected AR.ARHeader header;
|
||||
protected IAddressFactory addressFactory;
|
||||
protected MachO.Attribute attributes;
|
||||
protected MachOHelper.Sizes sizes;
|
||||
protected ISymbol[] symbols;
|
||||
protected String soname;
|
||||
protected String[] needed;
|
||||
protected long timeStamp;
|
||||
private static final String[] NO_NEEDED = new String[0];
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
* @param header
|
||||
*/
|
||||
public MachOBinaryObject(IBinaryParser parser, IPath path, AR.ARHeader header) {
|
||||
super(parser, path, IBinaryFile.OBJECT);
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
* @param type
|
||||
*/
|
||||
public MachOBinaryObject(IBinaryParser parser, IPath path, int type) {
|
||||
super(parser, path, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BinaryObjectInfo getBinaryObjectInfo() {
|
||||
// we don't use this method
|
||||
// overload to do nothing
|
||||
return new BinaryObjectInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContents() throws IOException {
|
||||
if (getPath() != null && header != null) {
|
||||
return new ByteArrayInputStream(header.getObjectData());
|
||||
}
|
||||
return super.getContents();
|
||||
}
|
||||
|
||||
protected MachOHelper getMachOHelper() throws IOException {
|
||||
IPath path = getPath();
|
||||
if (path != null) {
|
||||
if (header != null) {
|
||||
return new MachOHelper(path.toOSString(), header.getObjectDataOffset());
|
||||
} else {
|
||||
return new MachOHelper(path.toOSString());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (header != null) {
|
||||
return header.getObjectName();
|
||||
}
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAddressFactory getAddressFactory() {
|
||||
if (addressFactory == null) {
|
||||
addressFactory = new Addr32Factory();
|
||||
}
|
||||
return addressFactory;
|
||||
}
|
||||
|
||||
protected void clearCachedValues() {
|
||||
attributes = null;
|
||||
sizes = null;
|
||||
symbols = null;
|
||||
soname = null;
|
||||
needed = null;
|
||||
}
|
||||
|
||||
protected MachO.Attribute internalGetAttributes() {
|
||||
if (hasChanged()) {
|
||||
clearCachedValues();
|
||||
}
|
||||
if (attributes == null) {
|
||||
MachOHelper helper = null;
|
||||
try {
|
||||
helper = getMachOHelper();
|
||||
if (helper != null) {
|
||||
attributes = helper.getMachO().getAttributes();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
if (helper != null) {
|
||||
helper.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
protected MachOHelper.Sizes internalGetSizes() {
|
||||
if (hasChanged()) {
|
||||
clearCachedValues();
|
||||
}
|
||||
if (sizes == null) {
|
||||
MachOHelper helper = null;
|
||||
try {
|
||||
helper = getMachOHelper();
|
||||
if (helper != null) {
|
||||
sizes = helper.getSizes();
|
||||
// since we're invoking the helper we might as well update
|
||||
// the attributes since it's a pretty lightweight operation
|
||||
if (attributes == null) {
|
||||
attributes = helper.getMachO().getAttributes();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
if (helper != null) {
|
||||
helper.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sizes;
|
||||
}
|
||||
|
||||
protected ISymbol[] internalGetSymbols() {
|
||||
if (hasChanged()) {
|
||||
clearCachedValues();
|
||||
}
|
||||
if (symbols == null) {
|
||||
loadBinaryInfo();
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
protected String internalGetSoName() {
|
||||
if (hasChanged()) {
|
||||
clearCachedValues();
|
||||
}
|
||||
if (soname == null) {
|
||||
loadBinaryInfo();
|
||||
}
|
||||
return soname;
|
||||
}
|
||||
|
||||
protected String[] internalGetNeeded() {
|
||||
if (hasChanged()) {
|
||||
clearCachedValues();
|
||||
}
|
||||
if (needed == null) {
|
||||
loadBinaryInfo();
|
||||
}
|
||||
return needed;
|
||||
}
|
||||
|
||||
protected void loadBinaryInfo() {
|
||||
MachOHelper helper = null;
|
||||
try {
|
||||
helper = getMachOHelper();
|
||||
if (helper != null) {
|
||||
//TODO we can probably optimize this further in MachOHelper
|
||||
|
||||
symbols = loadSymbols(helper);
|
||||
//TODO is the sort necessary?
|
||||
Arrays.sort(symbols);
|
||||
|
||||
soname = helper.getSoname();
|
||||
needed = helper.getNeeded();
|
||||
|
||||
// since we're invoking the helper we might as well update the
|
||||
// sizes since it's a pretty lightweight operation by comparison
|
||||
if (sizes == null) {
|
||||
sizes = helper.getSizes();
|
||||
}
|
||||
// since we're invoking the helper we might as well update the
|
||||
// attributes since it's a pretty lightweight operation by comparison
|
||||
if (attributes == null) {
|
||||
attributes = helper.getMachO().getAttributes();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
symbols = NO_SYMBOLS;
|
||||
} finally {
|
||||
if (helper != null) {
|
||||
helper.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ISymbol[] loadSymbols(MachOHelper helper) throws IOException {
|
||||
CPPFilt cppfilt = null;
|
||||
try {
|
||||
ArrayList<Symbol> list = new ArrayList<>();
|
||||
// Hack should be remove when Elf is clean
|
||||
helper.getMachO().setCppFilter(false);
|
||||
cppfilt = getCPPFilt();
|
||||
//TODO we can probably optimize this further in MachOHelper
|
||||
addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION, cppfilt, list);
|
||||
addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION, cppfilt, list);
|
||||
addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE, cppfilt, list);
|
||||
addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE, cppfilt, list);
|
||||
return list.toArray(new ISymbol[list.size()]);
|
||||
} finally {
|
||||
if (cppfilt != null) {
|
||||
cppfilt.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected CPPFilt getCPPFilt() {
|
||||
MachOParser parser = (MachOParser) getBinaryParser();
|
||||
return parser.getCPPFilt();
|
||||
}
|
||||
|
||||
private void addSymbols(MachO.Symbol[] array, int type, CPPFilt cppfilt, List<Symbol> list) {
|
||||
for (org.eclipse.cdt.utils.macho.MachO.Symbol element : array) {
|
||||
String name = element.toString();
|
||||
if (cppfilt != null) {
|
||||
try {
|
||||
name = cppfilt.getFunction(name);
|
||||
} catch (IOException e1) {
|
||||
cppfilt = null;
|
||||
}
|
||||
}
|
||||
long addr = element.n_value;
|
||||
int size = 0;
|
||||
String filename = element.getFilename();
|
||||
IPath filePath = (filename != null) ? new Path(filename) : null;
|
||||
list.add(new Symbol(this, name, type, new Addr32(element.n_value), size, filePath,
|
||||
element.getLineNumber(addr), element.getLineNumber(addr + size - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCPU() {
|
||||
MachO.Attribute attribute = internalGetAttributes();
|
||||
if (attribute != null) {
|
||||
return attribute.getCPU();
|
||||
}
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDebug() {
|
||||
MachO.Attribute attribute = internalGetAttributes();
|
||||
if (attribute != null) {
|
||||
return attribute.hasDebug();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLittleEndian() {
|
||||
MachO.Attribute attribute = internalGetAttributes();
|
||||
if (attribute != null) {
|
||||
return attribute.isLittleEndian();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBSS() {
|
||||
MachOHelper.Sizes size = internalGetSizes();
|
||||
if (size != null) {
|
||||
return size.bss;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getData() {
|
||||
MachOHelper.Sizes size = internalGetSizes();
|
||||
if (size != null) {
|
||||
return size.data;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getText() {
|
||||
MachOHelper.Sizes size = internalGetSizes();
|
||||
if (size != null) {
|
||||
return size.text;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISymbol[] getSymbols() {
|
||||
ISymbol[] syms = internalGetSymbols();
|
||||
if (syms != null) {
|
||||
return syms;
|
||||
}
|
||||
return NO_SYMBOLS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISymbol getSymbol(IAddress addr) {
|
||||
//TODO should this be cached?
|
||||
// fall back to super implementation for now
|
||||
return super.getSymbol(addr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNeededSharedLibs() {
|
||||
String[] libs = internalGetNeeded();
|
||||
if (libs != null) {
|
||||
return libs;
|
||||
}
|
||||
return NO_NEEDED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSoName() {
|
||||
String name = internalGetSoName();
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasChanged() {
|
||||
IPath path = getPath();
|
||||
if (path != null) {
|
||||
File file = path.toFile();
|
||||
if (file != null) {
|
||||
long modification = file.lastModified();
|
||||
if (modification != timeStamp) {
|
||||
timeStamp = modification;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getAdapter(Class<T> adapter) {
|
||||
if (adapter.equals(MachO.class)) {
|
||||
try {
|
||||
return (T) new MachO(getPath().toOSString());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (adapter.equals(ISymbolReader.class)) {
|
||||
try (MachO macho = getAdapter(MachO.class)) {
|
||||
if (macho != null) {
|
||||
return (T) macho.getSymbolReader();
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2009 QNX Software 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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.macho.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;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOBinaryShared64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MachOBinaryShared extends MachOBinaryObject implements IBinaryShared {
|
||||
|
||||
protected MachOBinaryShared(IBinaryParser parser, IPath path) {
|
||||
super(parser, path, IBinaryFile.SHARED);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2012 QNX Software 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:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.utils.macho.parser;
|
||||
|
||||
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.core.settings.model.ICConfigExtensionReference;
|
||||
import org.eclipse.cdt.utils.CPPFilt;
|
||||
import org.eclipse.cdt.utils.macho.AR;
|
||||
import org.eclipse.cdt.utils.macho.MachO;
|
||||
import org.eclipse.cdt.utils.macho.MachO.Attribute;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated as of CDT 6.1. Use 64 bit version {@link MachOParser64}.
|
||||
* This class is planned for removal in next major release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MachOParser extends AbstractCExtension implements IBinaryParser {
|
||||
|
||||
@Override
|
||||
public IBinaryFile getBinary(IPath path) throws IOException {
|
||||
return getBinary(null, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException {
|
||||
if (path == null) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.nullPath")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
IBinaryFile binary = null;
|
||||
try {
|
||||
MachO.Attribute attribute = null;
|
||||
if (hints != null && hints.length > 0) {
|
||||
try {
|
||||
attribute = MachO.getAttributes(hints);
|
||||
} catch (IOException eof) {
|
||||
// continue, the array was to small.
|
||||
}
|
||||
}
|
||||
|
||||
//Take a second run at it if the data array failed.
|
||||
if (attribute == null) {
|
||||
attribute = MachO.getAttributes(path.toOSString());
|
||||
}
|
||||
|
||||
if (attribute != null) {
|
||||
switch (attribute.getType()) {
|
||||
case Attribute.MACHO_TYPE_EXE:
|
||||
binary = createBinaryExecutable(path);
|
||||
break;
|
||||
|
||||
case Attribute.MACHO_TYPE_SHLIB:
|
||||
binary = createBinaryShared(path);
|
||||
break;
|
||||
|
||||
case Attribute.MACHO_TYPE_OBJ:
|
||||
binary = createBinaryObject(path);
|
||||
break;
|
||||
|
||||
case Attribute.MACHO_TYPE_CORE:
|
||||
binary = createBinaryCore(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
binary = createBinaryArchive(path);
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return "MACHO"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBinary(byte[] array, IPath path) {
|
||||
return MachO.isMachOHeader(array) || AR.isARHeader(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHintBufferSize() {
|
||||
return 128;
|
||||
}
|
||||
|
||||
public CPPFilt getCPPFilt() {
|
||||
IPath cppFiltPath = getCPPFiltPath();
|
||||
CPPFilt cppfilt = null;
|
||||
if (cppFiltPath != null && !cppFiltPath.isEmpty()) {
|
||||
try {
|
||||
cppfilt = new CPPFilt(cppFiltPath.toOSString());
|
||||
} catch (IOException e2) {
|
||||
}
|
||||
}
|
||||
return cppfilt;
|
||||
}
|
||||
|
||||
protected IPath getCPPFiltPath() {
|
||||
ICConfigExtensionReference ref = getConfigExtensionReference();
|
||||
String value = ref.getExtensionData("c++filt"); //$NON-NLS-1$
|
||||
if (value == null || value.length() == 0) {
|
||||
value = "c++filt"; //$NON-NLS-1$
|
||||
}
|
||||
return new Path(value);
|
||||
}
|
||||
|
||||
protected IBinaryArchive createBinaryArchive(IPath path) throws IOException {
|
||||
return new MachOBinaryArchive(this, path);
|
||||
}
|
||||
|
||||
protected IBinaryObject createBinaryObject(IPath path) throws IOException {
|
||||
return new MachOBinaryObject(this, path, IBinaryFile.OBJECT);
|
||||
}
|
||||
|
||||
protected IBinaryExecutable createBinaryExecutable(IPath path) throws IOException {
|
||||
return new MachOBinaryExecutable(this, path);
|
||||
}
|
||||
|
||||
protected IBinaryShared createBinaryShared(IPath path) throws IOException {
|
||||
return new MachOBinaryShared(this, path);
|
||||
}
|
||||
|
||||
protected IBinaryObject createBinaryCore(IPath path) throws IOException {
|
||||
return new MachOBinaryObject(this, path, IBinaryFile.CORE);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
|||
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
|
||||
import org.eclipse.cdt.debug.application.GCCCompileOptionsParser;
|
||||
import org.eclipse.cdt.debug.application.Messages;
|
||||
import org.eclipse.cdt.utils.coff.parser.PEParser;
|
||||
import org.eclipse.cdt.utils.coff.parser.PEParser64;
|
||||
import org.eclipse.cdt.utils.elf.parser.GNUElfParser;
|
||||
import org.eclipse.cdt.utils.macho.parser.MachOParser64;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
|
@ -80,7 +80,7 @@ public class CompilerOptionParser implements IWorkspaceRunnable {
|
|||
// Try Portable Executable (Windows)
|
||||
if (bf == null) {
|
||||
try {
|
||||
bf = new PEParser().getBinary(new Path(executable));
|
||||
bf = new PEParser64().getBinary(new Path(executable));
|
||||
} catch (IOException e) {
|
||||
// Will try other parsers
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class CompilerOptionParser implements IWorkspaceRunnable {
|
|||
if (bf == null) {
|
||||
bf = new MachOParser64().getBinary(new Path(executable));
|
||||
try {
|
||||
bf = new PEParser().getBinary(new Path(executable));
|
||||
bf = new PEParser64().getBinary(new Path(executable));
|
||||
} catch (IOException e) {
|
||||
// ignored, see below early return
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue