content: /*******************************************************************************
   * Copyright (c) 2011, J.W. Janssen
   * 
   * Copyright (c) 2000, 2010 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
   *     J.W. Janssen - Cleanup and make API more OO-oriented.
   *******************************************************************************/
  package org.flashtool.binutils.coff;
  
  
  import java.io.*;
  import java.text.*;
  import java.util.*;
  
  import org.flashtool.binutils.elf.ERandomAccessFile;
  
  import org.flashtool.binutils.elf.*;
  
  
  /**
   * 
   */
  public class FileHeader
  {
    // CONSTANTS
  
    public final static int FILHSZ = 20;
  
    // relocation info stripped from file
    public final static int F_RELFLG = 0x0001;
    // file is executable (no unresolved external references)
    public final static int F_EXEC = 0x0002;
    // line numbers stripped from file
    public final static int F_LNNO = 0x0004;
    // local symbols stripped from file
    public final static int F_LSYMS = 0x0008;
    // file is 16-bit little-endian
    public final static int F_AR16WR = 0x0080;
    // file is 32-bit little-endian
    public final static int F_AR32WR = 0x0100;
    // file is 32-bit big-endian
    public final static int F_AR32W = 0x0200;
    // rs/6000 aix: dynamically loadable w/imports & exports
    public final static int F_DYNLOAD = 0x1000;
    // rs/6000 aix: file is a shared object
    public final static int F_SHROBJ = 0x2000;
    // PE format DLL.
    public final static int F_DLL = 0x2000;
  
    // VARIABLES
  
    private final int magic; /* 00-01 2 bytes: magic number */
    private final int nscns; /* 02-03 2 bytes: number of sections: 2 bytes */
    private final int timdat; /* 04-07 4 bytes: time & date stamp */
    private final int symptr; /* 08-11 4 bytes: file pointer to symtab */
    private final int nsyms; /* 12-15 4 bytes: number of symtab entries */
    private final int opthdr; /* 16-17 2 bytes: sizeof(optional hdr) */
    private final int flags; /* 18-19 2 bytes: flags */
  
    // CONSTRUCTORS
  
    /**
     * Creates a new FileHeader instance.
     * 
     * @param aFile
     * @throws IOException
     */
    FileHeader(ERandomAccessFile aFile) throws IOException
    {
      this.magic = aFile.readShortE();
      this.nscns = aFile.readShortE();
      this.timdat = aFile.readIntE();
      this.symptr = aFile.readIntE();
      this.nsyms = aFile.readIntE();
      this.opthdr = aFile.readShortE();
      this.flags = aFile.readShortE();
    }
  
    // METHODS
  
    /**
     * Returns the time & date stamp.
     * 
     * @return a time & date stamp.
     */
    public int getDateTime()
    {
      return this.timdat;
    }
  
    /**
     * Returns the current value of flags.
     * 
     * @return the flags
     */
    public int getFlags()
    {
      return this.flags;
    }
  
    /**
     * Returns the current value of magic.
     * 
     * @return the magic
     */
    public int getMagic()
    {
      return this.magic;
    }
  
    /**
     * @return
     */
    public int getOptionalHeaderSize()
    {
      return this.opthdr;
    }
  
    /**
     * Returns the number of sections.
     * 
     * @return a section count, >= 0.
     */
    public int getSectionCount()
    {
      return this.nscns;
    }
  
    /**
     * @return the file pointer to symbol table.
     */
    public int getSymbolTableEntryCount()
    {
      return this.nsyms;
    }
  
    /**
     * @return the file pointer to symbol table.
     */
    public int getSymbolTableOffset()
    {
      return this.symptr;
    }
  
    /**
     * @return
     */
    public boolean hasOptionalHeader()
    {
      return this.opthdr > 0;
    }
  
    /**
     * @return
     */
    public boolean isDebug()
    {
      return !((this.flags & F_LNNO) == F_LNNO);
    }
  
    /**
     * @return
     */
    public boolean isExec()
    {
      return (this.flags & F_EXEC) == F_EXEC;
    }
  
    /**
     * @return
     */
    public boolean isStrip()
    {
      return (this.flags & F_RELFLG) == F_RELFLG;
    }
  
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
      StringBuilder buffer = new StringBuilder();
      buffer.append("FILE HEADER VALUES").append('\n');
  
      buffer.append("f_magic = ").append(this.magic).append('\n');
      buffer.append("f_nscns = ").append(this.nscns).append('\n');
  
      buffer.append("f_timdat = ");
      buffer.append(DateFormat.getDateInstance().format(new Date(this.timdat)));
      buffer.append('\n');
  
      buffer.append("f_symptr = ").append(this.symptr).append('\n');
      buffer.append("f_nsyms = ").append(this.nsyms).append('\n');
      buffer.append("f_opthdr = ").append(this.opthdr).append('\n');
      buffer.append("f_flags = ").append(this.flags).append('\n');
      return buffer.toString();
    }
  }
  