home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / DBIFEXT.C < prev    next >
Text File  |  1996-05-16  |  60KB  |  1,214 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   dbifext.c                                                               */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   More interface functions.                                               */
  7. /*                                                                           */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   02/08/91 Creation of 32-bit SD86, from 16-bit version.                  */
  12. /*                                                                           */
  13. /*...16->32 port.                                                            */
  14. /*...                                                                        */
  15. /*... 02/08/91  101   Joe       made changes for 32-bit compilation.         */
  16. /*... 05/20/91  106   Srinivas  hooking up the assembler window.             */
  17. /*... 05/29/91  105   Christina error in processing MODULE chain             */
  18. /*... 05/30/91  110   Srinivas  changes to make restart work.                */
  19. /*... 06/02/91  111   Christina fix warnings                                 */
  20. /*...                                                                        */
  21. /*...Release 1.00 (Pre-release 1)                                            */
  22. /*...                                                                        */
  23. /*... 08/22/91  234   Joe       PL/X gives "varname" is incorrect message    */
  24. /*...                           when entering a parameter name in the data   */
  25. /*...                           window.  This happens when the cursor is on  */
  26. /*...                           an internal procedure definition statement   */
  27. /*...                           and you use F2 to get into the data window   */
  28. /*...                           and then type the name.                      */
  29. /*... 08/30/91  235   Joe       Cleanup/rewrite ascroll() to fix several bugs*/
  30. /*...                                                                        */
  31. /*...Release 1.00 (After pre-release 1.08)                                   */
  32. /*...                                                                        */
  33. /*... 02/12/92  521   Joe       Port to C-Set/2.                             */
  34. /*... 02/14/92  530   Srinivas  Jumping across ID in case of PLX disassembly */
  35. /*... 02/17/92  533   Srinivas  Trap when we type in a variable in data      */
  36. /*...                           window, when we don't have debug info.       */
  37. /*...                                                                        */
  38. /*...Release 1.00 (03/03/92)                                                 */
  39. /*...                                                                        */
  40. /*... 03/18/92  606   Srinivas  Handle multiple segment numbers in lno table */
  41. /*...                           due to alloc_text pragma.                    */
  42. /*...Release 1.01 (03/31/92)                                                 */
  43. /*...                                                                        */
  44. /*... 05/04/92  700   Joe       Fix code/data object bitness.                */
  45. /*... 06/04/93  827   Joe       Add remote debug support.                    */
  46. /*... 02/03/93  905   Joe       Fix Data window update bug.                  */
  47. /*...                                                                        */
  48. /**Includes*******************************************************************/
  49.  
  50. #include "all.h"                        /* SD86 include files                */
  51.  
  52. /**Externs********************************************************************/
  53.  
  54. extern AFILE        *allfps;
  55. extern PROCESS_NODE *pnode;                                             /*827*/
  56.  
  57.  
  58. /*****************************************************************************/
  59. /*  DBFindPdf()                                                              */
  60. /*                                                                           */
  61. /* Description:                                                              */
  62. /*   Find the pointer to the debug file containing the mid parmater.         */
  63. /*                                                                           */
  64. /* Parameters:                                                               */
  65. /*   mid        module id in the debug file.                                 */
  66. /*                                                                           */
  67. /* Return:                                                                   */
  68. /*                                                                           */
  69. /*   pdf        pointer to debug file structure.                             */
  70. /*                                                                           */
  71. /*****************************************************************************/
  72.   DEBFILE *                             /*                                   */
  73. DBFindPdf( uint mid  )                  /*                                   */
  74. {                                       /* begin  DBPub                      */
  75.  DEBFILE      *pdf;                     /* executing debug file              */
  76.  MODULE       *mptr;                    /* -> to a module node               */
  77.                                         /*                                   */
  78.  for( pdf = pnode->ExeStruct;           /* scan all EXE/DLL nodes.           */
  79.       pdf;                              /*                                   */
  80.       pdf=pdf->next                     /*                                   */
  81.     )                                   /*                                   */
  82.  {                                      /*                                   */
  83.   for(                                  /* scan modules                      */
  84.       mptr = pdf->MidAnchor;            /*                                   */
  85.       mptr != NULL;                     /*                                   */
  86.       mptr = mptr->NextMod              /*                                   */
  87.      )                                  /*                                   */
  88.   {                                     /*                                   */
  89.    if(mptr->mid == mid)                 /* if found, break from inner loop   */
  90.     break;                              /*                                   */
  91.   }                                     /*                                   */
  92.   if (mptr != NULL)                     /* 105 */
  93.     if (mptr->mid == mid)               /* if found, break from outer loop   */
  94.       break;                            /*                                   */
  95.  }                                      /*                                   */
  96.  return(pdf);                           /*                                   */
  97. }                                       /* end DBFindPdf()                   */
  98. /*************************************************************************101*/
  99. /* FindExeOrDllWithAddr()                                                 101*/
  100. /*                                                                        101*/
  101. /* Description:                                                           101*/
  102. /*   Find the pointer to the debug file containing this address.          101*/
  103. /*                                                                        101*/
  104. /* Parameters:                                                            101*/
  105. /*   addr       address.                                                  101*/
  106. /*                                                                        101*/
  107. /* Return:                                                                101*/
  108. /*   pdf        pointer to debug file structure.                          101*/
  109. /*   NULL       did not locate the address.                               101*/
  110. /*                                                                        101*/
  111. /*************************************************************************101*/
  112.                                         /*                                101*/
  113.     DEBFILE *                           /*                                101*/
  114. FindExeOrDllWithAddr( ULONG addr )      /*                                101*/
  115. {                                       /*                                101*/
  116.  DEBFILE       *pdf;                    /* executing debug file           101*/
  117.  OBJTABLEENTRY *te;                     /* -> to a object table entry.    101*/
  118.  uint           NumCodeObjs;            /* number of table entries.       521*/
  119.  int            i;                      /*                                101*/
  120.  uint          *p;                      /*                                521*/
  121.  
  122.  if( addr == 0 )
  123.   return(NULL);
  124.  
  125. /*************************************************************************101*/
  126. /* The purpose of the following code is to scan the modules in the debug  101*/
  127. /* files and find the debug file that contains the address. This function 101*/
  128. /* used for a process with focus. There is a FindPdfAddr that is used     101*/
  129. /* when the process does not have focus.                                  101*/
  130. /*                                                                        101*/
  131. /* - get a pointer to the process node.                                   101*/
  132. /* - scan pdf object table for the object containing this addr.           101*/
  133. /* - return the pdf.                                                      101*/
  134. /*                                                                        101*/
  135. /*************************************************************************101*/
  136.  for( pdf = pnode->ExeStruct;                                           /*101*/
  137.       pdf;                                                              /*101*/
  138.       pdf=pdf->next                                                     /*101*/
  139.     )                                                                   /*101*/
  140.  {                                                                      /*101*/
  141. /*DumpObjectTable( pdf );*/
  142.   p=pdf->CodeObjs;                                                      /*521*/
  143.   NumCodeObjs = *p;                                                     /*521*/
  144.   te = (OBJTABLEENTRY *)++p;                                            /*101*/
  145.   for(i=1; i <= NumCodeObjs; i++,te++ )                                 /*101*/
  146.   {                                                                     /*101*/
  147.    if((addr >= te->ObjLoadAddr) &&                                      /*101*/
  148.       ( addr <  (te->ObjLoadAddr + te->ObjLoadSize)))                   /*101*/
  149.     return(pdf);                                                        /*101*/
  150.   }                                                                     /*101*/
  151.  }                                                                      /*101*/
  152.  return(NULL);                          /*                              /*101*/
  153. }                                       /* end FindExeOrDllWithAddr().  /*101*/
  154.  
  155. /*****************************************************************************/
  156. /* FindExeOrDllWithSelOff()                                                  */
  157. /*                                                                           */
  158. /* Description:                                                              */
  159. /*   Find the pointer to the debug file containing this sel:off.             */
  160. /*                                                                           */
  161. /* Parameters:                                                               */
  162. /*   sel        16 bit selector.                                             */
  163. /*   off        16 bit offset.                                               */
  164. /*                                                                           */
  165. /* Return:                                                                   */
  166. /*   pdf        pointer to debug file structure.                             */
  167. /*   NULL       did not locate the sel:off.                                  */
  168. /*                                                                           */
  169. /*****************************************************************************/
  170. DEBFILE *FindExeOrDllWithSelOff( USHORT sel, USHORT off )
  171. {
  172.  DEBFILE       *pdf;
  173.  OBJTABLEENTRY *te;
  174.  uint           NumObjs;
  175.  int            i;
  176.  uint          *p;
  177.  
  178.  for( pdf = pnode->ExeStruct;
  179.       pdf;
  180.       pdf=pdf->next
  181.     )
  182.  {
  183.   p=pdf->CodeObjs;
  184.   NumObjs = *p;
  185.   te = (OBJTABLEENTRY *)++p;
  186.   for(i=1; i <= NumObjs; i++,te++ )
  187.   {
  188.    if( (sel == te->ObjLoadSel ) )
  189.    {
  190.     USHORT LoOffset;
  191.     USHORT HiOffset;
  192.  
  193.     LoOffset = te->ObjLoadOff;
  194.     HiOffset = LoOffset + te->ObjLoadSize - 1;
  195.     if( (LoOffset <= off) && (off <= HiOffset) )
  196.      return(pdf);
  197.    }
  198.   }
  199.  }
  200.  return(NULL);
  201. }
  202.  
  203. /*****************************************************************************/
  204. /* dfilefree()                                                                 */
  205. /*                                                                           */
  206. /* Description:                                                              */
  207. /*   free the DFILE structures for a restart.                                */
  208. /*                                                                           */
  209. /* Parameters:                                                               */
  210. /*                                                                           */
  211. /* Return:                                                                   */
  212. /*                                                                           */
  213. /* Assumptions:                                                              */
  214. /*                                                                           */
  215. /*  Will be called only on a Restart().                                      */
  216. /*                                                                           */
  217. /*****************************************************************************/
  218. extern DFILE*      DataFileQ;
  219.  
  220. void dfilefree()
  221. {
  222.   DFILE *dfp;
  223.   DFILE *dfpnext;
  224.   DFILE *dfplast;
  225.  
  226.   /***************************************************************************/
  227.   /* - reset the pointers into the symbols areas.                            */
  228.   /***************************************************************************/
  229.   dfplast=(DFILE*)&DataFileQ;
  230.   dfp=DataFileQ;
  231.   for( dfp=DataFileQ ; dfp; dfp=dfp->next )
  232.   {
  233.    dfp->scope = NULL;
  234.   }
  235.  
  236.   dfplast=(DFILE*)&DataFileQ;
  237.   dfp=DataFileQ;
  238.   while( dfp )
  239.   {
  240.    dfpnext=dfp->next;
  241.    if( dfp->mid > MAXEXEMID )
  242.    {
  243.     Tfree((void*)dfp);                                                   /*521*/
  244.     dfplast->next=dfpnext;
  245.     dfp=dfpnext;
  246.    }
  247.    else
  248.    {
  249.     dfplast=dfp;
  250.     dfp=dfpnext;
  251.    }
  252.   }
  253. }
  254.  
  255. /*****************************************************************************/
  256. /* afilefree()                                                                 */
  257. /*                                                                           */
  258. /* Description:                                                              */
  259. /*   free the afile structures for a restart.                                */
  260. /*                                                                           */
  261. /* Parameters:                                                               */
  262. /*                                                                           */
  263. /* Return:                                                                   */
  264. /*                                                                           */
  265. /* Assumptions:                                                              */
  266. /*                                                                           */
  267. /*  Will be called only on a Restart().                                      */
  268. /*                                                                           */
  269. /*****************************************************************************/
  270. void afilefree()
  271. {
  272.  AFILE        *fp;
  273.  AFILE        *fpnext;
  274.  
  275.  fp=allfps;
  276.  
  277.  while( fp )                            /* scan afile linked list and        */
  278.  {
  279.   fpnext=fp->next;
  280.   freefp(fp);                           /* free each structure               */
  281.   fp=fpnext;
  282.  }
  283.  allfps=NULL;
  284. }
  285.  
  286. /*****************************************************************************/
  287. /* freepdf()                                                                 */
  288. /*                                                                           */
  289. /* Description:                                                              */
  290. /*   free up the memory allocated for the debug info associated with a DLL.  */
  291. /*                                                                           */
  292. /* Parameters:                                                               */
  293. /*   pdf        debug file.                                                  */
  294. /*                                                                           */
  295. /* Return:                                                                   */
  296. /*                                                                           */
  297. /* Assumptions:                                                              */
  298. /*                                                                           */
  299. /*  The pdf is valid.                                                        */
  300. /*                                                                           */
  301. /*****************************************************************************/
  302. void freepdf(DEBFILE *pdf)
  303. {
  304.  MODULE       *pModule;
  305.  MODULE       *pModuleNext;
  306.  AFILE        *fp;
  307.  AFILE        *fpnext;
  308.  FILENAME     *pFile;
  309.  FILENAME     *pFileNext;
  310.  CSECT        *pCsect;
  311.  CSECT        *pCsectNext;
  312.  
  313.  /****************************************************************************/
  314.  /* - scan the modules and free the line number tables.                      */
  315.  /****************************************************************************/
  316.  for( pModule = pdf->MidAnchor; pModule != NULL ; pModule=pModule->NextMod)
  317.  {
  318.   for(pCsect = pModule->pCsects; pCsect != NULL; pCsect=pCsect->next )
  319.   {
  320.    if(pCsect->pLnoTab)
  321.     Tfree(pCsect->pLnoTab);
  322.   }
  323.  }
  324.  
  325.  /****************************************************************************/
  326.  /* - now, scan the modules and free the csects.                             */
  327.  /****************************************************************************/
  328.  for( pModule = pdf->MidAnchor; pModule != NULL ; pModule=pModule->NextMod)
  329.  {
  330.   for(pCsect = pModule->pCsects; pCsect != NULL; )
  331.   {
  332.    pCsectNext = pCsect->next;
  333.    Tfree(pCsect);
  334.    pCsect=pCsectNext;
  335.   }
  336.  }
  337.  
  338.  /****************************************************************************/
  339.  /* - now, scan the modules and free the files.                              */
  340.  /****************************************************************************/
  341.  for( pModule = pdf->MidAnchor; pModule != NULL ; pModule=pModule->NextMod)
  342.  {
  343.   for(pFile = pModule->pFiles; pFile != NULL; )
  344.   {
  345.    pFileNext = pFile->next;
  346.    Tfree(pFile);
  347.    pFile=pFileNext;
  348.   }
  349.  }
  350.  
  351.  /****************************************************************************/
  352.  /* - now, free the modules.                                                 */
  353.  /****************************************************************************/
  354.  for( pModule = pdf->MidAnchor; pModule != NULL ; )
  355.  {
  356.   pModuleNext = pModule->NextMod;
  357.   Tfree(pModule);
  358.   pModule=pModuleNext;
  359.  }
  360.  
  361. /*****************************************************************************/
  362. /* Free symbols,types,publics, and line numbers.                             */
  363. /*****************************************************************************/
  364.   FreeSyms(pdf);
  365.   FreeTyps(pdf);
  366.   FreePubs(pdf);
  367.  
  368. /*****************************************************************************/
  369. /* Close the source file and free the MFILE structure and file name          */
  370. /* storage.                                                                  */
  371. /*****************************************************************************/
  372.  if( pdf->DebFilePtr->fh != 0 )
  373.    closedos(pdf->DebFilePtr->fh);
  374.  Tfree((void*)pdf->DebFilePtr->fn);      /* free file name space           521*/
  375.  Tfree((void*)pdf->DebFilePtr);          /* free the MFILE structure       521*/
  376.  
  377. /*************************************************************************813*/
  378. /* Free the object tables.                                                813*/
  379. /*************************************************************************813*/
  380.  if(pdf->CodeObjs)
  381.   Tfree(pdf->CodeObjs);
  382.  
  383.  /****************************************************************************/
  384.  /* Now, free any views that may have been built for this pdf.               */
  385.  /****************************************************************************/
  386.  for( fp = allfps; fp; )
  387.  {
  388.   fpnext = fp->next;
  389.   if( fp->pdf == pdf )
  390.   {
  391.    freefp(fp);
  392.   }
  393.   fp = fpnext;
  394.  }
  395. }
  396.  
  397. /*****************************************************************************/
  398. /* Free symbols.                                                             */
  399. /*****************************************************************************/
  400. void FreeSyms( DEBFILE *pdf )
  401. {
  402.  SYMNODE      *sptr;
  403.  SYMNODE      *sptrnext;
  404.   sptr=pdf->psyms;
  405.   while( sptr )
  406.   {
  407.    sptrnext=sptr->next;
  408.    if(sptr->symptr)
  409.     Tfree((void*)sptr->symptr);                                          /*521*/
  410.    Tfree((void*)sptr);                                                   /*521*/
  411.    sptr=sptrnext;
  412.   }
  413. }
  414. /*****************************************************************************/
  415. /* Free types.                                                               */
  416. /*****************************************************************************/
  417. void FreeTyps( DEBFILE *pdf )
  418. {
  419.  TYPENODE     *tptr;
  420.  TYPENODE     *tptrnext;
  421.   tptr=pdf->ptyps;
  422.   while( tptr )
  423.   {
  424.    tptrnext=tptr->next;
  425.    if(tptr->typptr)
  426.     Tfree((void*)tptr->typptr);                                          /*521*/
  427.    Tfree((void*)tptr);                                                   /*521*/
  428.    tptr=tptrnext;
  429.   }
  430. }
  431.  
  432. /*****************************************************************************/
  433. /* Free public info.                                                         */
  434. /*****************************************************************************/
  435. void FreePubs( DEBFILE *pdf )
  436. {
  437.  PUBNODE      *pptr;
  438.  PUBNODE      *pptrnext;
  439.   pptr=pdf->ppubs;
  440.   while( pptr )
  441.   {
  442.    pptrnext=pptr->next;
  443.    if(pptr->pubptr)
  444.     Tfree((void*)pptr->pubptr);                                          /*521*/
  445.    Tfree((void*)pptr);                                                   /*521*/
  446.    pptr=pptrnext;
  447.   }
  448. }
  449. /*****************************************************************************/
  450. /* DBGetAsmLines()                                                           */
  451. /*                                                                           */
  452. /* Description:                                                              */
  453. /*   get the number of assembler lines for an executable source line.        */
  454. /*                                                                           */
  455. /* Parameters:                                                               */
  456. /*                                                                           */
  457. /*   fp        input  - afile for this asm window.                           */
  458. /*   lno       input  - the executable line number.                          */
  459. /*   pAddr     output - -> to location receiving starting address of      235*/
  460. /*                         the executable line.                              */
  461. /*   SkipBytes input  - no of bytes to be skipped while calculating span  530*/
  462. /*                                                                           */
  463. /* Return:                                                                   */
  464. /*                                                                           */
  465. /*   count     the number of assembler lines required for this module.       */
  466. /*                                                                           */
  467. /* Assumptions:                                                              */
  468. /*                                                                           */
  469. /*   lno is executable.                                                      */
  470. /*                                                                           */
  471. /*****************************************************************************/
  472. extern INSTR   *icache;                 /* the instruction cache.         235*/
  473.  int                                    /*                                   */
  474. DBGetAsmLines( AFILE *fp , uint lno, uint *pAddr,uint SkipBytes )       /*530*/
  475. {                                       /*                                   */
  476.  uint  addr;                            /*                                235*/
  477.  ULONG span = 0;                        /*                                521*/
  478.  uchar *InstrBytesBuffer;               /*                                235*/
  479.  uint   BytesRead = 0;                  /*                                521*/
  480.  int    InstrCount;                     /*                                235*/
  481.  int    InstrLength;                    /*                                235*/
  482.  uchar *PtrToEndOfBuffer;               /*                                235*/
  483.  uchar *InstrPtr;                       /*                                235*/
  484.  UCHAR  type;
  485.  UCHAR  bitness;
  486.  
  487.  *pAddr = addr = DBMapLno(fp->mid, lno, fp->sfi, &span, fp->pdf);
  488.  
  489.  bitness = GetBitness( addr);
  490.  type = (bitness==BIT16)?USE16:USE32;
  491.  InstrBytesBuffer = GetCodeBytes( addr, span, &BytesRead );
  492.  if( BytesRead != span )
  493.   return(0);
  494.  
  495.  InstrCount = 0;
  496.  PtrToEndOfBuffer = InstrBytesBuffer + span;
  497.  InstrPtr = InstrBytesBuffer;
  498.  /****************************************************************************/
  499.  /* Modify the starting instr ptr depending on th Skip bytes value, this  530*/
  500.  /* Skip bytes is always 0 except when we try to handle names ID's in     530*/
  501.  /* PLX dis assembly.                                                     530*/
  502.  /****************************************************************************/
  503.  InstrPtr = InstrPtr + SkipBytes;                                       /*530*/
  504.  while( InstrPtr < PtrToEndOfBuffer )                                   /*235*/
  505.  {                                                                      /*235*/
  506.   InstrCount++;                                                         /*235*/
  507.   InstrLength = InstLengthGlob( InstrPtr , type );
  508.   InstrPtr += InstrLength;                                              /*235*/
  509.  }                                                                      /*235*/
  510.  return( InstrCount );                                                  /*235*/
  511. }                                                                       /*235*/
  512.  
  513. /*************************************************************************101*/
  514. /* GetBitness()                                                           101*/
  515. /*                                                                        101*/
  516. /* Description:                                                           101*/
  517. /*   Get the 16 or 32 bitness of the address parameter.                   101*/
  518. /*                                                                        101*/
  519. /* Parameters:                                                            101*/
  520. /*   addr       address.                                                  101*/
  521. /*                                                                        101*/
  522. /* Return:                                                                101*/
  523. /*   BIT32      address is 32 bit.                                        101*/
  524. /*   BIT16      address is 16 bit.                                        101*/
  525. /*   BITUNKNOWN can't determine.                                          101*/
  526. /*                                                                        101*/
  527. /*************************************************************************101*/
  528.  uchar                                  /*                                101*/
  529. GetBitness( uint addr )                 /*                                101*/
  530. {                                       /*                                101*/
  531.  DEBFILE       *pdf;                    /* executing debug file           101*/
  532.  OBJTABLEENTRY *te;                     /* -> to a object table entry.    101*/
  533.  uint           NumCodeObjs;            /* number of table entries.       521*/
  534.  int            i;                      /*                                101*/
  535.  uint          *p;                      /*                                521*/
  536.                                         /*                                101*/
  537. /*************************************************************************101*/
  538. /* - get a pointer to the process node.                                   101*/
  539. /* - scan pdf object table for the object containing this addr.           101*/
  540. /* - return the type of the object.                                       101*/
  541. /*************************************************************************101*/
  542.  pdf = pnode->ExeStruct;                                                /*101*/
  543.  for( ; pdf; pdf=pdf->next )                                            /*101*/
  544.  {                                                                      /*101*/
  545.   p=pdf->CodeObjs;                                                      /*101*/
  546.   if (p == NULL)                                                        /*107*/
  547.     continue;                                                           /*107*/
  548.   NumCodeObjs = *p;                                                     /*101*/
  549.   if ( NumCodeObjs == 0 )                                               /*101*/
  550.    continue;                                                            /*101*/
  551.   te = (OBJTABLEENTRY *)++p;                                            /*101*/
  552.   for(i=1; i <= NumCodeObjs; i++,te++ )                                 /*101*/
  553.   {                                                                     /*101*/
  554.    if( addr >= te->ObjLoadAddr &&                                       /*101*/
  555.        addr <  te->ObjLoadAddr + te->ObjLoadSize )                      /*101*/
  556.     return(te->ObjBitness);                                             /*606*/
  557.   }                                                                     /*101*/
  558.  }                                                                      /*101*/
  559.  return(BITUNKNOWN);                                                    /*101*/
  560. }                                       /* end GetBitness().            /*101*/
  561.  
  562. /*************************************************************************115*/
  563. /* MapAddrtoObjnum()                                                         */
  564. /*                                                                           */
  565. /* Description:                                                              */
  566. /*   Map a address to a object number                                        */
  567. /*                                                                           */
  568. /* Parameters:                                                               */
  569. /*   pdf        pointer to debug file structure.                             */
  570. /*   addr       address.                                                     */
  571. /*                                                                           */
  572. /* Return:                                                                   */
  573. /*   i          object number.                                               */
  574. /*                                                                           */
  575. /*************************************************************************115*/
  576. ushort
  577. MapAddrtoObjnum(DEBFILE *pdf , uint addr , uint *LoadAddr)
  578. {
  579.  OBJTABLEENTRY *te;                     /* -> to a object table entry.    115*/
  580.  uint           NumObjs;                /* number of table entries.       521*/
  581.  int            i;                      /*                                115*/
  582.  uint          *p;                      /*                                521*/
  583.                                         /*                                115*/
  584.   p=pdf->CodeObjs;
  585.   if (p == NULL)
  586.     return(0);
  587.   NumObjs = *p;
  588.   if ( NumObjs == 0 )
  589.     return(0);
  590.   te = (OBJTABLEENTRY *)++p;
  591.   for(i=1; i <= NumObjs; i++,te++ )
  592.   {
  593.      /************************************************************************/
  594.      /* search only the code objects                                      606*/
  595.      /************************************************************************/
  596.      if ( te->ObjType == CODE)                                          /*606*/
  597.      {
  598.         if( addr >= te->ObjLoadAddr &&
  599.            addr <  te->ObjLoadAddr + te->ObjLoadSize )
  600.         {
  601.            *LoadAddr = te->ObjLoadAddr;
  602.             return((ushort)i);
  603.         }
  604.      }
  605.   }
  606.   return(0);
  607. }                                       /* end MapAddrtoObjnum().        115*/
  608.  
  609. /*************************************************************************115*/
  610. /* MapFlatAddrToBase()                                                       */
  611. /*                                                                           */
  612. /* Description:                                                              */
  613. /*   Map a flat address to its 16:16 base.                                   */
  614. /*                                                                           */
  615. /* Parameters:                                                               */
  616. /*   pdf        pointer to debug file structure.                             */
  617. /*   addr       flat address in a 16 bit object.                             */
  618. /*   pLoadAddr  -> to receiver of flat load address.                         */
  619. /*   pSel       -> to receiver of 16 bit load selector.                      */
  620. /*   pOff       -> to receiver of 16 bit load offset.                        */
  621. /*                                                                           */
  622. /* Return:                                                                   */
  623. /*                                                                           */
  624. /*   0=>success                                                              */
  625. /*   1=>failure                                                              */
  626. /*                                                                           */
  627. /*************************************************************************115*/
  628. int  MapFlatAddrToBase(DEBFILE *pdf,
  629.                        ULONG    addr,
  630.                        ULONG   *pLoadAddr,
  631.                        USHORT  *pSel,
  632.                        USHORT  *pOff )
  633. {
  634.  OBJTABLEENTRY *te;
  635.  uint           NumObjs;
  636.  int            i;
  637.  uint          *p;
  638.  
  639.  p=pdf->CodeObjs;
  640.  if( (p == NULL) || ((NumObjs = *p) == 0) )
  641.   return(1);
  642.  
  643.  NumObjs = *p;
  644.  *pLoadAddr = 0;
  645.  *pSel      = 0;
  646.  *pOff      = 0;
  647.  te = (OBJTABLEENTRY *)++p;
  648.  for(i=1; i <= NumObjs; i++,te++ )
  649.  {
  650.   if((addr >= te->ObjLoadAddr) && (addr <  te->ObjLoadAddr + te->ObjLoadSize))
  651.   {
  652.    *pLoadAddr = te->ObjLoadAddr;
  653.    *pSel      = te->ObjLoadSel;
  654.    *pOff      = te->ObjLoadOff;
  655.    return(0);
  656.   }
  657.  }
  658.  return(1);
  659. }
  660.  
  661. /*****************************************************************************/
  662. /* MapSelOffToBase()                                                         */
  663. /*                                                                           */
  664. /* Description:                                                              */
  665. /*   Map a flat address to its 16:16 base.                                   */
  666. /*                                                                           */
  667. /* Parameters:                                                               */
  668. /*   pdf        pointer to debug file structure.                             */
  669. /*   Selector   16 bit selector.                                             */
  670. /*   Offset     16 offset.                                                   */
  671. /*   pLoadAddr  -> to receiver of flat load address.                         */
  672. /*   pLoadOff   -> to receiver of 16 bit load offset.                        */
  673. /*                                                                           */
  674. /* Return:                                                                   */
  675. /*                                                                           */
  676. /*   0=>success                                                              */
  677. /*   1=>failure                                                              */
  678. /*                                                                           */
  679. /*************************************************************************115*/
  680. int   MapSelOffToBase(DEBFILE *pdf,
  681.                       USHORT  Selector,
  682.                       USHORT  Offset,
  683.                       ULONG  *pLoadAddr,
  684.                       USHORT *pLoadOff)
  685. {
  686.  OBJTABLEENTRY *te;
  687.  uint           NumObjs;
  688.  int            i;
  689.  uint          *p;
  690.  
  691.  p=pdf->CodeObjs;
  692.  if( (p == NULL) || ((NumObjs = *p) == 0) )
  693.   return(1);
  694.  
  695.  NumObjs = *p;
  696.  *pLoadAddr = 0;
  697.  *pLoadOff  = 0;
  698.  te = (OBJTABLEENTRY *)++p;
  699.  for(i=1; i <= NumObjs; i++,te++ )
  700.  {
  701.   if( (Selector == te->ObjLoadSel ) )
  702.   {
  703.    USHORT LoOffset;
  704.    USHORT HiOffset;
  705.  
  706.    LoOffset = te->ObjLoadOff;
  707.    HiOffset = LoOffset + te->ObjLoadSize - 1;
  708.    if( (LoOffset <= Offset) && (Offset <= HiOffset) )
  709.    {
  710.     *pLoadAddr = te->ObjLoadAddr;
  711.     *pLoadOff  = te->ObjLoadOff;
  712.     return(0);
  713.    }
  714.   }
  715.  }
  716.  return(1);
  717. }
  718.  
  719. /*****************************************************************************/
  720. /* hexstr2higit()                                                            */
  721. /*                                                                           */
  722. /* Description:                                                              */
  723. /*   convert a string to higits.                                             */
  724. /*                                                                           */
  725. /* Parameters:                                                               */
  726. /*   cp         -> to string.                                                */
  727. /*   phigit     -> to higit buffer.                                          */
  728. /*                                                                           */
  729. /* Return:                                                                   */
  730. /*                                                                           */
  731. /* Assumptions:                                                              */
  732. /*                                                                           */
  733. /*  cp -> to a string of hex characters.                                     */
  734. /*                                                                           */
  735. /*****************************************************************************/
  736. void hexstr2higit( char *cp, char *phigit )
  737. {
  738.  char  c;
  739.  int   n = 1;
  740.  
  741.  while( (c=*cp++) != 0 )
  742.  {
  743.   if( '0'<=c && c<='9' )
  744.    c -= 0x30;
  745.   else
  746.    c -= 0x37;
  747.  
  748.   *phigit |= (c<<(n*4));
  749.   n = (n==1)?0:1;
  750.   phigit += n;
  751.  }
  752. }
  753.  
  754. /*****************************************************************************/
  755. /* GetCodebytes;                                                             */
  756. /*                                                                           */
  757. /* Description:                                                              */
  758. /*                                                                           */
  759. /*   gets n bytes of code from the app address space.                        */
  760. /*                                                                           */
  761. /* Parameters:                                                               */
  762. /*                                                                           */
  763. /*   address    pointer to address space in user's application.              */
  764. /*   nbytes     number of bytes to copy from the user's application.         */
  765. /*   totlptr    pointer to number of bytes that were read in.                */
  766. /*                                                                           */
  767. /* Return:                                                                   */
  768. /*                                                                           */
  769. /*   p          pointer to buffer that holds the bytes read in.              */
  770. /*                                                                           */
  771. /* Assumptions:                                                              */
  772. /*                                                                           */
  773. /*   address  is a flat address.                                             */
  774. /*                                                                           */
  775. /*****************************************************************************/
  776. static UCHAR *pCurrentBuffer = NULL;
  777. static ULONG HiAddr;
  778. static ULONG LoAddr;
  779. #define PAGESIZE 0x400
  780.  
  781. UCHAR* GetCodeBytes( ULONG address, UINT nbytes, UINT *totlptr  )
  782. {
  783.  APIRET         rc;
  784.  PtraceBuffer   ptb;
  785.  ULONG          LoObjectAddr;
  786.  ULONG          HiObjectAddr;
  787.  ULONG          ObjectSize;
  788.  ULONG          EndAddress;
  789.  ULONG          ReadAddr;
  790.  ULONG          ReadLen;
  791.  int            i;
  792.  UINT           NumCodeObjs;
  793.  UINT          *pObj;
  794.  OBJTABLEENTRY *te;
  795.  int            foundit = FALSE;
  796.  DEBFILE       *pdf;
  797.  int            twotries;
  798.  
  799.  for( twotries = 1; twotries <= 2; twotries++ )
  800.  {
  801.   /****************************************************************************/
  802.   /* - check to see if we already have the bytes cached.                      */
  803.   /****************************************************************************/
  804.   if( (address >= LoAddr) &&
  805.       ( (address + nbytes - 1) <= HiAddr )
  806.     )
  807.   {
  808.    *totlptr = nbytes;
  809.    return( pCurrentBuffer + (address - LoAddr) );
  810.   }
  811.   else
  812.   {
  813.    /****************************************************************************/
  814.    /* - at this point, we have to recache.                                     */
  815.    /* - get a ptr to the code object table entry that contains this address.   */
  816.    /****************************************************************************/
  817.    pdf = FindExeOrDllWithAddr( address );
  818.    if( pdf )
  819.    {
  820.     NumCodeObjs = *(pObj=pdf->CodeObjs);
  821.     te = (OBJTABLEENTRY *)++pObj;
  822.     for(i=1; (foundit == FALSE) && (i <= NumCodeObjs); i++,te++ )
  823.     {
  824.      if( (te->ObjType == CODE)     &&
  825.          (address >= te->ObjLoadAddr) &&
  826.          (address <  te->ObjLoadAddr + te->ObjLoadSize) )
  827.        {foundit=TRUE;break;}
  828.     }
  829.    }
  830.  
  831.    /****************************************************************************/
  832.    /*   if the read request spans the object then                              */
  833.    /*    cache the requested block.                                            */
  834.    /*   else if the object size is < a page size                               */
  835.    /*    cache the entire object.                                              */
  836.    /*   else if the requested block is near the bottom of the object           */
  837.    /*    cache a page at the botton of the object                              */
  838.    /*    ( we assume that the requested block is small enough to still be      */
  839.    /*      contained within a page after the start address for the read        */
  840.    /*      is adjusted to the object start address.)                           */
  841.    /*   else if the requested block is near the top of the page                */
  842.    /*    cache a page at the top of the object                                 */
  843.    /*   else if the requested block is in the "middle" of the object           */
  844.    /*    cache a page "around" the requested block.                            */
  845.    /*                                                                          */
  846.    /* At the time of this code, the largest read request block size was 300    */
  847.    /* bytes.                                                                   */
  848.    /****************************************************************************/
  849.    LoObjectAddr = te->ObjLoadAddr;
  850.    HiObjectAddr = te->ObjLoadAddr + te->ObjLoadSize - 1;
  851.    EndAddress   = address + nbytes -1;
  852.    ObjectSize   = te->ObjLoadSize;
  853.    ReadLen  = PAGESIZE;
  854.  
  855.    if( (foundit == FALSE) || (EndAddress > HiObjectAddr) )
  856.    {
  857.     ReadAddr = address;
  858.     ReadLen  = nbytes;
  859.    }
  860.    else if( ObjectSize <= PAGESIZE )
  861.    {
  862.     ReadAddr = te->ObjLoadAddr;
  863.     ReadLen  = te->ObjLoadSize;
  864.    }
  865.    else if( (address - LoObjectAddr + 1) <= PAGESIZE/2 )
  866.    {
  867.     ReadAddr = LoObjectAddr;
  868.    }
  869.    else if( (HiObjectAddr - address + 1) <= PAGESIZE/2 )
  870.    {
  871.     ReadAddr = HiObjectAddr - PAGESIZE + 1;
  872.    }
  873.    else
  874.    {
  875.     ReadAddr = address - PAGESIZE/2 + 1;
  876.    }
  877.  
  878.   /*****************************************************************************/
  879.   /* - Free the storage from the prevoius call.                                */
  880.   /* - Allocate the new storage block.                                         */
  881.   /* - Read in all the bytes if we can.                                        */
  882.   /* - If we can't, then try reading one at a time and return the number       */
  883.   /*   read.                                                                   */
  884.   /*                                                                           */
  885.   /*****************************************************************************/
  886.  
  887.    if ( pCurrentBuffer != NULL )
  888.      Tfree( (void*)pCurrentBuffer );
  889.    pCurrentBuffer = (UCHAR*)Talloc( ReadLen);
  890.  
  891.    *totlptr = 0;
  892.  
  893.    memset(&ptb,0,sizeof(ptb));
  894.    ptb.Pid    = DbgGetProcessID();
  895.    ptb.Cmd    = DBG_C_ReadMemBuf ;
  896.    ptb.Addr   = ReadAddr;
  897.    ptb.Buffer = (ULONG)pCurrentBuffer;
  898.    ptb.Len    = ReadLen;
  899.    rc = xDosDebug( &ptb );
  900.    *totlptr=ptb.Len;
  901.  
  902.    /***************************************************************************/
  903.    /* If not able to read the number of bytes asked for , try reading byte    */
  904.    /* by byte as many bytes as possible. This might be slow...                */
  905.    /***************************************************************************/
  906.    if(rc || ptb.Cmd != DBG_N_Success)
  907.    {
  908.     UINT ui;
  909.     *totlptr = 0;
  910.     for (ui = 0 ; ui < nbytes ; ui++)
  911.     {
  912.      memset(&ptb,0,sizeof(ptb));
  913.      ptb.Pid    = DbgGetProcessID();
  914.      ptb.Cmd    = DBG_C_ReadMemBuf ;
  915.      ptb.Addr   = address+ui;
  916.      ptb.Buffer = (ULONG)(pCurrentBuffer + ui);
  917.      ptb.Len    = 1;
  918.      rc = xDosDebug( &ptb );
  919.      if(rc || ptb.Cmd!=DBG_N_Success)
  920.          break;
  921.      (*totlptr)++;
  922.     }
  923.    }
  924.    LoAddr = ReadAddr;
  925.    HiAddr = LoAddr + *totlptr - 1;
  926.   }
  927.  }
  928.  /****************************************************************************/
  929.  /* - we were not able to read any bytes...address must be bogus.            */
  930.  /****************************************************************************/
  931.  return(NULL);
  932. }
  933.  
  934. /*****************************************************************************/
  935. /* GetDataBytes;                                                             */
  936. /*                                                                           */
  937. /* Description:                                                              */
  938. /*                                                                           */
  939. /*   gets n bytes of data from the app address space.                        */
  940. /*                                                                           */
  941. /* Parameters:                                                               */
  942. /*                                                                           */
  943. /*   address    pointer to address space in user's application.              */
  944. /*   nbytes     number of bytes to copy from the user's application.         */
  945. /*   totlptr    pointer to number of bytes that were read in.                */
  946. /*                                                                           */
  947. /* Return:                                                                   */
  948. /*                                                                           */
  949. /*   -> bytes requested or NULL.                                             */
  950. /*                                                                           */
  951. /* Assumptions:                                                              */
  952. /*                                                                           */
  953. /*   address  is a flat address.                                             */
  954. /*                                                                           */
  955. /*****************************************************************************/
  956. typedef struct _dblock
  957. {
  958.  struct _dblock *next;
  959.  ULONG           baseaddr;
  960.  int             size;
  961.  char           *pbytes;
  962. }DBLOCK;
  963.  
  964. static DBLOCK *pAllBlks = NULL;
  965.  
  966. extern int         DataRecalc;
  967.  
  968. UCHAR* GetDataBytes( ULONG address, UINT nbytes, UINT *totlptr  )
  969. {
  970.  DBLOCK       *pBlk;
  971.  DBLOCK       *pb;
  972.  ULONG         loaddr;
  973.  ULONG         hiaddr;
  974.  UCHAR        *pbytes;
  975.  int           BytesObtained;
  976.  
  977.  
  978.  /****************************************************************************/
  979.  /* - First filter out address = 0.                                          */
  980.  /****************************************************************************/
  981.  if( address == 0 )
  982.  {
  983.   *totlptr = 0;
  984.   return(NULL);
  985.  }
  986.  /****************************************************************************/
  987.  /* - refresh the memory blocks if necessary.                                */
  988.  /****************************************************************************/
  989.  if( DataRecalc == TRUE )
  990.  {
  991.   GetMemoryBlocks();
  992.   DataRecalc = FALSE;
  993.  }
  994.  
  995. rescan:
  996.  /****************************************************************************/
  997.  /* - scan the list of memory blocks and test for the address.               */
  998.  /****************************************************************************/
  999.  for( pBlk = pAllBlks; pBlk; pBlk=pBlk->next )
  1000.  {
  1001.   loaddr = pBlk->baseaddr;
  1002.   hiaddr = loaddr + pBlk->size - 1;     /* added the "-1"                    */
  1003.   if( (address >= loaddr) &&
  1004.       ( (address + nbytes - 1) >= loaddr ) && /* check for a wrap            */
  1005.       ( (address + nbytes - 1) <= hiaddr )
  1006.     )
  1007.   {
  1008.    *totlptr = nbytes;
  1009.    return( pBlk->pbytes + (address - loaddr) );
  1010.   }
  1011.  }
  1012.  
  1013.  /****************************************************************************/
  1014.  /* - Get the memory block.                                                  */
  1015.  /****************************************************************************/
  1016.  BytesObtained = 0;
  1017.  pbytes = xGetMemoryBlock( address, nbytes, &BytesObtained );
  1018.  if( pbytes && ( BytesObtained != 0 ) )
  1019.  {
  1020.   /***************************************************************************/
  1021.   /* - Scan the memory blocks and see if this block can be merged with       */
  1022.   /*   another block. This will help prevent fragmentation of the memory.    */
  1023.   /***************************************************************************/
  1024.   for( pBlk = pAllBlks; pBlk; pBlk=pBlk->next )
  1025.   {
  1026.    if( pBlk->baseaddr + pBlk->size == address )
  1027.    {
  1028.     UCHAR *pTemp;
  1029.     int    size;
  1030.  
  1031.     size = pBlk->size + BytesObtained;
  1032.  
  1033.     pTemp = Talloc( size );
  1034.     memcpy(pTemp,pBlk->pbytes,pBlk->size);
  1035.     memcpy(pTemp+pBlk->size,pbytes,BytesObtained);
  1036.     Tfree(pBlk->pbytes);
  1037.     pBlk->pbytes = pTemp;
  1038.     pBlk->size  = size;
  1039.     goto rescan;
  1040.    }
  1041.   }
  1042.   /***************************************************************************/
  1043.   /* - If we get here, then the block could not be merged and we have        */
  1044.   /*   to add to the chain. pBlk = NULL at this point.                       */
  1045.   /***************************************************************************/
  1046.   if( pBlk == NULL )
  1047.   {
  1048.    pBlk           = Talloc(sizeof(DBLOCK));
  1049.    pBlk->next     = NULL;
  1050.    pBlk->baseaddr = address;
  1051.    pBlk->size     = BytesObtained;
  1052.    pBlk->pbytes   = Talloc(BytesObtained);
  1053.    memcpy(pBlk->pbytes, pbytes , BytesObtained );
  1054.    for(pb = (DBLOCK*)&pAllBlks; pb->next; pb=pb->next){;}
  1055.    pb->next = pBlk;
  1056.  
  1057.    *totlptr = BytesObtained;
  1058.    return(pBlk->pbytes);
  1059.   }
  1060.  }
  1061.  /****************************************************************************/
  1062.  /* - return sadness.                                                       */
  1063.  /****************************************************************************/
  1064.  *totlptr = 0;
  1065.  return(NULL);
  1066. }
  1067.  
  1068. /*****************************************************************************/
  1069. /* GetMemoryBlocks()                                                         */
  1070. /*                                                                           */
  1071. /* Description:                                                              */
  1072. /*                                                                           */
  1073. /*   Get a refresh of the memory blocks currently being viewed.              */
  1074. /*                                                                           */
  1075. /* Parameters:                                                               */
  1076. /*                                                                           */
  1077. /* Return:                                                                   */
  1078. /*                                                                           */
  1079. /* Assumptions:                                                              */
  1080. /*                                                                           */
  1081. /*****************************************************************************/
  1082. void GetMemoryBlocks( void )
  1083. {
  1084.  typedef struct
  1085.  {
  1086.   ULONG addr;
  1087.   int   size;
  1088.  }MEM_BLK_DEF;
  1089.  
  1090.  MEM_BLK_DEF  *pDefBlks;
  1091.  MEM_BLK_DEF  *pd;
  1092.  DBLOCK       *pBlk;
  1093.  DBLOCK       *pnext;
  1094.  int           n;
  1095.  int           i;
  1096.  int           LengthOfDefBlk;
  1097.  
  1098.  typedef struct
  1099.  {
  1100.   ULONG addr;
  1101.   int   size;
  1102.   char  bytes[1];
  1103.  }MEM_BLKS;
  1104.  
  1105.  MEM_BLKS  *pMemBlks;
  1106.  MEM_BLKS  *pmblk;
  1107.  int        LengthOfMemBlks;
  1108.  DBLOCK    *pb;
  1109.  
  1110.  /****************************************************************************/
  1111.  /* - scan and get a count of the current number of blocks.                  */
  1112.  /****************************************************************************/
  1113.  n = 0;
  1114.  for(pBlk = pAllBlks; pBlk; pBlk=pBlk->next,n++){;}
  1115.  if( n == 0 )
  1116.   return;
  1117.  
  1118.  /****************************************************************************/
  1119.  /* - allocate the storage to contain the definitions of the memory blocks   */
  1120.  /*   and the total size of the memory blocks( including overhead ).         */
  1121.  /****************************************************************************/
  1122.  LengthOfDefBlk = (n+1)*sizeof(MEM_BLK_DEF);
  1123.  pd = pDefBlks = (MEM_BLK_DEF *)Talloc( sizeof(LengthOfMemBlks) +
  1124.                                                LengthOfDefBlk);
  1125.  /****************************************************************************/
  1126.  /* - bump past the field reserved for LengthOfMemBlks.                      */
  1127.  /****************************************************************************/
  1128.  pd = (MEM_BLK_DEF*)((char*)pd + sizeof(int));
  1129.  
  1130.  /****************************************************************************/
  1131.  /* - build an array of memory block definitions.                            */
  1132.  /* - terminate the blocks with a (NULL,0) entry.                            */
  1133.  /* - calculate the "expected" size of the return block.                     */
  1134.  /****************************************************************************/
  1135.  LengthOfMemBlks = 0;
  1136.  for(pBlk = pAllBlks; pBlk; pBlk=pBlk->next,pd++)
  1137.  {
  1138.   pd->addr = pBlk->baseaddr;
  1139.   pd->size = pBlk->size;
  1140.   LengthOfMemBlks += sizeof(MEM_BLK_DEF) + pd->size;
  1141.  }
  1142.  pd->addr = NULL;
  1143.  pd->size = 0;
  1144.  
  1145.  /****************************************************************************/
  1146.  /* - put in the total length of the memory blocks.                          */
  1147.  /****************************************************************************/
  1148.  *(int *)pDefBlks = LengthOfMemBlks;
  1149.  
  1150.  /****************************************************************************/
  1151.  /* - free the old chain.                                                    */
  1152.  /****************************************************************************/
  1153.  pnext = NULL;
  1154.  for(pBlk = pAllBlks; pBlk; pBlk=pnext,pd++)
  1155.  {
  1156.   if( pBlk->pbytes )
  1157.    Tfree(pBlk->pbytes);
  1158.   pnext = pBlk->next;
  1159.   Tfree( pBlk );
  1160.  }
  1161.  pAllBlks = NULL;
  1162.  
  1163.  /****************************************************************************/
  1164.  /* - Get the memory blocks.                                                 */
  1165.  /* - LengthOfMemBlks will contain the "expected" size of the new block      */
  1166.  /*   on the call and will contain the "real" size on return.                */
  1167.  /****************************************************************************/
  1168.  pmblk = pMemBlks = (MEM_BLKS *)xGetMemoryBlocks(pDefBlks, LengthOfDefBlk);
  1169.  
  1170.  /****************************************************************************/
  1171.  /* - free up the block definitions.                                         */
  1172.  /****************************************************************************/
  1173.  if( pDefBlks)
  1174.   Tfree(pDefBlks);
  1175.  
  1176.  /****************************************************************************/
  1177.  /* - Now build a new chain.                                                 */
  1178.  /****************************************************************************/
  1179.  pb = (DBLOCK*)&pAllBlks;
  1180.  for( i=0;i < n ; i++ )
  1181.  {
  1182.   pBlk           = Talloc(sizeof(DBLOCK));
  1183.   pBlk->next     = NULL;
  1184.   pBlk->baseaddr = pmblk->addr;
  1185.   pBlk->size     = pmblk->size;
  1186.   pBlk->pbytes   = Talloc(pBlk->size);
  1187.   memcpy(pBlk->pbytes,pmblk->bytes,pmblk->size);
  1188.  
  1189.   pb->next = pBlk;
  1190.   pb = pb->next;
  1191.   pmblk = (MEM_BLKS *)((UCHAR*)pmblk + sizeof(MEM_BLKS) - 1 + pmblk->size);
  1192.  }
  1193.  /****************************************************************************/
  1194.  /* - free the memory blocks.                                                */
  1195.  /****************************************************************************/
  1196.  if( pMemBlks )
  1197.   Tfree(pMemBlks);
  1198. }
  1199.  
  1200. void FreeMemBlks( void )
  1201. {
  1202.  DBLOCK       *pBlk;
  1203.  DBLOCK       *pBlkNext;
  1204.  
  1205.  for(pBlk = pAllBlks; pBlk != NULL; )
  1206.  {
  1207.   pBlkNext = pBlk->next;
  1208.   if(pBlk->pbytes) Tfree(pBlk->pbytes);
  1209.   Tfree( pBlk );
  1210.   pBlk = pBlkNext;
  1211.  }
  1212.  pAllBlks = NULL;
  1213. }
  1214.