
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/SYMUTIL.CPP   1.8   20 Jun 1996 09:29:08   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/SYMUTIL.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:29:08   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:23:46   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.4   29 May 1996 09:35:14   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:08:16   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:08:48   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:24:44   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 13:00:26   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:37:28   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:57:28   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:10:24   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:27:18   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:42:56   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:15:48   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:12:40   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:13:20   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:40:16   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:22:18   Shirley
** No change.
** 
**    Rev 1.19   18 Jan 1996 10:13:12   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:14:38   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:13:28   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:11:22   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:32:00   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:18:52   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:27:38   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:31:10   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:27:44   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:40:48   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:04:26   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:46:26   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:48:46   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:28:24   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:52:36   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:22:08   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:51:10   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:53:52   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:45:20   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:55:32   Shirley
** Initial revision.
**
****************************************************************************/

/*----------------------------------------------------------------------------
** Name: symutil.cpp
**
** Title: symbol utilities
**
** Purpose:
**  Utility code for symbol table; any routines that are used by a number of
**     symbol functions that warrant being placed in one central module.
**
** Status: PRELIMINARY
**
** $Log$
** 
** $Header:   D:/EPSLDV1/SRC/LOG/SYMUTIL.CPP   1.8   20 Jun 1996 09:29:08   ZJRD  $
**
** Copyright (C) 1995 Microtek International.  All rights reserved.
**
**--------------------------------------------------------------------------*/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdafx.h"                      
#include "basetbl.h"
#include "byadrtbl.h"
#include "hashtbl.h"
#include "indextbl.h"
#include "linenum.h"
#include "mempool.h"
#include "ordtbl.h"
#include "symadd.h"
#include "symblsvr.h"
#include "symget.h"
#include "symmgr.h"
#include "symutil.h"
#include "typetbl.h"

                       /****************************
                        *                          *
                        *        DEFINITIONS       *
                        *                          *
                        ****************************/

extern BaseIndexTable bit;
extern HashTable ht;
extern LinenumTable lt;
extern OrdinalTable ot;
extern MemPool st;
extern TypeTable tt;
extern IndexTable typit; 
// holds filename containing symbols to load
extern U8 loadFilename[MAX_SYMNAME_LENGTH];

RETCODE EXPORT LdrLoadModuleByDesc(SYM_DESCRIPTOR);

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

//------------------------------------------------------------------------
//                  SYMBOL UTILITIES
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// SymRemoveSymbols
//
// Purpose:
//    Removes all symbols from the symbol table.
//
// Input parameters:
//
// Output parameters:
//
//------------------------------------------------------------------------
RETCODE EXPORT SymRemoveSymbols(VOID) {

   RETCODE err;

   // remove all dynamically allocated memory ;
   if ((err = UtilDeleteTables()) != GOOD) return(err);
   
   // re-initialize all the tables ;
   if((err = InitSymTable()) != GOOD) return(err);
   if((err = tt.InitBasicTypes()) != GOOD) return(err);

   return(GOOD);
}  // end of SymRemoveSymbols

//------------------------------------------------------------------------
// UtilCmpTimestamp
//------------------------------------------------------------------------
S16 UtilCmpTimestamp(TIMESTAMP_TYPE *time1, TIMESTAMP_TYPE *time2) {

   S16 diff;

   if ((diff = time1->year - time2->year) != 0) return (diff);
   if ((diff = (S16)(time1->month - time2->month)) != 0) return (diff);
   if ((diff = (S16)(time1->day - time2->day)) != 0) return (diff);
   if ((diff = (S16)(time1->hour - time2->hour)) != 0) return (diff);
   if ((diff = (S16)(time1->minute - time2->minute)) != 0) return (diff);
   if ((diff = (S16)(time1->second - time2->second)) != 0) return (diff);

   return (0);
}

//------------------------------------------------------------------------
// UtilDeleteTables
//------------------------------------------------------------------------
RETCODE UtilDeleteTables(VOID) {

   // remove the base index table and all the by-address tables associated
   // with bit.  This call does both
   bit.ObliterateTable();
   
   // remove the storage for global name hash table;
   ht.ObliterateTable();
   
   // remove all line number info. ;
   lt.ObliterateTable();
   
   // remove info on what order symbols were loaded. ;
   ot.ObliterateTable();
   
   // remove all the memory for all type info. ;
   tt.ObliterateTable();
   
   // remove the index table for all the types just removed. ;
   typit.ObliterateTable();
   
   // remove all the memory for all symbols.  this is done last since it ;
   // holds information potentially stored in all the other tables. ;
   st.ObliterateTable();

   return(GOOD);
}

//--------------------------------------------------------------------------
//  UtilGetAddrFromSymDesc
//
//  Description:
//    Returns the base address of <symDesc>
//     
//  Parameters:
//    input:
//       symDesc: offset to a symbol
//    output:
//       baseAddr: the base address being returned
//--------------------------------------------------------------------------
RETCODE
UtilGetAddrFromSymDesc(SYM_DESCRIPTOR symDesc,
                       BASE_ADDRESS *baseAddr) {
   
   RETCODE    err;
   COMMON_SYMBOL_HEADER *symPtr;

   symPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(symDesc);
   err = SymGetBaseAddress(symPtr -> typeIndex.baseIndex,
                               baseAddr);
   return err;
}  // end of UtilGetAddrFromSymDesc

//------------------------------------------------------------------------
// UtilIsValidSymDescriptor
//
// Purpose:
//    Checks for validity of the passed symbol descriptor; i.e. that the
//       symbol descriptor is not outside the bounds of st
//    Checks that symbolNameOffset, symParentOffset, and symSiblingOffset
//       are also within the st bounds
//
// Input parameters:
//    symDesc: st table offset to be tested against size of table
//
// Output parameters:  returns FALSE if not valid, TRUE if valid
//------------------------------------------------------------------------
BOOLEAN UtilIsValidSymDescriptor(SYM_DESCRIPTOR symDesc) {

   BOOLEAN bool;
   COMMON_SYMBOL_HEADER *symPtr;

   if (symDesc == NULL_SYMBOL)
      return FALSE;
   bool = st.IsValidTableOffset(symDesc);
   if (bool) {
      symPtr = (COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(symDesc);
      bool &= st.IsValidTableOffset(symPtr->symbolNameOffset);
      bool &= st.IsValidTableOffset(symPtr->symParentOffset);
      bool &= st.IsValidTableOffset(symPtr->symSiblingOffset);
   }
   return bool;
} // end of UtilIsValidSymDescriptor

//------------------------------------------------------------------------
// UtilOnDemandLoad
//------------------------------------------------------------------------
RETCODE UtilOnDemandLoad(SYM_DESCRIPTOR inputSymbol) {

   RETCODE         err;
   COMMON_SYMBOL_HEADER *headPtr;
   SYM_TYPE_MODULE *modPtr;
   SYM_DESCRIPTOR  currentOffset, tmpOffset;
   SYM_TYPE_TYPE   symType;
   U8              modName[MAX_SYMNAME_LENGTH];
   U8              tmpSymType;
   
   headPtr = (COMMON_SYMBOL_HEADER *) st.GetHugeDataPtr(inputSymbol);
   tmpSymType = (U8)((headPtr->typeIndex.symType) & 0xF);
   if (!((tmpSymType == SYM_MODULE)  ||
         (tmpSymType == SYM_FUNCTION)||
         (tmpSymType == SYM_BLOCK))) {
      return(ER_SYMBOL_NOT_A_FUNCTION);
   }

   // find the module descriptor from the inputSymbol descriptor. ;
   // the input symbol is a func/block/module descriptor. ;
   currentOffset = inputSymbol;
   while (((headPtr->typeIndex.symType) & 0xF) != SYM_MODULE) {
      // search the symbols parent list until the module descriptor ;
      // is found.  Then check to see if the module symbols have been ;
      // loaded. ;
      if ((err = SymGetSymbolParent(currentOffset, &symType, 
         &tmpOffset)) != GOOD) return(err);
      headPtr = (COMMON_SYMBOL_HEADER *) st.GetHugeDataPtr(tmpOffset);
      currentOffset = tmpOffset;
   }
   modPtr = (SYM_TYPE_MODULE *) headPtr;
   if (modPtr->fileOffset != SYMBOLS_LOADED) {
      // Get the module name to do loading - currentOffset == symDesc
      if (GOOD != (err = SymAddGetModuleName(currentOffset,
                                                (LPSTR)modName)))
         return err;
      // Call loader to load symbols and set flag when done
      if ((err = LdrLoadModuleByDesc(currentOffset)) != GOOD) {
         // NOTES: 09/22/93 - Nghia
         // Filter out err if module does not contain line number information
         if ((err == ER_NO_LINENUMS_ADDED) ||
             (err == ER_NO_LINEBLK_IN_MODULE)) {
            // Notes: 01/18/94 - Nghia
            // Retrieve the headPtr again, in cases the table is expanded
            // which trashed the headPtr.  STRANGE PROBLEM with
            // Windows ReAlloc() function.
            headPtr = (COMMON_SYMBOL_HEADER *)
                      st.GetHugeDataPtr(currentOffset);
            if (((headPtr->typeIndex.symType) & 0xF) == SYM_MODULE) {
               modPtr = (SYM_TYPE_MODULE *) headPtr;            
               // indicate that the module does not have line information
               // so set flag to indicate that it's loaded
               modPtr->fileOffset = SYMBOLS_LOADED;
            }
         }
         // return err to avoid unwanted processing 
         // Caller need not report the filter errors  
         return err;
         
      } else {
         // Notes: 01/18/94 - Nghia
         // Retrieve the headPtr again, in cases the table is expanded
         // which trashed the headPtr.  STRANGE PROBLEM with
         // Windows ReAlloc() function.
         headPtr = (COMMON_SYMBOL_HEADER *)
                   st.GetHugeDataPtr(currentOffset);
         modPtr = (SYM_TYPE_MODULE *) headPtr;
         // Make sure that it is a module
         if (((headPtr->typeIndex.symType) & 0xF) != SYM_MODULE)
            return ER_SYMBOL_NOT_A_MODULE;
         // indicate that the rest of module symbols have been loaded
         modPtr->fileOffset = SYMBOLS_LOADED;
      }
   }
   return(GOOD);
}  // end of UtilOnDemandLoad

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