
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/SYMUTIL.CPP   1.2.1.4   17 Apr 1997 16:05:16   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/SYMUTIL.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 16:05:16   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:39:18   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:46:38   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:25:48   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:29:02   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:38:34   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:52:10   ZJRD
** 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:/ECB2S/SRC/LOG/SYMUTIL.CPP   1.2.1.4   17 Apr 1997 16:05:16   ZJRD  $
**
** Copyright (C) 1995 Microtek International.  All rights reserved.
**
**--------------------------------------------------------------------------*/

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

#include "stdafx.h"                      
#include "symbase.h"
#include "symbyadr.h"
#include "symhash.h"
#include "symindex.h"
#include "symline.h"
#include "sympool.h"
#include "symord.h"
#include "symadd.h"
#include "symblsvr.h"
#include "symget.h"
#include "symmgr.h"
#include "symutil.h"
#include "symtype.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];

#ifdef _LINK_WITH_LOADER_
RETCODE EXPORT LdrLoadModuleByDesc(SYM_DESCRIPTOR);
#endif

                       /****************************
                        *                          *
                        *     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
#ifdef _LINK_WITH_LOADER_      
      if ((err = LdrLoadModuleByDesc(currentOffset)) != GOOD) {
//	  if ( FALSE ) {
#else
	  if ( FALSE ) {
#endif	        
         // 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 *************************************/
