00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <assert.h>
00026 #if defined(_MSC_VER) && _MSC_VER <= 1200
00027 #pragma warning(disable:4786)
00028 #endif
00029
00030 #include <string>
00031 #include <sstream>
00032 #include "type.h"
00033 #include "signature.h"
00034 #include "exp.h"
00035 #include "prog.h"
00036 #include "BinaryFile.h"
00037 #include "frontend.h"
00038 #include "signature.h"
00039 #include "util.h"
00040 #include "cfg.h"
00041 #include "proc.h"
00042 #include "boomerang.h"
00043 #include "log.h"
00044 #include "managed.h"
00045
00046 extern char debug_buffer[];
00047
00048 char* Signature::platformName(platform plat) {
00049 switch (plat) {
00050 case PLAT_PENTIUM: return "pentium";
00051 case PLAT_SPARC: return "sparc";
00052 case PLAT_M68K: return "m68k";
00053 case PLAT_PARISC: return "parisc";
00054 case PLAT_PPC: return "ppc";
00055 case PLAT_MIPS: return "mips";
00056 case PLAT_ST20: return "st20";
00057 default: return "???";
00058 }
00059 }
00060
00061 char* Signature::conventionName(callconv cc) {
00062 switch (cc) {
00063 case CONV_C: return "stdc";
00064 case CONV_PASCAL: return "pascal";
00065 case CONV_THISCALL: return "thiscall";
00066 default: return "??";
00067 }
00068 }
00069
00070 namespace CallingConvention {
00071
00072 class Win32Signature : public Signature {
00073
00074 public:
00075 Win32Signature(const char *nam);
00076 Win32Signature(Signature &old);
00077 virtual ~Win32Signature() { }
00078 virtual Signature *clone();
00079 virtual bool operator==(Signature& other);
00080 static bool qualified(UserProc *p, Signature &candidate);
00081
00082 virtual void addReturn(Type *type, Exp *e = NULL);
00083 virtual void addParameter(Type *type, const char *nam = NULL, Exp *e = NULL, const char *boundMax = "");
00084 virtual Exp *getArgumentExp(int n);
00085
00086 virtual Signature *promote(UserProc *p);
00087 virtual Exp *getStackWildcard();
00088 virtual int getStackRegister() throw(StackRegisterNotDefinedException) {return 28; }
00089 virtual Exp *getProven(Exp *left);
00090 virtual bool isPreserved(Exp* e);
00091 virtual void setLibraryDefines(StatementList* defs);
00092
00093 virtual bool isPromoted() {
00094 return true; }
00095 virtual platform getPlatform() { return PLAT_PENTIUM; }
00096 virtual callconv getConvention() { return CONV_PASCAL; }
00097 };
00098
00099 class Win32TcSignature : public Win32Signature {
00100
00101
00102 public:
00103 Win32TcSignature(const char *nam);
00104 Win32TcSignature(Signature &old);
00105 virtual Exp *getArgumentExp(int n);
00106 virtual Exp *getProven(Exp* left);
00107 virtual Signature *clone();
00108 virtual platform getPlatform() { return PLAT_PENTIUM; }
00109 virtual callconv getConvention() { return CONV_THISCALL; }
00110 };
00111
00112
00113 namespace StdC {
00114 class PentiumSignature : public Signature {
00115 public:
00116 PentiumSignature(const char *nam);
00117 PentiumSignature(Signature &old);
00118 virtual ~PentiumSignature() { }
00119 virtual Signature *clone();
00120 virtual bool operator==(Signature& other);
00121 static bool qualified(UserProc *p, Signature &candidate);
00122
00123 virtual void addReturn(Type *type, Exp *e = NULL);
00124 virtual void addParameter(Type *type, const char *nam = NULL, Exp *e = NULL, const char *boundMax = "");
00125 virtual Exp *getArgumentExp(int n);
00126
00127 virtual Signature *promote(UserProc *p);
00128 virtual Exp *getStackWildcard();
00129 virtual int getStackRegister() throw(StackRegisterNotDefinedException) {return 28; }
00130 virtual Exp *getProven(Exp *left);
00131 virtual bool isPreserved(Exp* e);
00132 virtual void setLibraryDefines(StatementList* defs);
00133 virtual bool isPromoted() { return true; }
00134 virtual platform getPlatform() { return PLAT_PENTIUM; }
00135 virtual callconv getConvention() { return CONV_C; }
00136 virtual bool returnCompare(Assignment& a, Assignment& b);
00137 virtual bool argumentCompare(Assignment& a, Assignment& b);
00138 };
00139
00140 class SparcSignature : public Signature {
00141 public:
00142 SparcSignature(const char *nam);
00143 SparcSignature(Signature &old);
00144 virtual ~SparcSignature() { }
00145 virtual Signature *clone();
00146 virtual bool operator==(Signature& other);
00147 static bool qualified(UserProc *p, Signature &candidate);
00148
00149 virtual void addReturn(Type *type, Exp *e = NULL);
00150 virtual void addParameter(Type *type, const char *nam = NULL, Exp *e = NULL,
00151 const char *boundMax = "");
00152 virtual Exp *getArgumentExp(int n);
00153
00154 virtual Signature *promote(UserProc *p);
00155 virtual Exp *getStackWildcard();
00156 virtual int getStackRegister() throw(StackRegisterNotDefinedException) {return 14; }
00157 virtual Exp *getProven(Exp *left);
00158 virtual bool isPreserved(Exp* e);
00159 virtual void setLibraryDefines(StatementList* defs);
00160
00161 virtual bool isLocalOffsetPositive() {return true;}
00162
00163 virtual bool isAddrOfStackLocal(Prog* prog, Exp* e);
00164 virtual bool isPromoted() { return true; }
00165 virtual platform getPlatform() { return PLAT_SPARC; }
00166 virtual callconv getConvention() { return CONV_C; }
00167 virtual bool returnCompare(Assignment& a, Assignment& b);
00168 virtual bool argumentCompare(Assignment& a, Assignment& b);
00169 };
00170
00171 class SparcLibSignature : public SparcSignature {
00172 public:
00173 SparcLibSignature(const char *nam) : SparcSignature(nam) {}
00174 SparcLibSignature(Signature &old);
00175 virtual Signature *clone();
00176 virtual Exp* getProven(Exp* left);
00177 };
00178
00179 class PPCSignature : public Signature {
00180 public:
00181 PPCSignature(const char *name);
00182 PPCSignature(Signature& old);
00183 virtual ~PPCSignature() { }
00184 virtual Signature *clone();
00185 static bool qualified(UserProc *p, Signature &candidate);
00186 virtual void addReturn(Type *type, Exp *e = NULL);
00187 virtual Exp *getArgumentExp(int n);
00188 virtual void addParameter(Type *type, const char *nam , Exp *e , const char *boundMax );
00189 virtual Exp *getStackWildcard();
00190 virtual int getStackRegister() throw(StackRegisterNotDefinedException) {return 1; }
00191 virtual Exp *getProven(Exp *left);
00192 virtual bool isPreserved(Exp* e);
00193 virtual void setLibraryDefines(StatementList* defs);
00194 virtual bool isLocalOffsetPositive() {return true;}
00195 virtual bool isPromoted() { return true; }
00196 virtual platform getPlatform() { return PLAT_PPC; }
00197 virtual callconv getConvention() { return CONV_C; }
00198 };
00199 class ST20Signature : public Signature {
00200 public:
00201 ST20Signature(const char *name);
00202 ST20Signature(Signature &old);
00203 virtual ~ST20Signature() { }
00204 Signature *clone();
00205 virtual bool operator==(Signature& other);
00206 static bool qualified(UserProc *p, Signature &candidate);
00207
00208 virtual void addReturn(Type *type, Exp *e = NULL);
00209 void addParameter(Type *type, const char *nam , Exp *e , const char *boundMax );
00210 Exp *getArgumentExp(int n);
00211
00212 virtual Signature *promote(UserProc *p);
00213 virtual Exp *getStackWildcard();
00214 virtual int getStackRegister() throw(StackRegisterNotDefinedException) {return 3; }
00215 virtual Exp *getProven(Exp *left);
00216 virtual bool isPromoted() { return true; }
00217
00218 virtual platform getPlatform() { return PLAT_ST20; }
00219 virtual callconv getConvention() { return CONV_C; }
00220 };
00221 };
00222 };
00223
00224 CallingConvention::Win32Signature::Win32Signature(const char *nam) : Signature(nam) {
00225 Signature::addReturn(Location::regOf(28));
00226
00227
00228 }
00229
00230 CallingConvention::Win32Signature::Win32Signature(Signature &old) : Signature(old) {
00231 }
00232
00233 CallingConvention::Win32TcSignature::Win32TcSignature(const char *nam) : Win32Signature(nam) {
00234 Signature::addReturn(Location::regOf(28));
00235
00236
00237 }
00238
00239 CallingConvention::Win32TcSignature::Win32TcSignature(Signature &old) : Win32Signature(old) {
00240 }
00241
00242 static void cloneVec(std::vector<Parameter*>& from, std::vector<Parameter*>& to) {
00243 unsigned n = from.size();
00244 to.resize(n);
00245 for (unsigned i=0; i < n; i++)
00246 to[i] = from[i]->clone();
00247 }
00248
00249 static void cloneVec(Returns& from, Returns& to) {
00250 unsigned n = from.size();
00251 to.resize(n);
00252 for (unsigned i=0; i < n; i++)
00253 to[i] = from[i]->clone();
00254 }
00255
00256 Parameter *hack;
00257
00258 Parameter* Parameter::clone() {
00259 return new Parameter(type->clone(), name.c_str(), exp->clone(), boundMax.c_str());
00260 }
00261
00262 void Parameter::setBoundMax(const char *nam) {
00263 hack = this;
00264 boundMax = nam;
00265 }
00266
00267 Signature *CallingConvention::Win32Signature::clone()
00268 {
00269 Win32Signature *n = new Win32Signature(name.c_str());
00270 cloneVec(params, n->params);
00271
00272 cloneVec(returns, n->returns);
00273 n->ellipsis = ellipsis;
00274 n->rettype = rettype->clone();
00275 n->preferedName = preferedName;
00276 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
00277 else n->preferedReturn = NULL;
00278 n->preferedParams = preferedParams;
00279 return n;
00280 }
00281
00282 Signature *CallingConvention::Win32TcSignature::clone()
00283 {
00284 Win32TcSignature *n = new Win32TcSignature(name.c_str());
00285 cloneVec(params, n->params);
00286
00287 cloneVec(returns, n->returns);
00288 n->ellipsis = ellipsis;
00289 n->rettype = rettype->clone();
00290 n->preferedName = preferedName;
00291 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
00292 else n->preferedReturn = NULL;
00293 n->preferedParams = preferedParams;
00294 return n;
00295 }
00296
00297 bool CallingConvention::Win32Signature::operator==(Signature& other)
00298 {
00299 return Signature::operator==(other);
00300 }
00301
00302 static Exp* savedReturnLocation = Location::memOf(Location::regOf(28));
00303 static Exp* stackPlusFour = new Binary(opPlus,
00304 Location::regOf(28),
00305 new Const(4));
00306
00307 bool CallingConvention::Win32Signature::qualified(UserProc *p, Signature &candidate) {
00308 platform plat = p->getProg()->getFrontEndId();
00309 if (plat != PLAT_PENTIUM || !p->getProg()->isWin32()) return false;
00310
00311 if (VERBOSE)
00312 LOG << "consider promotion to stdc win32 signature for " << p->getName() << "\n";
00313
00314 bool gotcorrectret1, gotcorrectret2 = false;
00315 Exp *provenPC = p->getProven(new Terminal(opPC));
00316 gotcorrectret1 = provenPC && (*provenPC == *savedReturnLocation);
00317 if (gotcorrectret1) {
00318 if (VERBOSE)
00319 LOG << "got pc = m[r[28]]\n";
00320 Exp *provenSP = p->getProven(Location::regOf(28));
00321 gotcorrectret2 = provenSP && *provenSP == *stackPlusFour;
00322 if (gotcorrectret2 && VERBOSE)
00323 LOG << "got r[28] = r[28] + 4\n";
00324 }
00325 if (VERBOSE)
00326 LOG << "qualified: " << (gotcorrectret1 && gotcorrectret2) << "\n";
00327 return gotcorrectret1 && gotcorrectret2;
00328 }
00329
00330 void CallingConvention::Win32Signature::addReturn(Type *type, Exp *e)
00331 {
00332 if (type->isVoid())
00333 return;
00334 if (e == NULL) {
00335 if (type->isFloat())
00336 e = Location::regOf(32);
00337 else
00338 e = Location::regOf(24);
00339 }
00340 Signature::addReturn(type, e);
00341 }
00342
00343 void CallingConvention::Win32Signature::addParameter(Type *type, const char *nam , Exp *e , const char *boundMax )
00344 {
00345 if (e == NULL) {
00346 e = getArgumentExp(params.size());
00347 }
00348 Signature::addParameter(type, nam, e, boundMax);
00349 }
00350
00351 Exp *CallingConvention::Win32Signature::getArgumentExp(int n) {
00352 if (n < (int)params.size())
00353 return Signature::getArgumentExp(n);
00354 Exp *esp = Location::regOf(28);
00355 if (params.size() != 0 && *params[0]->getExp() == *esp)
00356 n--;
00357 Exp *e = Location::memOf(new Binary(opPlus, esp, new Const((n+1) * 4)));
00358 return e;
00359 }
00360
00361 Exp* CallingConvention::Win32TcSignature::getArgumentExp(int n) {
00362 if (n < (int)params.size())
00363 return Signature::getArgumentExp(n);
00364 Exp *esp = Location::regOf(28);
00365 if (params.size() != 0 && *params[0]->getExp() == *esp)
00366 n--;
00367 if (n == 0)
00368
00369 return Location::regOf(25);
00370
00371 Exp *e = Location::memOf(new Binary(opPlus, esp, new Const(n * 4)));
00372 return e;
00373 }
00374
00375 Signature *CallingConvention::Win32Signature::promote(UserProc *p)
00376 {
00377
00378
00379 return this;
00380 }
00381
00382 Exp *CallingConvention::Win32Signature::getStackWildcard() {
00383
00384 return Location::memOf(
00385 new Binary(opMinus,
00386 Location::regOf(28),
00387 new Terminal(opWild)));
00388 }
00389
00390 Exp *CallingConvention::Win32Signature::getProven(Exp *left) {
00391 int nparams = params.size();
00392 if (nparams > 0 && *params[0]->getExp() == *Location::regOf(28)) {
00393 nparams--;
00394 }
00395 if (left->isRegOfK()) {
00396 switch (((Const*)left->getSubExp1())->getInt()) {
00397 case 28:
00398
00399 return new Binary(opPlus, Location::regOf(28),
00400 new Const(4 + nparams*4));
00401 case 27:
00402 return Location::regOf(27);
00403 case 29:
00404 return Location::regOf(29);
00405 case 30:
00406 return Location::regOf(30);
00407 case 31:
00408 return Location::regOf(31);
00409
00410 }
00411 }
00412 return NULL;
00413 }
00414
00415 bool CallingConvention::Win32Signature::isPreserved(Exp* e) {
00416 if (e->isRegOfK()) {
00417 switch (((Const*)e->getSubExp1())->getInt()) {
00418 case 29:
00419 case 27:
00420 case 30:
00421 case 31:
00422 case 3:
00423 case 5:
00424 case 6:
00425 case 7:
00426 case 11:
00427 case 15:
00428 return true;
00429 default:
00430 return false;
00431 }
00432 }
00433 return false;
00434 }
00435
00436
00437 void CallingConvention::Win32Signature::setLibraryDefines(StatementList* defs) {
00438 if (defs->size()) return;
00439 Location* r24 = Location::regOf(24);
00440 Type* ty = new SizeType(32);
00441 if (returns.size() > 1) {
00442 ty = returns[1]->type;
00443 #if 0 // ADHOC TA
00444 if (ty->isFloat()) {
00445 Location* r32 = Location::regOf(32);
00446 r32->setType(ty);
00447 } else
00448 r24->setType(ty);
00449 #endif
00450 }
00451 defs->append(new ImplicitAssign(ty, r24));
00452 defs->append(new ImplicitAssign(Location::regOf(25)));
00453 defs->append(new ImplicitAssign(Location::regOf(26)));
00454 defs->append(new ImplicitAssign(Location::regOf(28)));
00455 }
00456
00457 Exp *CallingConvention::Win32TcSignature::getProven(Exp *left)
00458 {
00459 if (left->isRegOfK()) {
00460 if (((Const*)left->getSubExp1())->getInt() == 28) {
00461 int nparams = params.size();
00462 if (nparams > 0 && *params[0]->getExp() == *Location::regOf(28)) {
00463 nparams--;
00464 }
00465
00466 return new Binary(opPlus,
00467 Location::regOf(28),
00468 new Const(4 + nparams*4 - 4));
00469 }
00470 }
00471
00472 return Win32Signature::getProven(left);
00473 }
00474
00475
00476 CallingConvention::StdC::PentiumSignature::PentiumSignature(const char *nam) : Signature(nam)
00477 {
00478 Signature::addReturn(Location::regOf(28));
00479
00480
00481 }
00482
00483 CallingConvention::StdC::PentiumSignature::PentiumSignature(Signature &old) : Signature(old)
00484 {
00485
00486 }
00487
00488 Signature *CallingConvention::StdC::PentiumSignature::clone()
00489 {
00490 PentiumSignature *n = new PentiumSignature(name.c_str());
00491 cloneVec(params, n->params);
00492
00493 cloneVec(returns, n->returns);
00494 n->ellipsis = ellipsis;
00495 n->rettype = rettype->clone();
00496 n->preferedName = preferedName;
00497 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
00498 else n->preferedReturn = NULL;
00499 n->preferedParams = preferedParams;
00500 n->unknown = unknown;
00501 return n;
00502 }
00503
00504 bool CallingConvention::StdC::PentiumSignature::operator==(Signature& other)
00505 {
00506 return Signature::operator==(other);
00507 }
00508
00509
00510
00511
00512 bool CallingConvention::StdC::PentiumSignature::qualified(UserProc *p, Signature &candidate) {
00513 platform plat = p->getProg()->getFrontEndId();
00514 if (plat != PLAT_PENTIUM) return false;
00515
00516 if (VERBOSE)
00517 LOG << "consider promotion to stdc pentium signature for " << p->getName() << "\n";
00518
00519 #if 1
00520 if (VERBOSE)
00521 LOG << "qualified: always true\n";
00522 return true;
00523 #else
00524 bool gotcorrectret1 = false;
00525 bool gotcorrectret2 = false;
00526 StatementList internal;
00527
00528 internal.append(*p->getCFG()->getReachExit());
00529 StmtListIter it;
00530 for (Statement* s = internal.getFirst(it); s; s = internal.getNext(it)) {
00531 Assign *e = dynamic_cast<Assign*>(s);
00532 if (e == NULL) continue;
00533 if (e->getLeft()->getOper() == opPC) {
00534 if (e->getRight()->isMemOf() && e->getRight()->getSubExp1()->isRegOfN(28)) {
00535 if (VERBOSE)
00536 std::cerr << "got pc = m[r[28]]" << std::endl;
00537 gotcorrectret1 = true;
00538 }
00539 } else if (e->getLeft()->isRegOfK() &&
00540 ((Const*)e->getLeft()->getSubExp1())->getInt() == 28) {
00541 if (e->getRight()->getOper() == opPlus &&
00542 e->getRight()->getSubExp1()->isRegOfN(28) &&
00543 e->getRight()->getSubExp2()->isIntConst() &&
00544 ((Const*)e->getRight()->getSubExp2())->getInt() == 4) {
00545 if (VERBOSE)
00546 std::cerr << "got r[28] = r[28] + 4" << std::endl;
00547 gotcorrectret2 = true;
00548 }
00549 }
00550 }
00551 if (VERBOSE)
00552 LOG << "promotion: " << gotcorrectret1 && gotcorrectret2 << "\n";
00553 return gotcorrectret1 && gotcorrectret2;
00554 #endif
00555 }
00556
00557 void CallingConvention::StdC::PentiumSignature::addReturn(Type *type, Exp *e)
00558 {
00559 if (type->isVoid())
00560 return;
00561 if (e == NULL) {
00562 if (type->isFloat())
00563 e = Location::regOf(32);
00564 else
00565 e = Location::regOf(24);
00566 }
00567 Signature::addReturn(type, e);
00568 }
00569
00570 void CallingConvention::StdC::PentiumSignature::addParameter(Type *type, const char *nam , Exp *e , const char *boundMax )
00571 {
00572 if (e == NULL) {
00573 e = getArgumentExp(params.size());
00574 }
00575 Signature::addParameter(type, nam, e, boundMax);
00576 }
00577
00578 Exp *CallingConvention::StdC::PentiumSignature::getArgumentExp(int n) {
00579 if (n < (int)params.size())
00580 return Signature::getArgumentExp(n);
00581 Exp *esp = Location::regOf(28);
00582 if (params.size() != 0 && *params[0]->getExp() == *esp)
00583 n--;
00584 Exp *e = Location::memOf(new Binary(opPlus, esp, new Const((n+1) * 4)));
00585 return e;
00586 }
00587
00588 Signature *CallingConvention::StdC::PentiumSignature::promote(UserProc *p) {
00589
00590 return this;
00591 }
00592
00593 Exp *CallingConvention::StdC::PentiumSignature::getStackWildcard() {
00594
00595 return Location::memOf(
00596 new Binary(opMinus,
00597 Location::regOf(28),
00598 new Terminal(opWild)));
00599 }
00600
00601 Exp *CallingConvention::StdC::PentiumSignature::getProven(Exp *left) {
00602 if (left->isRegOfK()) {
00603 int r = ((Const*)left->getSubExp1())->getInt();
00604 switch (r) {
00605 case 28:
00606 return new Binary(opPlus, Location::regOf(28), new Const(4));
00607 case 29: case 30: case 31: case 27:
00608 return Location::regOf(r);
00609 }
00610 }
00611 return NULL;
00612 }
00613
00614 bool CallingConvention::StdC::PentiumSignature::isPreserved(Exp* e) {
00615 if (e->isRegOfK()) {
00616 switch (((Const*)e->getSubExp1())->getInt()) {
00617 case 29:
00618 case 27:
00619 case 30:
00620 case 31:
00621 case 3:
00622 case 5:
00623 case 6:
00624 case 7:
00625 case 11:
00626 case 15:
00627 return true;
00628 default:
00629 return false;
00630 }
00631 }
00632 return false;
00633 }
00634
00635
00636 void CallingConvention::StdC::PentiumSignature::setLibraryDefines(StatementList* defs) {
00637 if (defs->size()) return;
00638 Location* r24 = Location::regOf(24);
00639 Type* ty = new SizeType(32);
00640 if (returns.size() > 1) {
00641 ty = returns[1]->type;
00642 #if 0 // ADHOC TA
00643 if (ty->isFloat()) {
00644 Location* r32 = Location::regOf(32);
00645 r32->setType(ty);
00646 } else
00647 r24->setType(ty);
00648 #endif
00649 }
00650 defs->append(new ImplicitAssign(ty, r24));
00651 defs->append(new ImplicitAssign(Location::regOf(25)));
00652 defs->append(new ImplicitAssign(Location::regOf(26)));
00653 defs->append(new ImplicitAssign(Location::regOf(28)));
00654 }
00655
00656 CallingConvention::StdC::PPCSignature::PPCSignature(const char *nam) : Signature(nam) {
00657 Signature::addReturn(Location::regOf(1));
00658
00659
00660
00661 }
00662
00663 CallingConvention::StdC::PPCSignature::PPCSignature(Signature& old) : Signature(old) {
00664 }
00665
00666 Signature *CallingConvention::StdC::PPCSignature::clone() {
00667 PPCSignature *n = new PPCSignature(name.c_str());
00668 cloneVec(params, n->params);
00669
00670 cloneVec(returns, n->returns);
00671 n->ellipsis = ellipsis;
00672 n->rettype = rettype->clone();
00673 n->preferedName = preferedName;
00674 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
00675 else n->preferedReturn = NULL;
00676 n->preferedParams = preferedParams;
00677 n->unknown = unknown;
00678 return n;
00679 }
00680
00681
00682 Exp *CallingConvention::StdC::PPCSignature::getArgumentExp(int n) {
00683 if (n < (int)params.size())
00684 return Signature::getArgumentExp(n);
00685 Exp *e;
00686 if (n >= 8) {
00687
00688
00689 e = Location::memOf(new Binary(opPlus,
00690 Location::regOf(1),
00691 new Const(8 + (n-8)*4)));
00692 } else
00693 e = Location::regOf((int)(3 + n));
00694 return e;
00695 }
00696
00697 void CallingConvention::StdC::PPCSignature::addReturn(Type *type, Exp *e)
00698 {
00699 if (type->isVoid())
00700 return;
00701 if (e == NULL) {
00702 e = Location::regOf(3);
00703 }
00704 Signature::addReturn(type, e);
00705 }
00706
00707
00708 void CallingConvention::StdC::PPCSignature::addParameter(Type *type, const char *nam , Exp *e , const char *boundMax ) {
00709 if (e == NULL) {
00710 e = getArgumentExp(params.size());
00711 }
00712 Signature::addParameter(type, nam, e, boundMax);
00713 }
00714
00715 Exp* CallingConvention::StdC::PPCSignature::getStackWildcard() {
00716
00717 return Location::memOf(
00718 new Binary(opMinus,
00719 Location::regOf(1),
00720 new Terminal(opWild)));
00721 }
00722
00723 Exp *CallingConvention::StdC::PPCSignature::getProven(Exp* left) {
00724 if (left->isRegOfK()) {
00725 int r = ((Const*)((Location*)left)->getSubExp1())->getInt();
00726 switch (r) {
00727 case 1:
00728 return left;
00729 }
00730 }
00731 return NULL;
00732 }
00733
00734 bool CallingConvention::StdC::PPCSignature::isPreserved(Exp* e) {
00735 if (e->isRegOfK()) {
00736 int r = ((Const*)e->getSubExp1())->getInt();
00737 return r == 1;
00738 }
00739 return false;
00740 }
00741
00742
00743 void CallingConvention::StdC::PPCSignature::setLibraryDefines(StatementList* defs) {
00744 if (defs->size()) return;
00745 for (int r=3; r <= 12; ++r)
00746 defs->append(new ImplicitAssign(Location::regOf(r)));
00747 }
00748
00749
00750
00751 CallingConvention::StdC::ST20Signature::ST20Signature(const char *nam) : Signature(nam) {
00752 Signature::addReturn(Location::regOf(3));
00753
00754
00755 }
00756
00757 CallingConvention::StdC::ST20Signature::ST20Signature(Signature &old) : Signature(old)
00758 {
00759
00760 }
00761
00762 Signature *CallingConvention::StdC::ST20Signature::clone() {
00763 ST20Signature *n = new ST20Signature(name.c_str());
00764 n->params = params;
00765 n->returns = returns;
00766 n->ellipsis = ellipsis;
00767 n->rettype = rettype;
00768 n->preferedName = preferedName;
00769 n->preferedReturn = preferedReturn;
00770 n->preferedParams = preferedParams;
00771 n->unknown = unknown;
00772 return n;
00773 }
00774
00775 bool CallingConvention::StdC::ST20Signature::operator==(Signature& other)
00776 {
00777 return Signature::operator==(other);
00778 }
00779
00780
00781 Exp *CallingConvention::StdC::ST20Signature::getArgumentExp(int n) {
00782 if (n < (int)params.size())
00783 return Signature::getArgumentExp(n);
00784
00785 Exp *sp = Location::regOf(3);
00786 if (params.size() != 0 && *params[0]->getExp() == *sp)
00787 n--;
00788 Exp *e = Location::memOf(new Binary(opPlus, sp, new Const((n+1) * 4)));
00789 return e;
00790 }
00791
00792 void CallingConvention::StdC::ST20Signature::addReturn(Type *type, Exp *e)
00793 {
00794 if (type->isVoid())
00795 return;
00796 if (e == NULL) {
00797 e = Location::regOf(0);
00798 }
00799 Signature::addReturn(type, e);
00800 }
00801
00802 Signature *CallingConvention::StdC::ST20Signature::promote(UserProc *p) {
00803
00804 return this;
00805 }
00806
00807 void CallingConvention::StdC::ST20Signature::addParameter(Type *type, const char *nam , Exp *e , const char *boundMax )
00808 {
00809 if (e == NULL) {
00810 e = getArgumentExp(params.size());
00811 }
00812 Signature::addParameter(type, nam, e, boundMax);
00813 }
00814
00815 Exp* CallingConvention::StdC::ST20Signature::getStackWildcard() {
00816
00817 return Location::memOf(
00818 new Binary(opMinus,
00819 Location::regOf(3),
00820 new Terminal(opWild)));
00821 }
00822
00823 #if 1
00824 Exp *CallingConvention::StdC::ST20Signature::getProven(Exp *left) {
00825 if (left->isRegOfK()) {
00826 int r = ((Const*)left->getSubExp1())->getInt();
00827 switch (r) {
00828 case 3:
00829
00830 return left;
00831 case 0: case 1: case 2:
00832
00833 return Location::regOf(r);
00834 }
00835 }
00836 return NULL;
00837 }
00838 #else
00839 Exp *CallingConvention::StdC::ST20Signature::getProven(Exp* left) {
00840 if (left->isRegOfK()) {
00841 int r = ((Const*)((Location*)left)->getSubExp1())->getInt();
00842 switch (r) {
00843 case 3:
00844 return left;
00845 }
00846 }
00847 return NULL;
00848 }
00849 #endif
00850
00851 bool CallingConvention::StdC::ST20Signature::qualified(UserProc *p, Signature &candidate) {
00852 platform plat = p->getProg()->getFrontEndId();
00853 if (plat != PLAT_ST20) return false;
00854
00855 if (VERBOSE)
00856 LOG << "consider promotion to stdc st20 signature for " << p->getName() << "\n";
00857
00858 return true;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 CallingConvention::StdC::SparcSignature::SparcSignature(const char *nam) : Signature(nam) {
00875 Signature::addReturn(Location::regOf(14));
00876
00877
00878 }
00879
00880 CallingConvention::StdC::SparcSignature::SparcSignature(Signature &old) : Signature(old) {
00881 }
00882
00883 Signature *CallingConvention::StdC::SparcSignature::clone() {
00884 SparcSignature *n = new SparcSignature(name.c_str());
00885 cloneVec(params, n->params);
00886
00887 cloneVec(returns, n->returns);
00888 n->ellipsis = ellipsis;
00889 n->rettype = rettype->clone();
00890 n->preferedName = preferedName;
00891 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
00892 else n->preferedReturn = NULL;
00893 n->preferedParams = preferedParams;
00894 n->unknown = unknown;
00895 return n;
00896 }
00897
00898 Signature *CallingConvention::StdC::SparcLibSignature::clone() {
00899 SparcLibSignature *n = new SparcLibSignature(name.c_str());
00900 cloneVec(params, n->params);
00901
00902 cloneVec(returns, n->returns);
00903 n->ellipsis = ellipsis;
00904 n->rettype = rettype->clone();
00905 n->preferedName = preferedName;
00906 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
00907 else n->preferedReturn = NULL;
00908 n->preferedParams = preferedParams;
00909 return n;
00910 }
00911
00912 bool CallingConvention::StdC::SparcSignature::operator==(Signature& other) {
00913 return Signature::operator==(other);
00914 }
00915
00916
00917 bool CallingConvention::StdC::SparcSignature::qualified(UserProc *p, Signature &candidate) {
00918 if (VERBOSE)
00919 LOG << "consider promotion to stdc sparc signature for " << p->getName() << "\n";
00920
00921 platform plat = p->getProg()->getFrontEndId();
00922 if (plat != PLAT_SPARC) return false;
00923
00924 if (VERBOSE)
00925 LOG << "Promoted to StdC::SparcSignature\n";
00926
00927 return true;
00928 }
00929
00930 bool CallingConvention::StdC::PPCSignature::qualified(UserProc *p, Signature &candidate) {
00931 if (VERBOSE)
00932 LOG << "consider promotion to stdc PPC signature for " << p->getName() << "\n";
00933
00934 platform plat = p->getProg()->getFrontEndId();
00935 if (plat != PLAT_PPC) return false;
00936
00937 if (VERBOSE)
00938 LOG << "Promoted to StdC::PPCSignature (always qualifies)\n";
00939
00940 return true;
00941 }
00942
00943 void CallingConvention::StdC::SparcSignature::addReturn(Type *type, Exp *e)
00944 {
00945 if (type->isVoid())
00946 return;
00947 if (e == NULL) {
00948 e = Location::regOf(8);
00949 }
00950 Signature::addReturn(type, e);
00951 }
00952
00953 void CallingConvention::StdC::SparcSignature::addParameter(Type *type, const char *nam , Exp *e , const char *boundMax ) {
00954 if (e == NULL) {
00955 e = getArgumentExp(params.size());
00956 }
00957 Signature::addParameter(type, nam, e, boundMax);
00958 }
00959
00960 Exp *CallingConvention::StdC::SparcSignature::getArgumentExp(int n) {
00961 if (n < (int)params.size())
00962 return Signature::getArgumentExp(n);
00963 Exp *e;
00964 if (n >= 6) {
00965
00966
00967 e = Location::memOf(new Binary(opPlus,
00968 Location::regOf(14),
00969 new Const(92 + (n-6)*4)));
00970 } else
00971 e = Location::regOf((int)(8 + n));
00972 return e;
00973 }
00974
00975 Signature *CallingConvention::StdC::SparcSignature::promote(UserProc *p) {
00976
00977 return this;
00978 }
00979
00980 Exp *CallingConvention::StdC::SparcSignature::getStackWildcard() {
00981 return Location::memOf(
00982 new Binary(opPlus,
00983 Location::regOf(14),
00984 new Terminal(opWild)));
00985 }
00986
00987 Exp *CallingConvention::StdC::SparcSignature::getProven(Exp* left) {
00988 if (left->isRegOfK()) {
00989 int r = ((Const*)((Location*)left)->getSubExp1())->getInt();
00990 switch (r) {
00991
00992 case 14:
00993 case 24: case 25: case 26: case 27:
00994 case 28: case 29: case 30: case 31:
00995
00996 return left;
00997 }
00998 }
00999 return NULL;
01000 }
01001
01002 bool CallingConvention::StdC::SparcSignature::isPreserved(Exp* e) {
01003 if (e->isRegOfK()) {
01004 int r = ((Const*)((Location*)e)->getSubExp1())->getInt();
01005 switch (r) {
01006
01007 case 14:
01008 case 24: case 25: case 26: case 27:
01009 case 28: case 29: case 30: case 31:
01010
01011 return true;
01012 default:
01013 return false;
01014 }
01015 }
01016 return false;
01017 }
01018
01019
01020 void CallingConvention::StdC::SparcSignature::setLibraryDefines(StatementList* defs) {
01021 if (defs->size()) return;
01022 for (int r=8; r <= 15; ++r)
01023 defs->append(new ImplicitAssign(Location::regOf(r)));
01024 }
01025
01026
01027 Exp *CallingConvention::StdC::SparcLibSignature::getProven(Exp* left) {
01028 if (left->isRegOfK()) {
01029 int r = ((Const*)((Location*)left)->getSubExp1())->getInt();
01030 switch (r) {
01031
01032 case 14:
01033 case 24: case 25: case 26: case 27:
01034 case 28: case 29: case 30: case 31:
01035
01036
01037
01038 case 2: case 3: case 4:
01039
01040
01041 return left;
01042 }
01043 }
01044 return NULL;
01045 }
01046
01047
01048
01049 Signature::Signature(const char *nam) : rettype(new VoidType()), ellipsis(false), unknown(true), forced(false),
01050 preferedReturn(NULL) {
01051 if (nam == NULL)
01052 name = "<ANON>";
01053 else
01054 name = nam;
01055 }
01056
01057 CustomSignature::CustomSignature(const char *nam) : Signature(nam), sp(0) {
01058 }
01059
01060 void CustomSignature::setSP(int nsp)
01061 {
01062 sp = nsp;
01063 if (sp) {
01064 addReturn(Location::regOf(sp));
01065
01066
01067 }
01068 }
01069
01070 Signature *Signature::clone()
01071 {
01072 Signature *n = new Signature(name.c_str());
01073 cloneVec(params, n->params);
01074
01075 cloneVec(returns, n->returns);
01076 n->ellipsis = ellipsis;
01077 n->rettype = rettype->clone();
01078 n->preferedName = preferedName;
01079 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
01080 else n->preferedReturn = NULL;
01081 n->preferedParams = preferedParams;
01082 n->unknown = unknown;
01083 n->sigFile = sigFile;
01084 return n;
01085 }
01086
01087 Signature *CustomSignature::clone()
01088 {
01089 CustomSignature *n = new CustomSignature(name.c_str());
01090 cloneVec(params, n->params);
01091
01092 cloneVec(returns, n->returns);
01093 n->ellipsis = ellipsis;
01094 n->rettype = rettype->clone();
01095 n->sp = sp;
01096 n->preferedName = preferedName;
01097 if (preferedReturn) n->preferedReturn = preferedReturn->clone();
01098 else n->preferedReturn = NULL;
01099 n->preferedParams = preferedParams;
01100 return n;
01101 }
01102
01103
01104 bool Signature::operator==(Signature& other)
01105 {
01106
01107 if (params.size() != other.params.size()) return false;
01108
01109 std::vector<Parameter*>::iterator it1, it2;
01110 for (it1 = params.begin(), it2 = other.params.begin(); it1 != params.end(); it1++, it2++)
01111 if (!(**it1 == **it2)) return false;
01112 if (returns.size() != other.returns.size()) return false;
01113 std::vector<Return*>::iterator rr1, rr2;
01114 for (rr1 = returns.begin(), rr2 = other.returns.begin(); rr1 != returns.end(); ++rr1, ++rr2)
01115 if (!(**rr1 == **rr2)) return false;
01116 return true;
01117 }
01118
01119 const char *Signature::getName()
01120 {
01121 return name.c_str();
01122 }
01123
01124 void Signature::setName(const char *nam)
01125 {
01126 name = nam;
01127 }
01128
01129 void Signature::addParameter(const char *nam ) {
01130 addParameter(new VoidType(), nam);
01131 }
01132
01133 void Signature::addParameter(Exp *e, Type* ty) {
01134 addParameter(ty, NULL, e);
01135 }
01136
01137 void Signature::addParameter(Type *type, const char *nam , Exp *e , const char *boundMax ) {
01138 if (e == NULL) {
01139 std::cerr << "No expression for parameter ";
01140 if (type == NULL)
01141 std::cerr << "<notype> ";
01142 else
01143 std::cerr << type->getCtype() << " ";
01144 if (nam == NULL)
01145 std::cerr << "<noname>";
01146 else
01147 std::cerr << nam;
01148 std::cerr << "\n";
01149 assert(e);
01150 }
01151
01152 std::string s;
01153 if (nam == NULL) {
01154 int n = params.size()+1;
01155 bool ok = false;
01156 while (!ok) {
01157 std::stringstream os;
01158 os << "param" << n << std::ends;
01159 s = os.str();
01160 ok = true;
01161 for (unsigned i = 0; i < params.size(); i++)
01162 if (!strcmp(s.c_str(), params[i]->getName()))
01163 ok = false;
01164 n++;
01165 }
01166 nam = s.c_str();
01167 }
01168 Parameter *p = new Parameter(type, nam, e, boundMax);
01169 addParameter(p);
01170
01171 }
01172
01173 void Signature::addParameter(Parameter *param)
01174 {
01175 Type *ty = param->getType();
01176 const char *nam = param->getName();
01177 Exp *e = param->getExp();
01178
01179 if (strlen(nam) == 0)
01180 nam = NULL;
01181
01182 if (ty == NULL || e == NULL || nam == NULL) {
01183 addParameter(ty, nam, e, param->getBoundMax());
01184 } else
01185 params.push_back(param);
01186 }
01187
01188 void Signature::removeParameter(Exp *e) {
01189 int i = findParam(e);
01190 if (i != -1)
01191 removeParameter(i);
01192 }
01193
01194 void Signature::removeParameter(int i) {
01195 for (unsigned j = i+1; j < params.size(); j++)
01196 params[j-1] = params[j];
01197 params.resize(params.size()-1);
01198 }
01199
01200 void Signature::setNumParams(int n) {
01201 if (n < (int)params.size()) {
01202
01203 params.erase(params.begin() + n, params.end());
01204 } else {
01205 for (int i = params.size(); i < n; i++)
01206 addParameter();
01207 }
01208 }
01209
01210 const char *Signature::getParamName(int n) {
01211 assert(n < (int)params.size());
01212 return params[n]->getName();
01213 }
01214
01215 Exp *Signature::getParamExp(int n) {
01216 assert(n < (int)params.size());
01217 return params[n]->getExp();
01218 }
01219
01220 Type *Signature::getParamType(int n) {
01221
01222
01223 if (n >= (int)params.size()) return NULL;
01224 return params[n]->getType();
01225 }
01226
01227 const char *Signature::getParamBoundMax(int n)
01228 {
01229 if (n >= (int)params.size()) return NULL;
01230 const char *s = params[n]->getBoundMax();
01231 if (strlen(s) == 0)
01232 return NULL;
01233 return s;
01234 }
01235
01236 void Signature::setParamType(int n, Type *ty) {
01237 params[n]->setType(ty);
01238 }
01239
01240 void Signature::setParamType(const char* nam, Type* ty) {
01241 int idx = findParam(nam);
01242 if (idx == -1) {
01243 LOG << "could not set type for unknown parameter " << nam << "\n";
01244 return;
01245 }
01246 params[idx]->setType(ty);
01247 }
01248
01249 void Signature::setParamType(Exp* e, Type* ty) {
01250 int idx = findParam(e);
01251 if (idx == -1) {
01252 LOG << "could not set type for unknown parameter expression " << e << "\n";
01253 return;
01254 }
01255 params[idx]->setType(ty);
01256 }
01257
01258 void Signature::setParamName(int n, const char *name)
01259 {
01260 params[n]->setName(name);
01261 }
01262
01263 void Signature::setParamExp(int n, Exp *e)
01264 {
01265 params[n]->setExp(e);
01266 }
01267
01268
01269 int Signature::findParam(Exp *e) {
01270 for (unsigned i = 0; i < getNumParams(); i++)
01271 if (*getParamExp(i) == *e)
01272 return i;
01273 return -1;
01274 }
01275
01276 void Signature::renameParam(const char *oldName, const char *newName)
01277 {
01278 for (unsigned i = 0; i < getNumParams(); i++)
01279 if (!strcmp(params[i]->getName(), oldName)) {
01280 params[i]->setName(newName);
01281 break;
01282 }
01283 }
01284
01285 int Signature::findParam(const char *nam) {
01286 for (unsigned i = 0; i < getNumParams(); i++)
01287 if (!strcmp(getParamName(i), nam))
01288 return i;
01289 return -1;
01290 }
01291
01292 int Signature::findReturn(Exp *e) {
01293 for (unsigned i = 0; i < getNumReturns(); i++)
01294 if (*returns[i]->exp == *e)
01295 return (int)i;
01296 return -1;
01297 }
01298
01299 void Signature::addReturn(Type *type, Exp *exp) {
01300 assert(exp);
01301 addReturn(new Return(type, exp));
01302 }
01303
01304
01305 void Signature::addReturn(Exp *exp) {
01306
01307 addReturn(new VoidType(), exp);
01308 }
01309
01310 void Signature::removeReturn(Exp *e)
01311 {
01312 int i = findReturn(e);
01313 if (i != -1) {
01314 for (unsigned j = i+1; j < returns.size(); j++)
01315 returns[j-1] = returns[j];
01316 returns.resize(returns.size()-1);
01317 }
01318 }
01319
01320 void Signature::setReturnType(int n, Type *ty) {
01321 if (n < (int)returns.size())
01322 returns[n]->type = ty;
01323 }
01324
01325 Exp *Signature::getArgumentExp(int n) {
01326 return getParamExp(n);
01327 }
01328
01329 Signature *Signature::promote(UserProc *p) {
01330
01331 if (CallingConvention::Win32Signature::qualified(p, *this)) {
01332 Signature *sig = new CallingConvention::Win32Signature(*this);
01333
01334 delete this;
01335 return sig;
01336 }
01337
01338 if (CallingConvention::StdC::PentiumSignature::qualified(p, *this)) {
01339 Signature *sig = new CallingConvention::StdC::PentiumSignature(*this);
01340
01341 delete this;
01342 return sig;
01343 }
01344
01345 if (CallingConvention::StdC::SparcSignature::qualified(p, *this)) {
01346 Signature *sig = new CallingConvention::StdC::SparcSignature(*this);
01347
01348 delete this;
01349 return sig;
01350 }
01351
01352 if (CallingConvention::StdC::PPCSignature::qualified(p, *this)) {
01353 Signature *sig = new CallingConvention::StdC::PPCSignature(*this);
01354
01355 delete this;
01356 return sig;
01357 }
01358
01359 if (CallingConvention::StdC::ST20Signature::qualified(p, *this)) {
01360 Signature *sig = new CallingConvention::StdC::ST20Signature(*this);
01361
01362 delete this;
01363 return sig;
01364 }
01365
01366 return this;
01367 }
01368
01369 Signature *Signature::instantiate(platform plat, callconv cc, const char *nam) {
01370 switch (plat) {
01371 case PLAT_PENTIUM:
01372 if (cc == CONV_PASCAL)
01373
01374 return new CallingConvention::Win32Signature(nam);
01375 else if (cc == CONV_THISCALL)
01376 return new CallingConvention::Win32TcSignature(nam);
01377 else
01378 return new CallingConvention::StdC::PentiumSignature(nam);
01379 case PLAT_SPARC:
01380 assert(cc == CONV_C);
01381 return new CallingConvention::StdC::SparcSignature(nam);
01382 case PLAT_PPC:
01383 return new CallingConvention::StdC::PPCSignature(nam);
01384 case PLAT_ST20:
01385 return new CallingConvention::StdC::ST20Signature(nam);
01386
01387 default:
01388 std::cerr << "unknown signature: " << conventionName(cc) << " " << platformName(plat) << "\n";
01389 assert(false);
01390 }
01391 return NULL;
01392 }
01393
01394 void Signature::print(std::ostream &out, bool html)
01395 {
01396 if (isForced())
01397 out << "*forced* ";
01398 if (returns.size() > 0) {
01399 out << "{ ";
01400 unsigned n = 0;
01401 for (Returns::iterator rr = returns.begin(); rr != returns.end(); rr++, n++) {
01402 out << (*rr)->type->getCtype() << " " << (*rr)->exp;
01403 if (n != returns.size() - 1)
01404 out << ", ";
01405 else
01406 out << " ";
01407 }
01408 out << "} ";
01409 } else
01410 out << "void ";
01411 out << name << "(";
01412 unsigned int i;
01413 for (i = 0; i < params.size(); i++) {
01414 out << params[i]->getType()->getCtype() << " " << params[i]->getName() << " " << params[i]->getExp();
01415 if (i != params.size()-1) out << ", ";
01416 }
01417 out << ")\n";
01418 }
01419
01420 char* Signature::prints() {
01421 std::ostringstream ost;
01422 print(ost);
01423 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
01424 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
01425 return debug_buffer;
01426 }
01427
01428 void Signature::printToLog()
01429 {
01430 std::ostringstream os;
01431 print(os);
01432 LOG << os.str().c_str();
01433 }
01434
01435 bool Signature::usesNewParam(UserProc *p, Statement *stmt, bool checkreach, int &n) {
01436 n = getNumParams() - 1;
01437 if (VERBOSE) {
01438 std::cerr << "searching ";
01439 stmt->printAsUse(std::cerr);
01440 std::cerr << std::endl;
01441 }
01442 StatementSet reachin;
01443
01444 for (int i = getNumParams(); i < 10; i++)
01445 if (stmt->usesExp(getParamExp(i))) {
01446 bool ok = true;
01447 if (checkreach) {
01448 bool hasDef = false;
01449 StatementSet::iterator it1;
01450 for (it1 = reachin.begin(); it1 != reachin.end(); it1++) {
01451 Assignment* as = (Assignment*)*it1;
01452 if (as->isAssignment() && *as->getLeft() == *getParamExp(i)) {
01453 hasDef = true; break;
01454 }
01455 }
01456 if (hasDef) ok = false;
01457 }
01458 if (ok) {
01459 n = i;
01460 }
01461 }
01462 return n > ((int)getNumParams() - 1);
01463 }
01464
01465
01466 Exp* Signature::getFirstArgLoc(Prog* prog) {
01467 MACHINE mach = prog->getMachine();
01468 switch (mach) {
01469 case MACHINE_SPARC: {
01470 CallingConvention::StdC::SparcSignature sig("");
01471 return sig.getArgumentExp(0);
01472 }
01473 case MACHINE_PENTIUM: {
01474
01475
01476
01477 Exp* e = Location::memOf(Location::regOf(28));
01478 return e;
01479 }
01480 case MACHINE_ST20: {
01481 CallingConvention::StdC::ST20Signature sig("");
01482 return sig.getArgumentExp(0);
01483
01484
01485 }
01486 default:
01487 std::cerr << "Signature::getFirstArgLoc: machine not handled\n";
01488 assert(0);
01489 }
01490 return 0;
01491 }
01492
01493
01494
01495
01496 Exp* Signature::getReturnExp2(BinaryFile* pBF) {
01497 switch (pBF->GetMachine()) {
01498 case MACHINE_SPARC:
01499 return Location::regOf(8);
01500 case MACHINE_PENTIUM:
01501 return Location::regOf(24);
01502 case MACHINE_ST20:
01503 return Location::regOf(0);
01504 default:
01505 std::cerr << "getReturnExp2: machine not handled\n";
01506 return NULL;
01507 }
01508 return NULL;
01509 }
01510
01511
01512
01513
01514 void Signature::setABIdefines(Prog* prog, StatementList* defs) {
01515 if (defs->size()) return;
01516 MACHINE mach = prog->getMachine();
01517 switch (mach) {
01518 case MACHINE_PENTIUM: {
01519 defs->append(new ImplicitAssign(Location::regOf(24)));
01520 defs->append(new ImplicitAssign(Location::regOf(25)));
01521 defs->append(new ImplicitAssign(Location::regOf(26)));
01522 }
01523 case MACHINE_SPARC: {
01524 for (int r=8; r <= 13; ++r)
01525 defs->append(new ImplicitAssign(Location::regOf(r)));
01526 defs->append(new ImplicitAssign(Location::regOf(1)));
01527 }
01528 case MACHINE_PPC: {
01529 for (int r=3; r <= 12; ++r)
01530 defs->append(new ImplicitAssign(Location::regOf(r)));
01531 }
01532 case MACHINE_ST20: {
01533 defs->append(new ImplicitAssign(Location::regOf(0)));
01534 defs->append(new ImplicitAssign(Location::regOf(1)));
01535 defs->append(new ImplicitAssign(Location::regOf(2)));
01536 }
01537 default:
01538 break;
01539 }
01540 }
01541
01542
01543 Exp* Signature::getEarlyParamExp(int n, Prog* prog) {
01544 MACHINE mach = prog->getMachine();
01545 switch (mach) {
01546 case MACHINE_SPARC: {
01547 CallingConvention::StdC::SparcSignature temp("");
01548 return temp.getParamExp(n);
01549 }
01550 case MACHINE_PENTIUM: {
01551
01552 CallingConvention::StdC::PentiumSignature temp("");
01553 return temp.getParamExp(n);
01554 }
01555 case MACHINE_ST20: {
01556 CallingConvention::StdC::ST20Signature temp("");
01557 return temp.getParamExp(n);
01558 }
01559 default:
01560 break;
01561 }
01562 assert(0);
01563 return NULL;
01564 }
01565
01566 StatementList& Signature::getStdRetStmt(Prog* prog) {
01567
01568 static Assign pent1ret(
01569 new Terminal(opPC),
01570 Location::memOf(Location::regOf(28)));
01571
01572 static Assign pent2ret(
01573 Location::regOf(28),
01574 new Binary(opPlus,
01575 Location::regOf(28),
01576 new Const(4)));
01577 static Assign st20_1ret(
01578 new Terminal(opPC),
01579 Location::memOf(Location::regOf(3)));
01580 static Assign st20_2ret(
01581 Location::regOf(3),
01582 new Binary(opPlus,
01583 Location::regOf(3),
01584 new Const(16)));
01585 MACHINE mach = prog->getMachine();
01586 switch (mach) {
01587 case MACHINE_SPARC:
01588 break;
01589 case MACHINE_PENTIUM: {
01590 StatementList* sl = new StatementList;
01591 sl->append((Statement*)&pent1ret);
01592 sl->append((Statement*)&pent2ret);
01593 return *sl;
01594 }
01595 case MACHINE_ST20: {
01596 StatementList* sl = new StatementList;
01597 sl->append((Statement*)&st20_1ret);
01598 sl->append((Statement*)&st20_2ret);
01599 return *sl;
01600 }
01601 default:
01602 break;
01603 }
01604 return *new StatementList;
01605 }
01606
01607 int Signature::getStackRegister() throw(StackRegisterNotDefinedException) {
01608 if (VERBOSE)
01609 LOG << "thowing StackRegisterNotDefinedException\n";
01610 throw StackRegisterNotDefinedException();
01611 }
01612
01613
01614 int Signature::getStackRegister(Prog* prog) throw(StackRegisterNotDefinedException) {
01615 MACHINE mach = prog->getMachine();
01616 switch (mach) {
01617 case MACHINE_SPARC:
01618 return 14;
01619 case MACHINE_PENTIUM:
01620 return 28;
01621 case MACHINE_PPC:
01622 return 1;
01623 case MACHINE_ST20:
01624 return 3;
01625 default:
01626 throw StackRegisterNotDefinedException();
01627 }
01628 }
01629
01630 bool Signature::isStackLocal(Prog* prog, Exp *e) {
01631
01632 if (e->isSubscript())
01633 return isStackLocal(prog, e->getSubExp1());
01634 if (!e->isMemOf()) return false;
01635 Exp* addr = ((Location*)e)->getSubExp1();
01636 return isAddrOfStackLocal(prog, addr);
01637 }
01638
01639 bool Signature::isAddrOfStackLocal(Prog* prog, Exp *e) {
01640 OPER op = e->getOper();
01641 if (op == opAddrOf)
01642 return isStackLocal(prog, e->getSubExp1());
01643
01644 static Exp *sp = Location::regOf(getStackRegister(prog));
01645 if (op != opMinus && op != opPlus) {
01646
01647 return (*e == *sp ||
01648 e->isSubscript() && ((RefExp*)e)->isImplicitDef() && *((RefExp*)e)->getSubExp1() == *sp);
01649 }
01650 if (op == opMinus && !isLocalOffsetNegative()) return false;
01651 if (op == opPlus && !isLocalOffsetPositive()) return false;
01652 Exp* sub1 = ((Binary*)e)->getSubExp1();
01653 Exp* sub2 = ((Binary*)e)->getSubExp2();
01654
01655 if (!sub2->isIntConst()) return false;
01656
01657 if (sub1->isSubscript()) {
01658 if (!((RefExp*)sub1)->isImplicitDef()) return false;
01659 sub1 = ((RefExp*)sub1)->getSubExp1();
01660 }
01661 return *sub1 == *sp;
01662 }
01663
01664
01665 bool CallingConvention::StdC::SparcSignature::isAddrOfStackLocal(Prog* prog, Exp* e) {
01666 OPER op = e->getOper();
01667 if (op == opAddrOf)
01668 return isStackLocal(prog, e->getSubExp1());
01669
01670 static Exp *sp = Location::regOf(14);
01671 if (op != opMinus && op != opPlus) {
01672
01673 return (*e == *sp ||
01674 e->isSubscript() && ((RefExp*)e)->isImplicitDef() && *((RefExp*)e)->getSubExp1() == *sp);
01675 }
01676 Exp* sub1 = ((Binary*)e)->getSubExp1();
01677 Exp* sub2 = ((Binary*)e)->getSubExp2();
01678
01679 if (!sub2->isIntConst()) return false;
01680
01681 if (sub1->isSubscript()) {
01682 if (!((RefExp*)sub1)->isImplicitDef()) return false;
01683 sub1 = ((RefExp*)sub1)->getSubExp1();
01684 }
01685 if (!(*sub1 == *sp)) return false;
01686
01687 int K = ((Const*)sub2)->getInt();
01688 return K < 92;
01689 }
01690
01691 bool Parameter::operator==(Parameter& other) {
01692 if (!(*type == *other.type)) return false;
01693
01694 if (!(name == other.name)) return false;
01695 if (!(*exp == *other.exp)) return false;
01696 return true;
01697 }
01698
01699
01700
01701
01702
01703 #if USING_MEMO
01704 class SignatureMemo : public Memo {
01705 public:
01706 SignatureMemo(int m) : Memo(m) { }
01707
01708 std::string name;
01709 std::vector<Parameter*> params;
01710
01711 Returns returns;
01712 Type *rettype;
01713 bool ellipsis;
01714 Type *preferedReturn;
01715 std::string preferedName;
01716 std::vector<int> preferedParams;
01717 };
01718
01719 Memo *Signature::makeMemo(int mId)
01720 {
01721 SignatureMemo *m = new SignatureMemo(mId);
01722 m->name = name;
01723 m->params = params;
01724
01725 m->returns = returns;
01726 m->rettype = rettype;
01727 m->ellipsis = ellipsis;
01728 m->preferedReturn = preferedReturn;
01729 m->preferedName = preferedName;
01730 m->preferedParams = preferedParams;
01731
01732 for (std::vector<Parameter*>::iterator it = params.begin(); it != params.end(); it++)
01733 (*it)->takeMemo(mId);
01734
01735
01736 for (Returns::iterator it = returns.begin(); it != returns.end(); it++)
01737 (*it)->takeMemo(mId);
01738 if (rettype)
01739 rettype->takeMemo(mId);
01740 if (preferedReturn)
01741 preferedReturn->takeMemo(mId);
01742 return m;
01743 }
01744
01745 void Signature::readMemo(Memo *mm, bool dec)
01746 {
01747 SignatureMemo *m = dynamic_cast<SignatureMemo*>(mm);
01748
01749 name = m->name;
01750 params = m->params;
01751
01752 returns = m->returns;
01753 rettype = m->rettype;
01754 ellipsis = m->ellipsis;
01755 preferedReturn = m->preferedReturn;
01756 preferedName = m->preferedName;
01757 preferedParams = m->preferedParams;
01758
01759 for (std::vector<Parameter*>::iterator it = params.begin(); it != params.end(); it++)
01760 (*it)->restoreMemo(m->mId, dec);
01761
01762
01763 for (Returns::iterator it = returns.begin(); it != returns.end(); it++)
01764 (*it)->restoreMemo(m->mId, dec);
01765 if (rettype)
01766 rettype->restoreMemo(m->mId, dec);
01767 if (preferedReturn)
01768 preferedReturn->restoreMemo(m->mId, dec);
01769 }
01770
01771 class ParameterMemo : public Memo {
01772 public:
01773 ParameterMemo(int m) : Memo(m) { }
01774
01775 Type *type;
01776 std::string name;
01777 Exp *exp;
01778 };
01779
01780 Memo *Parameter::makeMemo(int mId)
01781 {
01782 ParameterMemo *m = new ParameterMemo(mId);
01783
01784 m->type = type;
01785 m->name = name;
01786 m->exp = exp;
01787
01788 type->takeMemo(mId);
01789 exp->takeMemo(mId);
01790
01791 return m;
01792 }
01793
01794 void Parameter::readMemo(Memo *mm, bool dec)
01795 {
01796 ParameterMemo *m = dynamic_cast<ParameterMemo*>(mm);
01797 type = m->type;
01798 name = m->name;
01799 exp = m->exp;
01800
01801 type->restoreMemo(m->mId, dec);
01802 exp->restoreMemo(m->mId, dec);
01803 }
01804
01805
01806 class ImplicitParameterMemo : public ParameterMemo {
01807 public:
01808 ImplicitParameterMemo(int m) : ParameterMemo(m) { }
01809
01810 Parameter *parent;
01811 };
01812
01813 Memo *ImplicitParameter::makeMemo(int mId)
01814 {
01815 ImplicitParameterMemo *m = new ImplicitParameterMemo(mId);
01816
01817 m->type = getType();
01818 m->name = getName();
01819 m->exp = getExp();
01820 m->parent = parent;
01821
01822 m->type->takeMemo(mId);
01823 m->exp->takeMemo(mId);
01824
01825 return m;
01826 }
01827
01828 void ImplicitParameter::readMemo(Memo *mm, bool dec)
01829 {
01830 ImplicitParameterMemo *m = dynamic_cast<ImplicitParameterMemo*>(mm);
01831 setType(m->type);
01832 setName(m->name.c_str());
01833 setExp(m->exp);
01834 parent = m->parent;
01835
01836 m->type->restoreMemo(m->mId, dec);
01837 m->exp->restoreMemo(m->mId, dec);
01838 }
01839 #endif // #if USING_MEMO
01840
01841 bool Signature::isOpCompatStackLocal(OPER op) {
01842 if (op == opMinus) return isLocalOffsetNegative();
01843 if (op == opPlus) return isLocalOffsetPositive();
01844 return false;
01845 }
01846
01847 bool Signature::returnCompare(Assignment& a, Assignment& b) {
01848 return *a.getLeft() < *b.getLeft();
01849 }
01850
01851 bool Signature::argumentCompare(Assignment& a, Assignment& b) {
01852 return *a.getLeft() < *b.getLeft();
01853 }
01854
01855 bool CallingConvention::StdC::PentiumSignature::returnCompare(Assignment& a, Assignment& b) {
01856 Exp* la = a.getLeft();
01857 Exp* lb = b.getLeft();
01858
01859 if (la->isRegN(24)) return true;
01860 if (lb->isRegN(24)) return false;
01861
01862
01863 if (la->isRegN(30)) return true;
01864 if (lb->isRegN(30)) return false;
01865
01866
01867 return *la < *lb;
01868 }
01869
01870 static Unary spPlus64(opMemOf,
01871 new Binary(opPlus,
01872 Location::regOf(14),
01873 new Const(64)));
01874 bool CallingConvention::StdC::SparcSignature::returnCompare(Assignment& a, Assignment& b) {
01875 Exp* la = a.getLeft();
01876 Exp* lb = b.getLeft();
01877
01878 if (la->isRegN(8)) return true;
01879 if (lb->isRegN(8)) return false;
01880
01881
01882 if (la->isRegN(32)) return true;
01883 if (lb->isRegN(32)) return false;
01884
01885
01886 if (la->isRegN(64)) return true;
01887 if (lb->isRegN(64)) return false;
01888
01889
01890 if (*la == spPlus64) return true;
01891 if (*lb == spPlus64) return false;
01892
01893
01894 return *la < *lb;
01895 }
01896
01897
01898
01899 int stackOffset(Exp* e, int sp) {
01900 int ret = 0;
01901 if (e->isMemOf()) {
01902 Exp* sub = ((Location*)e)->getSubExp1();
01903 OPER op = sub->getOper();
01904 if (op == opPlus || op == opMinus) {
01905 Exp* op1 = ((Binary*)sub)->getSubExp1();
01906 if (op1->isSubscript())
01907 op1 = ((RefExp*)op1)->getSubExp1();
01908 if (op1->isRegN(sp)) {
01909 Exp* op2 = ((Binary*)sub)->getSubExp2();
01910 if (op2->isIntConst())
01911 ret = ((Const*)op2)->getInt();
01912 if (op == opMinus)
01913 ret = -ret;
01914 }
01915 }
01916 }
01917 return ret;
01918 }
01919
01920 bool CallingConvention::StdC::PentiumSignature::argumentCompare(Assignment& a, Assignment& b) {
01921 Exp* la = a.getLeft();
01922 Exp* lb = b.getLeft();
01923 int ma = stackOffset(la, 28);
01924 int mb = stackOffset(lb, 28);
01925
01926 if (ma && mb)
01927 return ma < mb;
01928 if (ma && !mb)
01929 return true;
01930 if (mb && !ma)
01931 return false;
01932
01933
01934 return *la < *lb;
01935 }
01936
01937 bool CallingConvention::StdC::SparcSignature::argumentCompare(Assignment& a, Assignment& b) {
01938 Exp* la = a.getLeft();
01939 Exp* lb = b.getLeft();
01940
01941 int ra = 0, rb = 0;
01942 if (la->isRegOf()) {
01943 int r = ((Const*)((Location*)la)->getSubExp1())->getInt();
01944 if (r >= 8 && r <= 13)
01945 ra = r;
01946 }
01947 if (lb->isRegOf()) {
01948 int r = ((Const*)((Location*)lb)->getSubExp1())->getInt();
01949 if (r >= 8 && r <= 13)
01950 rb = r;
01951 }
01952 if (ra && rb)
01953 return ra < rb;
01954 if (ra && rb == 0)
01955 return true;
01956 if (rb && ra == 0)
01957 return false;
01958
01959 int ma = stackOffset(la, 30);
01960 int mb = stackOffset(lb, 30);
01961
01962 if (ma && mb)
01963 return ma < mb;
01964 if (ma && !mb)
01965 return true;
01966 if (mb && !ma)
01967 return false;
01968
01969 return *la < *lb;
01970 }
01971
01972
01973 Return* Return::clone() {
01974 return new Return(type->clone(), exp->clone());
01975 }
01976
01977 bool Return::operator==(Return& other) {
01978 if (!(*type == *other.type)) return false;
01979 if (!(*exp == *other.exp)) return false;
01980 return true;
01981 }
01982
01983 #if USING_MEMO
01984 class ReturnMemo : public Memo {
01985 public:
01986 ReturnMemo(int m) : Memo(m) { }
01987
01988 Type *type;
01989 Exp *exp;
01990 };
01991
01992 Memo *Return::makeMemo(int mId)
01993 {
01994 ReturnMemo *m = new ReturnMemo(mId);
01995
01996 m->type = type;
01997 m->exp = exp;
01998
01999 type->takeMemo(mId);
02000 exp->takeMemo(mId);
02001
02002 return m;
02003 }
02004
02005 void Return::readMemo(Memo *mm, bool dec)
02006 {
02007 ReturnMemo *m = dynamic_cast<ReturnMemo*>(mm);
02008 type = m->type;
02009 exp = m->exp;
02010
02011 type->restoreMemo(m->mId, dec);
02012 exp->restoreMemo(m->mId, dec);
02013 }
02014 #endif // #if USING_MEMO
02015
02016 Type* Signature::getTypeFor(Exp* e) {
02017 int n = returns.size();
02018 for (int i=0; i < n; ++i) {
02019 if (*returns[i]->exp == *e)
02020 return returns[i]->type;
02021 }
02022 return NULL;
02023 }