home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dosdisas.zip / dccsrcoo.zip / frontend.cpp < prev    next >
C/C++ Source or Header  |  1997-10-14  |  18KB  |  653 lines

  1. /*****************************************************************************
  2.  *$Log:    frontend.c,v $
  3.  * 14/10/97 MVE Modified for ExeLoader object (if -DLOADER used)
  4.  *
  5.  * Revision 2.12  94/02/22  15:16:17  cifuente
  6.  * Code generation is done.
  7.  * ,.
  8.  * 
  9.  * Revision 2.11  93/12/08  16:58:34  cifuente
  10.  * FrontEnd is a void function now.
  11.  * 
  12.  * Revision 2.10  93/11/18  11:39:32  emmerik
  13.  * Extra parameter to interactDis()
  14.  * 
  15.  * Revision 2.9  93/11/17  16:28:38  cifuente
  16.  * Call graph references
  17.  * 
  18.  * Revision 2.8  93/10/20  14:39:09  cifuente
  19.  * New level of indirection for icode array (Icode.icode[])
  20.  * 
  21.  * Revision 2.7  93/10/11  11:37:33  cifuente
  22.  * First walk of HIGH_LEVEL icodes.
  23.  * 
  24.  * Revision 2.6  93/10/01  08:59:28  cifuente
  25.  * boolT type - for compilation under unix SVR4.2
  26.  * 
  27.  * Revision 2.5  93/09/29  10:46:38  cifuente
  28.  * LOW_LEVEL and HIGH_LEVEL icode definitions.  Increases llIcode indirection
  29.  * by 2 levels.
  30.  * 
  31.  * Revision 2.3  93/08/23  12:15:26  cifuente
  32.  * Interactive mode with curses
  33.  * 
  34.  * Revision 2.1  93/03/30  14:51:09  cifuente
  35.  * Compiled with gcc.
  36.  * 
  37.  *            RevComp project Front End module
  38.  * Loads a program into simulated main memory and builds the procedure list.
  39.  ****************************************************************************/
  40.  
  41. #include "dcc.h"
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #ifdef __BORLAND__
  46. #include <alloc.h>
  47. #else
  48. #include <malloc.h>            /* For malloc, free, realloc */
  49. #endif
  50. #ifdef LOADER
  51. #include "ExeLoader.h"
  52. static ExeLoader L;            // An instance of class ExeLoader
  53. #else
  54.  
  55. typedef struct {            /*        PSP structure                    */
  56.     word int20h;            /* interrupt 20h                        */
  57.     word eof;                /* segment, end of allocation block        */
  58.     byte res1;                /* reserved                             */
  59.     byte dosDisp[5];        /* far call to DOS function dispatcher    */
  60.     byte int22h[4];            /* vector for terminate routine            */
  61.     byte int23h[4];            /* vector for ctrl+break routine        */
  62.     byte int24h[4];            /* vector for error routine                */
  63.     byte res2[22];            /* reserved                                */
  64.     word segEnv;            /* segment address of environment block    */
  65.     byte res3[34];            /* reserved                                */
  66.     byte int21h[6];            /* opcode for int21h and far return        */
  67.     byte res4[6];            /* reserved                                */
  68.     byte fcb1[16];            /* default file control block 1            */
  69.     byte fcb2[16];          /* default file control block 2            */
  70.     byte res5[4];            /* reserved                                */
  71.     byte cmdTail[0x80];        /* command tail and disk transfer area    */
  72. } PSP;
  73.  
  74. typedef struct {            /*      EXE file header              */
  75.      byte    sigLo;            /* .EXE signature: 0x4D 0x5A     */
  76.      byte    sigHi;
  77.      word    lastPageSize;    /* Size of the last page         */
  78.      word    numPages;        /* Number of pages in the file     */
  79.      word    numReloc;        /* Number of relocation items     */
  80.      word    numParaHeader;    /* # of paragraphs in the header */
  81.      word    minAlloc;        /* Minimum number of paragraphs     */
  82.      word    maxAlloc;        /* Maximum number of paragraphs     */
  83.      word    initSS;            /* Segment displacement of stack */
  84.      word    initSP;            /* Contents of SP at entry       */
  85.      word    checkSum;        /* Complemented checksum         */
  86.      word    initIP;            /* Contents of IP at entry       */
  87.      word    initCS;            /* Segment displacement of code  */
  88.      word    relocTabOffset;    /* Relocation table offset       */
  89.      word    overlayNum;        /* Overlay number                */
  90. } HEADER;
  91. static HEADER header;
  92.  
  93. #define EXE_RELOCATION  0x10        /* EXE images rellocated to above PSP */
  94.  
  95. #endif    /* ifdef LOADER */
  96.  
  97.  
  98. static void LoadImage(char *filename);
  99. static void displayLoadInfo(HEADER* pHeader);
  100. static void displayMemMap(void);
  101.  
  102. /*****************************************************************************
  103.  * FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
  104.  * rewritter, and displays any useful information.
  105.  ****************************************************************************/
  106. void FrontEnd (char *filename, PCALL_GRAPH *pcallGraph)
  107. {
  108.     PPROC pProc;
  109.     PSYM psym;
  110.     Int    i, c;
  111.     
  112.     /* Load program into memory */
  113.     LoadImage(filename);
  114.  
  115.     if (option.verbose)
  116.     {
  117.         #ifdef LOADER
  118.             PSECTIONINFO pHdrScn = L.GetSectionInfoByName("$HEADER");
  119.             HEADER* pHeader = (HEADER*) pHdrScn->uHostAddr;
  120.             displayLoadInfo(pHeader);
  121.         #else
  122.             displayLoadInfo(&header);
  123.         #endif
  124.     }
  125.  
  126.     /* Do depth first flow analysis building call graph and procedure list,
  127.      * and attaching the I-code to each procedure          */
  128.     parse (pcallGraph);
  129.  
  130.     if (option.asm1)
  131.     {
  132.         printf("dcc: writing assembler file %s\n", asm1_name);
  133.     }
  134.  
  135.     /* Search through code looking for impure references and flag them */
  136.     for (pProc = pProcList; pProc; pProc = pProc->next)
  137.     {
  138.         for (i = 0; i < pProc->Icode.GetNumIcodes(); i++)
  139.         {
  140.             if (pProc->Icode.GetLlFlag(i) & (SYM_USE | SYM_DEF))
  141.             {
  142.                 psym = &symtab.sym[pProc->Icode.GetIcode(i)->ic.ll.caseTbl.numEntries];
  143.                 for (c = (Int)psym->label; c < (Int)psym->label+psym->size; c++)
  144.                 {
  145.                     if (BITMAP(c, BM_CODE))
  146.                     {
  147.                         pProc->Icode.SetLlFlag(i, IMPURE);
  148.                         pProc->flg |= IMPURE;
  149.                         break;
  150.                     }
  151.                 }
  152.             }
  153.         }
  154.         /* Print assembler listing */
  155.         if (option.asm1)
  156.             disassem(1, pProc);
  157.     }
  158.  
  159.     if (option.Interact)
  160.     {
  161.         interactDis(pProcList, 0);            /* Interactive disassembler */
  162.     }
  163.  
  164.     /* Converts jump target addresses to icode offsets */
  165.     for (pProc = pProcList; pProc; pProc = pProc->next)
  166.         bindIcodeOff (pProc); 
  167.  
  168.     /* Print memory bitmap */
  169.     if (option.Map)
  170.         displayMemMap();
  171. }
  172.  
  173.  
  174. /****************************************************************************
  175.  * displayLoadInfo - Displays low level loader type info.
  176.  ***************************************************************************/
  177. static void displayLoadInfo(HEADER* pHeader)
  178. {
  179.     Int    i;
  180.  
  181.     printf("File type is %s\n", (prog.fCOM)?"COM":"EXE");
  182.     if (! prog.fCOM) {
  183.         printf("Signature            = %02X%02X\n", pHeader->sigLo, pHeader->sigHi);
  184.         printf("File size %% 512      = %04X\n", LH(&pHeader->lastPageSize));
  185.         printf("File size / 512      = %04X pages\n", LH(&pHeader->numPages));
  186.         printf("# relocation items   = %04X\n", LH(&pHeader->numReloc));
  187.         printf("Offset to load image = %04X paras\n", LH(&pHeader->numParaHeader));
  188.         printf("Minimum allocation   = %04X paras\n", LH(&pHeader->minAlloc));
  189.         printf("Maximum allocation   = %04X paras\n", LH(&pHeader->maxAlloc));
  190.     }
  191.     printf("Load image size      = %04X\n", prog.cbImage - sizeof(PSP));
  192.     printf("Initial SS:SP        = %04X:%04X\n", prog.initSS, prog.initSP);
  193.     printf("Initial CS:IP        = %04X:%04X\n", prog.initCS, prog.initIP);
  194.  
  195.     if (option.VeryVerbose && prog.cReloc)
  196.     {
  197.         printf("\nRelocation Table\n");
  198.         for (i = 0; i < prog.cReloc; i++)
  199.         {
  200.             printf("%06X -> [%04X]\n", prog.relocTable[i],
  201.                     LH(prog.Image + prog.relocTable[i]));
  202.         }
  203.     }
  204.     printf("\n");
  205. }
  206.  
  207. #if 0
  208. static void displayLoadInfo(void)
  209. {
  210.     Int    i;
  211.  
  212.     printf("File type is %s\n", (prog.fCOM)?"COM":"EXE");
  213.     if (! prog.fCOM) {
  214.         printf("Signature            = %02X%02X\n", header.sigLo, header.sigHi);
  215.         printf("File size %% 512      = %04X\n", LH(&header.lastPageSize));
  216.         printf("File size / 512      = %04X pages\n", LH(&header.numPages));
  217.         printf("# relocation items   = %04X\n", LH(&header.numReloc));
  218.         printf("Offset to load image = %04X paras\n", LH(&header.numParaHeader));
  219.         printf("Minimum allocation   = %04X paras\n", LH(&header.minAlloc));
  220.         printf("Maximum allocation   = %04X paras\n", LH(&header.maxAlloc));
  221.     }
  222.     printf("Load image size      = %04X\n", prog.cbImage - sizeof(PSP));
  223.     printf("Initial SS:SP        = %04X:%04X\n", prog.initSS, prog.initSP);
  224.     printf("Initial CS:IP        = %04X:%04X\n", prog.initCS, prog.initIP);
  225.  
  226.     if (option.VeryVerbose && prog.cReloc)
  227.     {
  228.         printf("\nRelocation Table\n");
  229.         for (i = 0; i < prog.cReloc; i++)
  230.         {
  231.             printf("%06X -> [%04X]\n", prog.relocTable[i],
  232.                     LH(prog.Image + prog.relocTable[i]));
  233.         }
  234.     }
  235.     printf("\n");
  236. }
  237. #endif
  238.  
  239. /*****************************************************************************
  240.  * fill - Fills line for displayMemMap()
  241.  ****************************************************************************/
  242. static void fill(Int ip, char *bf)
  243. {
  244.     static byte type[4] = {'.', 'd', 'c', 'x'};
  245.     byte    i;
  246.  
  247.     for (i = 0; i < 16; i++, ip++)
  248.     {
  249.         *bf++ = ' ';
  250.         *bf++ = (ip < prog.cbImage)? 
  251.             type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' ';
  252.     }
  253.     *bf = '\0';
  254. }
  255.  
  256.  
  257. /*****************************************************************************
  258.  * displayMemMap - Displays the memory bitmap
  259.  ****************************************************************************/
  260. static void displayMemMap(void)
  261. {
  262.     char    c, b1[33], b2[33], b3[33];
  263.     byte i;
  264.     Int ip = 0;
  265.  
  266.     printf("\nMemory Map\n");
  267.     while (ip < prog.cbImage)
  268.     {
  269.         fill(ip, b1);
  270.         printf("%06X %s\n", ip, b1);
  271.         ip += 16;
  272.         for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2)
  273.             ;        /* Check if all same */
  274.         if (i > 32)
  275.         {
  276.             fill(ip, b2);    /* Skip until next two are not same */
  277.             fill(ip+16, b3);
  278.             if (! (strcmp(b1, b2) || strcmp(b1, b3)))
  279.             {
  280.                 printf("                   :\n");
  281.                 do
  282.                 {
  283.                     ip += 16;
  284.                     fill(ip+16, b1);
  285.                 } while (! strcmp(b1, b2));
  286.             }
  287.         }
  288.     }
  289.     printf("\n");
  290. }
  291.  
  292.  
  293. /*****************************************************************************
  294.  * LoadImage
  295.  ****************************************************************************/
  296. #ifdef LOADER
  297. static void LoadImage(char *filename)
  298. {
  299.  
  300.     /* Open the input file */
  301.     if (L.Load(filename) == 0)
  302.     {
  303.         fatalError(CANNOT_OPEN, filename);
  304.     }
  305.  
  306.     PSECTIONINFO pSectHdr   = L.GetSectionInfoByName("$HEADER");
  307.     PSECTIONINFO pSectImage = L.GetSectionInfoByName(".text");
  308.     PSECTIONINFO pSectReloc = L.GetSectionInfoByName("$RELOC");
  309.     prog.Image = (byte*) pSectImage->uHostAddr;
  310.     prog.cbImage  = pSectImage->uSectionSize;
  311.  
  312.     char* pHeader = (char*)pSectHdr->uHostAddr;
  313.     if (prog.fCOM = (boolT)((pHeader[0] == 'M') && (pHeader[1] == 'Z')))
  314.     {
  315.         unsigned initPC = L.GetInitPC();
  316.         unsigned initSP = L.GetInitSP();
  317.         prog.initCS = initPC >> 16;
  318.         prog.initIP = initPC & 0xFFFF;
  319.         prog.initSS = initSP >> 16;
  320.         prog.initSP = initSP & 0xFFFF;
  321.  
  322.         // Relocation table
  323.         prog.cReloc = pSectReloc->uSectionSize / sizeof(dword);
  324.  
  325.         /* Allocate the relocation table */
  326.         if (prog.cReloc)
  327.         {
  328.             prog.relocTable = (dword*) pSectReloc->uHostAddr;
  329.         }
  330.     }
  331.     else
  332.     {    /* COM file
  333.  
  334.         /* COM programs start off with an ORG 100H (to leave room for a PSP)
  335.          * This is also the implied start address so if we load the image
  336.          * at offset 100H addresses should all line up properly again.
  337.         */
  338.         prog.initCS = 0;
  339.         prog.initIP = 0x100;
  340.         prog.initSS = 0;
  341.         prog.initSP = 0xFFFE;
  342.         prog.cReloc = 0;
  343.  
  344.     }
  345.  
  346.     /* Set up memory map */
  347.     int cb = (prog.cbImage + 3) / 4;
  348.     prog.map = (byte *)memset(allocMem(cb), BM_UNKNOWN, (size_t)cb);
  349.  
  350.     /* Note that relocation of the segment constants is done in the
  351.         ExeLoader object */
  352.  
  353.     // Don't UnLoad here, since prog.Image (etc) point to the loaded
  354.     // image in the ExeLoader object.    
  355. }
  356.  
  357. void UnLoadImage()
  358. {
  359.     L.UnLoad();
  360. }
  361.  
  362. #else    // Old loader
  363.  
  364. static void LoadImage(char *filename)
  365. {
  366.     FILE   *fp;
  367.     Int        i, cb;
  368.     byte    buf[4];
  369.  
  370.     /* Open the input file */
  371.     if ((fp = fopen(filename, "rb")) == NULL)
  372.     {
  373.         fatalError(CANNOT_OPEN, filename);
  374.     }
  375.  
  376.     /* Read in first 2 bytes to check EXE signature */
  377.     if (fread(&header, 1, 2, fp) != 2)
  378.     {
  379.         fatalError(CANNOT_READ, filename);
  380.     }
  381.  
  382.     if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
  383.         /* Read rest of header */
  384.         fseek(fp, 0, SEEK_SET);
  385.         if (fread(&header, sizeof(header), 1, fp) != 1)
  386.         {
  387.             fatalError(CANNOT_READ, filename);
  388.         }
  389.  
  390.         /* This is a typical DOS kludge! */
  391.         if (LH(&header.relocTabOffset) == 0x40)
  392.         {
  393.             fatalError(NEWEXE_FORMAT);
  394.         }
  395.  
  396.         /* Calculate the load module size.
  397.          * This is the number of pages in the file
  398.          * less the length of the header and reloc table
  399.          * less the number of bytes unused on last page
  400.         */
  401.         cb = (dword)LH(&header.numPages) * 512 - (dword)LH(&header.numParaHeader) * 16;
  402.         if (header.lastPageSize)
  403.         {
  404.             cb -= 512 - LH(&header.lastPageSize);
  405.         }
  406.         
  407.         /* We quietly ignore minAlloc and maxAlloc since for our
  408.          * purposes it doesn't really matter where in real memory
  409.          * the program would end up.  EXE programs can't really rely on
  410.          * their load location so setting the PSP segment to 0 is fine.
  411.          * Certainly programs that prod around in DOS or BIOS are going
  412.          * to have to load DS from a constant so it'll be pretty 
  413.          * obvious.
  414.         */
  415.         prog.initCS = (int16)LH(&header.initCS) + EXE_RELOCATION;
  416.         prog.initIP = (int16)LH(&header.initIP);
  417.         prog.initSS = (int16)LH(&header.initSS) + EXE_RELOCATION;
  418.         prog.initSP = (int16)LH(&header.initSP);
  419.         prog.cReloc = (int16)LH(&header.numReloc);
  420.  
  421.         /* Allocate the relocation table */
  422.         if (prog.cReloc)
  423.         {
  424.             prog.relocTable = (dword*)allocMem(prog.cReloc * sizeof(Int));
  425.             fseek(fp, LH(&header.relocTabOffset), SEEK_SET);
  426.  
  427.             /* Read in seg:offset pairs and convert to Image ptrs */
  428.             for (i = 0; i < prog.cReloc; i++)
  429.             {
  430.                 fread(buf, 1, 4, fp);
  431.                 prog.relocTable[i] = LH(buf) + 
  432.                     (((Int)LH(buf+2) + EXE_RELOCATION)<<4);
  433.             }
  434.         }
  435.         /* Seek to start of image */
  436.         fseek(fp, (Int)LH(&header.numParaHeader) * 16, SEEK_SET);
  437.     }
  438.     else
  439.     {    /* COM file
  440.          * In this case the load module size is just the file length
  441.         */
  442.         fseek(fp, 0, SEEK_END);
  443.         cb = ftell(fp);
  444.  
  445.         /* COM programs start off with an ORG 100H (to leave room for a PSP)
  446.          * This is also the implied start address so if we load the image
  447.          * at offset 100H addresses should all line up properly again.
  448.         */
  449.         prog.initCS = 0;
  450.         prog.initIP = 0x100;
  451.         prog.initSS = 0;
  452.         prog.initSP = 0xFFFEU;
  453.         prog.cReloc = 0;
  454.  
  455.         fseek(fp, 0, SEEK_SET);
  456.     }
  457.  
  458.     /* Allocate a block of memory for the program. */
  459.     prog.cbImage  = cb + sizeof(PSP);
  460.     prog.Image    = (byte*)allocMem(prog.cbImage);
  461.     prog.Image[0] = 0xCD;        /* Fill in PSP Int 20h location */
  462.     prog.Image[1] = 0x20;        /* for termination checking     */
  463.  
  464.     /* Read in the image past where a PSP would go */
  465. #ifdef __DOSWIN__
  466.     if (cb > 0xFFFF)
  467.     {
  468.         printf("Image size of %ld bytes too large for fread!\n", cb);
  469.         fatalError(CANNOT_READ, filename);
  470.     }
  471. #endif
  472.     if (cb != (Int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp))
  473.     {
  474.         fatalError(CANNOT_READ, filename);
  475.     }
  476.  
  477.     /* Set up memory map */
  478.     cb = (prog.cbImage + 3) / 4;
  479.     prog.map = (byte *)memset(allocMem(cb), BM_UNKNOWN, (size_t)cb);
  480.  
  481.     /* Relocate segment constants */
  482.     if (prog.cReloc)
  483.     {
  484.         for (i = 0; i < prog.cReloc; i++)
  485.         {
  486.             byte *p = &prog.Image[prog.relocTable[i]];
  487.             word  w = (word)LH(p) + EXE_RELOCATION;
  488.             *p++    = (byte)(w & 0x00FF);
  489.             *p      = (byte)((w & 0xFF00) >> 8);
  490.         }
  491.     }
  492.  
  493.     fclose(fp);
  494. }
  495.  
  496. #endif        // ifdef LOADER
  497.  
  498.  
  499. /*****************************************************************************
  500.  * allocMem - malloc with failure test
  501.  ****************************************************************************/
  502. void *allocMem(Int cb)
  503. {
  504.     byte *p;
  505.  
  506. //printf("Attempt to allocMem %5ld bytes\n", cb);
  507.  
  508. #if 0        /* Microsoft specific heap debugging code */
  509. switch (_heapset('Z'))
  510. {
  511.     case _HEAPBADBEGIN: printf("aM: Bad heap begin\n"); break;
  512.     case _HEAPBADNODE:    printf("aM: Bad heap node\n");
  513.     printf("Attempt to allocMem %5d bytes\n", cb);
  514.     {
  515.         _HEAPINFO hinfo;
  516.         int heapstatus;
  517.         boolT cont = TRUE;
  518.  
  519.         hinfo._pentry = NULL;
  520.  
  521.         while (cont)
  522.         {
  523.             switch (heapstatus = _heapwalk(&hinfo))
  524.             {
  525.                 case _HEAPOK:
  526.                     printf("%6s block at %Fp of size %4.4X\n",
  527.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  528.                         hinfo._pentry, hinfo._size);
  529.                     break;
  530.                 case _HEAPBADBEGIN:
  531.                     printf("Heap bad begin\n");
  532.                     break;
  533.                 case _HEAPBADNODE:
  534.                     printf("BAD NODE %6s block at %Fp of size %4.4X\n",
  535.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  536.                         hinfo._pentry, hinfo._size);
  537.                     break;
  538.                 case _HEAPEND:
  539.                     cont = FALSE;
  540.                     break;
  541.                 case _HEAPBADPTR:
  542.                     printf("INFO BAD %6s block at %Fp of size %4.4X\n",
  543.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  544.                         hinfo._pentry, hinfo._size);
  545.                     cont=FALSE;
  546.  
  547.             }
  548.         }
  549.     }
  550.     getchar();
  551.     exit(1);
  552.  
  553.     case _HEAPEMPTY:    printf("aM: Heap empty\n");        getchar(); break;
  554.     case _HEAPOK:putchar('.');break;
  555. }
  556. #endif
  557.  
  558.     if (! (p = (byte*)malloc((size_t)cb)))
  559. /*    if (! (p = (byte*)calloc((size_t)cb, 1)))    */
  560.     {
  561.         fatalError(MALLOC_FAILED, cb);
  562.     }
  563. /*printf("allocMem: %p\n", p);/**/
  564.     return p;
  565. }
  566.  
  567.  
  568. /*****************************************************************************
  569.  * reallocVar - reallocs extra variable space
  570.  ****************************************************************************/
  571. void *reallocVar(void *p, Int newsize)
  572. {
  573. /*printf("Attempt to reallocVar %5d bytes\n", newsize);/**/
  574. #if 0
  575. switch (_heapset('Z'))
  576. {
  577.     case _HEAPBADBEGIN: printf("aV: Bad heap begin\n"); /*getchar()*/; break;
  578.     case _HEAPBADNODE:    printf("aV: Bad heap node\n");
  579.     printf("Attempt to reallocVar %5d bytes at %p\n", newsize, p);/**/
  580.     {
  581.         _HEAPINFO hinfo;
  582.         int heapstatus;
  583.         boolT cont = TRUE;
  584.  
  585.         hinfo._pentry = NULL;
  586.  
  587.         while (cont)
  588.         {
  589.             switch (heapstatus = _heapwalk(&hinfo))
  590.             {
  591.                 case _HEAPOK:
  592.                     printf("%6s block at %Fp of size %4.4X\n",
  593.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  594.                         hinfo._pentry, hinfo._size);
  595.                     break;
  596.                 case _HEAPBADBEGIN:
  597.                     printf("Heap bad begin\n");
  598.                     break;
  599.                 case _HEAPBADNODE:
  600.                     printf("BAD NODE %6s block at %Fp of size %4.4X\n",
  601.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  602.                         hinfo._pentry, hinfo._size);
  603.                     break;
  604.                 case _HEAPEND:
  605.                     cont = FALSE;
  606.                     break;
  607.                 case _HEAPBADPTR:
  608.                     printf("INFO BAD %6s block at %Fp of size %4.4X\n",
  609.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  610.                         hinfo._pentry, hinfo._size);
  611.                     cont=FALSE;
  612.  
  613.             }
  614.         }
  615.     }
  616.     getchar();
  617.     break;
  618.  
  619.     case _HEAPEMPTY:    printf("aV: Heap empty\n");        getchar(); break;
  620.     case _HEAPOK:putchar('!');break;
  621. }
  622. #endif
  623.  
  624.     void* newp;
  625.     if (! (newp = realloc((byte *)p, (size_t)newsize)))
  626.     {
  627.         fatalError(MALLOC_FAILED, newsize);
  628.     }
  629.     if (p && (newp != p) && option.verbose)
  630.     {
  631.         printf("Warning! realloc of %d bytes moved from %p to %p\n",
  632.             newsize, p, newp);
  633.     }
  634.  
  635. /*printf("reallocVar: %p\n", newp);/**/
  636.     return newp;
  637. }
  638.  
  639. #if 0
  640. void free(void *p)
  641. {
  642.     _ffree(p);
  643. switch (_heapset('Z'))
  644. {
  645.     case _HEAPBADBEGIN: printf("f: Bad heap begin\n"); getchar(); break;
  646.     case _HEAPBADNODE:    printf("f: Bad heap node\n");  getchar(); break;
  647.     case _HEAPEMPTY:    printf("f: Heap empty\n");        getchar(); break;
  648.     case _HEAPOK:putchar('!');break;
  649. }/**/
  650. }
  651. #endif
  652.  
  653.