/****************************************************************************
**
**  Name:  LSYM.C
**
**  Description:
**      Routines in support of Symbol Table access.
**
**  Status:  CODED
**
**  $Log:   S:/tbird/mt2_68k/l695/lsym.c_v  $
** 
**    Rev 1.0   13 Feb 1997 08:51:02   gene
** Initial revision.
** 
**    Rev 1.1   19 Jan 1996 09:09:08   kevin
** added GetBaseType()
** 
**    Rev 1.0   07 Sep 1995 10:32:26   gene
** Initial revision.
** 
**    Rev 1.10   03 Aug 1993 17:48:50   nghia
** Removed LERR_xxxx to use standard error codes.
** 
**    Rev 1.9   16 Apr 1993 13:52:54   nghia
** Added check for MergeSections flag to return error.
** This will force all section to the default ones - call FindBaseCode/DataIndex
** 
**    Rev 1.8   12 Apr 1993 18:12:24   nghia
** Revised FindBaseCodeIndex and FindDataIndex to search for section name only
** once, save the index for any request later.
** Cleanup for coding standard.
** 
**    Rev 1.7   23 Mar 1993 17:17:08   nghia
** Updated and minor cleanup.
** 
**    Rev 1.6   18 Mar 1993 17:24:04   nghia
** Revised all non-standard return code to RETCODE.
** Added comment block and removed junks.
** 
**    Rev 1.5   08 Mar 1993 11:02:52   nghia
** Revised to used sectionsName to support different toolchains.
** Major cleanup and revised.
** 
**    Rev 1.4   07 Oct 1992 18:50:48   courtney
** Restore DiffTimestamp (needed by loader callback).
** 
**    Rev 1.3   25 Sep 1992 20:56:04   courtney
** Minor revisions.
** 
**    Rev 1.2   09 Jan 1992 17:02:56   courtney
** Timestamp for loadfile now obtained via getftime() - since Borland
** fstat() doesn't work.
** 
**    Rev 1.1   31 Dec 1991 10:57:26   courtney
** Timestamp support routines added.
** 
**    Rev 1.0   12 Dec 1991 13:45:36   courtney
** Initial revision.
**
**  $Header:   S:/tbird/mt2_68k/l695/lsym.c_v   1.0   13 Feb 1997 08:51:02   gene  $
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include <io.h>
#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif

#ifndef __LDR__
#include "ldr.h"
#endif

#ifndef __LDEBUG__
#include "ldebug.h"
#endif

#ifndef __LSYM__
#include "lsym.h"
#endif

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

#ifndef __LPROFILE_
#include "lprofile.h"
#endif


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

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

extern SEC_INFO *section_info[MAX_SECTIONS];
extern U16 nSections, codeSecIndex, dataSecIndex, rtaSecIndex;
extern BOOLEAN findCode, findData, findRTA;
extern BOOLEAN mergeSections;
extern CHAR sectionNames[MAX_NUM_SECTION_NAMES][SIZE_SECTION_NAME];

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

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
/******************************************************************************
**
**  FindBaseIndex
**
******************************************************************************/
RETCODE FindBaseIndex(U32 addr, U16 *psindex, BOOLEAN *pisConst) {
   /* addr - address of variable
      psindex - pointer to section index (returned)
      pisConst - is this section const?
   */
   LOOP_VAR i;
   *pisConst = FALSE;
   if (mergeSections) {
      /* When MergeSections, Caller must call to get the default section */
      return(ER_SECTION_NOT_FOUND);
   }
   for (i=0; i < nSections; i++) {
      if ((addr >= section_info[i]->offset) &&
         (addr <= section_info[i]->offset+section_info[i]->size)) {
         *psindex = i;
         /* since sections can be renamed by user, we check modifier */
         if (section_info[i]->sindex == SECID_ROM)
            *pisConst = TRUE;
         return(GOOD);
      }
   }
   return(ER_SECTION_NOT_FOUND);
}  /* FindBaseIndex */

/* Before any functions within a module are symbol-loaded, we need to obtain
   the 'base' index for the module symbol to be loaded.  We look at the names
   of the sections added, since we don't get the start address till we look
   at the first function within it (we may want to defer loading the module
   till then, but then we'd have to seek back to capture all the globals
   that precede the function).
*/
/******************************************************************************
**
**  FindBaseCodeIndex
**
******************************************************************************/
RETCODE FindBaseCodeIndex(U16 *pcindex) {
   LOOP_VAR i;
   /*
   ** Locate CodeBaseIndex:
   ** 1. Search for section defined in PWRVIEWS.INI
   ** 2. if 1 failed - map to the default code section
   */
   if (!findCode) {
      for (i=0; i < nSections; i++) {
         if (stricmp(section_info[i]->name,
            (CHAR *)&sectionNames[CODE_SECT][0]) == 0) {
            *pcindex = codeSecIndex = i;
            /* Save the index found to use later */
            findCode = TRUE;
            return(GOOD);
         }
      }
      /* Used the default code section */
      if (stricmp(section_info[codeSecIndex]->name, (CHAR *)SBASE_CODE) != 0)
         return(ER_SECTION_NOT_FOUND);
      findCode = TRUE;
   }
   *pcindex = codeSecIndex;
   return(GOOD);
}  /* FindBaseCodeIndex */

/* default section base for data symbols */
/* Used when creating Symbol Table entries for ATN5 items, which haven't
   had their address or section index information given yet (may appear
   in Public Part of file.  Though there may be several sections for data
   in an IEEE 695 file, we choose the simple one specified in PWRVIEWS.INI.
   If not found, then use the default one.
*/
/******************************************************************************
**
**  FindBaseDataIndex
**
******************************************************************************/
RETCODE FindBaseDataIndex(U16 *pdindex) {
   LOOP_VAR i;

   /* pdindex - pointer to data index */
   if (!findData) {
      for (i=0; i < nSections; i++) {
         if (stricmp(section_info[i]->name,
               (CHAR *)&sectionNames[DATA_SECT][0]) == 0) {
            *pdindex = dataSecIndex = i;
            findData = TRUE;
            return(GOOD);
         }
      }
      /* Used the default data section */
      if (stricmp(section_info[dataSecIndex]->name, (CHAR *)SBASE_DATA) != 0)
         return(ER_SECTION_NOT_FOUND);
      findData = TRUE;
   }
   *pdindex = dataSecIndex;
   return(GOOD);
}  /* FindBaseDataIndex */

/******************************************************************************
**
**  FindBaseRTAIndex - Find run-time activated base for stack/reg variables
**
******************************************************************************/
RETCODE FindBaseRTAIndex(U16 *psindex) {

   /* It's the last section in list - Only need to chek for the first time */
   if (!findRTA) {
      if (stricmp(section_info[rtaSecIndex]->name, SBASE_RTA) != 0)
         return(ER_SECTION_NOT_FOUND);
      findRTA = TRUE;
   }
   *psindex = rtaSecIndex;  /* It's the last one in the list */
   return(GOOD);
}  /* FindBaseRTAIndex */

/******************************************************************************
**
**  FindSecModifier
**
******************************************************************************/
U16 FindSecModifier(U16 stype) {
   /* Returns the 'base type' needed for the symbol table, based on modifier
   ** kept in section info.  Note that not all sections have base type
   ** (such as these weird sections the compiler creates for heap base,
   ** and things like this).
   */
   switch (stype) {
      case SECID_CODE:
          return(BASE_CODE);
      case SECID_ROM:
          return(BASE_CODE_DATA);
      case SECID_DATA:
          return(BASE_DATA);
   }
   return(BASE_UNKNOWN);
}  /* FindSecModifier */

/******************************************************************************
**
**  Get695Time
**
******************************************************************************/
RETCODE Get695Time(HANDLE hfile, TIMESTAMP_TYPE *pts) {

   Get695Number(hfile, (U16 *) &(pts->year));
   Get695Number(hfile, (U16 *) &(pts->month));
   Get695Number(hfile, (U16 *) &(pts->day));
   Get695Number(hfile, (U16 *) &(pts->hour));
   Get695Number(hfile, (U16 *) &(pts->minute));
   Get695Number(hfile, (U16 *) &(pts->second));
   return(GOOD);
}  /* Get695Time */

/******************************************************************************
**
**  GetTimesstamp
**
******************************************************************************/
RETCODE GetTimestamp(HANDLE hfile, TIMESTAMP_TYPE *pts) {
   struct ftime ft;

   /* Get time info from disk file specified by handle */
   /* Munge info to timestamp type for use by symbol table */
    /* DOS-specific */
    getftime(hfile, &ft);
    pts->year = ft.ft_year+1980;
    pts->month = ft.ft_month;
    pts->day = ft.ft_day;
    pts->hour = ft.ft_hour;
    pts->minute = ft.ft_min;
    pts->second = ft.ft_tsec*2;

    return(GOOD);
}  /* GetTimestamp */

/******************************************************************************
**
**  DiffTimestamp
**
******************************************************************************/
S16 DiffTimestamp(TIMESTAMP_TYPE *pt1, TIMESTAMP_TYPE *pt2) {
   S16 diff;

   /* Return the difference between two 695-style timestamps;
   ** Returns 0 if they are identical in all fields,
   **        <0 if t1 < t2,
   **        >0 if t1 > t2
   ** where the value returned is the amount of difference, in
   ** the first field where they differ.
   */
   if ((diff = pt1->year - pt2->year) != 0)
       return(diff);
   if ((diff = pt1->month - pt2->month) != 0)
       return(diff);
   if ((diff = pt1->day - pt2->day) != 0)
       return(diff);
   if ((diff = pt1->hour - pt2->hour) != 0)
       return(diff);
   if ((diff = pt1->minute - pt2->minute) != 0)
       return(diff);
   if ((diff = pt1->second - pt2->second) != 0)
       return(diff);

   return(0);  /* pt1 == pt2 */
}  /* DiffTimestamp */

/******************************************************************************
**
**  GetBaseType
**
******************************************************************************/
RETCODE GetBaseType(BASE_INDEX baseIndex, BASE_TYPE *baseType) {
LOOP_VAR i;

   if (mergeSections) {
      /* When MergeSections, Caller must call to get the default section */
      return(ER_SECTION_NOT_FOUND);
   }
   for (i=0; i < nSections; i++) {
      if (section_info[i]->sindex == baseIndex) {
         if ((*baseType = FindSecModifier(section_info[i]->modifier))
                        != BASE_CODE)
            *baseType = BASE_DATA; // default is data
         return GOOD;
      }
   }
   return(ER_SECTION_NOT_FOUND);
}  /* GetBaseType */

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