mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 01:06:01 +02:00
2004-06-21 Alain Magloire
Big Patch from Vladimir Hirsl This patch contains a binary parser core and UI elements to 'support' AIX XCOFF32 binaries.
This commit is contained in:
parent
43bd85438e
commit
416238652a
14 changed files with 1852 additions and 1 deletions
|
@ -1,3 +1,9 @@
|
|||
2004-06-21 Alain Magloire
|
||||
|
||||
Big Patch from Vladimir Hirsl
|
||||
This patch contains a binary parser core and UI elements to 'support' AIX
|
||||
XCOFF32 binaries.
|
||||
|
||||
2004-06-21 Alain Magloire
|
||||
|
||||
The PathEntryManager was returning the array instead
|
||||
|
|
|
@ -19,6 +19,7 @@ ElfParser.name=Elf Parser
|
|||
GNUElfParser.name=GNU Elf Parser
|
||||
PEWindowsParser.name=PE Windows Parser
|
||||
CygwinPEParser.name=Cygwin PE Parser
|
||||
XCOFF32Parser.name=AIX XCOFF32 Parser
|
||||
|
||||
CDTGNUCErrorParser.name=CDT GNU C/C++ Error Parser
|
||||
CDTGNUAssemblerErrorParser.name=CDT GNU Assembler Error Parser
|
||||
|
|
|
@ -97,6 +97,16 @@
|
|||
</run>
|
||||
</cextension>
|
||||
</extension>
|
||||
<extension
|
||||
id="XCOFF32"
|
||||
name="%XCOFF32Parser.name"
|
||||
point="org.eclipse.cdt.core.BinaryParser">
|
||||
<cextension>
|
||||
<run
|
||||
class="org.eclipse.cdt.utils.xcoff.parser.XCOFF32Parser">
|
||||
</run>
|
||||
</cextension>
|
||||
</extension>
|
||||
<!-- This is for backward compatibility: an Typo was introduce in on of the realease
|
||||
and "ELF" instead of "Elf" -->
|
||||
<extension
|
||||
|
|
|
@ -47,6 +47,7 @@ Util.exception.arrayToSmall=Array to small
|
|||
Util.exception.notPE=Not a PE format
|
||||
Util.exception.notELF=Not ELF format
|
||||
Util.exception.notDOSFormat=Not DOS EXE format
|
||||
Util.exception.notXCOFF32=Not XCOFF32 format
|
||||
Util.exception.unknownFormat=Unknow machine/format
|
||||
Util.exception.nullPath=Path is null
|
||||
Util.exception.noFileAssociation=No file associated with Binary
|
||||
|
|
|
@ -0,0 +1,380 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.utils.xcoff;
|
||||
|
||||
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 XCOFF32 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 XCOFF32 object for performing XCOFF32
|
||||
* class operations.
|
||||
* @see MemberHeader
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class AR {
|
||||
protected String filename;
|
||||
protected RandomAccessFile file;
|
||||
private ARHeader header;
|
||||
private MemberHeader[] memberHeaders;
|
||||
|
||||
/**
|
||||
* TODO Provide description
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class ARHeader {
|
||||
private final static int SAIAMAG = 8;
|
||||
|
||||
private byte[] fl_magic = new byte[SAIAMAG];// Archive magic string
|
||||
private byte[] fl_memoff = new byte[20]; // Offset to member table
|
||||
private byte[] fl_gstoff = new byte[20]; // Offset to global symbol table
|
||||
private byte[] fl_gst64off = new byte[20]; // Offset to global symbol table for 64-bit objects
|
||||
private byte[] fl_fstmoff = new byte[20]; // Offset to first archive member
|
||||
private byte[] fl_lstmoff = new byte[20]; // Offset to last archive member
|
||||
private byte[] fl_freeoff = new byte[20]; // Offset to first member on free list
|
||||
|
||||
private long fstmoff = 0;
|
||||
private long lstmoff = 0;
|
||||
private long memoff = 0;
|
||||
|
||||
public ARHeader() throws IOException {
|
||||
try {
|
||||
getRandomAccessFile();
|
||||
file.seek(0);
|
||||
file.read(fl_magic);
|
||||
if (isARHeader(fl_magic)) {
|
||||
file.read(fl_memoff);
|
||||
file.read(fl_gstoff);
|
||||
file.read(fl_gst64off);
|
||||
file.read(fl_fstmoff);
|
||||
file.read(fl_lstmoff);
|
||||
file.read(fl_freeoff);
|
||||
fstmoff = Long.parseLong(removeBlanks(new String(fl_fstmoff)));
|
||||
lstmoff = Long.parseLong(removeBlanks(new String(fl_lstmoff)));
|
||||
memoff = Long.parseLong(removeBlanks(new String(fl_memoff)));
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
dispose();
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isXcoffARHeader() {
|
||||
return (fstmoff != 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
|
||||
header = new ARHeader();
|
||||
if (!header.isXcoffARHeader()) {
|
||||
file.close();
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
if (file != null) {
|
||||
file.close();
|
||||
file = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
dispose();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isARHeader(byte[] ident) {
|
||||
if (ident.length < 8
|
||||
|| ident[0] != '<'
|
||||
|| ident[1] != 'b'
|
||||
|| ident[2] != 'i'
|
||||
|| ident[3] != 'g'
|
||||
|| ident[4] != 'a'
|
||||
|| ident[5] != 'f'
|
||||
|| ident[6] != '>'
|
||||
|| ident[7] != '\n')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>ARHeader</code> class is used to store the per-object file
|
||||
* archive headers. It can also create an XCOFF32 object for inspecting
|
||||
* the object file data.
|
||||
*/
|
||||
public class MemberHeader {
|
||||
byte[] ar_size = new byte[20]; // File member size - decimal
|
||||
byte[] ar_nxtmem = new byte[20]; // Next member offset - decimal
|
||||
byte[] ar_prvmem = new byte[20]; // Previous member offset - decimal
|
||||
byte[] ar_date = new byte[12]; // File member date - decimal
|
||||
byte[] ar_uid = new byte[12]; // File member userid - decimal
|
||||
byte[] ar_gid = new byte[12]; // File member group id - decimal
|
||||
byte[] ar_mode = new byte[12]; // File member mode - octal
|
||||
byte[] ar_namlen = new byte[4]; // File member name length -decimal
|
||||
byte[] ar_name; // Start of member name
|
||||
byte[] ar_fmag = new byte[2]; // AIAFMAG - string to end "`\n"
|
||||
|
||||
// converted values
|
||||
long size;
|
||||
long nxtmem;
|
||||
long prvmem;
|
||||
int namlen;
|
||||
String name;
|
||||
|
||||
long file_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>file</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 {
|
||||
// StringBuffer name = new StringBuffer(0);
|
||||
// long pos = file.getFilePointer();
|
||||
//
|
||||
// try {
|
||||
// if (strtbl_pos != -1) {
|
||||
// byte temp;
|
||||
// file.seek(strtbl_pos + offset);
|
||||
// while ((temp = file.readByte()) != '\n')
|
||||
// name.append((char) temp);
|
||||
// }
|
||||
// } finally {
|
||||
// file.seek(pos);
|
||||
// }
|
||||
//
|
||||
// return name.toString();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Creates a new archive header object.
|
||||
*
|
||||
* Assumes that file is already at the correct location in the file.
|
||||
*
|
||||
* @throws IOException
|
||||
* There was an error processing the header data from the file.
|
||||
*/
|
||||
public MemberHeader() throws IOException {
|
||||
//
|
||||
// Read in the archive header data. Fixed sizes.
|
||||
//
|
||||
file.read(ar_size);
|
||||
file.read(ar_nxtmem);
|
||||
file.read(ar_prvmem);
|
||||
file.read(ar_date);
|
||||
file.read(ar_uid);
|
||||
file.read(ar_gid);
|
||||
file.read(ar_mode);
|
||||
file.read(ar_namlen);
|
||||
namlen = Integer.parseInt(removeBlanks(new String(ar_namlen)));
|
||||
ar_name = new byte[namlen];
|
||||
file.read(ar_name);
|
||||
file.read(ar_fmag);
|
||||
|
||||
size = Long.parseLong(removeBlanks(new String(ar_size)));
|
||||
nxtmem = Long.parseLong(removeBlanks(new String(ar_nxtmem)));
|
||||
prvmem = Long.parseLong(removeBlanks(new String(ar_prvmem)));
|
||||
name = new String(ar_name, 0, namlen);
|
||||
|
||||
//
|
||||
// Save this location so we can create the XCOFF32 object later.
|
||||
//
|
||||
file_offset = file.getFilePointer();
|
||||
if ((file_offset % 2) == 1) {
|
||||
++file_offset;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the name of the object file */
|
||||
public String getObjectName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Get the size of the object file . */
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getArchiveName() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an new XCOFF32 object for the object file.
|
||||
*
|
||||
* @throws IOException
|
||||
* Not a valid XCOFF32 object file.
|
||||
* @return A new XCOFF32 object.
|
||||
* @see XCoff32#XCoff32( String, long )
|
||||
*/
|
||||
public XCoff32 getXCoff() throws IOException {
|
||||
return new XCoff32(filename, file_offset);
|
||||
}
|
||||
|
||||
public byte[] getObjectData() throws IOException {
|
||||
byte[] temp = new byte[(int) size];
|
||||
file = getRandomAccessFile();
|
||||
file.seek(file_offset);
|
||||
file.read(temp);
|
||||
dispose();
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the headers from the file (if required). */
|
||||
private void loadHeaders() throws IOException {
|
||||
if (memberHeaders != null)
|
||||
return;
|
||||
|
||||
Vector v = new Vector();
|
||||
try {
|
||||
//
|
||||
// Check for EOF condition
|
||||
//
|
||||
MemberHeader aHeader;
|
||||
for (long pos = header.fstmoff; pos < file.length(); pos = aHeader.nxtmem) {
|
||||
file.seek(pos);
|
||||
aHeader = new MemberHeader();
|
||||
String name = aHeader.getObjectName();
|
||||
v.add(aHeader);
|
||||
if (pos == 0 || pos == header.lstmoff) { // end of double linked list
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
memberHeaders = (MemberHeader[]) v.toArray(new MemberHeader[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 MemberHeader[] getHeaders() throws IOException {
|
||||
loadHeaders();
|
||||
return memberHeaders;
|
||||
}
|
||||
|
||||
public String[] extractFiles(String outdir, String[] names) throws IOException {
|
||||
Vector names_used = new Vector();
|
||||
String object_name;
|
||||
int count;
|
||||
|
||||
loadHeaders();
|
||||
|
||||
count = 0;
|
||||
for (int i = 0; i < memberHeaders.length; i++) {
|
||||
object_name = memberHeaders[i].getObjectName();
|
||||
if (names != null && !stringInStrings(object_name, names))
|
||||
continue;
|
||||
|
||||
object_name = "" + count + "_" + object_name; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
count++;
|
||||
|
||||
byte[] data = memberHeaders[i].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 (String[]) names_used.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private boolean stringInStrings(String str, String[] set) {
|
||||
for (int i = 0; i < set.length; i++)
|
||||
if (str.compareTo(set[i]) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public String[] extractFiles(String outdir) throws IOException {
|
||||
return extractFiles(outdir, null);
|
||||
}
|
||||
|
||||
private RandomAccessFile getRandomAccessFile () throws IOException {
|
||||
if (file == null) {
|
||||
file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
AR ar = new AR(args[0]);
|
||||
ar.getHeaders();
|
||||
ar.extractFiles(args[0]);
|
||||
System.out.println(ar);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,828 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.utils.xcoff;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.utils.coff.ReadMemoryAccess;
|
||||
|
||||
/**
|
||||
* TODO Provide description
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class XCoff32 {
|
||||
public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
String filename;
|
||||
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;
|
||||
|
||||
// Consts
|
||||
public final static int U802TOCMAGIC = 0x01df; // XCOFF32
|
||||
public final static int U803TOCMAGIC = 0x01e7; // obsolete XCOFF64 - not used
|
||||
public final static int U803XTOCMAGIC = 0x01ef; // discontinued AIX XCOFF64
|
||||
public final static int U64_TOCMAGIC = 0x01f7; // XCOFF64
|
||||
|
||||
// Flags
|
||||
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_FDPR_PROF = 0x0010; // file was profiled with fdpr command
|
||||
public final static int F_FDPR_OPTI = 0x0020; // file was reordered with fdpr command
|
||||
public final static int F_DSA = 0x0040; // file uses Very Large Program Support
|
||||
// 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_LOADONLY = 0x4000;// rs/6000 aix: if the object file is a member of an archive;
|
||||
// it can be loaded by the system loader but the member is ignored by the binder.
|
||||
|
||||
// Fields
|
||||
public short f_magic; /* 00-01 2 bytes: magic number */
|
||||
public short 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 short f_opthdr; /* 16-17 2 bytes: sizeof(optional hdr) */
|
||||
public short 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, false);
|
||||
}
|
||||
|
||||
public FileHeader (byte[] hdr, boolean little) throws IOException {
|
||||
commonSetup(hdr, little);
|
||||
}
|
||||
|
||||
public void commonSetup(byte[] hdr, boolean little) throws IOException {
|
||||
if (hdr == null || hdr.length < FILHSZ) {
|
||||
throw new EOFException(CCorePlugin.getResourceString("Util.exception.arrayToSmall")); //$NON-NLS-1$
|
||||
}
|
||||
if (!isXCOFF32Header(hdr)) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.notXCOFF32")); //$NON-NLS-1$
|
||||
}
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, little);
|
||||
f_magic = memory.getShort();
|
||||
f_nscns = memory.getShort();
|
||||
f_timdat = memory.getInt();
|
||||
f_symptr = memory.getInt();
|
||||
f_nsyms = memory.getInt();
|
||||
f_opthdr = memory.getShort();
|
||||
f_flags = memory.getShort();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
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 = 72; // First 28 bytes same as for COFF
|
||||
|
||||
// Fields (as in COFF)
|
||||
public short magic; /* 2 bytes: type of file (0x010B) */
|
||||
public short vstamp; /* 2 bytes: version stamp (1) */
|
||||
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 */
|
||||
// Additional fields
|
||||
public int o_toc; /* 4 bytes: Address of TOC anchor */
|
||||
public short o_snentry; /* 2 bytes: Section number for entry point */
|
||||
public short o_sntext; /* 2 bytes: Section number for .text */
|
||||
public short o_sndata; /* 2 bytes: Section number for .data */
|
||||
public short o_sntoc; /* 2 bytes: Section number for TOC */
|
||||
public short o_snloader;/* 2 bytes: Section number for loader data */
|
||||
public short o_snbss; /* 2 bytes: Section number for .bss */
|
||||
public short o_algntext;/* 2 bytes: Maximum alignment for .text */
|
||||
public short o_algndata;/* 2 bytes: Maximum alignment for .data */
|
||||
public short o_modtype; /* 2 bytes: Maximum alignment for .data */
|
||||
public byte o_cpuflag; /* 1 byte: Bit flags - cpu types of objects */
|
||||
public byte o_cputype; /* 1 byte: Reserved for cpu type */
|
||||
public int o_maxstack; /* 4 bytes: Maximum stack size allowed (bytes) */
|
||||
public int o_maxdata; /* 4 bytes: Maximum data size allowed (bytes) */
|
||||
public int o_debugger; /* 4 bytes: Reserved for debuggers */
|
||||
// public byte o_resv2[8]; /* 8 bytes: Reserved. Field must contain 0s */
|
||||
|
||||
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, false); // big endian
|
||||
// COFF common
|
||||
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();
|
||||
// XCOFF32 specific
|
||||
o_toc = memory.getInt();
|
||||
o_snentry = memory.getShort();
|
||||
o_sntext = memory.getShort();
|
||||
o_sndata = memory.getShort();
|
||||
o_sntoc = memory.getShort();
|
||||
o_snloader = memory.getShort();
|
||||
o_snbss = memory.getShort();
|
||||
o_algntext = memory.getShort();
|
||||
o_algndata = memory.getShort();
|
||||
o_modtype = memory.getShort();
|
||||
o_cpuflag = memory.getByte();
|
||||
o_cputype = memory.getByte();
|
||||
o_maxstack = memory.getInt();
|
||||
o_maxdata = memory.getInt();
|
||||
o_debugger = memory.getInt();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
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$
|
||||
buffer.append("o_toc = ").append(o_toc).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_snentry = ").append(o_snentry).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_sntext = ").append(o_sntext).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_sndata = ").append(o_sndata).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_sntoc = ").append(o_sntoc).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_snloader = ").append(o_snloader).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_snbss = ").append(o_snbss).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_algntext = ").append(o_algntext).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_algndata = ").append(o_algndata).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_modtype = ").append(o_modtype).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_cpuflag = ").append(o_cpuflag).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_cputype = ").append(o_cputype).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_maxstack = ").append(o_maxstack).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_maxdata = ").append(o_maxdata).append(NL); //$NON-NLS-1$
|
||||
buffer.append("o_debugger = ").append(o_debugger).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 _PAD = ".pad"; //$NON-NLS-1$
|
||||
public final static String _LOADER = ".loader"; //$NON-NLS-1$
|
||||
public final static String _DEBUG = ".debug"; //$NON-NLS-1$
|
||||
public final static String _TYPCHK = ".typchk"; //$NON-NLS-1$
|
||||
public final static String _EXCEPT = ".except"; //$NON-NLS-1$
|
||||
public final static String _OVRFLO = ".ovrflo"; //$NON-NLS-1$
|
||||
public final static String _INFO = ".info"; //$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 STYP_EXCEPT = 0x0080; /* section contains exceptions info 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_LOADER = 0x1000; /* loader section:
|
||||
imported symbols,
|
||||
exported symbols,
|
||||
relocation data,
|
||||
type-check information and
|
||||
shared object names */
|
||||
// public final static int STYP_MERGE = 0x2000; /* merge section -- combines with
|
||||
// text, data or bss sections only */
|
||||
public final static int STYP_DEBUG = 0x2000; /* debug section - su
|
||||
information used by the symbolic debugger */
|
||||
// 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_TYPCHK = 0x4000; /* type-check section - contains
|
||||
parameter/argument type-check strings used by the binder */
|
||||
public final static int STYP_OVRFLO = 0x8000; /* overflow section:
|
||||
Specifies a relocation or line-number field overflow section.
|
||||
A section header of this type contains the count of relocation
|
||||
entries and line number entries for some other section.
|
||||
This section header is required when either of the counts
|
||||
exceeds 65,534. */
|
||||
|
||||
// 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 short s_nreloc; // 2 bytes: number of relocation entries
|
||||
public short 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, false);
|
||||
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.getShort();
|
||||
s_nlnno = memory.getShort();
|
||||
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;
|
||||
// }
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public class Symbol {
|
||||
public final static int SYMSZ = 18;
|
||||
public final static int SYMNMLEN = 8;
|
||||
|
||||
/* section number, in n_scnum. */
|
||||
public final static int N_DEBUG = -2;
|
||||
public final static int N_ABS = -1;
|
||||
public final static int N_UNDEF = 0;
|
||||
|
||||
/* Storage class, in n_sclass. */
|
||||
public final static int C_BCOMM = 135; /* beginning of the common block */
|
||||
public final static int C_BINCL = 108; /* beginning of include file */
|
||||
public final static int C_BLOCK = 100; /* beginning or end of inner block */
|
||||
public final static int C_BSTAT = 143; /* beginning of static block */
|
||||
public final static int C_DECL = 140; /* declaration of object (type) */
|
||||
public final static int C_ECOML = 136; /* local member of common block */
|
||||
public final static int C_ECOMM = 127; /* end of common block */
|
||||
public final static int C_EINCL = 109; /* end of include file */
|
||||
public final static int C_ENTRY = 141; /* alternate entry */
|
||||
public final static int C_ESTAT = 144; /* end of static block */
|
||||
public final static int C_EXT = 2; /* external symbol */
|
||||
public final static int C_FCN = 101; /* beginning or end of function */
|
||||
public final static int C_FILE = 103; /* source file name and compiler information */
|
||||
public final static int C_FUN = 142; /* function or procedure */
|
||||
public final static int C_GSYM = 128; /* global variable */
|
||||
public final static int C_HIDEXT = 107; /* unnamed external symbol */
|
||||
public final static int C_INFO = 100; /* comment section reference */
|
||||
public final static int C_LSYM = 129; /* automatic variable allocated on stack */
|
||||
public final static int C_NULL = 0; /* symbol table entry marked for deletion */
|
||||
public final static int C_PSYM = 130; /* argument to subroutine allocated on stack */
|
||||
public final static int C_RPSYM = 132; /* argument to function or procedure stored in register */
|
||||
public final static int C_RSYM = 131; /* register variable */
|
||||
public final static int C_STAT = 3; /* static symbol (unknown) */
|
||||
public final static int C_STSYM = 133; /* statically allocated symbol */
|
||||
public final static int C_TCSYM = 134; /* reserved */
|
||||
public final static int C_WEAKEXT = 111;/* weak external symbol */
|
||||
|
||||
/* csect storage class, in x_smlas. */
|
||||
public final static int XMC_PR = 0; /* program code */
|
||||
public final static int XMC_RO = 1; /* read only constant */
|
||||
public final static int XMC_DB = 2; /* debug dictionary table */
|
||||
public final static int XMC_TC = 3; /* general TOC entry */
|
||||
public final static int XMC_UA = 4; /* unclassified */
|
||||
public final static int XMC_RW = 5; /* read/write data */
|
||||
public final static int XMC_GL = 6; /* global linkage */
|
||||
public final static int XMC_XO = 7; /* extended operation */
|
||||
public final static int XMC_SV = 8; /* 32-bit supervisor call descriptor csect */
|
||||
public final static int XMC_BS = 9; /* BSS class (uninitialized static internal) */
|
||||
public final static int XMC_DS = 10; /* csect containing a function descriptor */
|
||||
public final static int XMC_UC = 11; /* unnamed FORTRAN common */
|
||||
public final static int XMC_TI = 12; /* reserved */
|
||||
public final static int XMC_TB = 13; /* reserved */
|
||||
public final static int XMC_TC0 = 15; /* TOC anchor for TOC addressability */
|
||||
public final static int XMC_TD = 16; /* scalar data entry in TOC */
|
||||
public final static int XMC_SV64 = 17; /* 64-bit supervisor call descriptor csect */
|
||||
public final static int XMC_SV3264 = 18;/* supervisor call descriptor csect for both 32-bit and 64-bit */
|
||||
|
||||
|
||||
// fields
|
||||
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 short n_type; /* Unsigned short. Symbolic type. Obsolete in XCOFF */
|
||||
public byte n_sclass; /* char, Storage class. */
|
||||
public byte n_numaux; /* char. Nuymber of auxiliary enties. */
|
||||
private byte[] aux;
|
||||
public byte x_smclas; /* storage mapping class in csect auxiliary entry */
|
||||
|
||||
public Symbol(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public Symbol(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] bytes = new byte[SYMSZ];
|
||||
file.readFully(bytes);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(bytes, false); // big endian
|
||||
memory.getBytes(_n_name);
|
||||
n_value = memory.getInt();
|
||||
n_scnum = memory.getShort();
|
||||
n_type = memory.getShort();
|
||||
n_sclass = memory.getByte();
|
||||
n_numaux = memory.getByte();
|
||||
aux = new byte[n_numaux * SYMSZ];
|
||||
file.readFully(aux);
|
||||
// 11th byte in the last auxiliary entry (csect)
|
||||
x_smclas = (n_numaux > 0) ? aux[aux.length - 7] : 0;
|
||||
}
|
||||
|
||||
private boolean isLongName() {
|
||||
return (_n_name[0] == 0 &&
|
||||
_n_name[1] == 0 &&
|
||||
_n_name[2] == 0 &&
|
||||
_n_name[3] == 0);
|
||||
}
|
||||
|
||||
private String getShortName() {
|
||||
for (int i = 0; i < _n_name.length; i++) {
|
||||
if (_n_name[i] == 0) {
|
||||
return new String(_n_name, 0, i);
|
||||
}
|
||||
}
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public String getName(byte[] table) {
|
||||
if (table.length > 0 && isLongName()) {
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(_n_name, false);
|
||||
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 getShortName();
|
||||
}
|
||||
|
||||
public boolean isFunction() {
|
||||
return ((n_sclass == C_EXT || n_sclass == C_HIDEXT || n_sclass == C_WEAKEXT) &&
|
||||
n_scnum == opthdr.o_sntext &&
|
||||
!getShortName().equals(SectionHeader._TEXT));
|
||||
}
|
||||
|
||||
public boolean isVariable() {
|
||||
return ((n_sclass == C_EXT || n_sclass == C_HIDEXT || n_sclass == C_WEAKEXT) &&
|
||||
(n_scnum == opthdr.o_snbss || n_scnum == opthdr.o_sndata) &&
|
||||
x_smclas != XMC_TC0 && x_smclas != XMC_TC && x_smclas != XMC_DS &&
|
||||
!getShortName().equals(SectionHeader._BSS) &&
|
||||
!getShortName().equals(SectionHeader._DATA));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("SYMBOL TABLE ENTRY").append(NL); //$NON-NLS-1$
|
||||
buffer.append("n_value = ").append(n_value).append(NL); //$NON-NLS-1$
|
||||
buffer.append("n_scnum = ").append(n_scnum).append(NL); //$NON-NLS-1$
|
||||
buffer.append("n_type = ").append(n_type).append(NL); //$NON-NLS-1$
|
||||
buffer.append("n_sclass = ").append(n_sclass).append(NL); //$NON-NLS-1$
|
||||
buffer.append("n_numaux = ").append(n_numaux).append(NL); //$NON-NLS-1$
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Attribute {
|
||||
public static final int XCOFF_TYPE_EXE = 1;
|
||||
public static final int XCOFF_TYPE_SHLIB = 2;
|
||||
public static final int XCOFF_TYPE_OBJ = 3;
|
||||
public static final int XCOFF_TYPE_CORE = 4;
|
||||
|
||||
String cpu;
|
||||
int type;
|
||||
boolean bDebug;
|
||||
boolean isle;
|
||||
|
||||
public String getCPU() {
|
||||
return cpu;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean hasDebug() {
|
||||
return bDebug;
|
||||
}
|
||||
|
||||
public boolean isLittleEndian() {
|
||||
return isle;
|
||||
}
|
||||
}
|
||||
|
||||
public Attribute getAttributes() {
|
||||
Attribute attrib = new Attribute();
|
||||
// Machine type.
|
||||
switch (filehdr.f_magic) {
|
||||
case FileHeader.U802TOCMAGIC:
|
||||
attrib.cpu = "xcoff32"; //$NON-NLS-1$
|
||||
break;
|
||||
case FileHeader.U64_TOCMAGIC:
|
||||
attrib.cpu = "xcoff64"; //$NON-NLS-1$
|
||||
break;
|
||||
default:
|
||||
attrib.cpu = "unknown"; //$NON-NLS-1$
|
||||
break;
|
||||
}
|
||||
|
||||
/* XCOFF characteristics, FileHeader.f_flags. */
|
||||
if ((filehdr.f_flags & FileHeader.F_SHROBJ) != 0) {
|
||||
attrib.type = Attribute.XCOFF_TYPE_SHLIB;
|
||||
} else if ((filehdr.f_flags & FileHeader.F_EXEC) != 0) {
|
||||
attrib.type = Attribute.XCOFF_TYPE_EXE;
|
||||
} else {
|
||||
attrib.type = Attribute.XCOFF_TYPE_OBJ;
|
||||
}
|
||||
|
||||
// For AIX XCOFF always assume big endian unless otherwise.
|
||||
attrib.isle = false;
|
||||
|
||||
// No debug information.
|
||||
if ((filehdr.f_flags & (FileHeader.F_LNNO & FileHeader.F_LSYMS & FileHeader.F_RELFLG)) != 0) {
|
||||
attrib.bDebug = false;
|
||||
} else {
|
||||
attrib.bDebug = true;
|
||||
}
|
||||
|
||||
return attrib;
|
||||
}
|
||||
|
||||
public FileHeader getFileHeader() throws IOException {
|
||||
return filehdr;
|
||||
}
|
||||
|
||||
public OptionalHeader getOptionalHeader() throws IOException {
|
||||
return opthdr;
|
||||
}
|
||||
|
||||
public SectionHeader[] getSectionHeaders() throws IOException {
|
||||
if (scnhdrs == null) {
|
||||
getRandomAccessFile();
|
||||
scnhdrs = new SectionHeader[getFileHeader().f_nscns];
|
||||
long sec = startingOffset + 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 = startingOffset + getFileHeader().f_symptr;
|
||||
getRandomAccessFile();
|
||||
rfile.seek(offset);
|
||||
int numSymbols = getFileHeader().f_nsyms;
|
||||
ArrayList symList = new ArrayList(numSymbols);
|
||||
for (int i = 0; i < numSymbols; ++i) {
|
||||
Symbol v = new Symbol(rfile);
|
||||
symList.add(v);
|
||||
i += v.n_numaux; // account for auxiliary entries
|
||||
}
|
||||
symbols = (Symbol[]) symList.toArray(new Symbol[symList.size()]);
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
public byte[] getStringTable() throws IOException {
|
||||
if (string_table == null) {
|
||||
if (filehdr.f_nsyms > 0) {
|
||||
getRandomAccessFile();
|
||||
long symbolsize = Symbol.SYMSZ * getFileHeader().f_nsyms;
|
||||
long offset = startingOffset+ getFileHeader().f_symptr + symbolsize;
|
||||
rfile.seek(offset);
|
||||
byte[] bytes = new byte[4];
|
||||
rfile.readFully(bytes);
|
||||
int str_len = ReadMemoryAccess.getIntBE(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;
|
||||
}
|
||||
|
||||
// A hollow entry, to be used with caution in controlled situations
|
||||
protected XCoff32() {
|
||||
}
|
||||
|
||||
public XCoff32(String filename) throws IOException {
|
||||
this(filename, 0);
|
||||
}
|
||||
|
||||
public XCoff32(String filename, long offset) throws IOException {
|
||||
this.filename = filename;
|
||||
commonSetup(new RandomAccessFile(filename, "r"), offset);
|
||||
}
|
||||
|
||||
void commonSetup(RandomAccessFile file, long offset) throws IOException {
|
||||
startingOffset = offset;
|
||||
rfile = file;
|
||||
try {
|
||||
filehdr = new FileHeader(rfile, startingOffset);
|
||||
if (filehdr.f_opthdr > 0) {
|
||||
opthdr = new OptionalHeader(rfile, startingOffset + FileHeader.FILHSZ);
|
||||
}
|
||||
if (filehdr.f_opthdr < OptionalHeader.AOUTHDRSZ) {
|
||||
// auxiliary header does not contain needed information,
|
||||
// must load section headers
|
||||
getSectionHeaders();
|
||||
for (int i = 0; i < filehdr.f_nscns; ++i) {
|
||||
if ((scnhdrs[i].s_flags & SectionHeader.STYP_TEXT) != 0) {
|
||||
opthdr.o_sntext = (short)(i+1);
|
||||
}
|
||||
else if ((scnhdrs[i].s_flags & SectionHeader.STYP_BSS) != 0) {
|
||||
opthdr.o_snbss = (short)(i+1);
|
||||
}
|
||||
else if ((scnhdrs[i].s_flags & SectionHeader.STYP_DATA) != 0) {
|
||||
opthdr.o_sndata = (short)(i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
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]).append("n_name = "); //$NON-NLS-1$
|
||||
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 void dispose() throws IOException {
|
||||
if (rfile != null) {
|
||||
rfile.close();
|
||||
rfile = null;
|
||||
}
|
||||
}
|
||||
|
||||
RandomAccessFile getRandomAccessFile () throws IOException {
|
||||
if (rfile == null) {
|
||||
rfile = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
|
||||
}
|
||||
return rfile;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
XCoff32 xcoff = new XCoff32(args[0]);
|
||||
System.out.println(xcoff);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hints
|
||||
* @return
|
||||
*/
|
||||
public static boolean isXCOFF32Header(byte[] hints) {
|
||||
if (hints != null && hints[0] == 0x01 && (hints[1] == (byte)0xdf) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hints
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Attribute getAttributes(byte[] hints) throws IOException {
|
||||
XCoff32 emptyXCoff = new XCoff32();
|
||||
emptyXCoff.filehdr = new XCoff32.FileHeader(hints, false); // big endian
|
||||
Attribute attribute = emptyXCoff.getAttributes();
|
||||
emptyXCoff.dispose();
|
||||
return attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Attribute getAttributes(String file) throws IOException {
|
||||
XCoff32 xcoff = new XCoff32(file);
|
||||
Attribute attribute = xcoff.getAttributes();
|
||||
xcoff.dispose();
|
||||
return attribute;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.utils.xcoff.parser;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||
import org.eclipse.cdt.utils.Addr2line;
|
||||
import org.eclipse.cdt.utils.CPPFilt;
|
||||
import org.eclipse.cdt.utils.CygPath;
|
||||
import org.eclipse.cdt.utils.Symbol;
|
||||
import org.eclipse.cdt.utils.xcoff.AR;
|
||||
import org.eclipse.cdt.utils.xcoff.XCoff32;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* A member of an XCOFF32 archive
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class ARMember extends XCOFFBinaryObject {
|
||||
AR.MemberHeader header;
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
*/
|
||||
public ARMember(IBinaryParser parser, IPath path, AR.MemberHeader header) {
|
||||
super(parser, path);
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents()
|
||||
*/
|
||||
public InputStream getContents() {
|
||||
InputStream stream = null;
|
||||
if (path != null && header != null) {
|
||||
try {
|
||||
stream = new ByteArrayInputStream(header.getObjectData());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (stream == null) {
|
||||
stream = super.getContents();
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getShortName()
|
||||
*/
|
||||
public String getName() {
|
||||
if (header != null) {
|
||||
return header.getObjectName();
|
||||
}
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.xcoff.parser.XCOFFBinaryObject#addSymbols(org.eclipse.cdt.utils.xcoff.XCoff32.Symbol[], byte[], org.eclipse.cdt.utils.Addr2line, org.eclipse.cdt.utils.CPPFilt, org.eclipse.cdt.utils.CygPath, java.util.List)
|
||||
*/
|
||||
protected void addSymbols(XCoff32.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath, List list) {
|
||||
for (int i = 0; i < peSyms.length; i++) {
|
||||
if (peSyms[i].isFunction() || peSyms[i].isVariable()) {
|
||||
String name = peSyms[i].getName(table);
|
||||
if (name == null || name.trim().length() == 0 /*||
|
||||
!Character.isJavaIdentifierStart(name.charAt(0))*/) {
|
||||
continue;
|
||||
}
|
||||
Symbol sym = new Symbol(this);
|
||||
sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
|
||||
sym.addr = peSyms[i].n_value;
|
||||
|
||||
sym.name = name;
|
||||
if (cppfilt != null) {
|
||||
try {
|
||||
sym.name = cppfilt.getFunction(sym.name);
|
||||
} catch (IOException e1) {
|
||||
cppfilt = null;
|
||||
}
|
||||
}
|
||||
|
||||
list.add(sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.xcoff.parser.XCOFFBinaryObject#getXCoff32()
|
||||
*/
|
||||
protected XCoff32 getXCoff32() throws IOException {
|
||||
if (header != null) {
|
||||
return header.getXCoff();
|
||||
}
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.noFileAssociation")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.utils.xcoff.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.xcoff.AR;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* XCOFF32 binary archive
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class BinaryArchive extends BinaryFile implements IBinaryArchive {
|
||||
private ArrayList children;
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
* @throws IOException
|
||||
*/
|
||||
public BinaryArchive(IBinaryParser parser, IPath path) throws IOException {
|
||||
super(parser, path);
|
||||
new AR(path.toOSString()).dispose(); // check file type
|
||||
children = new ArrayList(5);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.ARCHIVE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects()
|
||||
*/
|
||||
public IBinaryObject[] getObjects() {
|
||||
if (hasChanged()) {
|
||||
children.clear();
|
||||
AR ar = null;
|
||||
try {
|
||||
ar = new AR(getPath().toOSString());
|
||||
AR.MemberHeader[] headers = ar.getHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
IBinaryObject bin = new ARMember(getBinaryParser(), getPath(), headers[i]);
|
||||
children.add(bin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (ar != null) {
|
||||
ar.dispose();
|
||||
}
|
||||
children.trimToSize();
|
||||
}
|
||||
return (IBinaryObject[]) children.toArray(new IBinaryObject[0]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.utils.xcoff.parser;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.utils.ToolsProvider;
|
||||
import org.eclipse.cdt.utils.xcoff.AR;
|
||||
import org.eclipse.cdt.utils.xcoff.XCoff32;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* XCOFF 32bit binary parser for AIX
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class XCOFF32Parser extends ToolsProvider implements IBinaryParser {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser#getBinary(byte[], org.eclipse.core.runtime.IPath)
|
||||
*/
|
||||
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;
|
||||
if (isBinary(hints, path)) {
|
||||
try {
|
||||
XCoff32.Attribute attribute = null;
|
||||
if (hints != null && hints.length > 0) {
|
||||
try {
|
||||
attribute = XCoff32.getAttributes(hints);
|
||||
} catch (EOFException eof) {
|
||||
// continue, the array was to small.
|
||||
}
|
||||
}
|
||||
|
||||
//Take a second run at it if the data array failed.
|
||||
if(attribute == null) {
|
||||
attribute = XCoff32.getAttributes(path.toOSString());
|
||||
}
|
||||
|
||||
if (attribute != null) {
|
||||
switch (attribute.getType()) {
|
||||
case XCoff32.Attribute.XCOFF_TYPE_EXE :
|
||||
binary = createBinaryExecutable(path);
|
||||
break;
|
||||
|
||||
case XCoff32.Attribute.XCOFF_TYPE_SHLIB :
|
||||
binary = createBinaryShared(path);
|
||||
break;
|
||||
|
||||
case XCoff32.Attribute.XCOFF_TYPE_OBJ :
|
||||
binary = createBinaryObject(path);
|
||||
break;
|
||||
|
||||
case XCoff32.Attribute.XCOFF_TYPE_CORE :
|
||||
binary = createBinaryCore(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
binary = createBinaryArchive(path);
|
||||
}
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath)
|
||||
*/
|
||||
public IBinaryFile getBinary(IPath path) throws IOException {
|
||||
return getBinary(null, path);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser#getFormat()
|
||||
*/
|
||||
public String getFormat() {
|
||||
return "XCOFF32"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
|
||||
*/
|
||||
public boolean isBinary(byte[] hints, IPath path) {
|
||||
return XCoff32.isXCOFF32Header(hints) || AR.isARHeader(hints);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize()
|
||||
*/
|
||||
public int getHintBufferSize() {
|
||||
return 512;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private IBinaryFile createBinaryExecutable(IPath path) {
|
||||
return new XCOFFBinaryObject(this, path) {
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.EXECUTABLE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private IBinaryFile createBinaryShared(IPath path) {
|
||||
return new XCOFFBinaryObject(this, path) {
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.SHARED;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private IBinaryFile createBinaryObject(IPath path) {
|
||||
return new XCOFFBinaryObject(this, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private IBinaryFile createBinaryCore(IPath path) {
|
||||
return new XCOFFBinaryObject(this, path) {
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.CORE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private IBinaryFile createBinaryArchive(IPath path) throws IOException {
|
||||
return new BinaryArchive(this, path);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.utils.xcoff.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||
import org.eclipse.cdt.utils.Addr2line;
|
||||
import org.eclipse.cdt.utils.BinaryObjectAdapter;
|
||||
import org.eclipse.cdt.utils.CPPFilt;
|
||||
import org.eclipse.cdt.utils.CygPath;
|
||||
import org.eclipse.cdt.utils.Objdump;
|
||||
import org.eclipse.cdt.utils.Symbol;
|
||||
import org.eclipse.cdt.utils.xcoff.XCoff32;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* TODO Provide description
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class XCOFFBinaryObject extends BinaryObjectAdapter {
|
||||
BinaryObjectInfo info;
|
||||
ISymbol[] symbols;
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param path
|
||||
*/
|
||||
public XCOFFBinaryObject(IBinaryParser parser, IPath path) {
|
||||
super(parser, path);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols()
|
||||
*/
|
||||
public ISymbol[] getSymbols() {
|
||||
if (hasChanged() || symbols == null) {
|
||||
try {
|
||||
loadAll();
|
||||
} catch (IOException e) {
|
||||
symbols = NO_SYMBOLS;
|
||||
}
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo()
|
||||
*/
|
||||
protected BinaryObjectInfo getBinaryObjectInfo() {
|
||||
if (hasChanged() || info == null) {
|
||||
try {
|
||||
loadInfo();
|
||||
} catch (IOException e) {
|
||||
info = new BinaryObjectInfo();
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
|
||||
*/
|
||||
public int getType() {
|
||||
return IBinaryFile.OBJECT;
|
||||
}
|
||||
|
||||
protected XCoff32 getXCoff32() throws IOException {
|
||||
return new XCoff32(getPath().toOSString());
|
||||
}
|
||||
|
||||
protected void loadAll() throws IOException {
|
||||
XCoff32 xcoff = null;
|
||||
try {
|
||||
xcoff = getXCoff32();
|
||||
loadInfo(xcoff);
|
||||
loadSymbols(xcoff);
|
||||
} finally {
|
||||
if (xcoff != null) {
|
||||
xcoff.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadInfo() throws IOException {
|
||||
XCoff32 xcoff = null;
|
||||
try {
|
||||
xcoff = getXCoff32();
|
||||
loadInfo(xcoff);
|
||||
} finally {
|
||||
if (xcoff != null) {
|
||||
xcoff.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadInfo(XCoff32 xcoff) throws IOException {
|
||||
info = new BinaryObjectInfo();
|
||||
XCoff32.Attribute attribute = xcoff.getAttributes();
|
||||
info.isLittleEndian = attribute.isLittleEndian();
|
||||
info.hasDebug = attribute.hasDebug();
|
||||
info.cpu = attribute.getCPU();
|
||||
}
|
||||
|
||||
protected void loadSymbols(XCoff32 xcoff) throws IOException {
|
||||
ArrayList list = new ArrayList();
|
||||
Addr2line addr2line = getAddr2line();
|
||||
CPPFilt cppfilt = getCPPFilt();
|
||||
CygPath cygpath = getCygPath();
|
||||
|
||||
XCoff32.Symbol[] peSyms = xcoff.getSymbols();
|
||||
byte[] table = xcoff.getStringTable();
|
||||
addSymbols(peSyms, table, addr2line, cppfilt, cygpath, list);
|
||||
|
||||
if (addr2line != null) {
|
||||
addr2line.dispose();
|
||||
}
|
||||
if (cppfilt != null) {
|
||||
cppfilt.dispose();
|
||||
}
|
||||
if (cygpath != null) {
|
||||
cygpath.dispose();
|
||||
}
|
||||
|
||||
symbols = (ISymbol[])list.toArray(NO_SYMBOLS);
|
||||
Arrays.sort(symbols);
|
||||
list.clear();
|
||||
}
|
||||
|
||||
protected void addSymbols(XCoff32.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath, List list) {
|
||||
for (int i = 0; i < peSyms.length; i++) {
|
||||
if (peSyms[i].isFunction() || peSyms[i].isVariable()) {
|
||||
String name = peSyms[i].getName(table);
|
||||
if (name == null || name.trim().length() == 0 /*||
|
||||
!Character.isJavaIdentifierStart(name.charAt(0))*/) {
|
||||
continue;
|
||||
}
|
||||
Symbol sym = new Symbol(this);
|
||||
sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
|
||||
sym.addr = peSyms[i].n_value;
|
||||
|
||||
sym.name = name;
|
||||
if (cppfilt != null) {
|
||||
try {
|
||||
sym.name = cppfilt.getFunction(sym.name);
|
||||
} catch (IOException e1) {
|
||||
cppfilt = null;
|
||||
}
|
||||
}
|
||||
|
||||
sym.filename = null;
|
||||
sym.startLine = 0;
|
||||
sym.endLine = 0;
|
||||
if (addr2line != null) {
|
||||
try {
|
||||
String filename = addr2line.getFileName(sym.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) {
|
||||
if (cygpath != null) {
|
||||
sym.filename = new Path(cygpath.getFileName(filename));
|
||||
} else {
|
||||
sym.filename = new Path(filename);
|
||||
}
|
||||
}
|
||||
sym.startLine = addr2line.getLineNumber(sym.addr);
|
||||
} catch (IOException e) {
|
||||
addr2line = null;
|
||||
}
|
||||
}
|
||||
list.add(sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.BinaryObjectAdapter#getAddr2line()
|
||||
*/
|
||||
public Addr2line getAddr2line() {
|
||||
XCOFF32Parser parser = (XCOFF32Parser)getBinaryParser();
|
||||
return parser.getAddr2line(getPath());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.BinaryObjectAdapter#getCPPFilt()
|
||||
*/
|
||||
public CPPFilt getCPPFilt() {
|
||||
XCOFF32Parser parser = (XCOFF32Parser)getBinaryParser();
|
||||
return parser.getCPPFilt();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.utils.BinaryObjectAdapter#getObjdump()
|
||||
*/
|
||||
public Objdump getObjdump() {
|
||||
XCOFF32Parser parser = (XCOFF32Parser)getBinaryParser();
|
||||
return parser.getObjdump(getPath());
|
||||
}
|
||||
|
||||
private CygPath getCygPath() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
2004-06-21 Alain Magloire
|
||||
|
||||
Big Patch from Vladimir Hirsl
|
||||
This patch contains a binary parser core and UI elements to 'support' AIX
|
||||
XCOFF32 binaries.
|
||||
|
||||
2004-06-21 Hoda Amer
|
||||
Fix for PR 63439 : [Content Assist] When prefix is a C/C++ keyword, Content Assist does not complete templates
|
||||
|
||||
|
|
|
@ -698,6 +698,11 @@
|
|||
parserID="org.eclipse.cdt.core.Cygwin_PE"
|
||||
id="PEBinaryParserPage">
|
||||
</parserPage>
|
||||
<parserPage
|
||||
class="org.eclipse.cdt.ui.dialogs.GNUXCoffBinaryParserPage"
|
||||
parserID="org.eclipse.cdt.core.XCOFF32"
|
||||
id="XcoffBinaryParserPage">
|
||||
</parserPage>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.workingSets">
|
||||
|
|
|
@ -75,7 +75,7 @@ public class GNUElfBinaryParserPage extends AbstractCOptionPage {
|
|||
for (int i = 0; i < infos.length; i++) {
|
||||
String id = infos[i].getAttribute("parserID"); //$NON-NLS-1$
|
||||
String clazz = infos[i].getAttribute("class"); //$NON-NLS-1$
|
||||
String ego = getClass().getName();
|
||||
String ego = getRealBinaryParserPage().getClass().getName();
|
||||
if (clazz != null && clazz.equals(ego)) {
|
||||
parserID = id;
|
||||
break;
|
||||
|
@ -104,6 +104,14 @@ public class GNUElfBinaryParserPage extends AbstractCOptionPage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this class is inherited from then this method MUST be implemented
|
||||
* in the derived class.
|
||||
*/
|
||||
protected Object getRealBinaryParserPage() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.ui.dialogs;
|
||||
|
||||
/**
|
||||
* Reusing GNUElfBinaryParserPage.
|
||||
* New class is required for the algorithm in method performApply.
|
||||
* Must implement getRealBinaryParserPage method.
|
||||
*
|
||||
* @author vhirsl
|
||||
*/
|
||||
public class GNUXCoffBinaryParserPage extends GNUElfBinaryParserPage {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.ui.dialogs.GNUElfBinaryParserPage#getRealBinaryParserPage()
|
||||
*/
|
||||
protected Object getRealBinaryParserPage() {
|
||||
return this;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue