home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
dosdisas.zip
/
dccsrcoo.zip
/
dcc.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-14
|
6KB
|
200 lines
/*****************************************************************************
*$Log: dcc.c,v $
* 14/10/97 MVE Added UnLoadImage() if using the ExeLoader object
*
* Revision 1.9 94/02/22 15:15:19 cifuente
* Code generation done.
*
* Revision 1.8 93/12/03 09:39:37 cifuente
* FrontEnd() doesn't return a PPROC any more, uses global pProcList.
*
* Revision 1.7 93/11/18 15:29:30 cifuente
* pLastProc: pointer to last procedure in pProcList. Equivalent
* to reverse invocation order of the call graph.
*
* Revision 1.6 93/11/17 16:28:58 cifuente
* Call graph references
*
* Revision 1.5 93/10/11 11:35:32 cifuente
* First walk through HIGH_LEVEL icodes.
* Does not invoke code generator.
*
* Revision 1.4 93/09/20 11:49:47 cifuente
* Changed tabs to spaces
*
* Revision 1.3 93/09/17 08:35:15 cifuente
* Moved pProclist to a global
* Removed heap check code
*
* Revision 1.2 93/08/23 12:14:57 cifuente
* Interactive mode with curses
*
* Revision 2.1 93/03/30 14:54:52 cifuente
* Compiled with gcc.
*
* dcc decompiler
* Reads the command line switches and then executes each major section in turn
****************************************************************************/
#include "dcc.h"
#include <string.h>
#ifdef __UNIX__
#include <unistd.h>
#else
#include <stdio.h>
#include <io.h> /* For unlink() */
#endif
/* Global variables - extern to other modules */
char *progname; /* argv[0] - for error msgs */
char *asm1_name, *asm2_name; /* Assembler output filenames */
SYMTAB symtab; /* Global symbol table */
STATS stats; /* cfg statistics */
PROG prog; /* programs fields */
OPTION option; /* Command line options */
PPROC pProcList; /* List of procedures, topologically sort */
PPROC pLastProc; /* Pointer to last node in procedure list */
CALL_GRAPH *callGraph; /* Call graph of the program */
static char *initargs(int argc, char *argv[]);
static void displayTotalStats();
void UnLoadImage(); // frontend.cpp (if using -DLOADER)
/****************************************************************************
* main
***************************************************************************/
void main(int argc, char *argv[])
{
/* Extract switches and filename */
strcpy(option.filename, initargs(argc, argv));
/* Front end reads in EXE or COM file, parses it into I-code while
* building the call graph and attaching appropriate bits of code for
* each procedure.
*/
FrontEnd (option.filename, &callGraph);
/* In the middle is a so called Universal Decompiling Machine.
* It processes the procedure list and I-code and attaches where it can
* to each procedure an optimised cfg and ud lists
*/
udm();
/* Back end converts each procedure into C using I-code, interval
* analysis, data flow etc. and outputs it to output file ready for
* re-compilation.
*/
BackEnd(option.filename, callGraph);
writeCallGraph (callGraph);
if (option.Stats)
displayTotalStats();
/*
freeDataStructures(pProcList);
*/
#ifdef LOADER
UnLoadImage(); // Unload the binary image (etc)
#endif
}
/****************************************************************************
* initargs - Extract command line arguments
***************************************************************************/
static char *initargs(int argc, char *argv[])
{
char *pc;
progname = *argv; /* Save invocation name for error messages */
while (--argc > 0 && (*++argv)[0] == '-') {
for (pc = argv[0]+1; *pc; pc++)
switch (*pc) {
case 'a': /* Print assembler listing */
if (*(pc+1) == '2')
option.asm2 = TRUE;
else
option.asm1 = TRUE;
if (*(pc+1) == '1' || *(pc+1) == '2')
pc++;
break;
case 'c':
option.Calls = TRUE;
break;
case 'i':
option.Interact = TRUE;
break;
case 'm': /* Print memory map */
option.Map = TRUE;
break;
case 's': /* Print Stats */
option.Stats = TRUE;
break;
case 'V': /* Very verbose => verbose */
option.VeryVerbose = TRUE;
case 'v': /* Make everything verbose */
option.verbose = TRUE;
break;
case 'o': /* assembler output file */
if (*(pc+1)) {
asm1_name = asm2_name = pc+1;
goto NextArg;
}
else if (--argc > 0) {
asm1_name = asm2_name = *++argv;
goto NextArg;
}
default:
fatalError(INVALID_ARG, *pc);
return *argv;
}
NextArg:;
}
if (argc == 1)
{
if (option.asm1 || option.asm2)
{
if (! asm1_name)
{
asm1_name = strcpy((char*)allocMem(strlen(*argv)+4), *argv);
pc = strrchr(asm1_name, '.');
if (pc > strrchr(asm1_name, '/'))
{
*pc = '\0';
}
asm2_name = (char*)allocMem(strlen(asm1_name)+4) ;
strcat(strcpy(asm2_name, asm1_name), ".a2");
unlink(asm2_name);
strcat(asm1_name, ".a1");
}
unlink(asm1_name); /* Remove asm output files */
}
return *argv; /* filename of the program to decompile */
}
fatalError(USAGE);
return *argv;
}
static void
displayTotalStats ()
/* Displays final statistics for the complete program */
{
printf ("\nFinal Program Statistics\n");
printf (" Total number of low-level Icodes : %ld\n", stats.totalLL);
printf (" Total number of high-level Icodes: %ld\n", stats.totalHL);
printf (" Total reduction of instructions : %2.2f%%\n", 100.0 -
(stats.totalHL * 100.0) / stats.totalLL);
}