boomerang.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002, Trent Waddington
00003  *
00004  * See the file "LICENSE.TERMS" for information on usage and
00005  * redistribution of this file, and for a DISCLAIMER OF ALL
00006  * WARRANTIES.
00007  *
00008  */
00009 
00010 /** \file   boomerang.h
00011  * Interface for the boomerang singleton object.
00012  *
00013  * $Revision: 1.77 $    // 1.61.2.2
00014  * 04 Dec 2002: Trent: Created
00015  */
00016 
00017 /** \mainpage Introduction
00018  *
00019  * \section Introduction
00020  *
00021  * Welcome to the Doxygen generated documentation for the 
00022  * %Boomerang decompiler. Not all classes and functions have been documented
00023  * yet, but eventually they will. If you have figured out what a function is doing
00024  * please update the documentation and submit it as a patch.
00025  *
00026  * More information on the %Boomerang decompiler can be found at
00027  * http://boomerang.sourceforge.net.
00028  *
00029  */
00030 
00031 
00032 #ifndef BOOMERANG_H
00033 #define BOOMERANG_H
00034 
00035 // Defines to control experimental features
00036 #define USE_DOMINANCE_NUMS 1                // Set true to store a statement number that has dominance properties
00037 
00038 #include <iostream>
00039 #include <string>
00040 #include <set>
00041 #include <vector>
00042 #include <map>
00043 
00044 #include "types.h"
00045 
00046 class Log;
00047 class Prog;
00048 class Proc;
00049 class UserProc;
00050 class HLLCode;
00051 class ObjcModule;
00052 
00053 #define LOG Boomerang::get()->log()
00054 #define LOGTAIL Boomerang::get()->logTail()
00055 
00056 #define DEBUG_RANGE_ANALYSIS 0
00057 
00058 /// Virtual class to monitor the decompilation.
00059 class Watcher {
00060 public:
00061         Watcher() { }
00062 virtual ~Watcher() { };                         // Prevent gcc4 warning
00063 
00064 virtual void        alert_complete() { }
00065 virtual void        alert_new(Proc *p) { }
00066 virtual void        alert_remove(Proc *p) { }
00067 virtual void        alert_update_signature(Proc *p) { }
00068 virtual void        alert_decode(ADDRESS pc, int nBytes) { }
00069 virtual void        alert_baddecode(ADDRESS pc) { }
00070 virtual void        alert_start_decode(ADDRESS start, int nBytes) { }
00071 virtual void        alert_end_decode() { }
00072 virtual void        alert_decode(Proc *p, ADDRESS pc, ADDRESS last, int nBytes) { }
00073 virtual void        alert_start_decompile(UserProc *p) { }
00074 virtual void        alert_proc_status_change(UserProc *p) { }
00075 virtual void        alert_decompile_SSADepth(UserProc *p, int depth) { }
00076 virtual void        alert_decompile_beforePropagate(UserProc *p, int depth) { }
00077 virtual void        alert_decompile_afterPropagate(UserProc *p, int depth) { }
00078 virtual void        alert_decompile_afterRemoveStmts(UserProc *p, int depth) { }
00079 virtual void        alert_end_decompile(UserProc *p) { }
00080 virtual void        alert_load(Proc *p) { }
00081 virtual void        alert_considering(Proc *parent, Proc *p) { }
00082 virtual void        alert_decompiling(UserProc *p) { }
00083 virtual void        alert_decompile_debug_point(UserProc *p, const char *description) { }
00084 };
00085 
00086 /**
00087  * Controls the loading, decoding, decompilation and code generation for a program.
00088  * This is the main class of the decompiler.
00089  */
00090 class Boomerang {
00091 private:
00092 static Boomerang *boomerang;
00093         /// String with the path to the boomerang executable.
00094         std::string progPath;
00095         /// The path where all output files are created.
00096         std::string outputPath;
00097         /// Takes care of the log messages.
00098         Log         *logger;
00099         /// The watchers which are interested in this decompilation.
00100         std::set<Watcher*> watchers;
00101         
00102         
00103         /* Documentation about a function should be at one place only
00104          * So: Document all functions at the point of implementation (in the .c file)
00105          */
00106 
00107         void        usage();
00108         void        help();
00109         void        helpcmd();
00110         int         splitLine(char *line, char ***pargv);
00111         int         parseCmd(int argc, const char **argv);
00112         int         cmdLine();
00113 
00114 
00115                 Boomerang();
00116         /// The destructor is virtual to force this object to be created on the heap (with \em new).
00117 virtual         ~Boomerang() {}
00118 public:
00119         /** 
00120          * \return The global boomerang object. It will be created if it didn't already exist.
00121          */ 
00122 static Boomerang *get() { 
00123                 if (!boomerang) boomerang = new Boomerang(); 
00124                 return boomerang;
00125             }
00126 
00127 static  char*       getVersionStr();
00128         Log         &log();
00129         void        setLogger(Log *l) { logger = l; }
00130         bool        setOutputDirectory(const char *path);
00131 
00132         /// \return The HLLCode for the specified UserProc.
00133         HLLCode     *getHLLCode(UserProc *p = NULL);
00134 
00135         int         commandLine(int argc, const char **argv);
00136         /// Set the path to the %Boomerang executable.
00137         void        setProgPath(const char* p) { progPath = p; }
00138         /// Get the path to the %Boomerang executable.
00139         const std::string& getProgPath() { return progPath; }
00140         /// Set the path where the output files are saved.
00141         void        setOutputPath(const char* p) { outputPath = p; }
00142         /// Returns the path to where the output files are saved.
00143         const std::string& getOutputPath() { return outputPath; }
00144 
00145         Prog        *loadAndDecode(const char *fname, const char *pname = NULL);
00146         int         decompile(const char *fname, const char *pname = NULL);
00147         /// Add a Watcher to the set of Watchers for this Boomerang object.
00148         void        addWatcher(Watcher *watcher) { watchers.insert(watcher); }
00149         void        persistToXML(Prog *prog);
00150         Prog        *loadFromXML(const char *fname);
00151 
00152         void        objcDecode(std::map<std::string, ObjcModule> &modules, Prog *prog);
00153 
00154         /// Alert the watchers that decompilation has completed.
00155         void        alert_complete() {
00156                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00157                             (*it)->alert_complete();
00158                     }
00159         /// Alert the watchers we have found a new %Proc.
00160         void        alert_new(Proc *p) {
00161                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00162                             (*it)->alert_new(p);
00163                     }
00164         /// Alert the watchers we have removed a %Proc.
00165         void        alert_remove(Proc *p) {
00166                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00167                             (*it)->alert_remove(p);
00168                     }
00169         /// Alert the watchers we have updated this Procs signature
00170         void        alert_update_signature(Proc *p) { 
00171                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00172                             (*it)->alert_update_signature(p);
00173                     }
00174         /// Alert the watchers we are currently decoding \a nBytes bytes at address \a pc.
00175         void        alert_decode(ADDRESS pc, int nBytes) {
00176                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00177                             (*it)->alert_decode(pc, nBytes);
00178                     }
00179         /// Alert the watchers of a bad decode of an instruction at \a pc.
00180         void        alert_baddecode(ADDRESS pc) {
00181                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00182                             (*it)->alert_baddecode(pc);
00183                     }
00184         /// Alert the watchers we have succesfully decoded this function
00185         void        alert_decode(Proc *p, ADDRESS pc, ADDRESS last, int nBytes) {
00186                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00187                             (*it)->alert_decode(p, pc, last, nBytes);
00188                     }
00189         /// Alert the watchers we have loaded the Proc.
00190         void        alert_load(Proc *p) {
00191                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00192                             (*it)->alert_load(p);
00193             }
00194         /// Alert the watchers we are starting to decode.
00195         void        alert_start_decode(ADDRESS start, int nBytes) { 
00196                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00197                             (*it)->alert_start_decode(start, nBytes);
00198                     }
00199         /// Alert the watchers we finished decoding.
00200         void        alert_end_decode() { 
00201                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00202                             (*it)->alert_end_decode();
00203                     }
00204 virtual void        alert_start_decompile(UserProc *p) { 
00205                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00206                             (*it)->alert_start_decompile(p);
00207                     }
00208 virtual void        alert_proc_status_change(UserProc *p) {
00209                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00210                             (*it)->alert_proc_status_change(p);
00211                     }
00212 virtual void        alert_decompile_SSADepth(UserProc *p, int depth) {
00213                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00214                             (*it)->alert_decompile_SSADepth(p, depth);
00215             }
00216 virtual void        alert_decompile_beforePropagate(UserProc *p, int depth) {
00217                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00218                             (*it)->alert_decompile_beforePropagate(p, depth);
00219                     }
00220 virtual void        alert_decompile_afterPropagate(UserProc *p, int depth) {
00221                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00222                             (*it)->alert_decompile_afterPropagate(p, depth);
00223                     }
00224 virtual void        alert_decompile_afterRemoveStmts(UserProc *p, int depth) {
00225                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00226                             (*it)->alert_decompile_afterRemoveStmts(p, depth);
00227                     }
00228 virtual void        alert_end_decompile(UserProc *p) { 
00229                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00230                             (*it)->alert_end_decompile(p);
00231                     }
00232 virtual void        alert_considering(Proc *parent, Proc *p) { 
00233                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00234                             (*it)->alert_considering(parent, p);
00235                     }
00236 virtual void        alert_decompiling(UserProc *p) { 
00237                         for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00238                             (*it)->alert_decompiling(p);
00239                     }
00240 virtual void        alert_decompile_debug_point(UserProc *p, const char *description);
00241 
00242         void        logTail();
00243 
00244         // Command line flags
00245         bool        vFlag;
00246         bool        printRtl;
00247         bool        noBranchSimplify;
00248         bool        noRemoveNull;
00249         bool        noLocals;
00250         bool        noRemoveLabels;
00251         bool        noDataflow;
00252         bool        noDecompile;
00253         bool        stopBeforeDecompile;
00254         bool        traceDecoder;
00255         /// The file in which the dotty graph is saved
00256         const char  *dotFile;
00257         int         numToPropagate;
00258         bool        noPromote;
00259         bool        propOnlyToAll;
00260         bool        debugGen;
00261         int         maxMemDepth;
00262         bool        debugSwitch;
00263         bool        noParameterNames;
00264         bool        debugLiveness;
00265         bool        stopAtDebugPoints;
00266         bool        debugTA;
00267         /// A vector which contains all know entrypoints for the Prog.
00268         std::vector<ADDRESS> entrypoints;
00269         /// A vector containing the names off all symbolfiles to load.
00270         std::vector<std::string> symbolFiles;
00271         /// A map to find a name by a given address.
00272         std::map<ADDRESS, std::string> symbols;
00273         /// When true, attempt to decode main, all children, and all procs.
00274         /// \a decodeMain is set when there are no -e or -E switches given
00275         bool        decodeMain;                 
00276         bool        printAST;
00277         bool        dumpXML;
00278         bool        noRemoveReturns;
00279         bool        debugDecoder;
00280         bool        decodeThruIndCall;
00281         std::ofstream* ofsIndCallReport;
00282         bool        noDecodeChildren;
00283         bool        debugProof;
00284         bool        debugUnused;
00285         bool        loadBeforeDecompile;
00286         bool        saveBeforeDecompile;
00287         bool        noProve;
00288         bool        noChangeSignatures;
00289         bool        conTypeAnalysis;
00290         bool        dfaTypeAnalysis;
00291         int         propMaxDepth;       ///< Max depth of expression that will be propagated to more than one dest
00292         bool        generateCallGraph;
00293         bool        generateSymbols;
00294         bool        noGlobals;
00295         bool        assumeABI;          ///< Assume ABI compliance
00296         bool        experimental;       ///< Activate experimental code. Caution!
00297         int         minsToStopAfter;
00298 };
00299 
00300 #define VERBOSE             (Boomerang::get()->vFlag)
00301 #define DEBUG_TA            (Boomerang::get()->debugTA)
00302 #define DEBUG_PROOF         (Boomerang::get()->debugProof)
00303 #define DEBUG_UNUSED        (Boomerang::get()->debugUnused)
00304 #define DEBUG_LIVENESS      (Boomerang::get()->debugLiveness)
00305 #define DFA_TYPE_ANALYSIS   (Boomerang::get()->dfaTypeAnalysis)
00306 #define CON_TYPE_ANALYSIS   (Boomerang::get()->conTypeAnalysis)
00307 #define ADHOC_TYPE_ANALYSIS (!Boomerang::get()->dfaTypeAnalysis && !Boomerang::get()->conTypeAnalysis)
00308 #define DEBUG_GEN           (Boomerang::get()->debugGen)
00309 #define DUMP_XML            (Boomerang::get()->dumpXML)
00310 #define DEBUG_SWITCH        (Boomerang::get()->debugSwitch)
00311 #define EXPERIMENTAL        (Boomerang::get()->experimental)
00312 
00313 
00314 
00315 #endif

Generated on Tue Sep 19 21:18:15 2006 for Boomerang by  doxygen 1.4.6