_Object File Formats_
by Rand Gray and Deepak Mulchandani


Listing One
struct filehdr {
unsigned short f_magic; /* the magic number of the object file */
unsigned short f_nscns; /* number of sections contained in this object file */
long f_timdat; /* information regarding when this object file was created */
long f_symptr; /* pointer to the symbol table */
long f_nsyms; /* number of symbol table entries */
unsigned short f_opthdr; /* size of the optional header */
unsigned short f_flags; /* flags used for compilation */
};

Listing Two
struct opthdr
{ 
short magic; /* Magic number */
short vstamp; /* Version stamp */
long tsize; /* Size of text in bytes */
long dsize; /* Size of data in bytes */
long bsize; /* Size of .bss in bytes */
unsigned long entry; /* Entry point */
long text_start; /* Base address of text */
long data_start; /* Base address of data */
} ;

Listing Three
struct scnhdr 
{
char s_name[8]; /* name of the section */
long s_paddr; /* physical address where this section' data is located */
long s_vaddr; /* virtual address where this section' data is located */
long s_size; /* size of this section' data (in bytes) */
long s_scnptr; /* pointer to this sections data */
long s_relptr; /* pointer to this sections relocation data */
long s_lnnoptr; /* pointer to the line number information for this section */
unsigned short s_nreloc; /* number of relocation entries */
unsigned short s_nlnno; /* number of line number entries */
long s_flags; /* flags indicating status of information written */
};

Listing Four
;; Example program used to generate example COFF object file using
;; the Motorola MCUasm Assembly Language Toolset.
;; The example program defines 1 variable
;;
org     $50
var1            rmb     1         ; define dummy variable #1 (size 1 byte)
                org     $6e00
start:          lda     #$ff    ; load hex value 0xff into accumulator
                clr     var1    ; clear the loop variable 
loop:           cmpa    var1    ; compare if the two values are equal 
                beq     equal   ; the two values are equal - exit loop
                deca            ; not equal - decrement accumulator
                bra     loop    ; not equal - continue looping
equal:          bra     start   ; start all over again

Listing Five
/************************************************************************/
/* Program Module : COFF.C                                              */
/*   This program contains the "simple dump" utility for COFF object    */
/*   files. It was compiled using GCC on UNIX (SunOS 4.1.3)             */
/*  Written By : Rand Gray and Deepak Mulchandani                       */
/************************************************************************/

#include        <stdio.h>
#include        <string.h>
#include        <stdlib.h>
#include        <malloc.h>

#include        "linenum.h" 
#include        "syms.h"
#include        "coffio.h"
#include        "coff.h"
                       
/*-------------------------------------------------------------------------*/
/* Global Variable declarations                                            */
/*-------------------------------------------------------------------------*/
FILHDR          coffHdr;       /* structure for the COFF file header */
SCNHDR          sctHdr;        /* structure to contain a section header */
FILE            *coffFilePtr;  /* file pointer to the COFF object file */
                      
/*-------------------------------------------------------------------------*/
/* Function : main                                                         */
/*-------------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
    if ( argc == 2 )
    {
        coffLineToAddr ( argv[1] );
        exit ( 0 );
    }
    else
    {
        /* if they didn't enter the object file name, then print */
        /* the usage and exit.                                   */
        fprintf ( stderr, "\nError : Object File Not Entered\n" );
        fprintf ( stderr, "Usage : ddjcoff object-file-name\n" );
        exit ( 1 );
    }
}                                          
/*----------------------------------------------------------------------*/
/* Function Name : coffcmd                                              */
/*              This function reads in a COFF format object file        */
/*              It reads it all into a structure called "mapTrans"      */
/*              which is shared by the MAP object file reader           */
/*----------------------------------------------------------------------*/
short coffLineToAddr(char *fileName)
{
    coffFilePtr = coffOpenFile(fileName);
    if (coffFilePtr != NULL)
    {                                 

        printf ( "\n\nExample Print Utility for COFF Object Files\n" );
        printf ( "-------------------------------------------\n\n" );
        printf ( "Contents of File Header\n\n" ); 
        
        readCoffHdr(coffFilePtr);   
        coffReadSymbols();

        fclose ( coffFilePtr );

        printf ( "\n\n" );
        printf ( "-------------------------------------------\n\n" );

        return ( 0 );
    }
    return ( -1 );
}
/*-----------------------------------------------------------------------*/ 
/*   Open the COFF file to be read and return a pointer to it.           */
/*-----------------------------------------------------------------------*/
FILE *coffOpenFile(char *coffFileName)
{
    FILE *tempPtr;
    /* As mentioned, COFF files are in binary format. Therefore we need */
    /* to open the file as a binary stream.                             */
                                                                      
    tempPtr = fopen(coffFileName, "rb");
    return (tempPtr);
}
/* Read in the COFF file header. Tells us: 
 *        - The Size (in bytes) of the Optional Header
 *        - The Number of Sections in the Object File
 */
void readCoffHdr(FILE *coffFilePtr)
{
  extern char   *ctime();   
  AOUTHDR   coffAoutHdr; /* structure for the auxiliary file header */
  fread( &coffHdr, sizeof(FILHDR), 1, coffFilePtr );
  /* Show a little test of how to determine if the object file is of    */
  /* the correct architecture. Just compare the magic number received   */
  /* against the correct magic number. The Motorola MCUasm toolset uses */
  /* the magic number (decimal) 808 when generating object files for    */
  /* the Motorola 68HC08 microcontroller.                               */

  if ( coffHdr.f_magic == 808 )
  {
   printf ( "\tMagic Number             : %d\n", coffHdr.f_magic );
   printf ( "\tNumber of Sections       : %d\n", coffHdr.f_nscns );
   printf ( "\tTime of File Creation    : %s\n", ctime ( &coffHdr.f_timdat ) );
   printf ( "\tNumber of Symbol Table Entries : %d\n", coffHdr.f_nsyms );
   printf ( "\n" );

    /* read in the auxiliary file header. For our example program */
    /* we really don't need this information. However, if needed  */
    /* you can easily print it using the scheme for the header above */

    fread ( &coffAoutHdr, sizeof(AOUTHDR), 1, coffFilePtr );
  } 
  else
  {
    fprintf ( stderr, "\nError : Invalid Magic Number\n" );
    exit ( 1 );
  }
}
/*-FH----------------------------------------------------------------------*/
/*  Function : coffReadSymbols                                             */
/*-EH----------------------------------------------------------------------*/
void coffReadSymbols()
{   
   SYMENT       se;
   int          index;
   fseek(coffFilePtr, coffHdr.f_symptr, 0);

   index = 0;
   while ( index != coffHdr.f_nsyms )
   {
     fread ( &se, sizeof(SYMENT), 1, coffFilePtr );
     if ( se._n._n_name )
       printf ( "\tSymbol Table Entry #%d = %s\n", index+1, se._n._n_name );
     index++;
   }
 }

Figure 2:

(a)                         (b)
1                                                                         
2                           
3   #include <stdio.h>      Function Name: main(), Arguments: None        
4                           Function Begin                                
5   main()                                                                
6   {                       Define Local Variable: "x"; Type "integer"    
7                                                                         
8      int x;               Assign the variable "x" the value 5           
9                                                                         
10     x=5;                 Function End                                  
11                          
12  }                       
13                          
    


Figure 4: Example print utility for COFF object files
 
Contents of File Header

        Magic Number                   : 808
        Number of Sections             : 2
        Time of File Creation          : Mon Jul 24 14:24:37 1995

        Number of Symbol Table Entries : 9


        Symbol Table Entry #1 = t.asm
        Symbol Table Entry #2 = .bss
        Symbol Table Entry #3 = 
        Symbol Table Entry #4 = .text
        Symbol Table Entry #5 = 
        Symbol Table Entry #6 = var1
        Symbol Table Entry #7 = start
        Symbol Table Entry #8 = loop
        Symbol Table Entry #9 = equal



9



