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

  1. /*****************************************************************************
  2.  * 08/10/97 MVE  Modified for ExeLoader object
  3.  *
  4.  *$Log:    frontend.c,v $
  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. #include "ExeLoader.h"        // Loader object
  51.  
  52.  
  53. static void LoadImage(char *filename);
  54. static void displayLoadInfo(void);
  55. static void displayMemMap(void);
  56.  
  57.  
  58. static ExeLoader L;            // An instance of class ExeLoader
  59.  
  60.  
  61. /*****************************************************************************
  62.  * FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
  63.  * rewritter, and displays any useful information.
  64.  ****************************************************************************/
  65. void FrontEnd (char *filename, PCALL_GRAPH *pcallGraph)
  66. {
  67.     PPROC pProc;
  68.     PSYM psym;
  69.     Int    i, c;
  70.     
  71.     /* Load program into memory */
  72.     LoadImage(filename);
  73.  
  74.     if (option.verbose)
  75.     {
  76.         displayLoadInfo();
  77.     }
  78.     
  79.     /* Do depth first flow analysis building call graph and procedure list,
  80.      * and attaching the I-code to each procedure          */
  81.     parse (pcallGraph);
  82.  
  83.     if (option.asm1)
  84.     {
  85.         printf("dcc: writing assembler file %s\n", asm1_name);
  86.     }
  87.  
  88.     /* Search through code looking for impure references and flag them */
  89.     for (pProc = pProcList; pProc; pProc = pProc->next)
  90.     {
  91.         for (i = 0; i < pProc->Icode.GetNumIcodes(); i++)
  92.         {
  93.             if (pProc->Icode.GetLlFlag(i) & (SYM_USE | SYM_DEF))
  94.             {
  95.                 psym = &symtab.sym[pProc->Icode.GetIcode(i)->ic.ll.caseTbl.numEntries];
  96.                 for (c = (Int)psym->label; c < (Int)psym->label+psym->size; c++)
  97.                 {
  98.                     if (BITMAP(c, BM_CODE))
  99.                     {
  100.                         pProc->Icode.SetLlFlag(i, IMPURE);
  101.                         pProc->flg |= IMPURE;
  102.                         break;
  103.                     }
  104.                 }
  105.             }
  106.         }
  107.         /* Print assembler listing */
  108.         if (option.asm1)
  109.             disassem(1, pProc);
  110.     }
  111.  
  112.     if (option.Interact)
  113.     {
  114.         interactDis(pProcList, 0);            /* Interactive disassembler */
  115.     }
  116.  
  117.     /* Converts jump target addresses to icode offsets */
  118.     for (pProc = pProcList; pProc; pProc = pProc->next)
  119.         bindIcodeOff (pProc); 
  120.  
  121.     /* Print memory bitmap */
  122.     if (option.Map)
  123.         displayMemMap();
  124. }
  125.  
  126.  
  127. /****************************************************************************
  128.  * displayLoadInfo - Displays low level loader type info.
  129.  ***************************************************************************/
  130. static void displayLoadInfo()
  131. {
  132.     Int    i;
  133.     PSECTIONINFO pHdrScn = L.GetSectionInfoByName("$HEADER");
  134.     HEADER* pHeader = (HEADER*) pHdrScn->uHostAddr;
  135.  
  136.     printf("File type is %s\n", (prog.fCOM)?"COM":"EXE");
  137.     if (! prog.fCOM) {
  138.         printf("Signature            = %02X%02X\n", pHeader->sigLo, pHeader->sigHi);
  139.         printf("File size %% 512      = %04X\n", LH(&pHeader->lastPageSize));
  140.         printf("File size / 512      = %04X pages\n", LH(&pHeader->numPages));
  141.         printf("# relocation items   = %04X\n", LH(&pHeader->numReloc));
  142.         printf("Offset to load image = %04X paras\n", LH(&pHeader->numParaHeader));
  143.         printf("Minimum allocation   = %04X paras\n", LH(&pHeader->minAlloc));
  144.         printf("Maximum allocation   = %04X paras\n", LH(&pHeader->maxAlloc));
  145.     }
  146.     printf("Load image size      = %04X\n", prog.cbImage - sizeof(PSP));
  147.     printf("Initial SS:SP        = %04X:%04X\n", prog.initSS, prog.initSP);
  148.     printf("Initial CS:IP        = %04X:%04X\n", prog.initCS, prog.initIP);
  149.  
  150.     if (option.VeryVerbose && prog.cReloc)
  151.     {
  152.         printf("\nRelocation Table\n");
  153.         for (i = 0; i < prog.cReloc; i++)
  154.         {
  155.             printf("%06X -> [%04X]\n", prog.relocTable[i],
  156.                     LH(prog.Image + prog.relocTable[i]));
  157.         }
  158.     }
  159.     printf("\n");
  160. }
  161.  
  162.  
  163. /*****************************************************************************
  164.  * fill - Fills line for displayMemMap()
  165.  ****************************************************************************/
  166. static void fill(Int ip, char *bf)
  167. {
  168.     static byte type[4] = {'.', 'd', 'c', 'x'};
  169.     byte    i;
  170.  
  171.     for (i = 0; i < 16; i++, ip++)
  172.     {
  173.         *bf++ = ' ';
  174.         *bf++ = (ip < prog.cbImage)? 
  175.             type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' ';
  176.     }
  177.     *bf = '\0';
  178. }
  179.  
  180.  
  181. /*****************************************************************************
  182.  * displayMemMap - Displays the memory bitmap
  183.  ****************************************************************************/
  184. static void displayMemMap(void)
  185. {
  186.     char    c, b1[33], b2[33], b3[33];
  187.     byte i;
  188.     Int ip = 0;
  189.  
  190.     printf("\nMemory Map\n");
  191.     while (ip < prog.cbImage)
  192.     {
  193.         fill(ip, b1);
  194.         printf("%06X %s\n", ip, b1);
  195.         ip += 16;
  196.         for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2)
  197.             ;        /* Check if all same */
  198.         if (i > 32)
  199.         {
  200.             fill(ip, b2);    /* Skip until next two are not same */
  201.             fill(ip+16, b3);
  202.             if (! (strcmp(b1, b2) || strcmp(b1, b3)))
  203.             {
  204.                 printf("                   :\n");
  205.                 do
  206.                 {
  207.                     ip += 16;
  208.                     fill(ip+16, b1);
  209.                 } while (! strcmp(b1, b2));
  210.             }
  211.         }
  212.     }
  213.     printf("\n");
  214. }
  215.  
  216.  
  217. /*****************************************************************************
  218.  * LoadImage
  219.  ****************************************************************************/
  220. static void LoadImage(char *filename)
  221. {
  222.  
  223.     /* Open the input file */
  224.     if (L.Load(filename) == 0)
  225.     {
  226.         fatalError(CANNOT_OPEN, filename);
  227.     }
  228.  
  229.     PSECTIONINFO pSectHdr   = L.GetSectionInfoByName("$HEADER");
  230.     PSECTIONINFO pSectImage = L.GetSectionInfoByName(".text");
  231.     PSECTIONINFO pSectReloc = L.GetSectionInfoByName("$RELOC");
  232.     prog.Image = (byte*) pSectImage->uHostAddr;
  233.     prog.cbImage  = pSectImage->uSectionSize;
  234.  
  235.     char* pHeader = (char*)pSectHdr->uHostAddr;
  236.     if (prog.fCOM = (boolT)((pHeader[0] == 'M') && (pHeader[1] == 'Z')))
  237.     {
  238.         unsigned initPC = L.GetInitPC();
  239.         unsigned initSP = L.GetInitSP();
  240.         prog.initCS = initPC >> 16;
  241.         prog.initIP = initPC & 0xFFFF;
  242.         prog.initSS = initSP >> 16;
  243.         prog.initSP = initSP & 0xFFFF;
  244.  
  245.         // Relocation table
  246.         prog.cReloc = pSectReloc->uSectionSize / sizeof(dword);
  247.  
  248.         /* Allocate the relocation table */
  249.         if (prog.cReloc)
  250.         {
  251.             prog.relocTable = (dword*) pSectReloc->uHostAddr;
  252.         }
  253.     }
  254.     else
  255.     {    /* COM file
  256.  
  257.         /* COM programs start off with an ORG 100H (to leave room for a PSP)
  258.          * This is also the implied start address so if we load the image
  259.          * at offset 100H addresses should all line up properly again.
  260.         */
  261.         prog.initCS = 0;
  262.         prog.initIP = 0x100;
  263.         prog.initSS = 0;
  264.         prog.initSP = 0xFFFE;
  265.         prog.cReloc = 0;
  266.  
  267.     }
  268.  
  269.     /* Set up memory map */
  270.     int cb = (prog.cbImage + 3) / 4;
  271.     prog.map = (byte *)memset(allocMem(cb), BM_UNKNOWN, (size_t)cb);
  272.  
  273.     /* Note that relocation of the segment constants is done in the
  274.         ExeLoader object */
  275.  
  276.     // Don't UnLoad here, since prog.Image (etc) point to the loaded
  277.     // image in the ExeLoader object.    
  278. }
  279.  
  280. void UnLoadImage()
  281. {
  282.     L.UnLoad();
  283. }
  284.  
  285.  
  286.  
  287. /*****************************************************************************
  288.  * allocMem - malloc with failure test
  289.  ****************************************************************************/
  290. void *allocMem(Int cb)
  291. {
  292.     byte *p;
  293.  
  294. //printf("Attempt to allocMem %5ld bytes\n", cb);
  295.  
  296. #if 0        /* Microsoft specific heap debugging code */
  297. switch (_heapset('Z'))
  298. {
  299.     case _HEAPBADBEGIN: printf("aM: Bad heap begin\n"); break;
  300.     case _HEAPBADNODE:    printf("aM: Bad heap node\n");
  301.     printf("Attempt to allocMem %5d bytes\n", cb);
  302.     {
  303.         _HEAPINFO hinfo;
  304.         int heapstatus;
  305.         boolT cont = TRUE;
  306.  
  307.         hinfo._pentry = NULL;
  308.  
  309.         while (cont)
  310.         {
  311.             switch (heapstatus = _heapwalk(&hinfo))
  312.             {
  313.                 case _HEAPOK:
  314.                     printf("%6s block at %Fp of size %4.4X\n",
  315.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  316.                         hinfo._pentry, hinfo._size);
  317.                     break;
  318.                 case _HEAPBADBEGIN:
  319.                     printf("Heap bad begin\n");
  320.                     break;
  321.                 case _HEAPBADNODE:
  322.                     printf("BAD NODE %6s block at %Fp of size %4.4X\n",
  323.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  324.                         hinfo._pentry, hinfo._size);
  325.                     break;
  326.                 case _HEAPEND:
  327.                     cont = FALSE;
  328.                     break;
  329.                 case _HEAPBADPTR:
  330.                     printf("INFO BAD %6s block at %Fp of size %4.4X\n",
  331.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  332.                         hinfo._pentry, hinfo._size);
  333.                     cont=FALSE;
  334.  
  335.             }
  336.         }
  337.     }
  338.     getchar();
  339.     exit(1);
  340.  
  341.     case _HEAPEMPTY:    printf("aM: Heap empty\n");        getchar(); break;
  342.     case _HEAPOK:putchar('.');break;
  343. }
  344. #endif
  345.  
  346.     if (! (p = (byte*)malloc((size_t)cb)))
  347. /*    if (! (p = (byte*)calloc((size_t)cb, 1)))    */
  348.     {
  349.         fatalError(MALLOC_FAILED, cb);
  350.     }
  351. /*printf("allocMem: %p\n", p);/**/
  352.     return p;
  353. }
  354.  
  355.  
  356. /*****************************************************************************
  357.  * reallocVar - reallocs extra variable space
  358.  ****************************************************************************/
  359. void *reallocVar(void *p, Int newsize)
  360. {
  361. /*printf("Attempt to reallocVar %5d bytes\n", newsize);/**/
  362. #if 0
  363. switch (_heapset('Z'))
  364. {
  365.     case _HEAPBADBEGIN: printf("aV: Bad heap begin\n"); /*getchar()*/; break;
  366.     case _HEAPBADNODE:    printf("aV: Bad heap node\n");
  367.     printf("Attempt to reallocVar %5d bytes at %p\n", newsize, p);/**/
  368.     {
  369.         _HEAPINFO hinfo;
  370.         int heapstatus;
  371.         boolT cont = TRUE;
  372.  
  373.         hinfo._pentry = NULL;
  374.  
  375.         while (cont)
  376.         {
  377.             switch (heapstatus = _heapwalk(&hinfo))
  378.             {
  379.                 case _HEAPOK:
  380.                     printf("%6s block at %Fp of size %4.4X\n",
  381.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  382.                         hinfo._pentry, hinfo._size);
  383.                     break;
  384.                 case _HEAPBADBEGIN:
  385.                     printf("Heap bad begin\n");
  386.                     break;
  387.                 case _HEAPBADNODE:
  388.                     printf("BAD NODE %6s block at %Fp of size %4.4X\n",
  389.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  390.                         hinfo._pentry, hinfo._size);
  391.                     break;
  392.                 case _HEAPEND:
  393.                     cont = FALSE;
  394.                     break;
  395.                 case _HEAPBADPTR:
  396.                     printf("INFO BAD %6s block at %Fp of size %4.4X\n",
  397.                         (hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
  398.                         hinfo._pentry, hinfo._size);
  399.                     cont=FALSE;
  400.  
  401.             }
  402.         }
  403.     }
  404.     getchar();
  405.     break;
  406.  
  407.     case _HEAPEMPTY:    printf("aV: Heap empty\n");        getchar(); break;
  408.     case _HEAPOK:putchar('!');break;
  409. }
  410. #endif
  411.  
  412.     void* newp;
  413.     if (! (newp = realloc((byte *)p, (size_t)newsize)))
  414.     {
  415.         fatalError(MALLOC_FAILED, newsize);
  416.     }
  417.     if (p && (newp != p) && option.verbose)
  418.     {
  419.         printf("Warning! realloc of %d bytes moved from %p to %p\n",
  420.             newsize, p, newp);
  421.     }
  422.  
  423. /*printf("reallocVar: %p\n", newp);/**/
  424.     return newp;
  425. }
  426.  
  427. #if 0
  428. void free(void *p)
  429. {
  430.     _ffree(p);
  431. switch (_heapset('Z'))
  432. {
  433.     case _HEAPBADBEGIN: printf("f: Bad heap begin\n"); getchar(); break;
  434.     case _HEAPBADNODE:    printf("f: Bad heap node\n");  getchar(); break;
  435.     case _HEAPEMPTY:    printf("f: Heap empty\n");        getchar(); break;
  436.     case _HEAPOK:putchar('!');break;
  437. }/**/
  438. }
  439. #endif
  440.  
  441.