prog.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2001, The University of Queensland
00003  * Copyright (C) 2001, Sun Microsystems, Inc
00004  * Copyright (C) 2002, Trent Waddington
00005  *
00006  * See the file "LICENSE.TERMS" for information on usage and
00007  * redistribution of this file, and for a DISCLAIMER OF ALL
00008  * WARRANTIES.
00009  *
00010  */
00011 
00012 /*=============================================================================
00013  * FILE:        prog.h
00014  * OVERVIEW:    interface for the program object.
00015  *============================================================================*/
00016 /*
00017  * $Revision: 1.93 $    // 1.73.2.5
00018  * 16 Apr 01 - Mike: Mods for boomerang
00019  */
00020 
00021 #ifndef _PROG_H_
00022 #define _PROG_H_
00023 
00024 #include <map>
00025 #include "BinaryFile.h"
00026 #include "frontend.h"
00027 #include "type.h"
00028 #include "cluster.h"
00029 
00030 class RTLInstDict;
00031 class Proc;
00032 class UserProc;
00033 class LibProc;
00034 class Signature;
00035 class Statement;
00036 class StatementSet;
00037 class Cluster;
00038 class XMLProgParser;
00039 
00040 typedef std::map<ADDRESS, Proc*, std::less<ADDRESS> > PROGMAP;
00041 
00042 class Global {
00043 private:
00044     Type *type;
00045     ADDRESS uaddr;
00046     std::string nam;
00047 
00048 public:
00049                     Global(Type *type, ADDRESS uaddr, const char *nam) : type(type), uaddr(uaddr), nam(nam) { }
00050 virtual             ~Global();
00051 
00052         Type        *getType() { return type; }
00053         void        setType(Type* ty) { type = ty; }
00054         void        meetType(Type* ty);
00055         ADDRESS     getAddress() { return uaddr; }
00056         const char *getName() { return nam.c_str(); }
00057         Exp*        getInitialValue(Prog* prog);    // Get the initial value as an expression
00058                                                     // (or NULL if not initialised)
00059         void        print(std::ostream& os, Prog* prog);    // Print to stream os
00060 
00061 protected:
00062                     Global() : type(NULL), uaddr(0), nam("") { }
00063         friend class XMLProgParser;
00064 };      // class Global
00065 
00066 class Prog {
00067 public:
00068                     Prog();                         // Default constructor
00069 virtual             ~Prog();
00070                     Prog(const char* name);         // Constructor with name
00071         void        setFrontEnd(FrontEnd* fe);
00072         void        setName(const char *name);      // Set the name of this program
00073         Proc*       setNewProc(ADDRESS uNative);    // Set up new proc
00074         // Return a pointer to a new proc
00075         Proc*       newProc(const char* name, ADDRESS uNative, bool bLib = false);
00076         void        remProc(UserProc* proc);        // Remove the given UserProc
00077         void        removeProc(const char *name);
00078         char*       getName();                      // Get the name of this program
00079         const char *getPath() { return m_path.c_str(); }
00080         const char *getPathAndName() {return (m_path+m_name).c_str(); }
00081         int         getNumProcs();                  // # of procedures stored in prog
00082         int         getNumUserProcs();              // # of user procedures stored in prog
00083         Proc*       getProc(int i) const;           // returns pointer to indexed proc
00084         // Find the Proc with given address, NULL if none, -1 if deleted
00085         Proc*       findProc(ADDRESS uAddr) const;
00086         // Find the Proc with the given name
00087         Proc*       findProc(const char *name) const;
00088         // Find the Proc that contains the given address
00089         Proc*       findContainingProc(ADDRESS uAddr) const;
00090         bool        isProcLabel (ADDRESS addr);     // Checks if addr is a label or not
00091         // Create a dot file for all CFGs
00092         bool        createDotFile(const char*, bool bMainOnly = false) const;
00093         // get the filename of this program
00094         std::string  getNameNoPath() const;
00095         std::string  getNameNoPathNoExt() const;
00096         // This pair of functions allows the user to iterate through all the procs
00097         // The procs will appear in order of native address
00098         Proc*       getFirstProc(PROGMAP::const_iterator& it);
00099         Proc*       getNextProc(PROGMAP::const_iterator& it);
00100 
00101         // This pair of functions allows the user to iterate through all the UserProcs
00102         // The procs will appear in topdown order
00103         UserProc*   getFirstUserProc(std::list<Proc*>::iterator& it);
00104         UserProc*   getNextUserProc (std::list<Proc*>::iterator& it);
00105 
00106         // list of UserProcs for entry point(s)
00107         std::list<UserProc*> entryProcs;    
00108 
00109         // clear the prog object NOTE: deletes everything!
00110         void        clear();
00111 
00112         // Lookup the given native address in the code section, returning a host pointer corresponding to the same
00113         // address
00114         const void* getCodeInfo(ADDRESS uAddr, const char*& last, int& delta);
00115 
00116         const char *getRegName(int idx) { return pFE->getRegName(idx); }
00117         int getRegSize(int idx) { return pFE->getRegSize(idx); }
00118 
00119         void        decodeEntryPoint(ADDRESS a);
00120         void        setEntryPoint(ADDRESS a);           // As per the above, but don't decode
00121         void        decodeEverythingUndecoded();
00122         void        decodeFragment(UserProc* proc, ADDRESS a);
00123 
00124         // Re-decode this proc from scratch
00125         void        reDecode(UserProc* proc);
00126 
00127         // Well form all the procedures/cfgs in this program
00128         bool        wellForm();
00129         
00130         // last fixes after decoding everything
00131         void        finishDecode();
00132 
00133         // Recover return locations
00134         void        recoverReturnLocs();
00135 
00136         // Remove interprocedural edges
00137         void        removeInterprocEdges();
00138 
00139         // Do the main non-global decompilation steps
00140         void        decompile();
00141 
00142         // All that used to be done in UserProc::decompile, but now done globally: propagation, recalc DFA, remove null
00143         // and unused statements, compressCfg, process constants, promote signature, simplify a[m[]].
00144         void        decompileProcs();
00145 
00146         // Remove null, unused, and restored statements
00147         void        removeNullStmts();
00148         void        removeUnusedStmts();
00149         void        removeUnusedGlobals();
00150         void        removeUnusedLocals();
00151         void        removeRestoreStmts(StatementSet& rs);
00152 
00153         // Process constants
00154         void        processConstants();
00155 
00156         // Type analysis
00157         void        globalTypeAnalysis();
00158 
00159         /// Remove unused return locations
00160         /// \return true if any returns are removed
00161         bool        removeUnusedReturns();
00162 
00163         // Convert from SSA form
00164         void        fromSSAform();
00165 
00166         // Type analysis
00167         void        conTypeAnalysis();
00168         void        dfaTypeAnalysis();
00169 
00170         // Range analysis
00171         void        rangeAnalysis();
00172 
00173         // Generate dotty file
00174         void        generateDotFile();
00175 
00176         // Generate code
00177         void        generateCode(std::ostream &os);
00178         void        generateCode(Cluster *cluster = NULL, UserProc *proc = NULL, bool intermixRTL = false);
00179         void        generateRTL(Cluster *cluster = NULL, UserProc *proc = NULL);
00180 
00181         // Print this program (primarily for debugging)
00182         void        print(std::ostream &out);
00183 
00184         // lookup a library procedure by name; create if does not exist
00185         LibProc     *getLibraryProc(const char *nam);
00186 
00187         // Get a library signature for a given name (used when creating a new library proc.
00188         Signature   *getLibSignature(const char *name);
00189         void        rereadLibSignatures();
00190 
00191         Statement   *getStmtAtLex(Cluster *cluster, unsigned int begin, unsigned int end);
00192 
00193         // Get the front end id used to make this prog
00194         platform    getFrontEndId();
00195 
00196         std::map<ADDRESS, std::string> &getSymbols();
00197 
00198         Signature   *getDefaultSignature(const char *name);
00199 
00200         std::vector<Exp*> &getDefaultParams();
00201         std::vector<Exp*> &getDefaultReturns();
00202 
00203         // Returns true if this is a win32 program
00204         bool        isWin32();
00205 
00206         // Get a global variable if possible, looking up the loader's symbol table if necessary
00207         const char  *getGlobalName(ADDRESS uaddr);
00208         ADDRESS     getGlobalAddr(char *nam);
00209         Global*     getGlobal(char *nam);
00210 
00211         // Make up a name for a new global at address uaddr (or return an existing name if address already used)
00212         const char  *newGlobalName(ADDRESS uaddr);
00213 
00214         // Guess a global's type based on its name and address
00215         Type        *guessGlobalType(const char *nam, ADDRESS u);
00216 
00217         // Make an array type for the global array at u. Mainly, set the length sensibly
00218         ArrayType*  makeArrayType(ADDRESS u, Type* t);
00219 
00220         // Indicate that a given global has been seen used in the program.
00221         bool        globalUsed(ADDRESS uaddr, Type* knownType = NULL);
00222 
00223         // Get the type of a global variable
00224         Type        *getGlobalType(char* nam);
00225         
00226         // Set the type of a global variable
00227         void        setGlobalType(const char* name, Type* ty);
00228 
00229         // Dump the globals to stderr for debugging
00230         void        dumpGlobals();
00231 
00232         // get a string constant at a give address if appropriate
00233         char        *getStringConstant(ADDRESS uaddr, bool knownString = false);
00234         double      getFloatConstant(ADDRESS uaddr, bool &ok, int bits = 64);
00235 
00236         // Hacks for Mike
00237         MACHINE     getMachine()                // Get a code for the machine
00238                         { return pBF->GetMachine();}    // e.g. MACHINE_SPARC
00239         const char* symbolByAddress(ADDRESS dest) // Get a symbol from an address
00240                         { return pBF->SymbolByAddress(dest);}
00241         PSectionInfo getSectionInfoByAddr(ADDRESS a)
00242                         { return pBF->GetSectionInfoByAddr(a);}
00243         ADDRESS     getLimitTextLow() {return pBF->getLimitTextLow();}
00244         ADDRESS     getLimitTextHigh() {return pBF->getLimitTextHigh();}
00245         bool        isReadOnly(ADDRESS a) { return pBF->isReadOnly(a); }
00246         // Read 2, 4, or 8 bytes given a native address
00247         int         readNative1(ADDRESS a) {return pBF->readNative1(a);}
00248         int         readNative2(ADDRESS a) {return pBF->readNative2(a);}
00249         int         readNative4(ADDRESS a) {return pBF->readNative4(a);}
00250         float       readNativeFloat4(ADDRESS a) {return pBF->readNativeFloat4(a);}
00251         double      readNativeFloat8(ADDRESS a) {return pBF->readNativeFloat8(a);}
00252         QWord       readNative8(ADDRESS a) {return pBF->readNative8(a);}
00253         Exp         *readNativeAs(ADDRESS uaddr, Type *type);
00254         int         getTextDelta() { return pBF->getTextDelta(); }
00255 
00256         bool        isDynamicLinkedProcPointer(ADDRESS dest) { return pBF->IsDynamicLinkedProcPointer(dest); }
00257         const char* GetDynamicProcName(ADDRESS uNative) { return pBF->GetDynamicProcName(uNative); }
00258 
00259         bool        processProc(int addr, UserProc* proc)   // Decode a proc
00260                         { std::ofstream os; return pFE->processProc((unsigned)addr, proc, os);}
00261 
00262         void        readSymbolFile(const char *fname);
00263         unsigned    getImageSize() { return pBF->getImageSize(); }
00264         ADDRESS     getImageBase() { return pBF->getImageBase(); }
00265 
00266         // Public booleans that are set if and when a register jump or call is
00267         // found, respectively
00268         bool        bRegisterJump;
00269         bool        bRegisterCall;
00270 
00271         void        printSymbolsToFile();
00272         void        printCallGraph();
00273         void        printCallGraphXML();
00274 
00275         Cluster     *getRootCluster() { return m_rootCluster; }
00276         Cluster     *findCluster(const char *name) { return m_rootCluster->find(name); }
00277         Cluster     *getDefaultCluster(const char *name);
00278         bool        clusterUsed(Cluster *c);
00279 
00280         // Add the given RTL to the front end's map from address to aldready-decoded-RTL
00281         void        addDecodedRtl(ADDRESS a, RTL* rtl) {
00282                         pFE->addDecodedRtl(a, rtl); }
00283 
00284         // This does extra processing on a constant.  The Exp* is expected to be a Const,
00285         // and the ADDRESS is the native location from which the constant was read.
00286         Exp         *addReloc(Exp *e, ADDRESS lc);
00287 
00288 protected:
00289         BinaryFile* pBF;                    // Pointer to the BinaryFile object for the program
00290         FrontEnd    *pFE;                   // Pointer to the FrontEnd object for the project
00291 
00292         /* Persistent state */
00293         std::string m_name, m_path;         // name of the program and its full path
00294         std::list<Proc*> m_procs;           // list of procedures
00295         PROGMAP     m_procLabels;           // map from address to Proc*
00296         // FIXME: is a set of Globals the most appropriate data structure? Surely not.
00297         std::set<Global*> globals;          // globals to print at code generation time
00298         //std::map<ADDRESS, const char*> *globalMap; // Map of addresses to global symbols
00299         DataIntervalMap globalMap;          // Map from address to DataInterval (has size, name, type)
00300         int         m_iNumberedProc;        // Next numbered proc will use this
00301         Cluster     *m_rootCluster;         // Root of the cluster tree
00302 
00303         friend class XMLProgParser;
00304 };  // class Prog
00305 
00306 #endif

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