coff.c 4.32 KB
/*
 * coff.c:	routines to read contents of a coff file into a buffer for 
 * 		subsequent download to the ultra64 development system.
 *
 *		Cloned from an OS conversion utility suite
 *
 * Copyright 1995, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
 * the contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to restrictions
 * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
 * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
 * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
 * rights reserved under the Copyright Laws of the United States.
 *
 * $Revision: 1.1.1.1 $
 */

#include <stdio.h>
#include "sex.h"
#include "sym.h"
#include "cmplrs/stsupport.h"
#include "filehdr.h"
#include "ldfcn.h"
#include "scnhdr.h"

// Function prototypes for internal functions
//
static int Extract(unsigned int *buf);

// Global variables
//
unsigned int Address;                   /* Address being Dumped.    */
unsigned int Data0;                     /* Data being Dumped.       */
unsigned int Data1;                     /* Data being Dumped.       */
int      Swap   = 0;                    /* Swap Text Words.         */
char    *OFileName;                     /* Object File To Dump.     */
char    *AFileName;                     /* ASCII File To Dump into. */
char    *SName;                         /* Section to Dump.         */
LDFILE  *LDPtr;                         /* File's ld Pointer.       */
SCNHDR   SHeader;                       /* Section Header.          */
FILE    *AFile;                         /* ASCII File.              */


////////////////////////////////////////////////////////////////////////////////
// readCoff()
//
// Read a COFF file into a buffer.  Return number of bytes read,
// -1 if error.
//
int readCoff(char *fname, unsigned int *buf) {
  int textSize, dataSize, bssSize;
  
  OFileName = fname;
  SName     = ".text";	/* set section name = .text */
  textSize = Extract(buf);
  
  if (textSize < 0)
    return(-1);
  
  /*
   * Ignore .data & .bss; we would have to decide where to put them if we
   * needed to use them, but these short-lived bootstrap modules won't need
   * data or bss, so punt.
   */
#ifdef NOTDEF
  OFileName = fname;
  SName     = ".data";	/* set section name = .data */
  dataSize = Extract( ((unsigned int *)((int)buf + textSize)) );
  
  if (dataSize != 0)
    return(-1);
  
  OFileName = fname;
  SName     = ".bss";	/* set section name = .text */
  bssSize = Extract( ((unsigned int *)((int)buf + (textSize + dataSize))) );
  
  if (bssSize < 0)
    return(-1);
  return( (textSize + dataSize + bssSize) );
#endif
  return( textSize );
}


////////////////////////////////////////////////////////////////////////////////
// Extract()
//
//
//
static int Extract(unsigned int *buf) {
  int bytesRead;
  
  if ((LDPtr = (LDFILE *) ldopen (OFileName, NULL)) == NULL)
    {                                   /* Open File.               */
      fprintf (stderr, "Extract(): Cannot open %s.\n", OFileName);
      return (-1);
    }
  
  switch (HEADER (LDPtr).f_magic) 
    {
    case MIPSEBMAGIC:
    case MIPSEBMAGIC_2:
    case MIPSEBMAGIC_3:
      Swap = (gethostsex () == LITTLEENDIAN);
      break;
      
    case MIPSELMAGIC:
    case MIPSELMAGIC_2:
    case MIPSELMAGIC_3:
      Swap = (gethostsex () == BIGENDIAN);
      break;
    }
  if (ldnshread (LDPtr, SName, &SHeader) == FAILURE)
    {
#ifdef NO_HUSH
      fprintf (stderr, "Warning:  %s has no %s section.\n", OFileName, SName);
#endif
    } else {
      
      FSEEK (LDPtr, SHeader.s_scnptr, BEGINNING);
      
      for (Address = SHeader.s_paddr; 
	   (Address - SHeader.s_paddr) < SHeader.s_size; Address += 8) {
	FREAD ((char *)&Data0, 1, 4, LDPtr);
	if (Swap) Data0 = swap_word (Data0);
	FREAD ((char *)&Data1, 1, 4, LDPtr);
	if (Swap) Data1 = swap_word (Data1);
	if (Swap) {
	  *buf = Data1;
	  *(buf+1) = Data0;
	} else {
	  *buf = Data0;
	  *(buf+1) = Data1;
	}
	buf += 2;
      }
    }
  ldclose (LDPtr);                    /* Close File.              */
  return(SHeader.s_size);		/* # of bytes read */
}