signature.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002, Trent Waddington
00003  */
00004 /*==============================================================================
00005  * FILE:       signature.h
00006  * OVERVIEW:   Provides the definition for the signature classes.
00007  *============================================================================*/
00008 /*
00009  * $Revision: 1.68 $    // 1.53.2.11
00010  *
00011  * 12 Jul 02 - Trent: Created
00012  *
00013  * Trent had the idea of "promoting" to signatures with known behaviour (e.g. conforms to ABI). However, it seems more
00014  *  general to only assume ABI behaviour for library functions, and derive the signature information from child
00015  *  procedures in all user procedures. At present, this promotion is basically disabled (promotion always succeeds,
00016  *  but not much is assumed by the process of promotion). The role of the Signature classes is still being considered.
00017  *  - MVE Jun 2005.
00018  */
00019 
00020 #ifndef __SIGNATURE_H_
00021 #define __SIGNATURE_H_
00022 
00023 #if defined(_MSC_VER)
00024 #pragma warning(disable:4290)
00025 #endif
00026 
00027 #include <string>
00028 #include "exp.h"
00029 #include "type.h"
00030 #include "sigenum.h"        // For enums platform and cc
00031 #include "memo.h"
00032 #include "statement.h"      // For class Return
00033 
00034 class Statement;
00035 class StatementList;
00036 class BinaryFile;
00037 class XMLProgParser;
00038 
00039 class Parameter { 
00040 private:
00041         Type *type;
00042         std::string name;
00043         Exp *exp;
00044         std::string boundMax;
00045 
00046 public: 
00047                     Parameter(Type *type, const char *name, Exp *exp = NULL, const char *boundMax = "") :
00048                     type(type), name(name), exp(exp), boundMax(boundMax)    { }
00049 virtual             ~Parameter() { delete type; delete exp; }
00050         bool        operator==(Parameter& other);
00051         Parameter*  clone();
00052 
00053         Type        *getType() { return type; }
00054         void        setType(Type *ty) { type = ty; }
00055         const char  *getName() { return name.c_str(); }
00056         void        setName(const char *nam) { name = nam; }
00057         Exp         *getExp()       { return exp; }
00058         void        setExp(Exp *e) { exp = e; }
00059 
00060         // this parameter is the bound of another parameter with name nam
00061         const char  *getBoundMax() { return boundMax.c_str(); }
00062         void        setBoundMax(const char *nam);
00063 
00064 protected:
00065         friend      class XMLProgParser;
00066                     Parameter() : type(NULL), name(""), exp(NULL) { }
00067 };      // class Parameter
00068 
00069 class Return {
00070 public:
00071         Type        *type;
00072         Exp         *exp;
00073 
00074                     Return(Type *type, Exp *exp) : type(type), exp(exp) { }
00075 virtual             ~Return() { }
00076         bool        operator==(Return& other);
00077         Return*     clone();
00078 
00079                     Return() : type(NULL), exp(NULL) { }
00080         friend class XMLProgParser;
00081 };      // class Return
00082 
00083 typedef std::vector<Return*> Returns;
00084 
00085 
00086 class Signature {
00087 protected:
00088         std::string name;       // name of procedure
00089         std::string sigFile;    // signature file this signature was read from (for libprocs)
00090         std::vector<Parameter*> params;
00091         // std::vector<ImplicitParameter*> implicitParams;
00092         Returns     returns;
00093         Type        *rettype;
00094         bool        ellipsis;
00095         bool        unknown;
00096         //bool      bFullSig;           // True if have a full signature from a signature file etc
00097         // True if the signature is forced with a -sf entry, or is otherwise known, e.g. WinMain
00098         bool        forced;
00099         Type        *preferedReturn;
00100         std::string preferedName;
00101         std::vector<int> preferedParams;
00102 
00103 //      void        updateParams(UserProc *p, Statement *stmt, bool checkreach = true);
00104         bool        usesNewParam(UserProc *p, Statement *stmt, bool checkreach, int &n);
00105 
00106         //void      addImplicitParametersFor(Parameter *p);
00107         //void      addImplicitParameter(Type *type, const char *name, Exp *e, Parameter *parent);
00108 
00109 public:
00110                     Signature(const char *nam);
00111         // Platform plat, calling convention cc (both enums)
00112         // nam is name of the procedure (no longer stored in the Proc)
00113 static  Signature   *instantiate(platform plat, callconv cc, const char *nam);
00114 virtual             ~Signature() { }
00115 
00116 virtual bool        operator==(Signature& other);
00117 
00118         // clone this signature
00119 virtual Signature   *clone();
00120 
00121         bool        isUnknown() { return unknown; }
00122         void        setUnknown(bool b) { unknown = b; }
00123 //      void        setFullSig(bool full) {bFullSig = full;}
00124         bool        isForced() {return forced; }
00125         void        setForced(bool f) {forced = f; }
00126 
00127         // get the return location
00128 virtual void        addReturn(Type *type, Exp *e = NULL);
00129 virtual void        addReturn(Exp *e);
00130 virtual void        addReturn(Return *ret) { returns.push_back(ret); }
00131 virtual void        removeReturn(Exp *e);
00132 virtual unsigned    getNumReturns() {return returns.size();}
00133 virtual Exp         *getReturnExp(int n) {return returns[n]->exp;}
00134         void        setReturnExp(int n, Exp* e) {returns[n]->exp = e;}
00135 virtual Type        *getReturnType(int n) {return returns[n]->type;}
00136 virtual void        setReturnType(int n, Type *ty);
00137         int         findReturn(Exp *e);
00138 //      void        fixReturnsWithParameters();         // Needs description
00139         void        setRetType(Type *t) { rettype = t; }
00140         Returns&    getReturns() {return returns;}
00141         Type*       getTypeFor(Exp* e);
00142 
00143         // get/set the name
00144 virtual const char  *getName();
00145 virtual void        setName(const char *nam);
00146         // get/set the signature file
00147         const char  *getSigFile() { return sigFile.c_str(); }
00148         void        setSigFile(const char *nam) { sigFile = nam; }
00149 
00150         // add a new parameter to this signature
00151 virtual void        addParameter(const char *nam = NULL);
00152 virtual void        addParameter(Type *type, const char *nam = NULL, Exp *e = NULL, const char *boundMax = "");
00153 virtual void        addParameter(Exp *e, Type* ty);
00154 virtual void        addParameter(Parameter *param);
00155         void        addEllipsis() { ellipsis = true; }
00156         void        killEllipsis() {ellipsis = false; }
00157 virtual void        removeParameter(Exp *e);
00158 virtual void        removeParameter(int i);
00159         // set the number of parameters using defaults
00160 virtual void        setNumParams(int n);
00161 
00162         // accessors for parameters
00163 virtual unsigned    getNumParams() {return params.size();}
00164 virtual const char  *getParamName(int n);
00165 virtual Exp         *getParamExp(int n);
00166 virtual Type        *getParamType(int n);
00167 virtual const char  *getParamBoundMax(int n);
00168 virtual void        setParamType(int n, Type *ty);
00169 virtual void        setParamType(const char* nam, Type *ty);
00170 virtual void        setParamType(Exp* e, Type *ty);
00171 virtual void        setParamName(int n, const char *nam);
00172 virtual void        setParamExp(int n, Exp *e);
00173 virtual int         findParam(Exp *e);
00174 virtual int         findParam(const char *nam);
00175         // accessor for argument expressions
00176 virtual Exp         *getArgumentExp(int n);
00177 virtual bool        hasEllipsis() { return ellipsis; }
00178 
00179         void        renameParam(const char *oldName, const char *newName);
00180 
00181         // analysis determines parameters / return type
00182         //virtual void analyse(UserProc *p);
00183 
00184         // Data flow based type analysis. Meet the parameters with their current types.  Returns true if a change
00185         bool        dfaTypeAnalysis(Cfg* cfg);
00186 
00187         // any signature can be promoted to a higher level signature, if available
00188 virtual Signature *promote(UserProc *p);
00189         void        print(std::ostream &out, bool html = false);
00190         char*       prints();           // For debugging
00191         void        printToLog();
00192 
00193         // Special for Mike: find the location that conventionally holds the first outgoing (actual) parameter
00194         // MVE: Use the below now
00195         Exp*        getFirstArgLoc(Prog* prog);
00196 
00197         // This is like getParamLoc, except that it works before Signature::analyse is called.  It is used only to order
00198         // parameters correctly, for the common case where the proc will end up using a standard calling convention
00199         Exp*        getEarlyParamExp(int n, Prog* prog);
00200 
00201         // Get a wildcard to find stack locations
00202 virtual Exp         *getStackWildcard() { return NULL; }
00203     class StackRegisterNotDefinedException : public std::exception {
00204     public:
00205         StackRegisterNotDefinedException() { }
00206     };
00207 virtual int         getStackRegister(           ) throw(StackRegisterNotDefinedException);
00208 static  int         getStackRegister(Prog* prog) throw(StackRegisterNotDefinedException);
00209         // Does expression e represent a local stack-based variable?
00210         // Result can be ABI specific, e.g. sparc has locals in the parent's stack frame, at POSITIVE offsets from the
00211         // stack pointer register
00212         // Also, I believe that the PA/RISC stack grows away from 0
00213         bool        isStackLocal(Prog* prog, Exp *e);
00214         // Similar to the above, but checks for address of a local (i.e. sp{0} -/+ K)
00215 virtual bool        isAddrOfStackLocal(Prog* prog, Exp* e);
00216         // For most machines, local variables are always NEGATIVE offsets from sp
00217 virtual bool        isLocalOffsetNegative() {return true;}
00218         // For most machines, local variables are not POSITIVE offsets from sp
00219 virtual bool        isLocalOffsetPositive() {return false;}
00220         // Is this operator (between the stack pointer and a constant) compatible with a stack local pattern?
00221         bool        isOpCompatStackLocal(OPER op);  
00222 
00223         // Quick and dirty hack
00224 static  Exp*        getReturnExp2(BinaryFile* pBF);
00225 static  StatementList& getStdRetStmt(Prog* prog);
00226 
00227         // get anything that can be proven as a result of the signature
00228 virtual Exp         *getProven(Exp *left) { return NULL; }
00229 virtual bool        isPreserved(Exp* e) { return false; }       // Return whether e is preserved by this proc
00230 virtual void        setLibraryDefines(StatementList* defs) {}   // Set the locations defined by library calls
00231 static  void        setABIdefines(Prog* prog, StatementList* defs);
00232 
00233         // Return true if this is a known machine (e.g. SparcSignature as opposed to Signature)
00234 virtual bool        isPromoted() { return false; }
00235         // Return true if this has a full blown signature, e.g. main/WinMain etc.
00236         // Note that many calls to isFullSignature were incorrectly calls to isPromoted()
00237         //bool      isFullSignature() {return bFullSig;}
00238 
00239     // ascii versions of platform, calling convention name
00240 static char*        platformName(platform plat);
00241 static char*        conventionName(callconv cc);
00242 virtual platform    getPlatform() { return PLAT_GENERIC; }
00243 virtual callconv    getConvention() { return CONV_NONE; }
00244 
00245         // prefered format
00246         void        setPreferedReturn(Type *ty) { preferedReturn = ty; }
00247         void        setPreferedName(const char *nam) { preferedName = nam; }
00248         void        addPreferedParameter(int n) { preferedParams.push_back(n); }
00249         Type        *getPreferedReturn() { return preferedReturn; }
00250         const char  *getPreferedName() { return preferedName.c_str(); }
00251         unsigned int getNumPreferedParams() { return preferedParams.size(); }
00252         int         getPreferedParam(int n) { return preferedParams[n]; }
00253 
00254         // A compare function for arguments and returns. Used for sorting returns in calcReturn() etc
00255 virtual bool        argumentCompare(Assignment& a, Assignment& b);
00256 virtual bool        returnCompare(Assignment& a, Assignment& b);
00257 
00258 
00259 protected:
00260         friend class XMLProgParser;
00261                     Signature() : name(""), rettype(NULL), ellipsis(false), preferedReturn(NULL), preferedName("") { }
00262         void        appendParameter(Parameter *p) { params.push_back(p); }
00263         //void      appendImplicitParameter(ImplicitParameter *p) { implicitParams.push_back(p); }
00264         void        appendReturn(Return *r) { returns.push_back(r); }
00265 };  // class Signature
00266 
00267 class CustomSignature : public Signature {
00268 protected:
00269         int         sp;
00270 public:
00271     CustomSignature(const char *nam);
00272 virtual ~CustomSignature() { }
00273 virtual bool        isPromoted() { return true; }
00274 virtual Signature   *clone();
00275         void        setSP(int nsp);
00276 virtual int         getStackRegister() throw(StackRegisterNotDefinedException) {return sp; };
00277 };
00278 
00279 #endif

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