/****************************************************************************
**
**  Name:  LRECORD.C
**
**  Description:
**      Record operations on ELF binary file.
**
**  Status:  CODED
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef __LDR__
#include "ldr.h"
#endif

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


#include <ctype.h>
#include <io.h>
#include <limits.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

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

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

//**Hera 08/27/96**/
#ifndef _LPROFILE_
#include "lprofile.h"
#endif
//**Hera**/

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
//U16 curbyte;                        /* current byte obtained from file */
STATIC U8 FAR *lbuffer;
STATIC U8 *readPtr;
CHAR scratchBuffer[ELF_IDNLEN];
//#define LDR_BUFSIZE 4096    /* file read buffer size for ELF file */
U32 endDebugPart = 0L;
                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
			****************************/
extern U16 toolSelect;
extern Offset2Index *pOffset2IndexHead, *pOffset2IndexTail, *pOffset2IndexTemp;
                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

/****************************************************************************
**
**  OpenELFFile
**
*****************************************************************************/
/* return file handle, if success (else -1) */
S16 OpenELFFile(LPSTR file, OFSTRUCT *pof) {
   int hfile;

   /* fill in the file struct so caller has fully-qualified filename */
   if ((hfile = _lopen(file, READ)) == -1)
      return (-1);
   /* Still need to fill in ofstruct, since this is the only way to obtain
       the fully-qualified pathname (stored in symbol table). */
   OpenFile(file, pof, OF_PARSE);

   if ((lbuffer = (U8*)TMalloc(LDR_BUFSIZE)) == NULL)
      return (-1);

   //Initialization
   readPtr = NULL;
   return (hfile);
}  /* OpenELFFile */

/*****************************************************************************
**
**  SeekELFFile
**
*****************************************************************************/
LONG SeekELFFile(HANDLE hfile, LONG pos, S16 seekTo) {
    return (_llseek(hfile, pos, seekTo));
}  /* SeekELFFile */

/*****************************************************************************
**
**  CloseELFFile
**
*****************************************************************************/
RETCODE CloseELFFile(HANDLE hfile) {
   /* De-allocate file buffer */
   if ((lbuffer != NULL) && (TFree((LPSTR)lbuffer) != GOOD)) {
      Warning(ER_BAD_FREE);
   }
   lbuffer = NULL;
   while (pOffset2IndexHead != NULL){
      pOffset2IndexTemp = pOffset2IndexHead;
      pOffset2IndexHead = pOffset2IndexHead->next;
      if (TFree((LPSTR)pOffset2IndexTemp) != GOOD)
         Warning(ER_BAD_FREE);
   }
   pOffset2IndexHead = NULL;
   _lclose(hfile);
   return(GOOD);
}  /* CloseELFFile */

/*****************************************************************************
**
** GetELFByte
**
*****************************************************************************/
U8 GetELFByte(HANDLE hFile)
{
  U8 data[1];
  _lread(hFile,data,1);

  return(data[0]);
}/*GetELFByte*/

/*****************************************************************************
**
** GetELFU16
**
*****************************************************************************/
U16 GetELFU16(HANDLE hFile)
{
  U8 data[2];
  _lread(hFile,data,2);

  return(((U16)data[0] << 8) | data[1]);
}/*GetELFU16*/

/*****************************************************************************
**
** GetELFU32
**
*****************************************************************************/
U32 GetELFU32(HANDLE hFile)
{
  U8 data[4];
  U32 temp;
   
  _lread(hFile,data,4);
  temp = ((U32)data[0] << 24)|((U32)data[1] << 16);
  return(temp | ((U32)data[2] << 8) | ((U32)data[3]));
}/*GetELFU32*/

/*****************************************************************************
**
** StripPathString
**
** moduleName - the original module name
** newName    - the new module Name
**
*****************************************************************************/
RETCODE StripPathString(LPSTR moduleName, LPSTR *newName) {
   BOOLEAN done = FALSE;
   LOOP_VAR strLen, i;

   *newName = moduleName; /* Assign pointer */
   /* Check if moduleName is NULL */
   if ((strLen = strlen(moduleName)) >= 0) {
      strLen -= 1; /* String start from 0 index */
      for (i = strLen; i > 0 && !done; i--) {
         switch(*(moduleName+i)) {
            case '.':
               *(moduleName + i) = (CHAR)'\0';  /* Strip the suffix */
               break;
            case '\\':
            case '/':
            case ':':   
               if (i > 0)
                 *newName = (LPSTR)moduleName + (i + 1);
	       done = TRUE;
               break;
         }
      }
   }
   return(GOOD);
}  /* StripPathString */

/*****************************************************************************
**
**  GetELFBytes
**
*****************************************************************************/
RETCODE GetELFBytes(HANDLE hfile, U8 *pbyte, U32 number) {
   U16 size;
   S16 charsInBuffer;
   U32 bytes=0;

   while (number > 0)
   {
      if(number > LDR_BUFSIZE)
	charsInBuffer = _lread(hfile, (S8*)lbuffer, LDR_BUFSIZE);
      else
	charsInBuffer = _lread(hfile, (S8*)lbuffer, (U16)number);
      if (charsInBuffer <= 0) break;
      readPtr = lbuffer;
      size = min(charsInBuffer, number);
      memcpy((LPSTR)pbyte,(LPSTR)readPtr,size);
      readPtr += size;
      pbyte += size;
      bytes += (U32)size;
      number -= (U32)size;
   }
   return((bytes<number) ? ER_BAD_FILE : GOOD);
}

RETCODE Map2RegId(U32 *address, U32 tindex)
{

/*   *address += 3;

   if(toolSelect == GREEN_HILLS_TOOLCHAIN)
   {
      if(*address == 0)
	 *address = 60;
      //else if(*address == 1) *address = 1;
      else if(*address >= 2 && *address <= 30)
	 *address += 59;
      else if(*address == 31)
	 *address = 2;
      else if(*address >= 32)
	 *address += 58;
   }
   else if(toolSelect == DIAB_DATA_TOOLCHAIN)
   {
      if(tindex == FT_float || tindex == FT_dbl_prec_float
				      || tindex == FT_ext_prec_float)
	 *address += 90;
      //type is not floating point
      else if(*address == 0)
	 *address = 60;
      //else if(*address == 1) *address = 1;
      else if(*address >= 2 && *address <= 30)
	 *address += 59;
      else if(*address == 31)
         *address = 2;     
   }*/
   return GOOD;
}

RETCODE SearchForType(U32 offset, U32 *tindex, BOOLEAN *find){

   *find = FALSE;
   pOffset2IndexTemp = pOffset2IndexHead;
   while (pOffset2IndexTemp != NULL) {
      if (offset == pOffset2IndexTemp->offset){
	 *tindex = pOffset2IndexTemp->tindex;
	 pOffset2IndexTemp = NULL;
	 *find = TRUE;     
      }
      else
	 pOffset2IndexTemp = pOffset2IndexTemp->next;
   }
   return GOOD;
}
/******************************** E O F ***********************************/
