/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.utils.coff;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.eclipse.cdt.core.CCorePlugin;
public class Exe {
public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
protected RandomAccessFile rfile;
ExeHeader ehdr;
static public class ExeHeader {
public final static int EXEHDRSZ = 28;
public byte[] e_signature = new byte[2]; // 00-01 "MZ" - Link file .EXE signature
public short e_lastsize; // 02-03 Length of EXE file modulo 512
public short e_nblocks; // 04-05 Number of 512 pages (including the last page)
public short e_nreloc; // 06-07 Number of relocation entries
public short e_hdrsize; // 08-09 Size of header in 16 byte paragraphs,
// occupied by "EXE" header and relo table.
public short e_minalloc; // 0A-0B Minimum paragraphs of memory allocated
public short e_maxalloc; // 0C-0D Maximum number of paragraphs allocated
// in addition to the code size
public short e_ss; // 0E-0F Initial SS relative to start of executable
public short e_sp; // 10-11 Initial SP
public short e_checksum; // 12-13 Checksum (or 0) of executable
public short e_ip; // 14-15 CS:IP relative to start of executable
public short e_cs; // 16-17 CS:IP relative to start of executable
public short e_relocoffs; // 18-19 Offset of relocation table;
// 40h for new-(NE,LE,LX,W3,PE etc.) executable
public short e_noverlay; // 1A-1B Overlay number (0h = main program)
protected ExeHeader(RandomAccessFile file) throws IOException {
this(file, file.getFilePointer());
}
protected ExeHeader(RandomAccessFile file, long offset) throws IOException {
file.seek(offset);
byte[] hdr = new byte[EXEHDRSZ];
file.readFully(hdr);
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
commonSetup(memory);
}
public ExeHeader(byte[] hdr, boolean little) throws IOException {
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
commonSetup(memory);
}
public ExeHeader(ReadMemoryAccess memory) throws IOException {
commonSetup(memory);
}
void commonSetup(ReadMemoryAccess memory) throws IOException {
if (memory.getSize() < EXEHDRSZ) {
throw new IOException("Not DOS EXE format"); //$NON-NLS-1$
}
memory.getBytes(e_signature);
if (e_signature[0] != 'M' || e_signature[1] != 'Z') {
throw new IOException(CCorePlugin.getResourceString("Util.exception.notDOSFormat")); //$NON-NLS-1$
}
e_lastsize = memory.getShort();
e_nblocks = memory.getShort();
e_nreloc = memory.getShort();
e_hdrsize = memory.getShort();
e_minalloc = memory.getShort();
e_maxalloc = memory.getShort();
e_ss = memory.getShort();
e_sp = memory.getShort();
e_checksum = memory.getShort();
e_ip = memory.getShort();
e_cs = memory.getShort();
e_relocoffs = memory.getShort();
e_noverlay = memory.getShort();
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("EXE HEADER VALUES").append(NL); //$NON-NLS-1$
buffer.append("signature "); //$NON-NLS-1$
buffer.append((char)e_signature[0] + " " + (char)e_signature[1]); //$NON-NLS-1$
buffer.append(NL);
buffer.append("lastsize: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_lastsize).longValue()));
buffer.append(NL);
buffer.append("nblocks: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_nblocks).longValue()));
buffer.append(NL);
buffer.append("nreloc: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_nreloc).longValue()));
buffer.append(NL);
buffer.append("hdrsize: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_hdrsize).longValue()));
buffer.append(NL);
buffer.append("minalloc: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_minalloc).longValue()));
buffer.append(NL);
buffer.append("maxalloc: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_maxalloc).longValue()));
buffer.append(NL);
buffer.append("ss: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_ss).longValue()));
buffer.append(NL);
buffer.append("sp: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_sp).longValue()));
buffer.append(NL);
buffer.append("checksum: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_checksum).longValue()));
buffer.append(NL);
buffer.append("ip: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_ip).longValue()));
buffer.append(NL);
buffer.append("cs: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_cs).longValue()));
buffer.append(NL);
buffer.append("relocoffs: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_relocoffs).longValue()));
buffer.append(NL);
buffer.append("overlay: 0x"); //$NON-NLS-1$
buffer.append(Long.toHexString(new Short(e_noverlay).longValue()));
buffer.append(NL);
return buffer.toString();
}
}
public ExeHeader getExeHeader() throws IOException {
return ehdr;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(rfile).append(NL);
buffer.append(ehdr);
return buffer.toString();
}
public Exe(String file) throws IOException {
rfile = new RandomAccessFile(file, "r"); //$NON-NLS-1$
try {
ehdr = new ExeHeader(rfile);
} finally {
if (ehdr == null) {
rfile.close();
}
}
}
public static void main(String[] args) {
try {
Exe exe = new Exe(args[0]);
System.out.println(exe);
} catch (IOException e) {
e.printStackTrace();
}
}
}