/****************************************************************************
**
**  Name:  LENV.C
**
**  Description:
**      Process Environment Part of IEEE 695 binary file.
**
**  Status:  CODED
**
**  $Log:   S:/tbird/mt2_68k/l695/lenv.c_v  $
** 
**    Rev 1.0   13 Feb 1997 08:50:54   gene
** Initial revision.
** 
**    Rev 1.2   20 Aug 1996 10:08:44   kevin
** support SDS 6.3
** 
**    Rev 1.1   14 Jun 1996 08:45:56   kevin
** judy's modification
** 
**    Rev 1.0   07 Sep 1995 10:32:16   gene
** Initial revision.
** 
**    Rev 1.21   04 Apr 1994 12:21:02   john
** Oops, last fix wasn't
** 
**    Rev 1.20   30 Mar 1994 11:34:20   john
** Added changes for 360
** 
**    Rev 1.19   29 Mar 1994 18:02:50   nghia
** Removed the un-official name of WhiteSmith tool.
** 
**    Rev 1.18   29 Mar 1994 15:21:14   nghia
** Added SDS CrossCode tool to toolchains list.
** 
**    Rev 1.17   03 Mar 1994 15:24:50   nghia
** Remove reporting ER_NO_PC thru the message box.
** 
**    Rev 1.16   18 Jan 1994 17:05:38   nghia
** Added checking toolcode for HIWARE (cpu32 and HC16), and Introl.
** 
**    Rev 1.15   26 Oct 1993 13:28:12   nghia
** Revised Checking toolcode to check for CPU type.
** 
**    Rev 1.14   06 Aug 1993 15:09:56   courtney
** Return toolchain enum value from ProcessEnvPart.
** 
**    Rev 1.13   03 Aug 1993 17:40:08   nghia
** Removed LERR_xxxx to use standard error codes.
** Added check for reportWarning.
** 
**    Rev 1.12   29 Jul 1993 15:24:58   courtney
** toolUseName was not being initialized for Shell loader invocation - fixed.
** 
**    Rev 1.11   28 Jul 1993 15:11:22   nghia
** Revised to put up warning box and allow user to continue or cancel the
** loading process.  If continue, set useDefaultSection to force the loader
** create section using default names to add symbols.
** 
**    Rev 1.10   27 Jul 1993 22:34:46   nghia
** Revised to support wrong toolchain warning.
** - Define toolChainsTbl contains all toolchain names.
** - Detect Sierra and suppress warning.
** - Report warning if loadfile contains wrong toolchain.
** 
**    Rev 1.9   27 Jul 1993 18:56:42   courtney
** Added support for HP toolchain.
** 
**    Rev 1.8   26 Jul 1993 13:47:24   courtney
** Added support to pick tool code setting from Environment Part of
** file.
** 
**    Rev 1.7   14 Jun 1993 11:23:04   nghia
** Merged new error code usage to trunk.
** 
**    Rev 1.6   25 May 1993 10:35:42   ernie
** Virtualized _llseek() calls in Seek695File when file buffering added.
** 
**    Rev 1.5.1.0   03 Jun 1993 18:47:40   nghia
** Revised to used the new error code.
** Report error using only Warning() and WarningEx().
** 
**    Rev 1.5   12 Apr 1993 16:24:10   nghia
** Revised to use the new ProcessATN().
** 
**    Rev 1.4   23 Mar 1993 17:10:32   nghia
** Updated to use the new MatchRecord and Match2Record.
** Minor cleanup.
** 
**    Rev 1.3   08 Mar 1993 10:39:10   nghia
** Moved GetLoadItem() to this file.
** Major cleanup for names and comments.
** 
**    Rev 1.2   21 Oct 1992 16:37:24   courtney
** Cleaned up error reporting to use string resource.
** 
**    Rev 1.1   24 Mar 1992 21:11:14   courtney
** Added routine to process trailer part of file - to get startPC.
** 
**    Rev 1.0   31 Dec 1991 11:00:08   courtney
** Initial revision.
** 
**  $Header:   S:/tbird/mt2_68k/l695/lenv.c_v   1.0   13 Feb 1997 08:50:54   gene  $
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
*****************************************************************************/
                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef _PROC_
#include "proc.h"
#endif

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

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

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

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

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

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
/* Table of toolchains, indexing by TOOLCHAIN_TYPE - defined lprofile.h */
PRIVATE CHAR *toolChainsTbl[NUM_TOOLCHAINS] = {
  "Unknown","Diab Data","MRI","Sierra","Intermetrics",
  "Whitesmiths","Introl", "HiWare", "SDS CrossCode",
  "Green Hills"
  }; // <JUDY 5/27/96>
  
BOOLEAN useDefaultSection = FALSE;
  
                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern HDR695 Hdr695;       /* Defined in LDR.C */
extern CHAR toolUseName[];  /* Defined in LPROFILE.C */
extern CHAR pwrViewsDir[];
extern U16 reportWarning;   /* Defined in LDR.C */

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

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
/******************************************************************************
**
**  GetLoadItem
**
******************************************************************************/
RETCODE GetLoadItem(HANDLE hfile, U32 *pvalue) {
   RETCODE err;

   if ((err = MatchRecord(hfile, RT_LIBE)) != GOOD)
      return(err);
   Get695Offset(hfile, pvalue);
   return(MatchRecord(hfile, RT_LIBF));
}  /* GetLoadItem */

/******************************************************************************
**
**  ProcessEnvPart
**
** This Part is processed, and interesting information returned to caller,
** which sends it to the project presenter, or anyone else interested.
** Currently, only certain pieces of information are kept:
**      timestamp of loadfile
**      generation status (successful link, failure, etc.)
**      host OS
**      toolchain id
******************************************************************************/
RETCODE ProcessEnvPart(HANDLE hfile, TIMESTAMP_TYPE *pts, U16 *pstatus,
							  U16 *phostos, TOOLCHAIN_TYPE *toolchainID) {
    RETCODE err = GOOD;
    CHAR cmdline[MAX_CMDLINE], sname[IEEE_IDNLEN];
    U16 atn_type, nindex, cbyte;
    U32 tindex, tdummy = 0; /* toffset */
    U16 toolCode, toolVersion, toolRevision, toolLevel;
    TOOLCHAIN_TYPE compilerID = UNKNOWN_TOOLCHAIN;  /* initialize */
    S16 continueLoading;

    /* first, seek to Environmental Part of file */
    if (Seek695File(hfile, Hdr695.hdr_env, SEEK_SET) == -1L)
        return(ER_BAD_SEEK);

    /* single NN */
    if (MatchRecord(hfile, RT_NN) == GOOD)
        Get695Nrecord(hfile, &nindex, (LPSTR)sname);

    /* loop over ATN records found */
    while (1) {
       /* Since we're processing an entire Part of the file here, its
          ok if we eat too many bytes; the next Part will re-seek */
       if (Match2Record(hfile, RT_ATN) != GOOD)
           break;
       ProcessATN(hfile, &nindex, &tindex, tdummy, &atn_type);
       switch(atn_type) {
           case ATN_CREATION_TIME:
               Get695Time(hfile, pts);
               break;
           case ATN_CMDLINE:
               /* we don't care about the link commandline */
               Get695Idn(hfile, (LPSTR)cmdline);
               break;
           case ATN_STATUS:
               Get695Number(hfile, pstatus);
               break; 
           case ATN_HOSTOS:
               Get695Number(hfile, phostos);
               break;
           case ATN_TOOL:  /* ATN54 */
               /* Most toolchains set toolcode in ATN54, refer to Appx P
                  in 695 specification 'Tool Type Codes'.
               */
               Get695Number(hfile, &toolCode);
               Get695Number(hfile, &toolVersion);
               Get695Number(hfile, &toolRevision);
               /* optional [x4] field: tool revision level */
               Peek695Byte(hfile, &cbyte);
               // <Judy 05/08/96>
               //if (cbyte == RP_ATTR)
               //   break;   next ATN record
               //else
               //   Get695Number(hfile, &toolLevel);
               // <Judy 05/08/96>
               if (cbyte != RP_ATTR)
                  Get695Number(hfile, &toolLevel);
               //
               // Default is UNKNOWN_TOOLCHAIN
               compilerID = UNKNOWN_TOOLCHAIN;
               if ((Hdr695.hdr_cpu == PROC_CPU_CPU32) ||
                   (Hdr695.hdr_cpu == PROC_CPU_68000) ||
                   (Hdr695.hdr_cpu == PROC_CPU_CPU32P)) {
                  switch(toolCode) {
                     case UNKNOWN_TOOLCODE:
                        /* Check for Sierra - currently 'Unknown'!!! */
                        if (lstrcmpi((LPSTR)toolChainsTbl[SIERRA_TOOLCHAIN],
                                     (LPSTR) toolUseName) == 0)
                           /* Sierra's users must know what they select */
                           compilerID = SIERRA_TOOLCHAIN;
                        break;
                     case MRI_TOOLCODE:
                        compilerID = MRI_TOOLCHAIN;
                        break;
                     case INTERM_TOOLCODE:
                        compilerID = INTERM_TOOLCHAIN;
                        break;
                     case INTROL_TOOLCODE:
                        // This is the Introl toolchain CPU32
                        // <Judy 5/8/96>
                        // ToolCode of Introl and Green Hills are the same.
                        compilerID = INTROL_TOOLCHAIN;
                        if (lstrcmpi((LPSTR)toolChainsTbl[compilerID], (LPSTR)toolUseName) == 0)
                           break;
                        compilerID = GREEN_HILLS_TOOLCHAIN;
                        break;
                     case DIAB_DATA_TOOLCODE:    // <JUDY 5/27/96>
                        compilerID = DIAB_DATA_TOOLCHAIN;
                        break;
                     case HIWARE_CPU32_TOOLCODE:
                        compilerID = HIWARE_TOOLCHAIN;
                        break;
              /*     case HP_TOOLCODE:   <Judy 6/3/96>
                        compilerID = HP_TOOLCHAIN;
                        break;        */
                     case SDS_TOOLCODE_6: /* <Judy 8/12/96> */
                     case SDS_TOOLCODE:
                        compilerID = SDS_TOOLCHAIN;
                        break;
                  }
               } else {
                  // Only if it's CPU16 that we support the following:
                  switch(toolCode) {
                     case HIWARE_HC16_TOOLCODE:
                        compilerID = HIWARE_TOOLCHAIN;
                        break;
                     case WHITESMITHS_TOOLCODE:
                        // This is WhiteSmiths toolchain
                        compilerID = WHITESMITHS_TOOLCHAIN;
                        break;
                     case INTROL_TOOLCODE:
                        // This is the Introl toolchain
                        compilerID = INTROL_TOOLCHAIN;
                        break;                       
                  }
               }
               break;
               
           case ATN_COMMENT:  /* ATN55 */
               /* Cosmic is the only exception: read string in ATN55 */
               Get695Idn(hfile, (LPSTR)sname);
               if (strstr(sname, "Cosmic") != NULL)
                  compilerID = WHITESMITHS_TOOLCHAIN;
               break;
           default:
               return(GOOD);
       }
    }  /* while (1) */
    
    *toolchainID = compilerID;

    /* Check if compilerID is the same as the toolUseName */       
    if (lstrcmpi((LPSTR)toolChainsTbl[compilerID], (LPSTR)toolUseName) != 0) {
       /* Only report warning when flag is TRUE */
       if (reportWarning) {
          err = ER_LOADFILE_HAD_INCOMPATIBLE_TOOLCHAIN;
          /* Report Error */
          ErrDisplayFormattedError(err, CHECK_MODE,
                                (LPSTR) toolChainsTbl[compilerID],
                                (LPSTR) toolUseName,
                                (LPSTR) NULL,
                                MB_OKCANCEL,
                                (S16 FAR *) &continueLoading);
          /* If user cancel then stop loading */
          if (continueLoading == IDCANCEL)
             return(err);
       }
       /* Global flag to force using default section */
       useDefaultSection = TRUE; 
    }                     
    return(GOOD);
}  /* ProcessEnvPart */

/******************************************************************************
**
**  ProcessTrailPart
**
******************************************************************************/
RETCODE ProcessTrailPart(HANDLE hfile, U32 *pstartPC) {
    /* first, seek to Trailer Part of file */
    if (Seek695File(hfile, Hdr695.hdr_trlr, SEEK_SET) == -1L)
        return(ER_BAD_SEEK);

    if ((Match2Record(hfile, RT_ASG) != GOOD) ||
         (GetLoadItem(hfile, pstartPC) != GOOD)) { 
       // 03/03/94 - Nghia
       // Only report to the Shell - Progress Indicator already displayed
       // the PC as Unknown, so do not return the err again.
       if (reportWarning)
          ErrDisplayError(ER_NO_PC, FORCE_CLI);
    }
    
    return(GOOD);
}  /* ProcessTrailPart */

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