/****************************************************************************
**
**  Name:  LDEBUG.C
**
**  Description:
**      Process debug records in ELF binary file.  Load them into the
**      Symbol Table via the Symbol Server.
**
**  $Log:   S:/tbird/arcppc/lelf/ldebug.c_v  $
** 
**    Rev 1.17   03 Apr 1998 14:59:28   Winky
** 
**    Rev 1.16   02 Apr 1998 16:27:30   hera
** 
**    Rev 1.12   13 Jan 1998 09:20:58   kevin
** For Motorola test file, currect linenum part
** 
**    Rev 1.11   25 Sep 1997 17:25:40   kevin
** winky's modification
** 
**    Rev 1.9   28 Aug 1997 10:22:20   cjchen
** 
**    Rev 1.8   30 Jun 1997 14:39:18   hera
** 
**    Rev 1.7   31 Mar 1997 08:45:54   hera
** 
**    Rev 1.6   24 Mar 1997 13:57:44   hera
** Process Tag_subroutine_type in ProcessDbgType().
**
**  Status:  CODED
**
**  $Header:   S:/tbird/arcppc/lelf/ldebug.c_v   1.17   03 Apr 1998 14:59:28   Winky  $
**
**  Copyright (C) 1991-1993 Microtek International.  All rights reserved.
**
*****************************************************************************/
                                          
                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include <limits.h>
#include <io.h>

#ifndef _PROC_
#include "proc.h"
#endif

#ifndef _PVTASK_
#include "pvtask.h"
#endif

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

#ifndef _SYMERROR_
#include "symerror.h"
#endif

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

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

#ifndef __LFLAGS__
#include "lflags.h"
#endif
#ifndef __ERR__
#include "err.h"
#endif
#ifndef __LDEBUG__
#include "ldebug.h"
#endif
#ifndef __LOPT__
#include "lopt.h"
#endif
#ifndef __LPROFILE__
#include "lprofile.h"
#endif
#ifndef __LMANGLE__
#include "lmangle.h"
#endif
#ifndef __LDMANGLE__
#include "ldmangle.h"
#endif
#ifndef _CLIULIB_
#include "cliulib.h"
#endif
                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
			****************************/
/* Number of modules loaded */
U32 numberOfModulesLoaded;
long Tag_Size;
int ProducerChecked;
BOOLEAN toflag;
U16 tlflags;
//Hera 2/2/98
BOOLEAN FuncEnd;
typedef struct{
   U16 offset;
   U8  sfname[ELF_IDNLEN];
   U32 startaddr;
   SYM_DESCRIPTOR mDesc;
   BOOLEAN pass;
}SRCINFO;
SRCINFO SrcInfo[100];
//Hera
                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
			****************************/
extern Lowpc2MDesc LowPC2MDesc[MAX_MODULE];
//extern long LineSize, DebugSize;
extern U32 LineSize, DebugSize;//Hera
extern U32 DebugOffset,LineOffset;
extern Elf32_Shdr *section_info[MAX_SECTIONS];
extern U16 nSections;
extern U16 ldrDemangle;
extern LDRSTATBLOCK FAR *lstb; /* progress reporting status block */
extern U32 startRangeNotSet, endRangeNotSet;
extern CHAR toolUseName[];
extern U16 toolSelect;
extern U16 reportWarning;   /* Defined in LDR.C */
extern TIMESTAMP_TYPE tsLoadfile; /*Defined in LDR.C*/
//extern Offset2Index *pOffset2IndexHead, *pOffset2IndexTail, *pOffset2IndexTemp;
//Hera 2/2/98
extern U32 sfname_offset, sfname_size;
extern U32 srcinfo_offset, srcinfo_size;
//Hera
extern ClassLink *CLbegin;

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
			****************************/
RETCODE PRIVATE ProcessSourceInfo(HANDLE hfile);//Hera 2/2/98
RETCODE PRIVATE ProcessDwarf1(HANDLE hfile, BOOLEAN oflag, U16 lflags,
			      U32* ptrNumModules);
//RETCODE PRIVATE ProcessDwarf2(HANDLE hfile, BOOLEAN oflag, U16 lflags,
//			      U32* ptrNumModules);
RETCODE PRIVATE ProcessDbgVariable(HANDLE hfile, U32* tindex, BOOLEAN* isConst,
	      BYTE* Location, VAR_LOCKED_REG* address, LPSTR VName, U16 isType);
RETCODE ProcessDbgLinesCPlus(HANDLE hfile, BOOLEAN ondemand, BOOLEAN oflag);
RETCODE PRIVATE ProcessUndefinedType(U32 tmin);

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
/******************************************************************************
**
** ProcessDebugPart
**
** oflag - MCREATE or MOPEN
**   MCREATE is passed when this is the main loader invocation.  This will
**   create initial symbol table entries for modules and functions.
**   MOPEN is passed when we are loading strictly locals
**
** lflags - tells what to load (e.g., globals, locals - defined in lflags.h)
**
** version, debug_offset - the version and the file offset of debug infomation
**
** ptrNumModules - Number of processed modules.
**
******************************************************************************/
RETCODE ProcessDebugPart(HANDLE hfile, BOOLEAN oflag, U16 lflags,
                         U16 version, U32 *ptrNumModules)
{
   RETCODE err;
   ClassLink *cltmp;
   U32 tmin;

   if ((err = ProcessSourceInfo(hfile)) != GOOD) return err; //Hera 2/2/98
   if(DebugOffset == 0) return GOOD;
   toflag = oflag; tlflags = lflags;
   if (SeekELFFile(hfile, DebugOffset, SEEK_SET) == -1L)
      return (ER_BAD_SEEK);

   //Initialization
   ProducerChecked = 0;
   if ((err = SymGetTypeIndexMax(&tmin)) != GOOD)
      return(err);
   //if(version == 1)
   err = ProcessDwarf1(hfile, oflag, lflags, ptrNumModules);
   ProcessUndefinedType(tmin+1); //Hera 3/11/98
   //Hera 2/26/98
   cltmp = CLbegin;
   while(cltmp != NULL){
      CLbegin = cltmp->next;
      TFree(cltmp);
      cltmp = CLbegin;
   }//Hera
   return err;
   //else /*version 2*/
   //   return(ProcessDwarf2(hfile, oflag, lflags, ptrNumModules));   
}
//Hera 2/2/98
RETCODE PRIVATE ProcessSourceInfo(HANDLE hfile) {
   U8 *sfname, *sfntmp;
   U32 size,startaddr,endaddr;
   U16 index;
   if(sfname_offset == 0 || srcinfo_offset == 0) return GOOD;
   memset(SrcInfo,0,sizeof(SrcInfo));
   SeekELFFile(hfile, sfname_offset, SEEK_SET);
   sfntmp = (U8 *)TMalloc(sfname_size);
   GetELFBytes(hfile, sfntmp, sfname_size);
   SeekELFFile(hfile, srcinfo_offset, SEEK_SET);
   size = srcinfo_size;
   index = 0;
   while(size > 0){
      U32 tmp;
      U32 lbase,sfnbase;

      lbase = GetELFU32(hfile);
      sfnbase = GetELFU32(hfile);
      startaddr = GetELFU32(hfile);
      endaddr = GetELFU32(hfile);
      SeekELFFile(hfile,4,SEEK_CUR);
      size -= 20;
      sfname = (U8*)(sfntmp + sfnbase);
      while((tmp = GetELFU32(hfile)) != 0xFFFFFFFFL){
	 //char *stmp;
         SrcInfo[index].startaddr = startaddr;
	 SrcInfo[index].offset = tmp+lbase;
	 lstrcpy(SrcInfo[index].sfname,(U8 *)(sfname+GetELFU32(hfile)));
	 //if ((stmp = strstr(SrcInfo[index].sfname,".h")) != NULL)
	 //   *stmp = 'H';
	 //StripPathString(SrcInfo[index].sfname, &str);
	 //lstrcpy(SrcInfo[index].sfname,str);
	 size -= 8;
         if(startaddr < endaddr)
         index++;
      }
      size -= 4;//size of 0xFFFFFFFF
   }
   TFree(sfntmp);
   return (GOOD);
}
RETCODE PRIVATE ProcessDwarf1(HANDLE hfile, BOOLEAN oflag, U16 lflags,
			      U32* ptrNumModules)
{
   BOOLEAN abortFromEsc;
   BOOLEAN updateModuleRange;
   RETCODE err = GOOD;
   SYM_DESCRIPTOR moduleDesc = 0L;
   U32 typeOffset = 0L;
   U32 ModuleOffset,NextModuleOffset;
   U16 Tag;
   int quit;

   numberOfModulesLoaded = 0L; 

   /* Main block-processing loop for loading symbols */
   quit = 0;
   while (!quit) {
	ModuleOffset = SeekELFFile(hfile,0L,SEEK_CUR);
	Tag_Size = GetELFU32(hfile);
	if(Tag_Size == 4)
        {
	  Tag = TAG_padding;
	  Tag_Size = 0;
	}
	else
        {
          Tag = GetELFU16(hfile);
	  Tag_Size -= 6;
        }
	switch (Tag)
	{
	 case TAG_padding:
	      quit = 1;
	      break;

	 case TAG_compile_unit:
	      moduleDesc = NULL_SYMBOL;
	      updateModuleRange = FALSE;
	      if((err = ProcessDbgModule(hfile, oflag, lflags,ModuleOffset, &NextModuleOffset, &moduleDesc)) != GOOD)
		return err;
	      numberOfModulesLoaded++;
	      /* Check for user abort */
              if (((err = TskCheckAbort(&abortFromEsc)) != GOOD) || abortFromEsc)
              {
                  LdrProgressDone(err != GOOD ? err : ER_LDR_ABORT);
                  return (err != GOOD ? err : ER_LDR_ABORT);
               }
              if (lstb != NULL)
                  lstb->curLocation = tell(hfile);
              if ((err = LdrProgressInc()) != GOOD)
              {
                  LdrProgressDone(err);
                  return (err);
	      }
	      if(NextModuleOffset != DebugSize)
		 SeekELFFile(hfile,(DebugOffset+NextModuleOffset),SEEK_SET);
	      else
                 quit = 1; // reach the end of .debug
	      break;      		      
        }    
   } /* end of while */

endloop:
   *ptrNumModules = numberOfModulesLoaded;
   return(err);   
}  /* ProcessDwarf1 */

/*RETCODE PRIVATE ProcessDwarf2(HANDLE hfile, BOOLEAN oflag, U16 lflags,
			      U32* ptrNumModules)
{
  return GOOD;
}*/

/*****************************************************************************
**
**  ProcessDbgModule - TAG_compile_unit
**
*****************************************************************************/
RETCODE ProcessDbgModule(HANDLE hfile,BOOLEAN oflag,U16 lflags,
	    U32 ModuleOffset,U32 *NextModuleOffset, SYM_DESCRIPTOR *moduleDesc)
{
   BASE_INDEX baseIndex;
   BOOLEAN ondemand, localflag;
   OFFSET_ADDR_RANGE_TYPE modRange;
   QUAL_ADDR_RANGE_TYPE modAddr;
   RETCODE symerr, err;
   U16 Attribution, Tag;

   CHAR ModuleName[ELF_IDNLEN] = "\0",byte;
   int index = 0,quit;
   CHAR Producer[ELF_IDNLEN];
   CHAR Dir[ELF_IDNLEN];
   LPSTR TempPtr;
   U32  tempOffset,language;
   U16  funcClass, numParam;
   U32  NextSubroutine, typeParam[ELF_IDNLEN];

   /* Range will get set with successive functions */
   modRange.offsetStartAddr = startRangeNotSet;
   modRange.offsetEndAddr = endRangeNotSet;

   /* Get the default code index from section_info table */
   if ((err = FindBaseCodeIndex(&baseIndex)) != GOOD)
      Warning(err);

   /* If we want to create module, and load locals, then ondemand false */
   ondemand = LOAD_LOCALS(lflags) ? FALSE : TRUE;
   quit = 0;
   while(!quit && Tag_Size > 0)
   {
     Attribution = GetELFU16(hfile);
     Tag_Size -= 2;
     switch(Attribution)
     {
      case AT_sibling:
	  *NextModuleOffset = GetELFU32(hfile);
          Tag_Size -= 4;
	  break;

      case AT_name:
          index = 0;
	  while((byte=GetELFByte(hfile)) != 0)
	    ModuleName[index++] = byte;
	  ModuleName[index] = '\0';/*have extended name*/
	  LowPC2MDesc[(U16)numberOfModulesLoaded].srcname = (char *)TMalloc(index+1);
	  strcpy(LowPC2MDesc[(U16)numberOfModulesLoaded].srcname, ModuleName);
	  StripPathString(ModuleName,&TempPtr);/*no have extended name and path*/
	  lstrcpy(ModuleName,TempPtr);
          Tag_Size -= (index+1);
	  break;

      case AT_low_pc:
	  modRange.offsetStartAddr = GetELFU32(hfile);
          LowPC2MDesc[(U16)numberOfModulesLoaded].lowpc = modRange.offsetStartAddr;
          Tag_Size -= 4;
	  break;

      case AT_high_pc:
	  modRange.offsetEndAddr = GetELFU32(hfile);
          modRange.offsetEndAddr--; // <Judy 8/25/97>
          //Hera 1/12/98
          LowPC2MDesc[(U16)numberOfModulesLoaded].hipc = modRange.offsetEndAddr;
          Tag_Size -= 4;
	  break;

      case AT_producer:
	  index = 0;
	  while((byte=GetELFByte(hfile)) != 0)
	  {
	    Producer[index] = byte;
	    index++;
	  }
	  Producer[index] = '\0';
	  Tag_Size -= (index+1);
	  if(!ProducerChecked)
	  {
            ProducerChecked = 1;
	    if(!strncmpi(Producer, "GHS C", 5)) {
	       strcpy(Producer, "Green Hills");
	       toolSelect = GREEN_HILLS_TOOLCHAIN;//Hera 2/12/98
            }
	    else if(!strncmpi(Producer, "Diab Data", 9)){
	       strcpy(Producer, "Diab Data");
	       toolSelect = DIAB_DATA_TOOLCHAIN;//Hera 2/12/98
            }
            //Hera 2/12/98
            //if(stricmp(Producer, toolUseName))
	    //{
	       //S16 continueLoading;
	       /* Only report warning when flag is TRUE */
	       //if (reportWarning)
	       //{
		 //err = ER_LOADFILE_HAD_INCOMPATIBLE_TOOLCHAIN;
		 /* Report Error */
                 //ErrDisplayFormattedError(err, CHECK_MODE,
		 //   		          (LPSTR) Producer,
                 //                         (LPSTR) toolUseName,
                 //                         (LPSTR) NULL,
		 //			  MB_OKCANCEL,
		 //			  MB_OK,
                 //                         (S16 FAR *) &continueLoading);
                 /* If user cancel then stop loading */
		 //if (continueLoading == IDCANCEL)
		 //return(err);
	        //}
	      //}
	      //Hera
	    }//if(!ProducerChecked)
	  break;

      case AT_language:
	  language = GetELFU32(hfile);
          Tag_Size -= 4;
	  break;

      case AT_comp_dir:
	  index = 0;
	  while((byte=GetELFByte(hfile)) != 0)
	    Dir[index++] = byte;
	  Dir[index] = '\0';
          Tag_Size -= (index+1);
	  break;
      case AT_stmt_list:
      default:
	  if(Tag_Size > 0)
             SeekELFFile(hfile,Tag_Size,SEEK_CUR);
	  Tag_Size = 0;
          quit = 1;
	  break;

     }
   }
   if (modRange.offsetStartAddr == modRange.offsetEndAddr)
       return GOOD;

   if ((symerr = SymAddModuleCreate(ModuleName, baseIndex,&modRange,ModuleOffset,
				    ondemand,moduleDesc, &tsLoadfile)) != GOOD)
   {
	 WarningEx(ER_CANNOT_ADD_MOD, ModuleName);
         return(ER_CANNOT_ADD_MOD);
   }
   LowPC2MDesc[(U16)numberOfModulesLoaded].mDesc = (SYM_DESCRIPTOR)*moduleDesc;

   /* Clear function list before loading (for C++ duplicate detection) */
   CppClearFunctionTable();
   quit = 0;
   while (!quit) {
	Tag_Size = GetELFU32(hfile); /*Tag Size*/
	if(Tag_Size == 4)
	{
	  Tag = TAG_padding;
	  Tag_Size = 0;
	}
	else
        {
	  Tag = GetELFU16(hfile);
	  Tag_Size -= 6;
	}

	switch(Tag)
	{
	  case TAG_global_subroutine:
	       funcClass = FUNC_GLOBAL;
	       err = ProcessDbgFunctions(hfile,funcClass,oflag,lflags,&NextSubroutine);
               SeekELFFile(hfile,(DebugOffset+NextSubroutine),SEEK_SET);
	       break;

	  case TAG_subroutine:
	       funcClass = FUNC_LOCAL;
	       err = ProcessDbgFunctions(hfile,funcClass,oflag,lflags,&NextSubroutine);
               SeekELFFile(hfile,(DebugOffset+NextSubroutine),SEEK_SET);
	       break;

          case TAG_class_type: //Hera 2/2/98
	  case TAG_array_type:
	  case TAG_typedef:
	  case TAG_structure_type:
	  case TAG_union_type:
	  case TAG_enumeration_type:
          case TAG_subroutine_type:
 	       ProcessDbgTypes(hfile, ModuleName, Tag);
	       break;
 
	  case TAG_global_variable:
	       tempOffset = tell(hfile);
	       tempOffset -= 6;
               SeekELFFile(hfile,tempOffset,SEEK_SET);
	       if (LOAD_GLOBALS(lflags))
	           err = ProcessDbgGlobals(hfile, TRUE);
               else  /* module-only load, just process */
		   err = ProcessDbgGlobals(hfile, FALSE);
	       break;

          case TAG_local_variable:
	       tempOffset = tell(hfile);
	       tempOffset -= 6;
               SeekELFFile(hfile,tempOffset,SEEK_SET);
               numParam = 0;
               typeParam[0] = 0;
               ProcessDbgLocals(hfile, &numParam, typeParam);
	       break;

	  case TAG_padding:
	       quit = 1;
	       break;

	  default:
	       quit = 1;
	       tempOffset = tell(hfile);
	       tempOffset -= 6;
	       SeekELFFile(hfile,tempOffset,SEEK_SET);
	       break;
        }
  }
  /* set state to boolean result, will be passed to ModuleClose */
  localflag = (LOAD_LOCALS(lflags) ? TRUE : FALSE);
  if ((symerr = SymAddModuleClose(localflag)) != GOOD) 
      Warning(symerr);
  modAddr.startAddr  = modRange.offsetStartAddr;
  modAddr.endAddr    = modRange.offsetEndAddr;
  modAddr.startValid = modAddr.endValid = TRUE;
  if ((symerr = SymAddSymbolSetAddr(&modAddr)) != GOOD)
         Warning(ER_SYM_NOT_UPDATED);
  return(symerr);
}  /* ProcessDbgModule */

/*****************************************************************************
**
**  ProcessDbgTypes - TAG_structure_type
**
******************************************************************************/
RETCODE ProcessDbgTypes(HANDLE hfile, LPSTR blockName, U16 Tag) {
   TYPE_HEADER_TYPE typeHdrInfo;
   U16 typeErr = 0;
   char byte;
   RETCODE err;
   U32 NextTag;
   U16 Attribution;
   int index,q;
   U32 tempOffset,Offset;

   /* get max type registered thus far, and use this to compute offset */
   err = GOOD;
   blockName[0] = '\0';
       
   Offset = (U32)(tell(hfile)-DebugOffset-6);
   typeHdrInfo.typeChoice    =  COMPLEX_TYPE_CLASS;
   typeHdrInfo.sizeInMAUs    = 0L;  /* default MAU size for all type */
   typeHdrInfo.typeName = blockName;
   typeHdrInfo.dirty = 0;//Hera 3/11/98
   switch(Tag)
   {
     case TAG_subroutine_type:
	typeHdrInfo.t.complexType = Function;
	typeHdrInfo.sizeCalculated = TRUE;
	err = GetTypeProc(hfile,Offset,&typeHdrInfo);
        break;

     case TAG_array_type:
	typeHdrInfo.t.complexType = Array_Type;
	typeHdrInfo.sizeCalculated = FALSE;
        err = GetTypeArr(hfile, Offset, &typeHdrInfo);
	break;

     case TAG_typedef:
	typeHdrInfo.t.complexType = Typedef;
	typeHdrInfo.sizeCalculated = FALSE;
        err = GetTypeTypedef(hfile, Offset, &typeHdrInfo);
	break;

     case TAG_class_type: //Hera 2/2/98
     case TAG_union_type:
     case TAG_structure_type:
     case TAG_enumeration_type:
          //Hera 2/2/98
	  if(Tag == TAG_class_type)
	     typeHdrInfo.t.complexType = Class_Type;
          //Hera
	  if(Tag == TAG_union_type)
	    typeHdrInfo.t.complexType = Union_Type;
          else if(Tag == TAG_structure_type)
	    typeHdrInfo.t.complexType = Structure;
	  else if(Tag == TAG_enumeration_type)
	    typeHdrInfo.t.complexType = Enumeration;
	  typeHdrInfo.sizeCalculated = FALSE;
          q = 0;
	  while(!q && Tag_Size > 0)
          {
	      Attribution = GetELFU16(hfile);
	      Tag_Size -= 2;
	      switch(Attribution)
	      {
	        case AT_sibling:
	             NextTag = GetELFU32(hfile);
		     Tag_Size -= 4;
		     break;

                case AT_name:
		     index = 0;
	             while((byte=GetELFByte(hfile)) != 0)
	                blockName[index++] = byte;
		     blockName[index] = '\0';
		     typeHdrInfo.typeName = blockName;
		     //Hera 2/2/98
		     if (Tag == TAG_class_type)
			SetTypeClass(blockName);
                     //Hera
                     Tag_Size -= (index+1);
		     break;

	        case AT_byte_size:
		     typeHdrInfo.sizeInMAUs = GetELFU32(hfile);
		     typeHdrInfo.sizeCalculated = TRUE;
		     Tag_Size -= 4;
		     break;

		case AT_element_list:
                     q = 1;
		     break;

		case TAG_member:
		default:
		     tempOffset = tell(hfile);
		     tempOffset -= 2;
		     SeekELFFile(hfile,tempOffset,SEEK_SET);
		     Tag_Size = 0;
		     q = 1;
		     break;
                }
	    } //While(!q)

	   if(Tag == TAG_enumeration_type) //Enumeration
	      err = GetTypeEnum(hfile, Offset, &typeHdrInfo);
	   else if(Tag == TAG_class_type){
	      if (typeHdrInfo.sizeInMAUs != 0L)
		 err = GetTypeClass(hfile,Offset,&typeHdrInfo, toflag, tlflags);
           }
	   else{ //Structure and Union
	      if (typeHdrInfo.sizeInMAUs != 0L)
		 err = GetTypeSU(hfile, Offset, &typeHdrInfo);
              //Hera 2/6/98
	      if (err == TAG_global_subroutine){
	         typeHdrInfo.t.complexType = Class_Type;
		 err = GetTypeClass(hfile,Offset,&typeHdrInfo,toflag,tlflags);
	      }
	      //Hera
	   }
	   SeekELFFile(hfile,(DebugOffset+NextTag),SEEK_SET);
	   if(err != GOOD)
	     return ER_SYM_TYPE;	   
           break;
   }
   return(err);
}/* ProcessDbgTypes */

/*****************************************************************************
**
**  ProcessDbgModuleOnDemand - TAG_compile_unit
**
*****************************************************************************/
RETCODE ProcessDbgModuleOnDemand(HANDLE hfile, U16 lflags)
{
   CHAR ModuleName[ELF_IDNLEN];
   RETCODE symerr, err;
   BOOLEAN localflag;
   U16 Tag,funcClass;
   U32 tempOffset,NextSubroutine;
   int quit;

   /* set state to boolean result, will be passed to ModuleClose */
   localflag = (LOAD_LOCALS(lflags) ? TRUE : FALSE);
   /* Clear function list before loading (for C++ duplicate detection) */
   CppClearFunctionTable();
   quit = 0;
   while (!quit)
   {
	Tag_Size = GetELFU32(hfile); /*Tag Size*/
	if(Tag_Size == 4)
	{
	  Tag = TAG_padding;
	  Tag_Size = 0;
	}
	else
        {
	  Tag = GetELFU16(hfile);
	  Tag_Size -= 6;
	}

	switch(Tag)
	{
	  case TAG_global_subroutine:
	       funcClass = FUNC_GLOBAL;
	       err = ProcessDbgFunctions(hfile,funcClass,MOPEN,lflags,&NextSubroutine);
               SeekELFFile(hfile,(DebugOffset+NextSubroutine),SEEK_SET);
	       break;

	  case TAG_subroutine:
	       funcClass = FUNC_LOCAL;
	       err = ProcessDbgFunctions(hfile,funcClass,MOPEN,lflags,&NextSubroutine);
               SeekELFFile(hfile,(DebugOffset+NextSubroutine),SEEK_SET);
	       break;

          case TAG_class_type: //Hera 2/2/98
 	  case TAG_array_type:
	  case TAG_typedef:
	  case TAG_structure_type:
	  case TAG_union_type:
	  case TAG_enumeration_type:
          case TAG_subroutine_type:
 	       ProcessDbgTypes(hfile, ModuleName, Tag);
	       break;
 
	  case TAG_global_variable:
	       tempOffset = tell(hfile);
	       tempOffset -= 6;
               SeekELFFile(hfile,tempOffset,SEEK_SET);
	       if (LOAD_GLOBALS(lflags))
	           err = ProcessDbgGlobals(hfile, TRUE);
               else  /* module-only load, just process */
		   err = ProcessDbgGlobals(hfile, FALSE);
	       break;

	  case TAG_padding:
	       quit = 1;
	       break;

	  default:
	       quit = 1;
	       tempOffset = tell(hfile);
	       tempOffset -= 6;
	       SeekELFFile(hfile,tempOffset,SEEK_SET);
	       break;
        }
  }
  /* set state to boolean result, will be passed to ModuleClose */
  localflag = (LOAD_LOCALS(lflags) ? TRUE : FALSE);
  if ((symerr = SymAddModuleClose(localflag)) != GOOD) 
      Warning(symerr);

  return(symerr);
}  /* ProcessDbgModuleOnDemand */



/*****************************************************************************
**
**  ProcessDbgGlobals
**
*****************************************************************************/
RETCODE ProcessDbgGlobals(HANDLE hfile, BOOLEAN addsym) {
   BOOLEAN isConst;
   CHAR sname[ELF_IDNLEN];
   RETCODE symerr, err;
   SYM_DESCRIPTOR symP;
   U16 sindex, atnErr = 0;
   U32 tindex;
   int quit;
   U32 addr;
   U32 tempOffset;
   BYTE location;
   U16 Tag;
   VAR_LOCKED_REG address;

   quit = 0;
   while(!quit)
   {
     Tag_Size = GetELFU32(hfile);
     if(Tag_Size == 4)
     {
	Tag = TAG_padding;
	Tag_Size = 0;
     }
     else
     {
        Tag = GetELFU16(hfile);
        Tag_Size -= 6;
     }

     switch(Tag)
     {
       case TAG_global_variable:
            isConst = FALSE;
            ProcessDbgVariable(hfile, &tindex, &isConst, &location,
					   &address, sname, 0);
	    if(addsym)
            {
              if(location == OP_ADDR)
              {
	        if((err = FindBaseDataIndex(&sindex)) != GOOD)
	        {
                     Warning(err);
                     break;
		}
		addr = address.regIndex;
                if ((symerr = SymAddVar((LPSTR)sname,
                    sindex,
                    tindex,
                    GLOBAL_VAR_CLASS,
	            NOT_REG,
                    (ADD_VAR_ADDR_UNION *)&addr,
		    isConst,
                    TRUE,  /* valid address */
		    &symP)) != GOOD)		   
		       WarningEx(ER_CANNOT_ADD_SYM, (LPSTR)sname);
             } 
	
             else if(location == OP_REG)
	     {
	        if ((err = FindBaseDataIndex(&sindex)) != GOOD)
	        {
                    Warning(err);
                    break;
                 }
                if ((symerr = SymAddVar((LPSTR)sname,
                     sindex,
                     tindex,
                     GLOBAL_VAR_CLASS,
                     LIVING_REG,
	      	    (ADD_VAR_ADDR_UNION *)&(address.regIndex),
                     isConst, 
                     TRUE,  /* valid address */
	             &symP)) != GOOD)		   
	       	        WarningEx(ER_CANNOT_ADD_SYM, (LPSTR)sname);
	      }
            }
       break;
     
       case TAG_padding:
             quit = 1;
       break;

       default:
	  quit = 1;
	  tempOffset = tell(hfile);
	  tempOffset -= 6;
          SeekELFFile(hfile,tempOffset,SEEK_SET);
       break;
     }
   } //While(!quit)
   return (GOOD);
}  /* ProcessDbgGlobals */

/*****************************************************************************
**
** ProcessDbgFunctions
**
*****************************************************************************/
RETCODE ProcessDbgFunctions(HANDLE hfile, U16 funcClass, BOOLEAN oflag,
                            U16 lflags,U32 *NextSubroutine) {
   CHAR FuncName[ELF_IDNLEN];
   CHAR tmpName[ELF_IDNLEN];
   CHAR CPPName[ELF_IDNLEN];//Hera 2/26/98
   OFFSET_ADDR_RANGE_TYPE fnAddr;
   //QUAL_ADDR_TANGE_TYPE fnFinalAddr;
   RETCODE symerr, err;
   U16 sindex;
   U32 endBlockPos = 0L;
   U32 nstack,rtn_type,BackOffset;
   int index,i,num;
   U8 Byte;
   U32 tempOffset,tmax,tindex;
   U16 Attribution,Tag,numParam;
   int quit;
   TYPE_HEADER_TYPE typeHdrInfo;
   CHAR parentName[1] = "";  /* 'fathername' field is not used for C */
   CHAR TypeName[ELF_IDNLEN] = "\0";
   U32 typeParam[ELF_IDNLEN]; 
   int pointerTimes;
   U32 value, svalue;
   BOOLEAN find;

   quit=0;
   pointerTimes = 0;
   typeHdrInfo.dirty = 0;//Hera 3/11/98
   rtn_type = FT_void; //default to FT_void
   fnAddr.offsetEndAddr = fnAddr.offsetStartAddr = 0L;
   while(!quit && Tag_Size > 0){
     Attribution = GetELFU16(hfile);
     Tag_Size -= 2;
     switch(Attribution){
       case AT_high_pc:
	    fnAddr.offsetEndAddr = GetELFU32(hfile);
            fnAddr.offsetEndAddr--; //<Judy 8/25/97>
            Tag_Size -= 4;
            break;
//     case AT_inline:
//     case AT_location:
       case AT_low_pc:
	    fnAddr.offsetStartAddr = GetELFU32(hfile);
            Tag_Size -= 4;
	    break;

       case AT_member: //To record class type Hera 2/2/98
	    GetELFU32(hfile);
	    Tag_Size -= 4;
	    break;

       case AT_DIAB_mangled: /* <Judy 7/7/1997 */
            index=0;
            while((Byte = GetELFByte(hfile)) != 0)
               tmpName[index++] = Byte;
            tmpName[index]='\0';
            tempOffset = tell(hfile);
	    //LdmangleDiabDemangle(tmpName, &FuncName); // <Judy 8/5/97>
	    LdmangleDiabDemangle(tmpName, &CPPName);
            //Hera 2/26/98
	    if(strchr(CPPName,':') != NULL)
	       strcpy(FuncName, CPPName);
	    //Hera
            if(fnAddr.offsetStartAddr == 0 && fnAddr.offsetEndAddr == 0) {
               if(LdmangleDiabGetValue(hfile,tmpName,&value, &svalue)==TRUE) {
                  fnAddr.offsetStartAddr=value;
                  fnAddr.offsetEndAddr=value+svalue;
               }
            }
            SeekELFFile(hfile,tempOffset,SEEK_SET);
            Tag_Size -= (index+1);
	    break;
       case AT_name:
            index = 0;
	    while((Byte = GetELFByte(hfile)) != 0)
               FuncName[index++] = Byte;
	    FuncName[index] = '\0';
            Tag_Size -= (index+1);
	    break;
       case AT_DIAB_frame_size:
            nstack = GetELFU32(hfile);
            Tag_Size -= 4;
            break;
       case AT_DIAB_push_mask:
           {
            U32 tmp;
            tmp = GetELFU32(hfile);
            Tag_Size -= 4;
            break;
	   }
      /*case AT_private:
      case AT_program:
      case AT_protected:
      case AT_prototyped:
      case AT_public:
      case AT_pure_virtual:
      case AT_return_addr:*/
   
      case AT_sibling:
	   *NextSubroutine = GetELFU32(hfile);
           Tag_Size -= 4;
	   break;

      case AT_user_def_type:
           rtn_type = GetELFU32(hfile);
	   Tag_Size -= 4;
           /*pOffset2IndexTemp = pOffset2IndexHead;
	   while (pOffset2IndexTemp != NULL) {
	      if (rtn_type == pOffset2IndexTemp->offset){
		 rtn_type = pOffset2IndexTemp->tindex;
		 pOffset2IndexTemp = NULL;                 
	      }
              else
	         pOffset2IndexTemp = pOffset2IndexTemp->next;
	   }*/
	   SearchForType(rtn_type,&rtn_type,&find);
	   if (!find) typeHdrInfo.dirty = 1;
	   break;

      case AT_mod_u_d_type:
      {
	   int num, num_mod, modifier, MD;
	   U32 utype;

           num = GetELFU16(hfile); // number
           num_mod = num - 4; //modifiers + file offset(4 bytes)
           while(num_mod > 0){
             MD = GetELFByte(hfile); //modifier
	     if(MD == MOD_pointer_to){
		modifier = MD;
		pointerTimes++;
	     }
	     else if(MD == MOD_reference_to)
                modifier = MD;
	     num_mod--;
           }
	   utype = GetELFU32(hfile); //poiter to utype
	   /*pOffset2IndexTemp = pOffset2IndexHead;
	   while (pOffset2IndexTemp != NULL) {
	      if (utype == pOffset2IndexTemp->offset){
		 utype = pOffset2IndexTemp->tindex;
		 pOffset2IndexTemp = NULL;
		 //typeHdrInfo.dirty = 0;              
	      }
              else{
		 pOffset2IndexTemp = pOffset2IndexTemp->next;
		 //typeHdrInfo.dirty = 1;
              }
	   }*/
	   SearchForType(utype,&utype,&find);
           if (!find) typeHdrInfo.dirty = 1;
	   while(modifier == MOD_pointer_to && pointerTimes)
	   {
	     typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
             typeHdrInfo.typeName = "\0";

             if ((err = SymGetTypeIndexMax(&tmax)) != GOOD)
                 return(err);
	     rtn_type = tmax+1;
	     typeHdrInfo.t.complexType = Pointer;
             typeHdrInfo.sizeInMAUs = 4;
             typeHdrInfo.sizeCalculated = TRUE;
	     if (SymAddTypeHeader(rtn_type, &typeHdrInfo) != GOOD) 
                 return(ER_SYM_TYPE);

	     err = GetTypePtr(rtn_type, utype);
	     utype = rtn_type;
             pointerTimes--;
	   }
	   //Hera 2/9/98
	   if (modifier == MOD_reference_to) {
	      typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
	      typeHdrInfo.typeName = "\0";
	      if ((err = SymGetTypeIndexMax(&tmax)) != GOOD) return(err);
	      rtn_type = tmax + 1;
	      typeHdrInfo.t.complexType = Reference;
	      typeHdrInfo.sizeInMAUs = 4;
	      typeHdrInfo.sizeCalculated = TRUE;
	      if (SymAddTypeHeader(rtn_type, &typeHdrInfo) != GOOD)
		 return(ER_SYM_TYPE);
	      err = GetTypeRef(rtn_type,utype);
	      utype = rtn_type;
	   }
	   Tag_Size -= (num+2);
	   break;
      }

      case AT_mod_fund_type:
      {
           int num_mod,MFlag;
           U8 modifier,MD;
	   U32 utype;
           num = GetELFU16(hfile);//number;
           num_mod = num - 2; //modifiers + type(2bytes)
           modifier = 0;
           MFlag = 0;
           while(num_mod > 0)
           {
              MD = GetELFByte(hfile);             
              if(MD == MOD_pointer_to){
		 modifier = MD;
		 pointerTimes++;
	      }
	      else if(MD == MOD_reference_to)
                 modifier = MD;
	      num_mod--;
	   }
           utype = (U32)GetELFU16(hfile);
	   //MOD_reference_to is not implemented
	   while(modifier == MOD_pointer_to && pointerTimes)
	   {
	      typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
              typeHdrInfo.typeName = "\0";
              if ((err = SymGetTypeIndexMax(&tmax)) != GOOD)
                  return(err);

	      rtn_type = tmax+1;
	      typeHdrInfo.t.complexType = Pointer;
              typeHdrInfo.sizeInMAUs = 4;
              typeHdrInfo.sizeCalculated = TRUE;
	      if (SymAddTypeHeader(rtn_type, &typeHdrInfo) != GOOD) 
                  return(ER_SYM_TYPE);

	      err = GetTypePtr(rtn_type, utype);
	      utype = rtn_type;
              pointerTimes--;
	    }
	    //Hera 2/9/98
	    if (modifier == MOD_reference_to) {
	       typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
	       typeHdrInfo.typeName = "\0";
	       if ((err = SymGetTypeIndexMax(&tmax)) != GOOD) return(err);
	       rtn_type = tmax + 1;
	       typeHdrInfo.t.complexType = Reference;
	       typeHdrInfo.sizeInMAUs = 4;
	       typeHdrInfo.sizeCalculated = TRUE;
	       if (SymAddTypeHeader(rtn_type, &typeHdrInfo) != GOOD)
		  return(ER_SYM_TYPE);
	       err = GetTypeRef(rtn_type,utype);
	       utype = rtn_type;
	    }
	   Tag_Size -= (num+2);           
	   break;
      }

      case AT_fund_type:
	   rtn_type = (U32)GetELFU16(hfile);
           Tag_Size -= 2;
	   break;

      default:
           tempOffset = tell(hfile);
	   if(Tag_Size > 0)
	      SeekELFFile(hfile,(tempOffset+Tag_Size),SEEK_SET);
	   Tag_Size = 0;
	   quit = 1;
           break;
     }
    }
    BackOffset = tell(hfile);
    Tag_Size = GetELFU32(hfile);
    numParam = 0;
    if(Tag_Size != 4 && (Tag = GetELFU16(hfile)) == TAG_formal_parameter)
    {
       SeekELFFile(hfile,BackOffset,SEEK_SET);
       ProcessDbgParameter(hfile,&numParam,typeParam);
    }

    /* note: size for function *type* definition has no meaning */
    if ((err = SymGetTypeIndexMax(&tmax)) != GOOD)
         return(err);
    tindex = tmax+1;
    typeHdrInfo.typeChoice =  COMPLEX_TYPE_CLASS;
    typeHdrInfo.t.complexType = Function;
    typeHdrInfo.sizeInMAUs = 0L;  /* default MAU size for all type */
    typeHdrInfo.typeName = TypeName;
    /* Size of procedure type is 0 and calculated */
    typeHdrInfo.sizeCalculated = TRUE;
    if ((symerr = SymAddTypeHeader(tindex, &typeHdrInfo)) != GOOD)
         err = ER_SYM_TYPE;
    if (SymAddTypeFunc(tindex, /*attr*/0, /*frame*/0,/*pushmask*/0, rtn_type,
			    numParam, /*level*/0, (LPSTR)parentName) != GOOD)
       return(ER_SYM_TYPE);
    /* don't add parms if function can't be created */
    for (i = 0; i < numParam; i++)
     if (SymAddTypeFuncParam(tindex, typeParam[i])  != GOOD)
     {
         err = ER_SYM_TYPE;
         break;
     }

    if (oflag == MCREATE)
    {
       if ((err = FindBaseCodeIndex(&sindex)) != GOOD)
	    Warning(err);
       nstack = 0;
       if ((symerr = SymAddFuncCreate((LPSTR)FuncName, sindex, funcClass,
					 nstack, &fnAddr, tindex)) != GOOD)
            WarningEx(ER_CANNOT_ADD_FUNC, (LPSTR)FuncName);

       if (lstb != NULL)
           lstb->numFunctions++;
   }
   else
   {
      if ((symerr = SymAddFuncOpen(FuncName)) != GOOD)
      {    
          err = ER_FN_NOT_FOUND;
	  WarningEx(err, (LPSTR)FuncName);
      }     
   }
   SeekELFFile(hfile,BackOffset,SEEK_SET);
   if (LOAD_LOCALS(lflags)) {
      quit = 0;
      while (!quit)
      {
	    Tag_Size = GetELFU32(hfile);
	    if(Tag_Size == 4)
	    {
	       Tag = TAG_padding;
	       Tag_Size = 0;
	    }
	    else
            {
	      Tag = GetELFU16(hfile);
	      Tag_Size -= 6;
	    }
	    switch (Tag) {
	       case TAG_formal_parameter:
	       case TAG_local_variable:
		    tempOffset = tell(hfile);
		    tempOffset -= 6;
		    SeekELFFile(hfile,tempOffset,SEEK_SET);
                    FuncEnd = FALSE; //Hera 2/2/98
		    ProcessDbgLocals(hfile,&numParam,typeParam);
                    if (FuncEnd) quit = 1; //Hera 2/2/98
		    break;

               case TAG_class_type://Hera 2/2/98
               case TAG_array_type:
               case TAG_typedef:
               case TAG_structure_type:
               case TAG_union_type:
	       case TAG_enumeration_type:
	       case TAG_subroutine_type:
	          {
                    long sizetmp = Tag_Size;
		    ProcessDbgTypes(hfile, FuncName, Tag);
		    Tag_Size = sizetmp;
	          }//Hera 1/23/98
	            break;

	       case TAG_padding:
		    quit = 1;
		    break;

	       default:
		    tempOffset = tell(hfile);
		    tempOffset -= 6;
		    SeekELFFile(hfile,tempOffset,SEEK_SET);
                    quit = 1;
		    break;                 
	    } 
       }
   } 
 
    /* close fn scope */
    if ((symerr = SymAddFuncClose()) != GOOD) {
	 Warning(symerr);
     }
    /*if (oflag == MCREATE) {
        if ((symerr = SymAddSymbolSetAddr(&fnAddr)) != GOOD) {
            err = ER_SYM_NOT_UPDATED;
            Warning(err);
         }
      }*/  
     /* Flush register assignments in preparation of new function scope */
    //LClearRegs();
    return(GOOD);

}  /* ProcessDbgFunctions */
/*****************************************************************************
**
** ProcessDbgClassFunctions
**
*****************************************************************************/
RETCODE ProcessDbgClassFunctions(HANDLE hfile, U16 funcClass, BOOLEAN oflag,
                            U16 lflags,U32 *NextSubroutine, classInfo* tptr1,
                            U32 *NUM_M_U_D_TYPE) {
   CHAR FuncName[ELF_IDNLEN];
   CHAR tmpName[ELF_IDNLEN];
   //OFFSET_ADDR_RANGE_TYPE fnAddr;
   //QUAL_ADDR_TANGE_TYPE fnFinalAddr;
   //RETCODE symerr, err;
   //U16 sindex;
   U32 endBlockPos = 0L;
   U32 nstack,rtn_type;//,BackOffset;
   int index,num;
   U8 Byte;
   U32 tempOffset;//,tmax,tindex;
   U16 Attribution;//,Tag,numParam;
   int quit;
   //TYPE_HEADER_TYPE typeHdrInfo;
   CHAR parentName[1] = "";  /* 'fathername' field is not used for C */
   CHAR TypeName[ELF_IDNLEN] = "\0";
   //U32 typeParam[ELF_IDNLEN]; 
   int pointerTimes;
   U32 value, svalue;
      
   quit=0;
   pointerTimes = 0;
   nstack = 0;

   rtn_type = FT_void; //default to FT_void
   while(!quit && Tag_Size > 0)
   {
     Attribution = GetELFU16(hfile);
     Tag_Size -= 2;
     switch(Attribution)
     {
       case AT_DIAB_mangled: /* <Judy 7/7/1997 */
       case AT_name:
            index = 0;
	    while((Byte = GetELFByte(hfile)) != 0)
               FuncName[index++] = Byte;
	    FuncName[index] = '\0';
            if (Attribution == AT_DIAB_mangled) {
	       tempOffset = tell(hfile);
               LdmangleDiabDemangle(FuncName, &tmpName);
               //Hera 4/3/98
               //if(LdmangleDiabGetValue(hfile,FuncName,&value, &svalue)==GOOD) {
               //  tptr1->fnAddr.offsetStartAddr=value;
               // tptr1->fnAddr.offsetEndAddr=value+svalue;
               //}
               tptr1->fnAddr.offsetStartAddr = 0;
               tptr1->fnAddr.offsetEndAddr = 0;
               //Hera
               strcpy(FuncName, tmpName);
               SeekELFFile(hfile,tempOffset,SEEK_SET);
            }
//            if (Attribution == AT_name)
               strcpy(tptr1->name, FuncName);
            Tag_Size -= (index+1);
	    break;
      case AT_public:
           tptr1->access=1;
           GetELFByte(hfile);
           break;
      case AT_private:
           tptr1->access=2;
           GetELFByte(hfile);
           break;
      case AT_protected:
           tptr1->access=3;
           GetELFByte(hfile);
           break;
      case AT_sibling:
	   *NextSubroutine = GetELFU32(hfile);
           Tag_Size -= 4;
	   break;
      case AT_user_def_type:
           tptr1->typeIndex = GetELFU32(hfile);
           tptr1->attribution = Attribution;
           Tag_Size -= 4;
           break;

      case AT_mod_u_d_type:
      case AT_mod_fund_type:
      {
        int num_mod;
        BYTE MD;

        num = GetELFU16(hfile);
        tptr1->attribution = Attribution;
        if(Attribution == AT_mod_u_d_type)
           num_mod = num - 4; //modifiers + file offset(4bytes)
        else //AT_mod_fund_type
           num_mod = num - 2;   //modifiers + type(2bytes)
        while(num_mod > 0)
        {
          MD = GetELFByte(hfile);
          if(MD == MOD_pointer_to){
             NUM_M_U_D_TYPE++;   //number of AT_mod_u_d_type + AT_mod_fund_type
             (tptr1->pointerTimes)++;
             tptr1->modifier = MD;
	   }
	   else if(MD == MOD_reference_to){
	      NUM_M_U_D_TYPE++;
	      tptr1->modifier = MD;
	   }
           num_mod--;
         }
         if(Attribution == AT_mod_u_d_type)
	    tptr1->utype = GetELFU32(hfile);
         else if(Attribution == AT_mod_fund_type)
            tptr1->utype = (U32)GetELFU16(hfile);
         Tag_Size -= (num+2);
         break;
      }

      case AT_fund_type:
         tptr1->attribution = Attribution;
         tptr1->typeIndex = GetELFU16(hfile);
         Tag_Size -= 2;
         break;
      default:
           tempOffset = tell(hfile);
	   if(Tag_Size > 0)
	      SeekELFFile(hfile,(tempOffset+Tag_Size),SEEK_SET);
	   Tag_Size = 0;
	   quit = 1;
           break;
     }
   }
 return(GOOD);

}  /* ProcessDbgClassFunctions */
/*****************************************************************************
**
**  ProcessDbgParameter - Get Parameter numbers and type
**
*****************************************************************************/
RETCODE ProcessDbgParameter(HANDLE hfile, U16* numParam, U32* TList)
{
   int quit;
   char VName[ELF_IDNLEN],typeName[ELF_IDNLEN]="";
   U16 Tag;
   BYTE  location;
   U32  tindex;
   BOOLEAN isConst;
   VAR_LOCKED_REG address;

   quit = 0;
   while(!quit)
   {
      Tag_Size = GetELFU32(hfile);
      if(Tag_Size == 4)
      {
	Tag = TAG_padding;
	Tag_Size = 0;
      }
      else
      {
        Tag = GetELFU16(hfile);
	Tag_Size -= 6;
      }
      switch(Tag)
      {
	case TAG_formal_parameter:
             isConst = FALSE;
	     ProcessDbgVariable(hfile, &tindex, &isConst, &location,
	                                             &address, VName,0);
	     TList[*numParam] = tindex;
             (*numParam)++;
	     break;
	//Hera 1/23/98
        case TAG_class_type:
	case TAG_array_type:
	case TAG_typedef:
	case TAG_union_type:
	case TAG_enumeration_type:
	case TAG_subroutine_type:
	    ProcessDbgTypes(hfile,typeName,Tag);
	    break;
	//Hera
	default:
	    quit = 1;
            break;
       }      
   }//While(!quit)		             
   return(GOOD);
}  /* ProcessDbgParameter*/


/*****************************************************************************
**
**  ProcessDbgLocals - TAG_local_variable
**
*****************************************************************************/
RETCODE ProcessDbgLocals(HANDLE hfile,U16* numParam, U32* typeParam)
{
   int quit,Index;
   char VName[ELF_IDNLEN];
   RETCODE symerr;
   U16 Tag,sindex;
   BYTE  location;
   U32 tindex,addr;
   SYM_DESCRIPTOR symP;
   U32 tempOffset;
   RETCODE err;
   BOOLEAN isConst;
   VAR_LOCKED_REG address;

   Index = 0;
   quit = 0;
   while(!quit)
   {
      Tag_Size = GetELFU32(hfile);
      if(Tag_Size == 4)
      {
	Tag = TAG_padding;
	Tag_Size = 0;
      }
      else
      {
        Tag = GetELFU16(hfile);
	Tag_Size -= 6;
      }
      switch(Tag)
      {
        case TAG_formal_parameter:
	case TAG_local_variable:
             isConst = FALSE;
	     ProcessDbgVariable(hfile, &tindex, &isConst, &location,
                                                &address, VName, *numParam);
	     if(*numParam)
             {
               tindex = typeParam[Index++];
	       (*numParam)--;
	     }

	     if ((err = FindBaseDataIndex(&sindex)) != GOOD)
			     Warning(err);
	     if(location == OP_ADDR){
                addr = address.regIndex;
	        symerr = SymAddVar((LPSTR)VName,
	                 sindex,  /* section index */
                         tindex,
			 STATIC_VAR_CLASS,
                         NOT_REG,
                         (ADD_VAR_ADDR_UNION *)&addr,
			 isConst,
                         TRUE,  /* address is valid */
			 &symP);
	      }
	      else if(location == OP_REG){
	
                 symerr = SymAddVar((LPSTR)VName,
		          sindex,
                          tindex,
                          AUTO_VAR_CLASS,
                          LIVING_REG,
                          (ADD_VAR_ADDR_UNION *)&(address.regIndex),
                          isConst,
                          TRUE,  /* valid address */
			  &symP);
	       }
              //Hera 6/30/97
	      else if(location == OP_BASEREG){
	          symerr = SymAddVar((LPSTR)VName,
                           sindex,
                           tindex,
                           AUTO_VAR_CLASS,
			   NOT_REG,
                           (ADD_VAR_ADDR_UNION *)&(address.autoVarOffset),
                           FALSE, 
                           TRUE,  /* valid address */
                           &symP);
	      }
                   

	       if ((symerr != GOOD) &&
			             (symerr != ER_DUPLICATE_GLOBAL_NAME))
		     WarningEx(ER_CANNOT_ADD_SYM, (LPSTR)VName);
	       break;

       case TAG_padding:
	    FuncEnd = TRUE;
	    quit = 1;
	    break;

       //Hera 1/16/98
       case TAG_class_type:
       case TAG_array_type:
       case TAG_typedef:
       case TAG_structure_type:
       case TAG_union_type:
       case TAG_enumeration_type:
       case TAG_subroutine_type:
	    if (*numParam > Index) {
	       GetELFU16(hfile);//Should be AT_sibling
  	       SeekELFFile(hfile,(DebugOffset+GetELFU32(hfile)),SEEK_SET);
	       break;
	    }
       default:
	    quit = 1;
	    tempOffset = tell(hfile);
	    tempOffset -= 6;
	    SeekELFFile(hfile,tempOffset,SEEK_SET);
            break;

       }      
   }//While(!quit)
   return(GOOD);
}  /* ProcessDbgLocals */


/****************************************************************************
**  ProcessDbgVariable : Process Type information about a variable         **
**                                                                         **
*****************************************************************************/                                                                         

RETCODE PRIVATE ProcessDbgVariable(HANDLE hfile, U32* tindex, BOOLEAN* isConst,
              BYTE* Location, VAR_LOCKED_REG* address, LPSTR VName, U16 isType)
{
   int q,index,num,found;
   U32 NextTag,utype,tmax,tempOffset;
   U16 Attribution,pointerTimes,Tag;
   RETCODE err;
   TYPE_HEADER_TYPE typeHdrInfo;
   BYTE byte;
   CHAR typeName[ELF_IDNLEN];
   long tempSize;

   typeHdrInfo.dirty = 0;//Hera 3/11/98
   typeName[0] ='\0';
   pointerTimes = 0;
   q = 0;
   while(!q  && Tag_Size > 0)
   {
     Attribution = GetELFU16(hfile);
     Tag_Size -= 2;

     switch(Attribution)
     {
        case AT_sibling:
             NextTag = GetELFU32(hfile);
             Tag_Size -= 4;
             break;

        case AT_name:
             index = 0;
             while((byte = GetELFByte(hfile)) != 0)
                 VName[index++] = byte;
	     VName[index] = '\0';
	     Tag_Size -= (index+1);
		break;

        case AT_user_def_type:
             *tindex = GetELFU32(hfile);
	     Tag_Size -= 4;
	     found = FALSE;
	     if (!isType)
	        SearchForType(*tindex,tindex,&found);
	     if(!found) typeHdrInfo.dirty = 1;
	     //while(!isType && !found){
		/*pOffset2IndexTemp = pOffset2IndexHead;
	        while (pOffset2IndexTemp != NULL) {
	           if (*tindex == pOffset2IndexTemp->offset){
		      *tindex = pOffset2IndexTemp->tindex;
                      found = TRUE;
		      pOffset2IndexTemp = NULL;
	           }
                   else
	              pOffset2IndexTemp = pOffset2IndexTemp->next;
		}*/
		/*if(!found){
		   tempOffset = tell(hfile);
                   tempSize = Tag_Size;
		   SeekELFFile(hfile,(DebugOffset+(*tindex)),SEEK_SET);
                   Tag_Size = GetELFU32(hfile);
		   Tag = GetELFU16(hfile);
                   //Hera 2/2/98
		   if (Tag != TAG_class_type) {
                      Tag_Size -= 6;
		      ProcessDbgTypes(hfile,typeName,Tag);
		   }else
		      goto notFound;
                   //Hera
		   Tag_Size = tempSize;
		   SeekELFFile(hfile,tempOffset,SEEK_SET);
		}*/
	     //}
	     break;

	 case AT_mod_u_d_type:
	 {
	      int num, num_mod, modifier, MD;
	      num = GetELFU16(hfile); // number
	      num_mod = num - 4; //modifiers + file offset(4 bytes)
	      while(num_mod > 0){
	         MD = GetELFByte(hfile); //modifier
		 if(MD == MOD_pointer_to){
		    modifier = MD;
		    pointerTimes++;
		 }
		 else if(MD == MOD_reference_to)
		    modifier = MD;
		 else if(MD == MOD_const)
		    *isConst = TRUE;
		 num_mod--;
              }
	      utype = GetELFU32(hfile); //poiter to utype
	      if(!isType)
	      {
		found = FALSE;
		SearchForType(utype,&utype,&found);
		if(!found) typeHdrInfo.dirty = 1;
		//while(!found){
		   /*pOffset2IndexTemp = pOffset2IndexHead;
	           while (pOffset2IndexTemp != NULL) {
	              if (utype == pOffset2IndexTemp->offset){
		         utype = pOffset2IndexTemp->tindex;
                         found = TRUE;
			 pOffset2IndexTemp = NULL;
                         //typeHdrInfo.dirty = 0;
	              }
                      else{
			 pOffset2IndexTemp = pOffset2IndexTemp->next;
			 //typeHdrInfo.dirty = 1;
                      }
		   }*/
		   
		   /*if(!found){
		      tempOffset = tell(hfile);
		      tempSize = Tag_Size;
		      //Hera 1/23/98
		      //if (tempOffset < (DebugOffset + utype){
		         SeekELFFile(hfile,(DebugOffset+utype),SEEK_SET);
                         Tag_Size = GetELFU32(hfile);
			 Tag = GetELFU16(hfile);
                         //Hera 2/2/98
			 if (Tag != TAG_class_type) {
			    Tag_Size -= 6;               
			    ProcessDbgTypes(hfile,typeName,Tag);
			 }else
			    goto notFound;
			 //Hera
		         Tag_Size = tempSize;
			 SeekELFFile(hfile,tempOffset,SEEK_SET);
		      //}
		   }*/                  
	        //}
	        while(modifier == MOD_pointer_to && pointerTimes){
		   typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
                   typeHdrInfo.typeName = "\0";

                   if ((err = SymGetTypeIndexMax(&tmax)) != GOOD)
         	       return(err);

	           *tindex = tmax+1;
	           typeHdrInfo.t.complexType = Pointer;
                   typeHdrInfo.sizeInMAUs = 4;
                   typeHdrInfo.sizeCalculated = TRUE;
	           if (SymAddTypeHeader(*tindex, &typeHdrInfo) != GOOD) 
                       return(ER_SYM_TYPE);

		   err = GetTypePtr(*tindex, utype);
		   utype = *tindex;
                   pointerTimes--;
		}
		//Hera 2/9/98
	        if (modifier == MOD_reference_to) {
	           typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
	           typeHdrInfo.typeName = "\0";
	           if ((err = SymGetTypeIndexMax(&tmax)) != GOOD) return(err);
	           *tindex = tmax + 1;
	           typeHdrInfo.t.complexType = Reference;
	           typeHdrInfo.sizeInMAUs = 4;
	           typeHdrInfo.sizeCalculated = TRUE;
	           if (SymAddTypeHeader(*tindex, &typeHdrInfo) != GOOD)
		      return(ER_SYM_TYPE);
	           err = GetTypeRef(*tindex,utype);
	           utype = *tindex;
	        }
	        if(*isConst)//MOD_const
		   *tindex = utype;
              }

	      Tag_Size -= (num+2);
	      break;
	 }

	 case AT_fund_type:
	      *tindex = (U32)GetELFU16(hfile);
	      Tag_Size -=2;
	      break;

	 case AT_mod_fund_type:
	 {
	      int num_mod,MFlag;
	      U8 modifier,MD;

	      num = GetELFU16(hfile);//number;
	      num_mod = num - 2; //modifiers + type(2bytes)
	      modifier = 0;
              MFlag = 0;
	      while(num_mod > 0)
	      {
                 MD = GetELFByte(hfile);              
		 if(MD == MOD_const)
	            *isConst = TRUE;
		 else if(MD == MOD_pointer_to){
		    modifier = MD;
		    pointerTimes++;
		 }
		 else if (MD == MOD_reference_to)
                    modifier = MD;
	         num_mod--;
	      }
              utype = (U32)GetELFU16(hfile);
	      if(!isType)
              {
	        //MOD_reference_to is not implemented
	        while(modifier == MOD_pointer_to && pointerTimes){
		   typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
                   typeHdrInfo.typeName = "\0";

                   if ((err = SymGetTypeIndexMax(&tmax)) != GOOD)
         	       return(err);
                    
		   *tindex = tmax+1;
	           typeHdrInfo.t.complexType = Pointer;
                   typeHdrInfo.sizeInMAUs = 4;
                   typeHdrInfo.sizeCalculated = TRUE;
	           if (SymAddTypeHeader(*tindex, &typeHdrInfo) != GOOD) 
                       return(ER_SYM_TYPE);

		   err = GetTypePtr(*tindex, utype);
		   utype = *tindex;
                   pointerTimes--;
		 }
		 //Hera 2/9/98
	         if (modifier == MOD_reference_to) {
	            typeHdrInfo.typeChoice = COMPLEX_TYPE_CLASS;
	            typeHdrInfo.typeName = "\0";
	            if ((err = SymGetTypeIndexMax(&tmax)) != GOOD) return(err);
	            *tindex = tmax + 1;
	            typeHdrInfo.t.complexType = Reference;
	            typeHdrInfo.sizeInMAUs = 4;
	            typeHdrInfo.sizeCalculated = TRUE;
	            if (SymAddTypeHeader(*tindex, &typeHdrInfo) != GOOD)
		       return(ER_SYM_TYPE);
	            err = GetTypeRef(*tindex,utype);
		    utype = *tindex;
	         }
	         if(*isConst)//MOD_const
		   *tindex = utype;
               }
	      Tag_Size -= (num+2);           
	      break;
	   } 

           case AT_location:
		num = GetELFU16(hfile); //number
		*Location = GetELFByte(hfile);
		if(*Location == OP_REG || *Location == OP_ADDR){
		   address->regIndex = GetELFU32(hfile);
		   if(*Location == OP_REG)
		      Map2RegId(&(address->regIndex), *tindex);
		Tag_Size -= (num+2);
                break;
		}
		else if(*Location == OP_BASEREG){
		   address->regIndex = GetELFU32(hfile);
                   GetELFByte(hfile); // OP_CONST
		   address->autoVarOffset = GetELFU32(hfile);
//wb
//                   if (toolSelect == GREEN_HILLS_TOOLCHAIN)
//                     address->autoVarOffset += 24;
//we
		   GetELFByte(hfile); //OP_ADD
                   Map2RegId((&address->regIndex), *tindex);
		   Tag_Size -= (num+2);
		   break;
                }

	   default:
		if(Tag_Size > 0)
		  SeekELFFile(hfile,Tag_Size,SEEK_CUR);
                Tag_Size = 0;
		q = 1;
		break;
	 }
    } //While(!q && Tag_Size > 0)
notFound://Hera 2/2/98
    return(SeekELFFile(hfile,(DebugOffset+NextTag),SEEK_SET));
}

/*****************************************************************************
**
** ProcessDbgLines - Line number block
**
** ondemand - if TRUE, skip over lines (initial load)
**    FALSE for load all, or for module only load (load lines)
** oflag - MCREATE or MOPEN
**    MCREATE = initial load (whether ondemand or not) - MOPEN = load lines
** *nextBlockPos - start position of the line number block, it will be set to
**    the next block for error recovery.
** moduleDesc - module descriptor
**
** if blockSize % 4 != 0, we need read more 2 bytes(0000) after block.
*****************************************************************************/
RETCODE ProcessDbgLines(HANDLE hfile, BOOLEAN ondemand, BOOLEAN oflag)
{
   char *srcname;
   U32 lineno;
   U16 colno,i;
   U32 blockSize,lineSize;
   U32 laddr;
   RETCODE symerr = GOOD, nsymerr = GOOD;
   U32 address;
   SYM_DESCRIPTOR moduleDesc;
   int DFlag;
   BOOLEAN cplus = FALSE;
   //Hera 2/2/98
   //Set which one is a existed module(mflag = 1)
   if(sfname_offset != 0 && srcinfo_offset != 0) {
      int index = 0;
      while (SrcInfo[index].offset != 0){
         for (i = 0; i < (U16)numberOfModulesLoaded; i++) {
            if (!strcmp(SrcInfo[index].sfname, LowPC2MDesc[i].srcname)){
	       SrcInfo[index].mDesc = LowPC2MDesc[i].mDesc;
	       i = numberOfModulesLoaded;
            }
	 }
	 if(SrcInfo[index].mDesc == 0L)
            cplus  = TRUE;
         index++;
      }
      if (cplus){
         symerr = ProcessDbgLinesCPlus(hfile,ondemand,oflag);
	 return(symerr);
      }
   }
   //Hera
   if (LineOffset == 0) return GOOD;
   SeekELFFile(hfile,LineOffset,SEEK_SET);
   lineSize = LineSize;

repeat:
   DFlag = 0;
   blockSize = GetELFU32(hfile);
   if(toolSelect == GREEN_HILLS_TOOLCHAIN && (blockSize % 4) != 0)
     DFlag = 1;
   address = GetELFU32(hfile);
   lineSize -= 8;
   blockSize -= 8;
   if (blockSize == 10) //0x0000 0x0000 0xFF
   {
      SeekELFFile(hfile,10,SEEK_CUR);
      blockSize -= 10;
      lineSize -= 10;
      if (lineSize > 0)
         goto repeat;
      return GOOD;
   }
   
   for(i = 0; i < (U16)numberOfModulesLoaded; i++)
     if(address == LowPC2MDesc[i].lowpc &&
                               LowPC2MDesc[i].lowpc < LowPC2MDesc[i].hipc)
     {
       moduleDesc = LowPC2MDesc[i].mDesc;
       srcname = LowPC2MDesc[i].srcname;
       i = (U16)numberOfModulesLoaded;
     }

   if(moduleDesc != 0L && oflag == MCREATE)
     if ((symerr = SymAddModuleReference(moduleDesc, (LPSTR)srcname)) != GOOD)
	   Warning(ER_MODREF);

   if(ondemand)
   {
      if(DFlag == 1)
      {
         SeekELFFile(hfile,(blockSize+2),SEEK_CUR);
	 lineSize -= (blockSize+2);
      }
      else
      {
	 SeekELFFile(hfile,blockSize,SEEK_CUR);
	 lineSize -= blockSize;
      }
      if(lineSize > 0)
	goto repeat;
      return GOOD;
   }

   /* START LOADING LINE NUMBER INFORMATION */
   if ((symerr = SymAddLinenumStart(moduleDesc)) != GOOD)
   {
     Warning(symerr);
     return(ER_LINE_NOT_ADDED);
   }

   while (blockSize > 0)
   {
     lineno = GetELFU32(hfile);
     colno = GetELFU16(hfile);
     if(colno == 0xFFFF)
	colno = 0;

     laddr = address + GetELFU32(hfile);
     if(lineno != 0)
     {
       nsymerr = SymAddLinenum(lineno,colno,laddr);
       if(lstb != NULL)
       lstb->numLines++;
       symerr |= nsymerr;
     }
     blockSize -= 10;
     lineSize -= 10;
   }
     
   if (symerr)
     Warning(ER_LINE_NOT_ADDED);

   if ((symerr = SymAddLinenumEnd()) != GOOD)
   {
      if (symerr == ER_NO_LINENUMS_ADDED)
      {
         DESCRIPTOR moduleNameDesc;
         if ((nsymerr = SymGetSymbolName(moduleDesc,
             (DESCRIPTOR FAR *) &moduleNameDesc)) == GOOD)
         TFree((LPSTR)moduleNameDesc);
      }
      else
         Warning(symerr);
   }
   if(DFlag)
   {   
      GetELFU16(hfile);
      lineSize -= 2;
   }
   if(lineSize > 0)
     goto repeat;
   
   for(i = 0; i < (U16)numberOfModulesLoaded; i++)
     TFree(LowPC2MDesc[i].srcname);
   return(symerr);
}  /* ProcessDbgLines */

/******************************************************************
*  For C++, Because there are some codes in a header file         *
*  -- HERA 2/3/98                                                 *
*                                                                 *
******************************************************************/
RETCODE ProcessDbgLinesCPlus(HANDLE hfile, BOOLEAN ondemand, BOOLEAN oflag) {

   U32 lineSize;
   U32 blockSize,readbytes;
   U32 nextoff;
   int index = 0,itmp;
   SYM_DESCRIPTOR moduleDesc;
   char *srcname;
   U32 lineno;
   U16 colno,i;
   U32 laddr;
   RETCODE symerr = GOOD, nsymerr = GOOD;
   U32 address;
   BASE_INDEX baseIndex;
   OFFSET_ADDR_RANGE_TYPE modRange;
   CHAR name[ELF_IDNLEN];

   if (LineOffset == 0) return GOOD;

   SeekELFFile(hfile,LineOffset,SEEK_SET);
   lineSize = LineSize;

   index=0;
   while (SrcInfo[index].offset != 0){
      if (SrcInfo[index].mDesc == 0L){
	 LPSTR str;
         RETCODE err;

         strcpy(name,SrcInfo[index].sfname);
	 StripPathString(name,&str);
	 FindBaseCodeIndex(&baseIndex);
	 memset(&modRange,0,sizeof(OFFSET_ADDR_RANGE_TYPE));
	 if ((err = SymAddModuleCreate(str,baseIndex,&modRange,
	       0/*moduleOffset*/,ondemand,&moduleDesc,&tsLoadfile)) != GOOD){
	    WarningEx(ER_CANNOT_ADD_MOD,str);
	    return(ER_CANNOT_ADD_MOD);
	 }
	 if ((err = SymAddModuleClose(TRUE/*Hera*/)) != GOOD)
            Warning(ER_SYM_NOT_UPDATED);
	 for (i = 0; SrcInfo[i].offset != 0 ; i++)
	    if (!strcmp(SrcInfo[i].sfname,SrcInfo[index].sfname))
	       SrcInfo[i].mDesc = moduleDesc;
      }
      moduleDesc = SrcInfo[index].mDesc;
      srcname = SrcInfo[index].sfname;
      if (moduleDesc != 0L && oflag == MCREATE)
	 if ((symerr = SymAddModuleReference(moduleDesc,(LPSTR)srcname)) != GOOD)
            Warning(ER_MODREF);
      index++;
   }
   /*if(ondemand)
      return(GOOD);*/

   index=0;
   blockSize = 0;
   readbytes = 0;
   while (SrcInfo[index].offset != 0){
      //Beginning of Adding a linenum
      moduleDesc = SrcInfo[index].mDesc;
      if (blockSize == 0){
         SeekELFFile(hfile,(LineOffset+SrcInfo[index].offset-8),SEEK_SET);
         blockSize = GetELFU32(hfile);
	 nextoff = tell(hfile)-LineOffset+blockSize;//Hera 2/20/98
         if (blockSize == 10){ //0x0000 0x0000 0xFF
            SeekELFFile(hfile,10,SEEK_CUR);
            blockSize -= 10;
            lineSize -= 10;
            readbytes += 10;
            if (lineSize == 0)
               return GOOD;
         }
         address = GetELFU32(hfile);
         lineSize -= 8;
         blockSize -= 8;
         readbytes += 8;
      }
      if (SrcInfo[index].pass){
         if (SrcInfo[index+1].offset != 0) {
	    if (SrcInfo[index+1].startaddr != SrcInfo[index].startaddr) {
               lineSize -= blockSize;
	       blockSize = 0;
            }
	    else {
	       U32 jmprange;

	       jmprange = (SrcInfo[index+1].offset - SrcInfo[index].offset);
	       blockSize -= jmprange;
	       lineSize -= jmprange;
	    }
	 }            
	 index++;
	 continue;
      }
      modRange.offsetStartAddr = 0xFFFFFFFFL;
      modRange.offsetEndAddr = 0; 
      if ((symerr = SymAddLinenumStart(moduleDesc)) != GOOD){
         Warning(symerr);
	 return(ER_LINE_NOT_ADDED);
      }
      for (itmp = index; SrcInfo[itmp].offset != 0; itmp++){
	 if (!strcmp(SrcInfo[index].sfname,SrcInfo[itmp].sfname)) {
	    //Hera 2/20/98 -- Skip the second part of the header file
	    if (SrcInfo[itmp].offset > nextoff) {
	       SrcInfo[itmp].pass = TRUE;
	       continue;
	    }//Hera
	    SeekELFFile(hfile,LineOffset+SrcInfo[itmp].offset,SEEK_SET);
            readbytes = SrcInfo[itmp].offset;	      
            if (SrcInfo[itmp+1].offset != 0) {
	       while (readbytes < SrcInfo[itmp+1].offset){
		  lineno = GetELFU32(hfile);  
		  colno = GetELFU16(hfile);      
	          if (colno == 0xFFFF)
		     colno = 0;	                   
		  //laddr = address + GetELFU32(hfile);
                  laddr = SrcInfo[itmp].startaddr+GetELFU32(hfile);//Hera 2/23/98
		  modRange.offsetStartAddr = min(laddr,modRange.offsetStartAddr);
		  modRange.offsetEndAddr = max(laddr,modRange.offsetEndAddr) - 1;
	          blockSize -= 10;
                  lineSize -= 10;
		  readbytes += 10;
		  if (lineno != 0) {
                     if (!ondemand) {
			nsymerr = SymAddLinenum(lineno,colno,laddr);
			if (lstb != NULL)
	                   lstb->numLines++;
			symerr |= nsymerr;
		     }
		     if(readbytes == SrcInfo[itmp+1].offset) {
			SeekELFFile(hfile,6,SEEK_CUR);
			modRange.offsetEndAddr = SrcInfo[itmp].startaddr
						    + GetELFU32(hfile) - 1;
                        SeekELFFile(hfile,tell(hfile)-6,SEEK_SET);
                     }
		  }
		  else//lineno = 0
		     break;
	       }
            }//If(SrcInfo[index+1].offset != 0)
            else{
	       while (lineSize) {
		  lineno = GetELFU32(hfile);
	          colno = GetELFU16(hfile);
	          if (colno == 0xFFFF)
	             colno = 0;
		  laddr = address + GetELFU32(hfile);
		  modRange.offsetStartAddr = min(laddr,modRange.offsetStartAddr);
		  modRange.offsetEndAddr = max(laddr,modRange.offsetEndAddr) - 1;
	          blockSize -= 10;
	          lineSize -= 10;
	          readbytes += 10;
		  if (lineno != 0){
		     if(!ondemand) {
                        nsymerr = SymAddLinenum(lineno,colno,laddr);
	                if (lstb != NULL)
			   lstb->numLines++;
			symerr |= nsymerr;
                     }
		  }
		  else
		     break;
	       }
	    }
            SrcInfo[itmp].pass = 1;
	 }
      }
      if (symerr)
	 Warning(ER_LINE_NOT_ADDED);
      SymSetSymbolAddrByDesc(moduleDesc,&modRange);
      if ((symerr = SymAddLinenumEnd()) != GOOD){
	 if (symerr == ER_NO_LINENUMS_ADDED) {
            DESCRIPTOR moduleNameDesc;
	    if ((nsymerr = SymGetSymbolName(moduleDesc,
               (DESCRIPTOR FAR *) &moduleNameDesc)) == GOOD)
               TFree((LPSTR)moduleNameDesc);
            }
            else
               Warning(symerr);
      }             
      index++;
   }//while(Srcinfo[index].offset != 0)
   SymModifyRelation();//Hera 2/5/98
   return(symerr);
}
 
/*****************************************************************************
**
** ProcessDbgLinesOnDemand - Line number block On Demand
**
** ondemand - if TRUE, skip over lines (initial load)
**    FALSE for load all, or for module only load (load lines)
** oflag - MCREATE or MOPEN
**    MCREATE = initial load (whether ondemand or not) - MOPEN = load lines
** *nextBlockPos - start position of the line number block, it will be set to
**    the next block for error recovery.
** moduleDesc - module descriptor
** if blockSize % 4 ! = 0, we need read more 2 bytes. 
**
*****************************************************************************/
RETCODE ProcessDbgLinesOnDemand(HANDLE hfile, char *srcname)
{
   U32 lineno;
   U16 colno;
   U32 blockSize, lineSize;
   U32 laddr;
   RETCODE symerr = GOOD, nsymerr = GOOD;
   U32 address;
   SYM_DESCRIPTOR moduleDesc;
   int i,DFlag;
   //Hera 2/2/98
   //if (sfname_offset != 0 && srcinfo_offset != 0){
   //   symerr = ProcessDbgLinesOnDemandCPlus(hfile,srcname);
   //   return(symerr);
   //}
   //Hera
   if(LineOffset == 0) return GOOD;
   SeekELFFile(hfile,LineOffset,SEEK_SET);
   lineSize = LineSize;
rep:
   DFlag = 0;
   blockSize = GetELFU32(hfile);
   if(toolSelect == GREEN_HILLS_TOOLCHAIN && (blockSize % 4) != 0)
       DFlag = 1;     
   address = GetELFU32(hfile);
   lineSize -= 8;
   blockSize -= 8;
   if (blockSize == 10) //0x0000 0x0000 0xFF
   {
      SeekELFFile(hfile,10,SEEK_CUR);
      blockSize -= 10;
      lineSize -= 10;
      if (lineSize > 0)
         goto rep;
      return GOOD;
   }
   for(i = 0; i < (int)numberOfModulesLoaded; i++)
   {
     if(address == LowPC2MDesc[i].lowpc &&
                         LowPC2MDesc[i].lowpc < LowPC2MDesc[i].hipc)
     {
        LPSTR TempPtr;
	StripPathString(LowPC2MDesc[i].srcname,&TempPtr);
	if(!strcmp(srcname,TempPtr))
        {
          moduleDesc = LowPC2MDesc[i].mDesc;
	  break;
        }
        else
	{
	  if(DFlag == 1)
          {
	     SeekELFFile(hfile,(blockSize+2),SEEK_CUR);
	     lineSize -= (blockSize+2);
	  }
	  else
	  { 
	     SeekELFFile(hfile,blockSize,SEEK_CUR);
	     lineSize -= blockSize;
	  }
          if(lineSize > 0)
	     goto rep;
	  return GOOD;
        }
     }
   }

   if(i == (int)numberOfModulesLoaded)
      return GOOD;

   /* START LOADING LINE NUMBER INFORMATION */
   if ((symerr = SymAddLinenumStart(moduleDesc)) != GOOD)
   {
     Warning(symerr);
     return(ER_LINE_NOT_ADDED);
   }

   while (blockSize > 0)
   {
     lineno = GetELFU32(hfile);
     colno = GetELFU16(hfile);
     if(colno == 0xFFFF)
       colno = 0;
     laddr = address + GetELFU32(hfile);
     if(lineno != 0)
     {
       nsymerr = SymAddLinenum(lineno,colno,laddr);
       if(lstb != NULL)
       lstb->numLines++;
       symerr |= nsymerr;
     }
     blockSize -= 10;
     lineSize -= 10;
   }
     
   if (symerr)
     Warning(ER_LINE_NOT_ADDED);

   if ((symerr = SymAddLinenumEnd()) != GOOD)
   {
      if (symerr == ER_NO_LINENUMS_ADDED)
      {
         DESCRIPTOR moduleNameDesc;
         if ((nsymerr = SymGetSymbolName(moduleDesc,
             (DESCRIPTOR FAR *) &moduleNameDesc)) == GOOD)
         TFree((LPSTR)moduleNameDesc);
      }
      else
         Warning(symerr);
   }

   return(symerr);
}  /* ProcessDbgLinesOnDemand */

RETCODE EXPORT LdrToolSelect(U16 *toolchain){
   *toolchain = toolSelect;
   return(GOOD);
}

RETCODE PRIVATE ProcessUndefinedType(U32 tmin){
   U32 tmax,tindex;
   TYPE_HEADER_TYPE typeHdrInfo;
   RETCODE err;
   CHAR typeName[ELF_IDNLEN] = " ";
   TYPE_INDEX ptindex;
   BOOLEAN flag;

   flag = FALSE;
   typeHdrInfo.typeName = (LPSTR) typeName;
   if ((err = SymGetTypeIndexMax(&tmax)) != GOOD)
      return(err);
   for(tindex = tmin; tindex <= tmax; tindex++){
      SymGetTypeHeader((TYPE_INDEX)tindex,&typeHdrInfo);

      if(typeHdrInfo.dirty && typeHdrInfo.typeChoice == COMPLEX_TYPE_CLASS) {
         switch(typeHdrInfo.t.complexType){
	    case Pointer:
            case Reference:    
	       SymGetTypePointerTypeIndex((TYPE_INDEX)tindex,(TYPE_INDEX FAR*)&ptindex);
	       SearchForType(ptindex,&ptindex,&flag);
	       if(flag)
	          SymUpdateTypePointerTypeIndex((TYPE_INDEX)tindex,ptindex);
	       break;
         }
      }//If(...)
   }
   return(GOOD);
}
/******************************** E O F *************************************/
