/****************************************************************************
**
**  Name:  SSECTION.C
**
**  Description:
**      Set up section bases for Srecord loading.
**
**  Status:  CODED
**
**  $Log:   S:/tbird/arcppc/loader/srec/ssection.c_v  $
** 
**    Rev 1.0   13 Jan 1998 14:00:36   hera
** Initial revision.
** 
**    Rev 1.0   13 Jan 1998 13:30:56   hera
** Initial revision.
** 
**    Rev 1.0   30 Sep 1997 16:03:30   gene
** Initial revision.
** 
**    Rev 1.7   04 Jun 1993 10:34:26   nghia
** Revised to meet coding standard.
** Report error using only the Warning() and WarningEx() routines.
** PIP for Source.
** 
**    Rev 1.6   12 Feb 1993 18:10:16   nghia
** Updated for release.
** 
**    Rev 1.5   06 Nov 1992 17:35:00   courtney
** Update local nSections after freeing.
** 
**    Rev 1.4   22 Oct 1992 16:15:56   courtney
** Cleanup error reporting to use generic loader's string resource messages.
** 
**    Rev 1.3   25 Sep 1992 21:07:26   courtney
** Added symbol support.
** 
**    Rev 1.2   25 Sep 1992 05:44:56   courtney
** Sections allocated only if symbol loading requested; use
** TMalloc/TFree.
** 
**    Rev 1.1   21 Aug 1992 10:28:02   courtney
** Add include wrappers.
** 
**    Rev 1.0   31 Dec 1991 09:38:14   courtney
** Initial revision.
**
**  $Header:   S:/tbird/arcppc/loader/srec/ssection.c_v   1.0   13 Jan 1998 14:00:36   hera  $
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
*****************************************************************************/
                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include <io.h>

#ifndef _HEAP_
#include "heap.h"
#endif

#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif

#ifndef _SLDR_
#include "sldr.h"
#endif
#ifndef __ERR__
#include "err.h"
#endif

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern char errbuf[];

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

int LRUbuf[4];  /* maintain an LRU stack of the last 4 unique code buffers
	(by index) written to. */
SEC_INFO *section_info[MAX_SECTIONS];
U16 nSections;

/* Various sections appear in an IEEE 695 binary file.  Thus far, this
	code has *only* been tested with output generated by the MRI C compiler.

	In particular, the various sections are allocated against one of the
	possible 4 open buffers maintained by the Shared Data Server, for
	downloading code and data.  That is, only 4 sections can be open at
	any one time.  If new incoming data requires that a new buffer be opened,
	a LRU strategy is followed to flush the least-recently-used.

	note: If the SDS services are not used, then perhaps the individual
	code sections will need to be GlobalAlloced/ReAlloced in aggregate,
	then written to their starting address (one at a time, or only after
	parsing the entire file?).

	Note: this is MRI-specific!!  Since the MRI .ABS format gives absolute
	addresses for variable values, we set the base address for all sections
	to be 0L (this may not be the case with other compilers/linkers).

	Note that the routines in lsym.c make certain assumptions about the
	section names that are created here.  If a user overrides the names
	with a command-line switch, we are in trouble (only when we need to
	find the default base for symbols).
*/

/*****************************************************************************
**
**  ProcessSecPart
**
*****************************************************************************/
S16 ProcessSecPart(U16 symflag) {
/* symflag - indicates whether to load section bases in symbol table */
   SEC_INFO *psection;
   RETCODE err;
   U16 index;  /* number of sections processed */

   /* Construct array of structs for section info: SEC_INFO
      For Srecord, we set up 2 fake sections, for loading code and symbols,
      respectively.
   */
   index = nSections = 0;

   /* fake section for code */
   if ((psection = (SEC_INFO *)TMalloc(sizeof(SEC_INFO))) == NULL) {
      err = LERR_NO_MEMORY;
      return(err);
   }
   memset(psection, 0, sizeof(SEC_INFO));
   strcpy(psection->name, SBASE_CODE);
   psection->sindex = SCODE_INDEX;
   section_info[index++] = psection;
   /* should this be created even if no symbols? */
   if (symflag) {
      if (SymAddBaseCreate((LPSTR)SBASE_CODE,
           SCODE_INDEX,
           0L,
           BASE_CODE) != GOOD) {
         err = LERR_SYMBASE;
         Warning(err);
      }
   }
   /* Fake section for symbols */
   if ((psection = (SEC_INFO *)TMalloc(sizeof(SEC_INFO))) == NULL) {
      err = LERR_NO_MEMORY;
      return(err);
   }
   memset(psection, 0, sizeof(SEC_INFO));
   strcpy(psection->name, SBASE_SYMBOL);
   psection->sindex = SSYM_INDEX;
   section_info[index++] = psection;
   if (symflag) {
      if (SymAddBaseCreate((LPSTR)SBASE_SYMBOL,
            SSYM_INDEX,
           	0L,
            BASE_DATA) != GOOD) {
         err = LERR_SYMBASE;
         Warning(err);
      }
   }
   /* Controls alloc/deallocation */
   nSections = index;

   /* thru processing section type records */
   return(GOOD);
}  /* Process_SecPart */

/*****************************************************************************
**
**  FreeSections
**
*****************************************************************************/
RETCODE FreeSections(U16 *pn) {
   LOOP_VAR i;
   RETCODE  err = GOOD;
   U16 n;

   /* free memory associated with section info struct */
   n = *pn;
   for (i=0; i < n; i++) {
      if (TFree((LPSTR)section_info[i]) != GOOD) {
         err = LERR_BAD_FREE;
         Warning(err);
      }
   }
   /* reset */
   *pn = 0;
   return(err);
}  /* FreeSections */

/********************************** E O F ***********************************/
