dcc.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*****************************************************************************
  2. * dcc decompiler
  3. * Reads the command line switches and then executes each major section in turn
  4. * (C) Cristina Cifuentes
  5. ****************************************************************************/
  6. #include "dcc.h"
  7. #include "project.h"
  8. #include <string.h>
  9. /* Global variables - extern to other modules */
  10. char *asm1_name, *asm2_name; /* Assembler output filenames */
  11. SYMTAB symtab; /* Global symbol table */
  12. STATS stats; /* cfg statistics */
  13. PROG prog; /* programs fields */
  14. OPTION option; /* Command line options */
  15. //Function * pProcList; /* List of procedures, topologically sort */
  16. //Function * pLastProc; /* Pointer to last node in procedure list */
  17. //FunctionListType pProcList;
  18. //CALL_GRAPH *callGraph; /* Call graph of the program */
  19. static char *initargs(int argc, char *argv[]);
  20. static void displayTotalStats(void);
  21. #include <llvm/Support/raw_os_ostream.h>
  22. /****************************************************************************
  23. * main
  24. ***************************************************************************/
  25. #include <iostream>
  26. extern Project g_proj;
  27. int main(int argc, char *argv[])
  28. {
  29. // llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
  30. // llvm::MCAsmInfo info;
  31. // llvm::raw_os_ostream wrap(std::cerr);
  32. // op.print(wrap,&info);
  33. // wrap.flush();
  34. /* Extract switches and filename */
  35. strcpy(option.filename, initargs(argc, argv));
  36. /* Front end reads in EXE or COM file, parses it into I-code while
  37. * building the call graph and attaching appropriate bits of code for
  38. * each procedure.
  39. */
  40. DccFrontend fe(option.filename);
  41. if(false==fe.FrontEnd ())
  42. return -1;
  43. /* In the middle is a so called Universal Decompiling Machine.
  44. * It processes the procedure list and I-code and attaches where it can
  45. * to each procedure an optimised cfg and ud lists
  46. */
  47. udm();
  48. /* Back end converts each procedure into C using I-code, interval
  49. * analysis, data flow etc. and outputs it to output file ready for
  50. * re-compilation.
  51. */
  52. BackEnd(option.filename, g_proj.callGraph);
  53. g_proj.callGraph->write();
  54. if (option.Stats)
  55. displayTotalStats();
  56. /*
  57. freeDataStructures(pProcList);
  58. */
  59. return 0;
  60. }
  61. /****************************************************************************
  62. * initargs - Extract command line arguments
  63. ***************************************************************************/
  64. static char *initargs(int argc, char *argv[])
  65. {
  66. char *pc;
  67. while (--argc > 0 && (*++argv)[0] == '-')
  68. {
  69. for (pc = argv[0]+1; *pc; pc++)
  70. switch (*pc)
  71. {
  72. case 'a': /* Print assembler listing */
  73. if (*(pc+1) == '2')
  74. option.asm2 = true;
  75. else
  76. option.asm1 = true;
  77. if (*(pc+1) == '1' || *(pc+1) == '2')
  78. pc++;
  79. break;
  80. case 'c':
  81. option.Calls = true;
  82. break;
  83. case 'i':
  84. option.Interact = true;
  85. break;
  86. case 'm': /* Print memory map */
  87. option.Map = true;
  88. break;
  89. case 's': /* Print Stats */
  90. option.Stats = true;
  91. break;
  92. case 'V': /* Very verbose => verbose */
  93. option.VeryVerbose = true;
  94. case 'v':
  95. option.verbose = true; /* Make everything verbose */
  96. break;
  97. case 'o': /* assembler output file */
  98. if (*(pc+1)) {
  99. asm1_name = asm2_name = pc+1;
  100. goto NextArg;
  101. }
  102. else if (--argc > 0) {
  103. asm1_name = asm2_name = *++argv;
  104. goto NextArg;
  105. }
  106. default:
  107. fatalError(INVALID_ARG, *pc);
  108. return *argv;
  109. }
  110. NextArg:;
  111. }
  112. if (argc == 1)
  113. {
  114. if (option.asm1 || option.asm2)
  115. {
  116. if (! asm1_name)
  117. {
  118. asm1_name = strcpy((char*)malloc(strlen(*argv)+4), *argv);
  119. pc = strrchr(asm1_name, '.');
  120. if (pc > strrchr(asm1_name, '/'))
  121. {
  122. *pc = '\0';
  123. }
  124. asm2_name = (char*)malloc(strlen(asm1_name)+4) ;
  125. strcat(strcpy(asm2_name, asm1_name), ".a2");
  126. unlink(asm2_name);
  127. strcat(asm1_name, ".a1");
  128. }
  129. unlink(asm1_name); /* Remove asm output files */
  130. }
  131. return *argv; /* filename of the program to decompile */
  132. }
  133. fatalError(USAGE);
  134. return *argv; // does not reach this.
  135. }
  136. static void
  137. displayTotalStats ()
  138. /* Displays final statistics for the complete program */
  139. {
  140. printf ("\nFinal Program Statistics\n");
  141. printf (" Total number of low-level Icodes : %ld\n", stats.totalLL);
  142. printf (" Total number of high-level Icodes: %ld\n", stats.totalHL);
  143. printf (" Total reduction of instructions : %2.2f%%\n", 100.0 -
  144. (stats.totalHL * 100.0) / stats.totalLL);
  145. }