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

  1. /*****************************************************************************
  2.  *$Log:    dcc.c,v $
  3.  * 14/10/97 MVE Added UnLoadImage() if using the ExeLoader object
  4.  *
  5.  * Revision 1.9  94/02/22  15:15:19  cifuente
  6.  * Code generation done.
  7.  * 
  8.  * Revision 1.8  93/12/03  09:39:37  cifuente
  9.  * FrontEnd() doesn't return a PPROC any more, uses global pProcList.
  10.  * 
  11.  * Revision 1.7  93/11/18  15:29:30  cifuente
  12.  * pLastProc: pointer to last procedure in pProcList.  Equivalent
  13.  * to reverse invocation order of the call graph.
  14.  * 
  15.  * Revision 1.6  93/11/17  16:28:58  cifuente
  16.  * Call graph references
  17.  * 
  18.  * Revision 1.5  93/10/11  11:35:32  cifuente
  19.  * First walk through HIGH_LEVEL icodes.
  20.  * Does not invoke code generator.
  21.  * 
  22.  * Revision 1.4  93/09/20  11:49:47  cifuente
  23.  * Changed tabs to spaces
  24.  * 
  25.  * Revision 1.3  93/09/17  08:35:15  cifuente
  26.  * Moved pProclist to a global
  27.  * Removed heap check code
  28.  * 
  29.  * Revision 1.2  93/08/23  12:14:57  cifuente
  30.  * Interactive mode with curses
  31.  * 
  32.  * Revision 2.1  93/03/30  14:54:52  cifuente
  33.  * Compiled with gcc.
  34.  * 
  35.  *              dcc decompiler  
  36.  * Reads the command line switches and then executes each major section in turn
  37.  ****************************************************************************/
  38.  
  39.  
  40. #include "dcc.h"
  41. #include <string.h>
  42. #ifdef __UNIX__
  43. #include <unistd.h>
  44. #else
  45. #include <stdio.h>
  46. #include <io.h>                /* For unlink() */
  47. #endif
  48.  
  49.  
  50. /* Global variables - extern to other modules */
  51. char    *progname;          /* argv[0] - for error msgs               */
  52. char    *asm1_name, *asm2_name;     /* Assembler output filenames     */
  53. SYMTAB  symtab;             /* Global symbol table                    */
  54. STATS   stats;              /* cfg statistics                         */
  55. PROG    prog;               /* programs fields                        */
  56. OPTION  option;             /* Command line options                   */
  57. PPROC   pProcList;            /* List of procedures, topologically sort */
  58. PPROC    pLastProc;            /* Pointer to last node in procedure list */
  59. CALL_GRAPH    *callGraph;        /* Call graph of the program              */
  60.  
  61. static char *initargs(int argc, char *argv[]);
  62. static void displayTotalStats();
  63. void UnLoadImage();            // frontend.cpp (if using -DLOADER)
  64.  
  65.  
  66. /****************************************************************************
  67.  * main
  68.  ***************************************************************************/
  69.  
  70.  
  71. void main(int argc, char *argv[])
  72. {
  73.     /* Extract switches and filename */
  74.     strcpy(option.filename, initargs(argc, argv));
  75.  
  76.     /* Front end reads in EXE or COM file, parses it into I-code while 
  77.      * building the call graph and attaching appropriate bits of code for 
  78.      * each procedure.
  79.     */
  80.     FrontEnd (option.filename, &callGraph);
  81.  
  82.     /* In the middle is a so called Universal Decompiling Machine.
  83.      * It processes the procedure list and I-code and attaches where it can 
  84.      * to each procedure an optimised cfg and ud lists
  85.     */
  86.     udm();
  87.  
  88.     /* Back end converts each procedure into C using I-code, interval 
  89.      * analysis, data flow etc. and outputs it to output file ready for 
  90.      * re-compilation.
  91.     */  
  92.     BackEnd(option.filename, callGraph);
  93.  
  94.     writeCallGraph (callGraph);
  95.  
  96.     if (option.Stats)
  97.         displayTotalStats();
  98.  
  99. /* 
  100.     freeDataStructures(pProcList);
  101. */
  102.  
  103. #ifdef LOADER
  104.     UnLoadImage();            // Unload the binary image (etc)
  105. #endif
  106. }
  107.  
  108. /****************************************************************************
  109.  * initargs - Extract command line arguments
  110.  ***************************************************************************/
  111. static char *initargs(int argc, char *argv[])
  112. {
  113.     char *pc;
  114.     progname = *argv;   /* Save invocation name for error messages */
  115.  
  116.     while (--argc > 0 && (*++argv)[0] == '-') {
  117.         for (pc = argv[0]+1; *pc; pc++)
  118.             switch (*pc) {
  119.             case 'a':       /* Print assembler listing */
  120.                 if (*(pc+1) == '2')
  121.                     option.asm2 = TRUE;
  122.                 else
  123.                     option.asm1 = TRUE;
  124.                 if (*(pc+1) == '1' || *(pc+1) == '2')
  125.                     pc++;
  126.                 break;
  127.             case 'c':
  128.                 option.Calls = TRUE;
  129.                 break;
  130.             case 'i':
  131.                 option.Interact = TRUE;
  132.                 break;
  133.             case 'm':       /* Print memory map */
  134.                 option.Map = TRUE;
  135.                 break;
  136.             case 's':       /* Print Stats */
  137.                 option.Stats = TRUE;
  138.                 break;
  139.             case 'V':       /* Very verbose => verbose */
  140.                 option.VeryVerbose = TRUE;
  141.             case 'v':       /* Make everything verbose */
  142.                 option.verbose = TRUE;
  143.                 break;
  144.             case 'o':       /* assembler output file */
  145.                 if (*(pc+1)) {
  146.                     asm1_name = asm2_name = pc+1;
  147.                     goto NextArg;
  148.                 }
  149.                 else if (--argc > 0) {
  150.                     asm1_name = asm2_name = *++argv;
  151.                     goto NextArg;
  152.                 }
  153.             default:
  154.                 fatalError(INVALID_ARG, *pc);
  155.                 return *argv;
  156.             }
  157.     NextArg:;
  158.     }
  159.  
  160.     if (argc == 1)
  161.     {
  162.         if (option.asm1 || option.asm2)
  163.         {
  164.             if (! asm1_name)
  165.             {
  166.                 asm1_name = strcpy((char*)allocMem(strlen(*argv)+4), *argv);
  167.                 pc = strrchr(asm1_name, '.'); 
  168.                 if (pc > strrchr(asm1_name, '/'))
  169.                 {
  170.                     *pc = '\0';
  171.                 }
  172.                 asm2_name = (char*)allocMem(strlen(asm1_name)+4) ;
  173.                 strcat(strcpy(asm2_name, asm1_name), ".a2"); 
  174.                 unlink(asm2_name);
  175.                 strcat(asm1_name, ".a1");
  176.             }
  177.             unlink(asm1_name);  /* Remove asm output files */
  178.         }
  179.         return *argv;       /* filename of the program to decompile */
  180.    }
  181.  
  182.     fatalError(USAGE);
  183.     return *argv;
  184. }
  185.  
  186. static void
  187. displayTotalStats ()
  188. /* Displays final statistics for the complete program */
  189. {
  190.     printf ("\nFinal Program Statistics\n");
  191.     printf ("  Total number of low-level Icodes : %ld\n", stats.totalLL);
  192.     printf ("  Total number of high-level Icodes: %ld\n", stats.totalHL);
  193.     printf ("  Total reduction of instructions  : %2.2f%%\n", 100.0 -
  194.             (stats.totalHL * 100.0) / stats.totalLL);
  195. }
  196.  
  197.  
  198.                
  199.  
  200.