Ejemplo n.º 1
0
unsigned __GrowSeg( unsigned short seg, unsigned int amount )
    {
        unsigned n;             /* number of paragraphs desired   */
        unsigned int old_heaplen;
        unsigned int old_heap_paras;
        struct heapblk _WCFAR *p;
        struct freelist _WCFAR *pfree;
        struct freelist _WCFAR *pnew;
        tag _WCFAR *last_tag;

        if( !__heap_enabled ) return( 0 );
        p = (struct heapblk _WCFAR *)MK_FP( seg, 0 );
        old_heaplen = p->heaplen;
        if( old_heaplen != 0 ) {                /* if not already 64K */
            amount += TAG_SIZE;                      /* 25-feb-91 */
            if( amount < TAG_SIZE ) amount = ~0;
            if( amount < _amblksiz )  amount = _amblksiz;
            n = ( amount + 0x0f ) >> 4;
            if( n == 0 )  n = PARAS_IN_64K;     /* 23-may-89 */
            old_heap_paras = old_heaplen >> 4;
            n += old_heap_paras;
            /*
                We shouldn't extend segments to 64k if we are not going to
                use the space for this allocation.  In protected-mode
                environments, it should be possible to extend segments
                later on when we know we can use the space.
            */
#if defined(__QNX__)
            if( n > PARAS_IN_64K ) return( 0 );
#elif defined(__OS2__) || defined(__WINDOWS_286__)
            if( n > PARAS_IN_64K ) {
                if( _osmode != DOS_MODE ) {
                    /* protected-mode */
                    return( 0 );
                } else {
                    n = PARAS_IN_64K;
                }
            }
#else
            if( n > PARAS_IN_64K ) n = PARAS_IN_64K;
#endif
#if defined(__OS2__)
            if( DosReallocSeg( n << 4, seg ) != 0 )             return( 0 );
#elif defined(__QNX__)
            if( qnx_segment_realloc( seg, ((long)n) << 4 ) == -1 ) return( 0 );
#elif defined(__WINDOWS_286__)
            if( old_heap_paras < (PARAS_IN_64K-2) && n == PARAS_IN_64K ) {
                n = PARAS_IN_64K - 2;
            } else if( n > ( PARAS_IN_64K - 2 ) ) {
                /*
                  in Standard mode, GlobalRealloc may change selectors
                  if size > 65519 (64k-17)! (p. 4-246 Windows Ref) AFS 23-apr-91
                */
                return( 0 );
            }
            {
                HANDLE hmem;

                hmem = (HANDLE)GlobalHandle( seg );
                if( hmem == NULL ) {
                    return( 0 );
                }
                if( GlobalReAlloc( hmem, ((long)n) << 4,
                        __win_realloc_flags) == NULL ){
                    return( 0 );
                }
            }
#else
            if( TINY_ERROR( TinySetBlock( n, seg ) ) )          return( 0 );
#endif
            p->heaplen = n << 4;        /* put in new heap length */
            pfree = MK_FP( seg, p->freehead.prev );
            if( FP_OFF(pfree) + pfree->len != old_heaplen - TAG_SIZE*2 ) {
                /* last free entry not at end of the heap */
                /* add a new free entry to end of list */
                pnew = MK_FP( seg, old_heaplen - TAG_SIZE*2 );
                pnew->prev = FP_OFF(pfree);
                pnew->next = pfree->next;
                pfree->next = FP_OFF(pnew);
                p->freehead.prev = FP_OFF(pnew);
                p->numfree++;
                pfree = pnew;
            }
            pfree->len = p->heaplen - FP_OFF(pfree) - TAG_SIZE*2;
            if( pfree->len > p->largest_blk )  p->largest_blk = pfree->len;
            last_tag = MK_FP( seg, p->heaplen - TAG_SIZE*2 );
            *last_tag = END_TAG;
            last_tag[1] = 0;            /* link to next piece of near heap */
            return( 1 );                /* indicate segment was grown */
        }
AFILE *makefp(DEBFILE *pdf, ULONG mid, ULONG instaddr, UCHAR *fname)
{
 uchar    *cp = NULL;
 uint      segbase;
 uchar    *srcbuf;
 uint      Nlines;
 uint      Tlines;
 SEL       srcsel;
 SEL       offsel;

 ushort    srcseglen;
 ushort   *offtab;
 AFILE    *fp;
 int       ftype;
 int       OffsetTableBufSize;
 char      FileNameBuffer[CCHMAXPATH];
 char      FileSpecBuffer[CCHMAXPATH];
 UCHAR     FileNameLength;
 LNOTAB   *pLnoTabEntry;
 int       sfi;
 MODULE   *pModule;
 CSECT    *pCsect;
 UCHAR    *pFileName;
 UCHAR    *fn;
 BOOL      found;
 ULONG     junk;
 int       lno;

 if( fname )
 {
  /***************************************************************************/
  /* - if fname is specified, then the view is to be build using the source  */
  /*   file name supplied by the user as in the case of getfile.             */
  /* - we need to find an sfi to associate with the file.                    */
  /* - build a length-prefixed z-string from the supplied name.              */
  /***************************************************************************/
  fn         = strrchr(fname, '\\');
  fn         = (fn) ? (fn + 1) : fname ;
  pFileName  = Talloc( strlen(fn) + 2 );
  *pFileName = (UCHAR)strlen(fn);
  strcpy( pFileName+1, fn );

  found = FALSE;
  for( sfi=mid=0, pdf = pnode->ExeStruct; pdf != NULL; pdf=pdf->next )
  {
   mid = MapSourceFileToMidSfi( pFileName, &sfi, pdf );
   if( mid && sfi )
   {
    found = TRUE;
    memset(FileNameBuffer, 0, sizeof(FileNameBuffer) );
    strcpy(FileNameBuffer+1, fname );
    FileNameBuffer[0] = (UCHAR)strlen(fname);
    break;
   }
  }

  Tfree( pFileName );

  if( found == FALSE )
   return(NULL);

  instaddr = DBMapLno(mid, 0, sfi, &junk , pdf );
  DBMapInstAddr(instaddr, &pLnoTabEntry, pdf);
  lno = 0;
  if( pLnoTabEntry )
   lno = pLnoTabEntry->lno;
 }
 else
 {
  /***************************************************************************/
  /* - we're going to build the view from an instruction address.            */
  /***************************************************************************/
  if ( pdf->SrcOrAsm == SOURCE_LEVEL )
  {
   mid = DBMapInstAddr(instaddr, &pLnoTabEntry, pdf);
   lno = sfi = 0;
   if( pLnoTabEntry )
   {
    lno = pLnoTabEntry->lno;
    sfi = pLnoTabEntry->sfi;
   }
   if( (pLnoTabEntry != NULL) && (sfi != 0) )
   {
    memset(FileNameBuffer, 0, sizeof(FileNameBuffer) );
    cp = GetFileName( mid, sfi );
    if( cp )
     strcpy(FileNameBuffer, cp);
   }
  }
 }

 if(ftype)
 {
  findsrc(FileNameBuffer+1,FileSpecBuffer+1,sizeof(FileSpecBuffer) );
  FileSpecBuffer[0] = (UCHAR)strlen(FileSpecBuffer+1);
  memcpy(FileNameBuffer,FileSpecBuffer,sizeof(FileSpecBuffer));
 }

 FileNameLength = FileNameBuffer[0];

 fp = (AFILE*) Talloc(SizeOfAFILE(FileNameLength));
 memcpy( fp->filename, FileNameBuffer, FileNameLength+1);

 /****************************************************************************/
 /* - allocate 64k for the source buffer.                                    */
 /* - allocate 20k for the offset buffer.                                    */
 /* - load source file into a buffer and define:                             */
 /*    - srcsel    =  source buffer selector.                                */
 /*    - offsel    =  offset buffer selector.                                */
 /*    - 0         =  number of lines to skip at the beginning of the file.  */
 /*    - srcseglen =  source buffer bytes actually used by the load.         */
 /*    - Nlines    =  number of source lines in the buffer.                  */
 /*    - Tlines    =  number of source lines in the entire file.             */
 /* - reallocate the source buffer to size really needed.                    */
 /****************************************************************************/
 Nlines = srcsel = offsel = 0;
 if( !DosAllocSeg(0,(PSEL)&srcsel,0) &&
     !DosAllocSeg(20*1024,(PSEL)&offsel, 0) )
 {
  LoadSource( fp->filename+1, (UCHAR *)Sel2Flat(srcsel),
             (USHORT *)Sel2Flat(offsel), 0, &srcseglen, &Nlines, &Tlines);
  if( Nlines )
   DosReallocSeg(srcseglen, srcsel);
 }

 /****************************************************************************/
 /* - now, define the view structure.                                        */
 /****************************************************************************/
 fp->shower   = showA;
 fp->pdf      = pdf;
 fp->mid      = mid;
 fp->sfi      = sfi;
 fp->mseg     = segbase;
 fp->Tlines   = Tlines;                 /* number of lines in file.          */
 fp->Nlines   = Nlines;                 /* number of lines in source buffer. */
 fp->Nbias    = 0;                      /* number of lines skipped in source.*/
 fp->topline  = 1;                      /* init to 1st line in the file.     */
 fp->csrline  = lno;                    /*  " "                              */
 fp->hotline  = lno;                    /*  " "                              */
 fp->hotaddr  = instaddr;
 fp->skipcols = 0;                      /* columns skipped on left.          */
 fp->Nshown   = 0;
 fp->topoff   = instaddr;
 fp->csr.row  = 0;
 fp->csr.col  = 0;
 fp->csr.mode = CSR_NORMAL;
 fp->sview    = NOSRC;                  /* assume no source disassembler view*/
 fp->flags    = ASM_VIEW_NEW;

 if( Nlines )
 {
  srcbuf = (uchar*)Sel2Flat(srcsel);
  fp->source = srcbuf;

  /**************************************************************************/
  /* Allocate the offtab[] buffer to hold Nlines + 1 offsets. We add the 1  */
  /* so that we can make the offset table indices line up with the          */
  /* source line numbers.                                                   */
  /**************************************************************************/
  OffsetTableBufSize = (Nlines+1)*sizeof(USHORT);
  offtab             = (USHORT*) Talloc(OffsetTableBufSize);

  memcpy(offtab + 1, (uchar*)Sel2Flat(offsel), Nlines*sizeof(USHORT) );

  fp->offtab = offtab;
  fp->flags  = 0;                      /* clear asm flag.                   */

  if( Tlines > Nlines )                /* does compressed source exceed 64k?*/
   fp->flags |= AF_HUGE;               /* mark afile with huge file flag    */

  fp->shower = showC;                  /*  display source                   */
  fp->sview  = MIXEDN;                 /* assume no source disassembler view*/

/*
  Flag all text lines for which a (line #, offset) pair exists.
*/

  pModule = GetModuleWithAddr( instaddr, pdf );
  if( pModule )
  {
   for(pCsect = pModule->pCsects; pCsect != NULL; pCsect=pCsect->next )
   {
    int NumEntries;

    NumEntries   = pCsect->NumEntries;
    pLnoTabEntry = pCsect->pLnoTab;

    if( (pLnoTabEntry != NULL) && ( NumEntries > 0 ) )
    {
     for( ; NumEntries; pLnoTabEntry++, NumEntries-- )
     {
      if( pLnoTabEntry->sfi == sfi )
      {
       int lno;

       lno = pLnoTabEntry->lno;
       if( (lno != 0) && (lno <= Nlines) )
       {
        *(srcbuf + offtab[lno] - 1) |= LINE_OK;
       }
      }
     }
    }
   }
  }
  MarkLineBRKs( fp );                   /* mark the active breakpoints       */
 }

 if( offsel )                           /* if there was an offset segment    */
  DosFreeSeg(offsel);                   /* allocated then free it up         */
 if( !Nlines && srcsel )                /* if there was no source then       */
  DosFreeSeg(srcsel);                   /* free up the temp source buffer    */

 return( fp );
}