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
00026 #include <assert.h>
00027 #include <iomanip>
00028
00029 #include <sstream>
00030 #include <algorithm>
00031 #include "statement.h"
00032 #include "exp.h"
00033 #include "cfg.h"
00034 #include "proc.h"
00035 #include "prog.h"
00036 #include "boomerang.h"
00037 #include "rtl.h"
00038 #include "util.h"
00039 #include "signature.h"
00040 #include "visitor.h"
00041 #include "dataflow.h"
00042 #include "log.h"
00043
00044
00045 extern char debug_buffer[];
00046
00047 #if defined(_MSC_VER) && _MSC_VER < 1310 // Ugh - MSC 7.0 doesn't have advance
00048 #define my_advance(aa, n) \
00049 for (int zz = 0; zz < n; zz++) \
00050 aa++;
00051 #else
00052 #define my_advance(aa, n) \
00053 advance(aa, n);
00054 #endif
00055
00056 void Statement::setProc(UserProc *p)
00057 {
00058 proc = p;
00059 LocationSet exps;
00060 addUsedLocs(exps);
00061 LocationSet defs;
00062 getDefinitions(defs);
00063 exps.makeUnion(defs);
00064 LocationSet::iterator ll;
00065 for (ll = exps.begin(); ll != exps.end(); ll++) {
00066 Location *l = dynamic_cast<Location*>(*ll);
00067 if (l) {
00068 l->setProc(p);
00069 }
00070 }
00071 }
00072
00073 Exp *Statement::getExpAtLex(unsigned int begin, unsigned int end)
00074 {
00075 return NULL;
00076 }
00077
00078 bool Statement::mayAlias(Exp *e1, Exp *e2, int size) {
00079 if (*e1 == *e2) return true;
00080
00081
00082 bool b = (calcMayAlias(e1, e2, size) && calcMayAlias(e2, e1, size));
00083 if (b && VERBOSE) {
00084 LOG << "May alias: " << e1 << " and " << e2 << " size " << size << "\n";
00085 }
00086 return b;
00087 }
00088
00089
00090 bool Statement::calcMayAlias(Exp *e1, Exp *e2, int size) {
00091
00092 if (!e1->isMemOf() || !e2->isMemOf()) {
00093 return false;
00094 }
00095 Exp *e1a = e1->getSubExp1();
00096 Exp *e2a = e2->getSubExp1();
00097
00098 if (e1a->isIntConst() && e2a->isIntConst()) {
00099 ADDRESS a1 = ((Const*)e1a)->getAddr();
00100 ADDRESS a2 = ((Const*)e2a)->getAddr();
00101 int diff = a1 - a2;
00102 if (diff < 0) diff = -diff;
00103 if (diff*8 >= size) return false;
00104 }
00105
00106 if (e1a->getArity() == 2 && e1a->getOper() == e2a->getOper() && e1a->getSubExp2()->isIntConst() &&
00107 e2a->getSubExp2()->isIntConst() && *e1a->getSubExp1() == *e2a->getSubExp1()) {
00108 int i1 = ((Const*)e1a->getSubExp2())->getInt();
00109 int i2 = ((Const*)e2a->getSubExp2())->getInt();
00110 int diff = i1 - i2;
00111 if (diff < 0) diff = -diff;
00112 if (diff*8 >= size) return false;
00113 }
00114
00115 if ((e2a->getOper() == opPlus || e2a->getOper() == opMinus) && *e1a == *e2a->getSubExp1() &&
00116 e2a->getSubExp2()->isIntConst()) {
00117 int i1 = 0;
00118 int i2 = ((Const*)e2a->getSubExp2())->getInt();
00119 int diff = i1 - i2;
00120 if (diff < 0) diff = -diff;
00121 if (diff*8 >= size) return false;
00122 }
00123
00124
00125 return true;
00126 }
00127
00128 RangeMap Statement::getInputRanges()
00129 {
00130 if (!isFirstStatementInBB()) {
00131 savedInputRanges = getPreviousStatementInBB()->getRanges();
00132 return savedInputRanges;
00133 }
00134
00135 assert(pbb && pbb->getNumInEdges() <= 1);
00136 RangeMap input;
00137 if (pbb->getNumInEdges() == 0) {
00138
00139 Range ra24(1, 0, 0, new Unary(opInitValueOf, Location::regOf(24)));
00140 Range ra25(1, 0, 0, new Unary(opInitValueOf, Location::regOf(25)));
00141 Range ra26(1, 0, 0, new Unary(opInitValueOf, Location::regOf(26)));
00142 Range ra27(1, 0, 0, new Unary(opInitValueOf, Location::regOf(27)));
00143 Range ra28(1, 0, 0, new Unary(opInitValueOf, Location::regOf(28)));
00144 Range ra29(1, 0, 0, new Unary(opInitValueOf, Location::regOf(29)));
00145 Range ra30(1, 0, 0, new Unary(opInitValueOf, Location::regOf(30)));
00146 Range ra31(1, 0, 0, new Unary(opInitValueOf, Location::regOf(31)));
00147 Range rpc(1, 0, 0, new Unary(opInitValueOf, new Terminal(opPC)));
00148 input.addRange(Location::regOf(24), ra24);
00149 input.addRange(Location::regOf(25), ra25);
00150 input.addRange(Location::regOf(26), ra26);
00151 input.addRange(Location::regOf(27), ra27);
00152 input.addRange(Location::regOf(28), ra28);
00153 input.addRange(Location::regOf(29), ra29);
00154 input.addRange(Location::regOf(30), ra30);
00155 input.addRange(Location::regOf(31), ra31);
00156 input.addRange(new Terminal(opPC), rpc);
00157 } else {
00158 PBB pred = pbb->getInEdges()[0];
00159 Statement *last = pred->getLastStmt();
00160 assert(last);
00161 if (pred->getNumOutEdges() != 2) {
00162 input = last->getRanges();
00163 } else {
00164 assert(pred->getNumOutEdges() == 2);
00165 assert(last->isBranch());
00166 input = ((BranchStatement*)last)->getRangesForOutEdgeTo(pbb);
00167 }
00168 }
00169
00170 savedInputRanges = input;
00171
00172 return input;
00173 }
00174
00175 void Statement::updateRanges(RangeMap &output, std::list<Statement*> &execution_paths, bool notTaken)
00176 {
00177 if (!output.isSubset(notTaken ? ((BranchStatement*)this)->getRanges2Ref() : ranges)) {
00178 if (notTaken)
00179 ((BranchStatement*)this)->setRanges2(output);
00180 else
00181 ranges = output;
00182 if (isLastStatementInBB()) {
00183 if (pbb->getNumOutEdges()) {
00184 int arc = 0;
00185 if (isBranch()) {
00186 if (pbb->getOutEdge(0)->getLowAddr() != ((BranchStatement*)this)->getFixedDest())
00187 arc = 1;
00188 if (notTaken)
00189 arc ^= 1;
00190 }
00191 execution_paths.push_back(pbb->getOutEdge(arc)->getFirstStmt());
00192 }
00193 } else
00194 execution_paths.push_back(getNextStatementInBB());
00195 }
00196 }
00197
00198 void Statement::rangeAnalysis(std::list<Statement*> &execution_paths)
00199 {
00200 RangeMap output = getInputRanges();
00201 updateRanges(output, execution_paths);
00202 }
00203
00204 void Assign::rangeAnalysis(std::list<Statement*> &execution_paths)
00205 {
00206 RangeMap output = getInputRanges();
00207 Exp *a_lhs = lhs->clone();
00208 if (a_lhs->isFlags()) {
00209
00210 assert(rhs->isFlagCall());
00211 Exp *a_rhs = rhs->clone();
00212 if (a_rhs->getSubExp2()->getSubExp1()->isMemOf())
00213 a_rhs->getSubExp2()->getSubExp1()->setSubExp1(
00214 output.substInto(a_rhs->getSubExp2()->getSubExp1()->getSubExp1()));
00215 if (!a_rhs->getSubExp2()->getSubExp2()->isTerminal() &&
00216 a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->isMemOf())
00217 a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->setSubExp1(
00218 output.substInto(a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->getSubExp1()));
00219 Range ra(1, 0, 0, a_rhs);
00220 output.addRange(a_lhs, ra);
00221 } else {
00222 if (a_lhs->isMemOf())
00223 a_lhs->setSubExp1(output.substInto(a_lhs->getSubExp1()->clone()));
00224 Exp *a_rhs = output.substInto(rhs->clone());
00225 if (a_rhs->isMemOf() && a_rhs->getSubExp1()->getOper() == opInitValueOf &&
00226 a_rhs->getSubExp1()->getSubExp1()->isRegOfK() &&
00227 ((Const*)a_rhs->getSubExp1()->getSubExp1()->getSubExp1())->getInt() == 28)
00228 a_rhs = new Unary(opInitValueOf, new Terminal(opPC));
00229 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00230 LOG << "a_rhs is " << a_rhs << "\n";
00231 if (a_rhs->isMemOf() && a_rhs->getSubExp1()->isIntConst()) {
00232 ADDRESS c = ((Const*)a_rhs->getSubExp1())->getInt();
00233 if (proc->getProg()->isDynamicLinkedProcPointer(c)) {
00234 char *nam = (char*)proc->getProg()->GetDynamicProcName(c);
00235 if (nam) {
00236 a_rhs = new Const(nam);
00237 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00238 LOG << "a_rhs is a dynamic proc pointer to " << nam << "\n";
00239 }
00240 } else if (proc->getProg()->isReadOnly(c)) {
00241 switch(type->getSize()) {
00242 case 8:
00243 a_rhs = new Const(proc->getProg()->readNative1(c));
00244 break;
00245 case 16:
00246 a_rhs = new Const(proc->getProg()->readNative2(c));
00247 break;
00248 case 32:
00249 a_rhs = new Const(proc->getProg()->readNative4(c));
00250 break;
00251 default:
00252 LOG << "error: unhandled type size " << type->getSize() << " for reading native address\n";
00253 }
00254 } else
00255 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00256 LOG << c << " is not dynamically linked proc pointer or in read only memory\n";
00257 }
00258 if ((a_rhs->getOper() == opPlus || a_rhs->getOper() == opMinus) &&
00259 a_rhs->getSubExp2()->isIntConst() && output.hasRange(a_rhs->getSubExp1())) {
00260 Range &r = output.getRange(a_rhs->getSubExp1());
00261 int c = ((Const*)a_rhs->getSubExp2())->getInt();
00262 if (a_rhs->getOper() == opPlus) {
00263 Range ra(1, r.getLowerBound() != Range::MIN ? r.getLowerBound() + c : Range::MIN,
00264 r.getUpperBound() != Range::MAX? r.getUpperBound() + c : Range::MAX, r.getBase());
00265 output.addRange(a_lhs, ra);
00266 } else {
00267 Range ra(1, r.getLowerBound() != Range::MIN ? r.getLowerBound() - c : Range::MIN,
00268 r.getUpperBound() != Range::MAX ? r.getUpperBound() - c : Range::MAX, r.getBase());
00269 output.addRange(a_lhs, ra);
00270 }
00271 } else {
00272 if (output.hasRange(a_rhs)) {
00273 output.addRange(a_lhs, output.getRange(a_rhs));
00274 } else {
00275 Exp *result;
00276 if (a_rhs->getMemDepth() == 0 && !a_rhs->search(new Unary(opRegOf, new Terminal(opWild)), result) &&
00277 !a_rhs->search(new Unary(opTemp, new Terminal(opWild)), result)) {
00278 if (a_rhs->isIntConst()) {
00279 Range ra(1, ((Const*)a_rhs)->getInt(), ((Const*)a_rhs)->getInt(), new Const(0));
00280 output.addRange(a_lhs, ra);
00281 }
00282 else {
00283 Range ra(1, 0, 0, a_rhs);
00284 output.addRange(a_lhs, ra);
00285 }
00286 } else {
00287 Range empty;
00288 output.addRange(a_lhs, empty);
00289 }
00290 }
00291 }
00292 }
00293 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00294 LOG << "added " << a_lhs << " -> " << output.getRange(a_lhs) << "\n";
00295 updateRanges(output, execution_paths);
00296 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00297 LOG << this << "\n";
00298 }
00299
00300 void BranchStatement::limitOutputWithCondition(RangeMap &output, Exp *e)
00301 {
00302 assert(e);
00303 if (output.hasRange(e->getSubExp1())) {
00304 Range &r = output.getRange(e->getSubExp1());
00305 if (e->getSubExp2()->isIntConst() && r.getBase()->isIntConst() && ((Const*)r.getBase())->getInt() == 0) {
00306 int c = ((Const*)e->getSubExp2())->getInt();
00307 switch(e->getOper()) {
00308 case opLess:
00309 case opLessUns: {
00310 Range ra(r.getStride(), r.getLowerBound() >= c ? c - 1 : r.getLowerBound(),
00311 r.getUpperBound() >= c ? c - 1 : r.getUpperBound(), r.getBase());
00312 output.addRange(e->getSubExp1(), ra);
00313 break;
00314 }
00315 case opLessEq:
00316 case opLessEqUns: {
00317 Range ra(r.getStride(), r.getLowerBound() > c ? c : r.getLowerBound(),
00318 r.getUpperBound() > c ? c : r.getUpperBound(), r.getBase());
00319 output.addRange(e->getSubExp1(), ra);
00320 break;
00321 }
00322 case opGtr:
00323 case opGtrUns: {
00324 Range ra(r.getStride(), r.getLowerBound() <= c ? c + 1 : r.getLowerBound(),
00325 r.getUpperBound() <= c ? c + 1 : r.getUpperBound(), r.getBase());
00326 output.addRange(e->getSubExp1(), ra);
00327 break;
00328 }
00329 case opGtrEq:
00330 case opGtrEqUns: {
00331 Range ra(r.getStride(), r.getLowerBound() < c ? c : r.getLowerBound(),
00332 r.getUpperBound() < c ? c : r.getUpperBound(), r.getBase());
00333 output.addRange(e->getSubExp1(), ra);
00334 break;
00335 }
00336 case opEquals: {
00337 Range ra(r.getStride(), c, c, r.getBase());
00338 output.addRange(e->getSubExp1(), ra);
00339 break;
00340 }
00341 case opNotEqual: {
00342 Range ra(r.getStride(), r.getLowerBound() == c ? c + 1 : r.getLowerBound(),
00343 r.getUpperBound() == c ? c - 1 : r.getUpperBound(), r.getBase());
00344 output.addRange(e->getSubExp1(), ra);
00345 break;
00346 }
00347 default:
00348 break;
00349 }
00350 }
00351 }
00352 }
00353
00354 void BranchStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
00355 {
00356 RangeMap output = getInputRanges();
00357
00358 Exp *e = NULL;
00359
00360 OPER op = pCond->getOper();
00361 if (op == opLess || op == opLessEq || op == opGtr || op == opGtrEq ||
00362 op == opLessUns || op == opLessEqUns || op == opGtrUns || op == opGtrEqUns ||
00363 op == opEquals || op == opNotEqual) {
00364 if (pCond->getSubExp1()->isFlags() && output.hasRange(pCond->getSubExp1())) {
00365 Range &r = output.getRange(pCond->getSubExp1());
00366 if (r.getBase()->isFlagCall() &&
00367 r.getBase()->getSubExp2()->getOper() == opList &&
00368 r.getBase()->getSubExp2()->getSubExp2()->getOper() == opList) {
00369 e = new Binary(op, r.getBase()->getSubExp2()->getSubExp1()->clone(), r.getBase()->getSubExp2()->getSubExp2()->getSubExp1()->clone());
00370 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00371 LOG << "calculated condition " << e << "\n";
00372 }
00373 }
00374 }
00375
00376 if (e)
00377 limitOutputWithCondition(output, e);
00378 updateRanges(output, execution_paths);
00379 output = getInputRanges();
00380 if (e)
00381 limitOutputWithCondition(output, (new Unary(opNot, e))->simplify());
00382 updateRanges(output, execution_paths, true);
00383
00384 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00385 LOG << this << "\n";
00386 }
00387
00388 void JunctionStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
00389 {
00390 RangeMap input;
00391 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00392 LOG << "unioning {\n";
00393 for (int i = 0; i < pbb->getNumInEdges(); i++) {
00394 Statement *last = pbb->getInEdges()[i]->getLastStmt();
00395 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00396 LOG << " in BB: " << pbb->getInEdges()[i]->getLowAddr() << " " << last << "\n";
00397 if (last->isBranch()) {
00398 input.unionwith(((BranchStatement*)last)->getRangesForOutEdgeTo(pbb));
00399 } else {
00400 if (last->isCall()) {
00401 Proc *d = ((CallStatement*)last)->getDestProc();
00402 if (d && !d->isLib() && ((UserProc*)d)->getCFG()->findRetNode() == NULL) {
00403 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00404 LOG << "ignoring ranges from call to proc with no ret node\n";
00405 } else
00406 input.unionwith(last->getRanges());
00407 } else
00408 input.unionwith(last->getRanges());
00409 }
00410 }
00411 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00412 LOG << "}\n";
00413
00414 if (!input.isSubset(ranges)) {
00415 RangeMap output = input;
00416
00417 if (output.hasRange(Location::regOf(28))) {
00418 Range &r = output.getRange(Location::regOf(28));
00419 if (r.getLowerBound() != r.getUpperBound() && r.getLowerBound() != Range::MIN) {
00420 if (VERBOSE)
00421 LOG << "stack height assumption violated " << r << " my bb: " << pbb->getLowAddr() << "\n";
00422 proc->printToLog();
00423 assert(false);
00424 }
00425 }
00426
00427 if (isLoopJunction()) {
00428 output = ranges;
00429 output.widenwith(input);
00430 }
00431
00432 updateRanges(output, execution_paths);
00433 }
00434
00435 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00436 LOG << this << "\n";
00437 }
00438
00439 void CallStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
00440 {
00441 RangeMap output = getInputRanges();
00442
00443 if (this->procDest == NULL) {
00444
00445 Exp *d = output.substInto(getDest()->clone());
00446 if (d->isIntConst() || d->isStrConst()) {
00447 if (d->isIntConst()) {
00448 ADDRESS dest = ((Const*)d)->getInt();
00449 procDest = proc->getProg()->setNewProc(dest);
00450 } else {
00451 procDest = proc->getProg()->getLibraryProc(((Const*)d)->getStr());
00452 }
00453 if (procDest) {
00454 Signature *sig = procDest->getSignature();
00455 pDest = d;
00456 arguments.clear();
00457 for (unsigned i = 0; i < sig->getNumParams(); i++) {
00458 Exp* a = sig->getParamExp(i);
00459 Assign* as = new Assign(new VoidType(), a->clone(), a->clone());
00460 as->setProc(proc);
00461 as->setBB(pbb);
00462 arguments.append(as);
00463 }
00464 signature = procDest->getSignature()->clone();
00465 m_isComputed = false;
00466 proc->undoComputedBB(this);
00467 proc->addCallee(procDest);
00468 LOG << "replaced indirect call with call to " << procDest->getName() << "\n";
00469 }
00470 }
00471 }
00472
00473 if (output.hasRange(Location::regOf(28))) {
00474 Range &r = output.getRange(Location::regOf(28));
00475 int c = 4;
00476 if (procDest == NULL) {
00477 LOG << "using push count hack to guess number of params\n";
00478 Statement *prev = this->getPreviousStatementInBB();
00479 while(prev) {
00480 if (prev->isAssign() && ((Assign*)prev)->getLeft()->isMemOf() &&
00481 ((Assign*)prev)->getLeft()->getSubExp1()->isRegOfK() &&
00482 ((Const*)((Assign*)prev)->getLeft()->getSubExp1()->getSubExp1())->getInt() == 28 &&
00483 ((Assign*)prev)->getRight()->getOper() != opPC) {
00484 c += 4;
00485 }
00486 prev = prev->getPreviousStatementInBB();
00487 }
00488 } else if (procDest->getSignature()->getConvention() == CONV_PASCAL)
00489 c += procDest->getSignature()->getNumParams() * 4;
00490 else if (!strncmp(procDest->getName(), "__imp_", 6)) {
00491 Statement *first = ((UserProc*)procDest)->getCFG()->getEntryBB()->getFirstStmt();
00492 assert(first && first->isCall());
00493 Proc *d = ((CallStatement*)first)->getDestProc();
00494 if (d->getSignature()->getConvention() == CONV_PASCAL)
00495 c += d->getSignature()->getNumParams() * 4;
00496 } else if (!procDest->isLib()) {
00497 UserProc *p = (UserProc*)procDest;
00498 if (VERBOSE) {
00499 LOG << "== checking for number of bytes popped ==\n";
00500 p->printToLog();
00501 LOG << "== end it ==\n";
00502 }
00503 Exp *eq = p->getProven(Location::regOf(28));
00504 if (eq) {
00505 if (VERBOSE)
00506 LOG << "found proven " << eq << "\n";
00507 if (eq->getOper() == opPlus && *eq->getSubExp1() == *Location::regOf(28) &&
00508 eq->getSubExp2()->isIntConst()) {
00509 c = ((Const*)eq->getSubExp2())->getInt();
00510 } else
00511 eq = NULL;
00512 }
00513 PBB retbb = p->getCFG()->findRetNode();
00514 if (retbb && eq == NULL) {
00515 Statement *last = retbb->getLastStmt();
00516 assert(last);
00517 if (last->isReturn()) {
00518 last->setBB(retbb);
00519 last = last->getPreviousStatementInBB();
00520 }
00521 if (last == NULL) {
00522
00523 for (int i = 0; i < retbb->getNumInEdges(); i++) {
00524 last = retbb->getInEdges()[i]->getLastStmt();
00525 if (last->isCall())
00526 break;
00527 }
00528 if (last->isCall()) {
00529 Proc *d = ((CallStatement*)last)->getDestProc();
00530 if (d && d->getSignature()->getConvention() == CONV_PASCAL)
00531 c += d->getSignature()->getNumParams() * 4;
00532 }
00533 last = NULL;
00534 }
00535 if (last && last->isAssign()) {
00536
00537 Assign *a = (Assign*)last;
00538 assert(a->getLeft()->isRegOfK() && ((Const*)a->getLeft()->getSubExp1())->getInt() == 28);
00539 Exp *t = a->getRight()->clone()->simplifyArith();
00540 assert(t->getOper() == opPlus &&
00541 t->getSubExp1()->isRegOfK() &&
00542 ((Const*)t->getSubExp1()->getSubExp1())->getInt() == 28);
00543 assert(t->getSubExp2()->isIntConst());
00544 c = ((Const*)t->getSubExp2())->getInt();
00545 }
00546 }
00547 }
00548 Range ra(r.getStride(), r.getLowerBound() == Range::MIN ? Range::MIN : r.getLowerBound() + c,
00549 r.getUpperBound() == Range::MAX ? Range::MAX : r.getUpperBound() + c, r.getBase());
00550 output.addRange(Location::regOf(28), ra);
00551 }
00552 updateRanges(output, execution_paths);
00553 }
00554
00555 bool JunctionStatement::isLoopJunction()
00556 {
00557 for (int i = 0; i < pbb->getNumInEdges(); i++)
00558 if (pbb->isBackEdge(i))
00559 return true;
00560 return false;
00561 }
00562
00563 RangeMap &BranchStatement::getRangesForOutEdgeTo(PBB out)
00564 {
00565 assert(this->getFixedDest() != NO_ADDRESS);
00566 if (out->getLowAddr() == this->getFixedDest())
00567 return ranges;
00568 return ranges2;
00569 }
00570
00571 bool Statement::isFirstStatementInBB()
00572 {
00573 assert(pbb);
00574 assert(pbb->getRTLs());
00575 assert(pbb->getRTLs()->size());
00576 assert(pbb->getRTLs()->front());
00577 assert(pbb->getRTLs()->front()->getList().size());
00578 return this == pbb->getRTLs()->front()->getList().front();
00579 }
00580
00581 bool Statement::isLastStatementInBB()
00582 {
00583 assert(pbb);
00584 return this == pbb->getLastStmt();
00585 }
00586
00587 Statement* Statement::getPreviousStatementInBB()
00588 {
00589 assert(pbb);
00590 std::list<RTL*> *rtls = pbb->getRTLs();
00591 assert(rtls);
00592 Statement *previous = NULL;
00593 for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
00594 RTL *rtl = *rit;
00595 for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
00596 if (*it == this)
00597 return previous;
00598 previous = *it;
00599 }
00600 }
00601 return NULL;
00602 }
00603
00604 Statement *Statement::getNextStatementInBB()
00605 {
00606 assert(pbb);
00607 std::list<RTL*> *rtls = pbb->getRTLs();
00608 assert(rtls);
00609 bool wantNext = false;
00610 for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
00611 RTL *rtl = *rit;
00612 for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
00613 if (wantNext)
00614 return *it;
00615 if (*it == this)
00616 wantNext = true;
00617 }
00618 }
00619 return NULL;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 std::ostream& operator<<(std::ostream& os, Statement* s) {
00631 if (s == NULL) {os << "NULL "; return os;}
00632 s->print(os);
00633 return os;
00634 }
00635
00636 bool Statement::isFlagAssgn() {
00637 if (kind != STMT_ASSIGN)
00638 return false;
00639 OPER op = ((Assign*)this)->getRight()->getOper();
00640 return (op == opFlagCall);
00641 }
00642
00643 char* Statement::prints() {
00644 std::ostringstream ost;
00645 print(ost);
00646 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00647 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00648 return debug_buffer;
00649 }
00650
00651
00652 void Statement::dump() {
00653 print(std::cerr);
00654 std::cerr << "\n";
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 bool hasSetFlags(Exp* e) {
00666 if (e->isFlagCall()) return true;
00667 OPER op = e->getOper();
00668 if (op != opBitAnd && op != opBitXor) return false;
00669 Exp* left = ((Binary*)e)->getSubExp1();
00670 Exp* right = ((Binary*)e)->getSubExp2();
00671 if (!right->isIntConst()) return false;
00672 if (left->isFlagCall()) {
00673 std::cerr << "hasSetFlags returns true with " << e << "\n";
00674 return true;
00675 }
00676 op = left->getOper();
00677 if (op != opBitAnd && op != opBitXor) return false;
00678 right = ((Binary*)left)->getSubExp2();
00679 left = ((Binary*)left)->getSubExp1();
00680 if (!right->isIntConst()) return false;
00681 bool ret = left->isFlagCall();
00682 if (ret)
00683 std::cerr << "hasSetFlags returns true with " << e << "\n";
00684 return ret;
00685 }
00686
00687
00688
00689
00690
00691 bool Statement::canPropagateToExp(Exp*e) {
00692 if (!e->isSubscript()) return false;
00693 if (((RefExp*)e)->isImplicitDef())
00694
00695 return false;
00696 Statement* def = ((RefExp*)e)->getDef();
00697
00698
00699
00700 if (def->isNullStatement())
00701
00702 return false;
00703 if (!def->isAssign()) return false;
00704 Assign* adef = (Assign*)def;
00705
00706 if (adef->getType()->isArray()) {
00707
00708 return false;
00709 }
00710 return true;
00711 }
00712
00713
00714
00715
00716 static int progress = 0;
00717 bool Statement::propagateTo(bool& convert, std::map<Exp*, int, lessExpStar>* destCounts ,
00718 LocationSet* usedByDomPhi , bool force ) {
00719 if (++progress > 1000) {
00720 std::cerr << 'p' << std::flush;
00721 progress = 0;
00722 }
00723 bool change;
00724 int changes = 0;
00725
00726
00727 int propMaxDepth = Boomerang::get()->propMaxDepth;
00728 do {
00729 LocationSet exps;
00730 addUsedLocs(exps, true);
00731
00732
00733 LocationSet::iterator ll;
00734 change = false;
00735
00736
00737 for (ll = exps.begin(); ll != exps.end(); ll++) {
00738 Exp* e = *ll;
00739 if (!canPropagateToExp(e))
00740 continue;
00741 Assign* def = (Assign*)((RefExp*)e)->getDef();
00742 Exp* rhs = def->getRight();
00743
00744 if (rhs->containsBadMemof(proc) && !(force && rhs->isMemOf()))
00745
00746
00747 continue;
00748 Exp* lhs = def->getLeft();
00749
00750 if (EXPERIMENTAL) {
00751 #if 0
00752
00753
00754
00755 LocationSet used;
00756 def->addUsedLocs(used);
00757 RefExp left(def->getLeft(), (Statement*)-1);
00758 RefExp *right = dynamic_cast<RefExp*>(def->getRight());
00759
00760 if (used.exists(&left) && !(right && *right->getSubExp1() == *left.getSubExp1()))
00761
00762 continue;
00763 #else
00764
00765
00766
00767
00768
00769
00770
00771 if (usedByDomPhi) {
00772 LocationSet rhsComps;
00773 rhs->addUsedLocs(rhsComps);
00774 LocationSet::iterator rcit;
00775 bool doNotPropagate = false;
00776 for (rcit = rhsComps.begin(); rcit != rhsComps.end(); ++rcit) {
00777 if (!(*rcit)->isSubscript()) continue;
00778 Exp* rhsBase = ((RefExp*)*rcit)->getSubExp1();
00779
00780
00781 Exp* OW = usedByDomPhi->findNS(rhsBase);
00782 if (OW) {
00783 Statement* OWdef = ((RefExp*)OW)->getDef();
00784 if (!OWdef->isAssign()) continue;
00785 Exp* lhsOWdef = ((Assign*)OWdef)->getLeft();
00786 LocationSet OWcomps;
00787 def->addUsedLocs(OWcomps);
00788 LocationSet::iterator cc;
00789 bool isOverwrite = false;
00790 for (cc = OWcomps.begin(); cc != OWcomps.end(); ++cc) {
00791 if (**cc *= *lhsOWdef) {
00792 isOverwrite = true;
00793 break;
00794 }
00795 }
00796 if (isOverwrite) {
00797
00798 if (def->getDomNumber() <= OWdef->getDomNumber() &&
00799 OWdef->getDomNumber() < dominanceNum)
00800
00801 doNotPropagate = true;
00802 break;
00803 }
00804 if (OW) std::cerr << "Ow is " << OW << "\n";
00805 }
00806 }
00807 if (doNotPropagate) {
00808 if (VERBOSE)
00809 LOG << "% propagation of " << def->getNumber() << " into " << number << " prevented by the "
00810 "propagate past overwriting statement in loop heuristic\n";
00811 continue;
00812 }
00813 }
00814 }
00815 #endif
00816
00817
00818 if (destCounts && !lhs->isFlags()) {
00819 std::map<Exp*, int, lessExpStar>::iterator ff = destCounts->find(e);
00820 if (ff != destCounts->end() && ff->second > 1 && rhs->getComplexityDepth(proc) >= propMaxDepth) {
00821 if (!def->getRight()->containsFlags()) {
00822
00823 continue;
00824 }
00825 }
00826 }
00827 change |= doPropagateTo(e, def, convert);
00828 }
00829 } while (change && ++changes < 10);
00830
00831
00832 simplify();
00833 return changes > 0;
00834 }
00835
00836
00837 bool Statement::propagateFlagsTo() {
00838 bool change = false, convert;
00839 int changes = 0;
00840 do {
00841 LocationSet exps;
00842 addUsedLocs(exps, true);
00843 LocationSet::iterator ll;
00844 for (ll = exps.begin(); ll != exps.end(); ll++) {
00845 Exp* e = *ll;
00846 if (!e->isSubscript()) continue;
00847 Assign* def = (Assign*)((RefExp*)e)->getDef();
00848 if (def == NULL || !def->isAssign()) continue;
00849 Exp* base = ((RefExp*)e)->getSubExp1();
00850 if (base->isFlags() || base->isMainFlag()) {
00851 change |= doPropagateTo(e, def, convert);
00852 }
00853 }
00854 } while (change && ++changes < 10);
00855 simplify();
00856 return change;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865 bool Statement::doPropagateTo(Exp* e, Assign* def, bool& convert) {
00866
00867 if (Boomerang::get()->numToPropagate >= 0) {
00868 if (Boomerang::get()->numToPropagate == 0) return false;
00869 Boomerang::get()->numToPropagate--;
00870 }
00871
00872 if (VERBOSE)
00873 LOG << "propagating " << def << "\n" << " into " << this << "\n";
00874
00875 bool change = replaceRef(e, def, convert);
00876
00877 if (VERBOSE) {
00878 LOG << " result " << this << "\n\n";
00879 }
00880 return change;
00881 }
00882
00883
00884
00885 bool Statement::replaceRef(Exp* e, Assign *def, bool& convert) {
00886 Exp* rhs = def->getRight();
00887 assert(rhs);
00888
00889 Exp* base = ((RefExp*)e)->getSubExp1();
00890
00891 Exp* lhs = def->getLeft();
00892 if (base->getOper() == opCF && lhs->isFlags()) {
00893 if (!rhs->isFlagCall())
00894 return false;
00895 char* str = ((Const*)((Binary*)rhs)->getSubExp1())->getStr();
00896 if (strncmp("SUBFLAGS", str, 8) == 0) {
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 Exp* relExp = new Binary(opLessUns,
00911 ((Binary*)rhs)->getSubExp2()->getSubExp1(),
00912 ((Binary*)rhs)->getSubExp2()->getSubExp2()->getSubExp1());
00913 searchAndReplace(new RefExp(new Terminal(opCF), def), relExp, true);
00914 return true;
00915 }
00916 }
00917
00918 if (base->getOper() == opZF && lhs->isFlags()) {
00919 if (!rhs->isFlagCall())
00920 return false;
00921 char* str = ((Const*)((Binary*)rhs)->getSubExp1())->getStr();
00922 if (strncmp("SUBFLAGS", str, 8) == 0) {
00923
00924 Exp* relExp = new Binary(opEquals,
00925 ((Binary*)rhs)->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1(),
00926 new Const(0));
00927 searchAndReplace(new RefExp(new Terminal(opZF), def), relExp, true);
00928 return true;
00929 }
00930 }
00931
00932
00933
00934
00935 bool ret = searchAndReplace(e, rhs, true);
00936
00937
00938 if (ret && isCall()) {
00939 convert |= ((CallStatement*)this)->convertToDirect();
00940 }
00941 return ret;
00942 }
00943
00944 bool Statement::isNullStatement() {
00945 if (kind != STMT_ASSIGN) return false;
00946 Exp* right = ((Assign*)this)->getRight();
00947 if (right->isSubscript()) {
00948
00949 return this == ((RefExp*)right)->getDef();
00950 }
00951 else
00952
00953 return *((Assign*)this)->getLeft() == *right;
00954 }
00955
00956 bool Statement::isFpush() {
00957 if (kind != STMT_ASSIGN) return false;
00958 return ((Assign*)this)->getRight()->getOper() == opFpush;
00959 }
00960 bool Statement::isFpop() {
00961 if (kind != STMT_ASSIGN) return false;
00962 return ((Assign*)this)->getRight()->getOper() == opFpop;
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972 #if defined(_MSC_VER) && _MSC_VER <= 1200
00973 #pragma warning(disable:4786)
00974 #endif
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 GotoStatement::GotoStatement()
00988 : pDest(NULL), m_isComputed(false) {
00989 kind = STMT_GOTO;
00990 }
00991
00992
00993
00994
00995
00996
00997
00998 GotoStatement::GotoStatement(ADDRESS uDest) : m_isComputed(false) {
00999 kind = STMT_GOTO;
01000 pDest = new Const(uDest);
01001 }
01002
01003
01004
01005
01006
01007
01008
01009 GotoStatement::~GotoStatement() {
01010 if (pDest) ;
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 ADDRESS GotoStatement::getFixedDest() {
01023 if (pDest->getOper() != opIntConst) return NO_ADDRESS;
01024 return ((Const*)pDest)->getAddr();
01025 }
01026
01027
01028
01029
01030
01031
01032
01033 void GotoStatement::setDest(Exp* pd) {
01034 pDest = pd;
01035 }
01036
01037
01038
01039
01040
01041
01042
01043 void GotoStatement::setDest(ADDRESS addr) {
01044
01045
01046
01047 if (pDest != NULL)
01048 ;
01049
01050 pDest = new Const(addr);
01051 }
01052
01053
01054
01055
01056
01057
01058
01059 Exp* GotoStatement::getDest() {
01060 return pDest;
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 void GotoStatement::adjustFixedDest(int delta) {
01073
01074 if (pDest == 0 || pDest->getOper() != opIntConst)
01075 LOG << "Can't adjust destination of non-static CTI\n";
01076
01077 ADDRESS dest = ((Const*)pDest)->getAddr();
01078 ((Const*)pDest)->setAddr(dest + delta);
01079 }
01080
01081 bool GotoStatement::search(Exp* search, Exp*& result) {
01082 result = NULL;
01083 if (pDest)
01084 return pDest->search(search, result);
01085 return false;
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 bool GotoStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
01097 bool change = false;
01098 if (pDest) {
01099 pDest = pDest->searchReplaceAll(search, replace, change);
01100 }
01101 return change;
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 bool GotoStatement::searchAll(Exp* search, std::list<Exp*> &result) {
01113 if (pDest) return pDest->searchAll(search, result);
01114 return false;
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 void GotoStatement::print(std::ostream& os, bool html) {
01126 os << std::setw(4) << std::dec << number << " ";
01127 if (html) {
01128 os << "</td><td>";
01129 os << "<a name=\"stmt" << std::dec << number << "\">";
01130 }
01131 os << "GOTO ";
01132 if (pDest == NULL)
01133 os << "*no dest*";
01134 else if (pDest->getOper() != opIntConst)
01135 pDest->print(os);
01136 else
01137 os << "0x" << std::hex << getFixedDest();
01138 if (html)
01139 os << "</a></td>";
01140 }
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 void GotoStatement::setIsComputed(bool b) {
01151 m_isComputed = b;
01152 }
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162 bool GotoStatement::isComputed() {
01163 return m_isComputed;
01164 }
01165
01166
01167
01168
01169
01170
01171
01172 Statement* GotoStatement::clone() {
01173 GotoStatement* ret = new GotoStatement();
01174 ret->pDest = pDest->clone();
01175 ret->m_isComputed = m_isComputed;
01176
01177 ret->pbb = pbb;
01178 ret->proc = proc;
01179 ret->number = number;
01180 return ret;
01181 }
01182
01183
01184 bool GotoStatement::accept(StmtVisitor* visitor) {
01185 return visitor->visit(this);
01186 }
01187
01188 void GotoStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
01189
01190 }
01191
01192 void GotoStatement::simplify() {
01193 if (isComputed()) {
01194 pDest = pDest->simplifyArith();
01195 pDest = pDest->simplify();
01196 }
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 BranchStatement::BranchStatement() : jtCond((BRANCH_TYPE)0), pCond(NULL), bFloat(false), size(0) {
01210 kind = STMT_BRANCH;
01211 }
01212
01213
01214
01215
01216
01217
01218
01219 BranchStatement::~BranchStatement() {
01220 if (pCond)
01221 ;
01222 }
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234 void BranchStatement::setCondType(BRANCH_TYPE cond, bool usesFloat ) {
01235 jtCond = cond;
01236 bFloat = usesFloat;
01237
01238
01239 Exp* p = NULL;
01240 switch(cond) {
01241 case BRANCH_JE:
01242 p = new Binary(opEquals, new Terminal(opFlags), new Const(0));
01243 break;
01244 case BRANCH_JNE:
01245 p = new Binary(opNotEqual, new Terminal(opFlags), new Const(0));
01246 break;
01247 case BRANCH_JSL:
01248 p = new Binary(opLess, new Terminal(opFlags), new Const(0));
01249 break;
01250 case BRANCH_JSLE:
01251 p = new Binary(opLessEq, new Terminal(opFlags), new Const(0));
01252 break;
01253 case BRANCH_JSGE:
01254 p = new Binary(opGtrEq, new Terminal(opFlags), new Const(0));
01255 break;
01256 case BRANCH_JSG:
01257 p = new Binary(opGtr, new Terminal(opFlags), new Const(0));
01258 break;
01259 case BRANCH_JUL:
01260 p = new Binary(opLessUns, new Terminal(opFlags), new Const(0));
01261 break;
01262 case BRANCH_JULE:
01263 p = new Binary(opLessEqUns, new Terminal(opFlags), new Const(0));
01264 break;
01265 case BRANCH_JUGE:
01266 p = new Binary(opGtrEqUns, new Terminal(opFlags), new Const(0));
01267 break;
01268 case BRANCH_JUG:
01269 p = new Binary(opGtrUns, new Terminal(opFlags), new Const(0));
01270 break;
01271 case BRANCH_JMI:
01272 p = new Binary(opLess, new Terminal(opFlags), new Const(0));
01273 break;
01274 case BRANCH_JPOS:
01275 p = new Binary(opGtr, new Terminal(opFlags), new Const(0));
01276 break;
01277 case BRANCH_JOF:
01278 p = new Binary(opLessUns, new Terminal(opFlags), new Const(0));
01279 break;
01280 case BRANCH_JNOF:
01281 p = new Binary(opGtrUns, new Terminal(opFlags), new Const(0));
01282 break;
01283 case BRANCH_JPAR:
01284
01285
01286
01287 p = new Binary(opEquals, new Terminal(opFlags), new Const(999));
01288 break;
01289 }
01290
01291
01292 if (!Boomerang::get()->noDecompile)
01293 p = new Terminal(usesFloat ? opFflags : opFlags);
01294 assert(p);
01295 setCondExpr(p);
01296 }
01297
01298
01299
01300
01301
01302
01303
01304 void BranchStatement::makeSigned() {
01305
01306 switch (jtCond)
01307 {
01308 case BRANCH_JUL : jtCond = BRANCH_JSL; break;
01309 case BRANCH_JULE: jtCond = BRANCH_JSLE; break;
01310 case BRANCH_JUGE: jtCond = BRANCH_JSGE; break;
01311 case BRANCH_JUG : jtCond = BRANCH_JSG; break;
01312 default:
01313
01314 break;
01315 }
01316 }
01317
01318
01319
01320
01321
01322
01323
01324 Exp* BranchStatement::getCondExpr() {
01325 return pCond;
01326 }
01327
01328
01329
01330
01331
01332
01333
01334 void BranchStatement::setCondExpr(Exp* e) {
01335 if (pCond) ;
01336 pCond = e;
01337 }
01338
01339 PBB BranchStatement::getFallBB()
01340 {
01341 ADDRESS a = getFixedDest();
01342 if (a == NO_ADDRESS)
01343 return NULL;
01344 if (pbb == NULL)
01345 return NULL;
01346 if (pbb->getNumOutEdges() != 2)
01347 return NULL;
01348 if (pbb->getOutEdge(0)->getLowAddr() == a)
01349 return pbb->getOutEdge(1);
01350 return pbb->getOutEdge(0);
01351 }
01352
01353
01354 void BranchStatement::setFallBB(PBB bb)
01355 {
01356 ADDRESS a = getFixedDest();
01357 if (a == NO_ADDRESS)
01358 return;
01359 if (pbb == NULL)
01360 return;
01361 if (pbb->getNumOutEdges() != 2)
01362 return;
01363 if (pbb->getOutEdge(0)->getLowAddr() == a) {
01364 pbb->getOutEdge(1)->deleteInEdge(pbb);
01365 pbb->setOutEdge(1, bb);
01366 bb->addInEdge(pbb);
01367 } else {
01368 pbb->getOutEdge(0)->deleteInEdge(pbb);
01369 pbb->setOutEdge(0, bb);
01370 bb->addInEdge(pbb);
01371 }
01372 }
01373
01374 PBB BranchStatement::getTakenBB()
01375 {
01376 ADDRESS a = getFixedDest();
01377 if (a == NO_ADDRESS)
01378 return NULL;
01379 if (pbb == NULL)
01380 return NULL;
01381 if (pbb->getNumOutEdges() != 2)
01382 return NULL;
01383 if (pbb->getOutEdge(0)->getLowAddr() == a)
01384 return pbb->getOutEdge(0);
01385 return pbb->getOutEdge(1);
01386 }
01387
01388 void BranchStatement::setTakenBB(PBB bb)
01389 {
01390 ADDRESS a = getFixedDest();
01391 if (a == NO_ADDRESS)
01392 return;
01393 if (pbb == NULL)
01394 return;
01395 if (pbb->getNumOutEdges() != 2)
01396 return;
01397 if (pbb->getOutEdge(0)->getLowAddr() == a) {
01398 pbb->getOutEdge(0)->deleteInEdge(pbb);
01399 pbb->setOutEdge(0, bb);
01400 bb->addInEdge(pbb);
01401 } else {
01402 pbb->getOutEdge(1)->deleteInEdge(pbb);
01403 pbb->setOutEdge(1, bb);
01404 bb->addInEdge(pbb);
01405 }
01406 }
01407
01408 bool BranchStatement::search(Exp* search, Exp*& result) {
01409 if (pCond) return pCond->search(search, result);
01410 result = NULL;
01411 return false;
01412 }
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422 bool BranchStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
01423 GotoStatement::searchAndReplace(search, replace, cc);
01424 bool change = false;
01425 if (pCond)
01426 pCond = pCond->searchReplaceAll(search, replace, change);
01427 return change;
01428 }
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 bool BranchStatement::searchAll(Exp* search, std::list<Exp*> &result) {
01439 if (pCond) return pCond->searchAll(search, result);
01440 return false;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450 void BranchStatement::print(std::ostream& os, bool html) {
01451 os << std::setw(4) << std::dec << number << " ";
01452 if (html) {
01453 os << "</td><td>";
01454 os << "<a name=\"stmt" << std::dec << number << "\">";
01455 }
01456 os << "BRANCH ";
01457 if (pDest == NULL)
01458 os << "*no dest*";
01459 else if (!pDest->isIntConst())
01460 os << pDest;
01461 else {
01462
01463 os << "0x" << std::hex << getFixedDest();
01464 }
01465 os << ", condition ";
01466 switch (jtCond) {
01467 case BRANCH_JE: os << "equals"; break;
01468 case BRANCH_JNE: os << "not equals"; break;
01469 case BRANCH_JSL: os << "signed less"; break;
01470 case BRANCH_JSLE: os << "signed less or equals"; break;
01471 case BRANCH_JSGE: os << "signed greater or equals"; break;
01472 case BRANCH_JSG: os << "signed greater"; break;
01473 case BRANCH_JUL: os << "unsigned less"; break;
01474 case BRANCH_JULE: os << "unsigned less or equals"; break;
01475 case BRANCH_JUGE: os << "unsigned greater or equals"; break;
01476 case BRANCH_JUG: os << "unsigned greater"; break;
01477 case BRANCH_JMI: os << "minus"; break;
01478 case BRANCH_JPOS: os << "plus"; break;
01479 case BRANCH_JOF: os << "overflow"; break;
01480 case BRANCH_JNOF: os << "no overflow"; break;
01481 case BRANCH_JPAR: os << "parity"; break;
01482 }
01483 if (bFloat) os << " float";
01484 os << std::endl;
01485 if (pCond) {
01486 if (html)
01487 os << "<br>";
01488 os << "High level: ";
01489 pCond->print(os, html);
01490 }
01491 if (html)
01492 os << "</a></td>";
01493 }
01494
01495
01496
01497
01498
01499
01500
01501 Statement* BranchStatement::clone() {
01502 BranchStatement* ret = new BranchStatement();
01503 ret->pDest = pDest->clone();
01504 ret->m_isComputed = m_isComputed;
01505 ret->jtCond = jtCond;
01506 if (pCond) ret->pCond = pCond->clone();
01507 else ret->pCond = NULL;
01508 ret->bFloat = bFloat;
01509
01510 ret->pbb = pbb;
01511 ret->proc = proc;
01512 ret->number = number;
01513 return ret;
01514 }
01515
01516
01517 bool BranchStatement::accept(StmtVisitor* visitor) {
01518 return visitor->visit(this);
01519 }
01520
01521 void BranchStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
01522
01523 }
01524
01525 bool BranchStatement::usesExp(Exp *e) {
01526 Exp *tmp;
01527 return pCond && pCond->search(e, tmp);
01528 }
01529
01530
01531
01532
01533 bool condToRelational(Exp*& pCond, BRANCH_TYPE jtCond) {
01534 pCond = pCond->simplifyArith()->simplify();
01535
01536 std::stringstream os;
01537 pCond->print(os);
01538 std::string s = os.str();
01539
01540 OPER condOp = pCond->getOper();
01541 if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "SUBFLAGS", 8) == 0) {
01542 OPER op = opWild;
01543
01544 bool makeUns = strncmp(((Const*)pCond->getSubExp1())->getStr(), "SUBFLAGSNL", 10) == 0;
01545 switch (jtCond) {
01546 case BRANCH_JE: op = opEquals; break;
01547 case BRANCH_JNE: op = opNotEqual; break;
01548 case BRANCH_JSL: if (makeUns) op = opLessUns; else op = opLess; break;
01549 case BRANCH_JSLE: if (makeUns) op = opLessEqUns; else op = opLessEq; break;
01550 case BRANCH_JSGE: if (makeUns) op = opGtrEqUns; else op = opGtrEq; break;
01551 case BRANCH_JSG: if (makeUns) op = opGtrUns; else op = opGtr; break;
01552 case BRANCH_JUL: op = opLessUns; break;
01553 case BRANCH_JULE: op = opLessEqUns; break;
01554 case BRANCH_JUGE: op = opGtrEqUns; break;
01555 case BRANCH_JUG: op = opGtrUns; break;
01556 case BRANCH_JMI:
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566 pCond = new Binary(opLess,
01567 pCond->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1()->clone(),
01568 new Const(0));
01569 break;
01570 case BRANCH_JPOS:
01571 pCond = new Binary(opGtrEq,
01572 pCond->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1()->clone(),
01573 new Const(0));
01574 break;
01575 case BRANCH_JOF:
01576 case BRANCH_JNOF:
01577 case BRANCH_JPAR:
01578 break;
01579 }
01580 if (op != opWild) {
01581 pCond = new Binary(op,
01582 pCond->getSubExp2()->getSubExp1()->clone(),
01583 pCond->getSubExp2()->getSubExp2()->getSubExp1()->clone());
01584 }
01585 }
01586 else if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "LOGICALFLAGS", 12) == 0) {
01587
01588 OPER op = opWild;
01589 switch (jtCond) {
01590 case BRANCH_JE: op = opEquals; break;
01591 case BRANCH_JNE: op = opNotEqual; break;
01592 case BRANCH_JMI: op = opLess; break;
01593 case BRANCH_JPOS: op = opGtrEq; break;
01594
01595
01596
01597 case BRANCH_JSL: op = opLess; break;
01598 case BRANCH_JSLE: op = opLessEq; break;
01599 case BRANCH_JSGE: op = opGtrEq; break;
01600 case BRANCH_JSG: op = opGtr; break;
01601
01602
01603 case BRANCH_JUL: op = opLessUns; break;
01604
01605 case BRANCH_JULE: op = opLessEqUns; break;
01606 case BRANCH_JUGE: op = opGtrEqUns; break;
01607 case BRANCH_JUG: op = opGtrUns; break;
01608 case BRANCH_JPAR: {
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 Exp* flagsParam = ((Binary*)((Binary*)pCond)->getSubExp2())->getSubExp1();
01625 Exp* test = flagsParam;
01626 if (test->isSubscript())
01627 test = ((RefExp*)test)->getSubExp1();
01628 if (test->isTemp())
01629 return false;
01630 int mask = 0;
01631 if (flagsParam->getOper() == opBitAnd) {
01632 Exp* setFlagsParam = ((Binary*)flagsParam)->getSubExp2();
01633 if (setFlagsParam->isIntConst())
01634 mask = ((Const*)setFlagsParam)->getInt();
01635 }
01636
01637
01638
01639 mask &= 0x41;
01640 OPER op;
01641 switch (mask) {
01642 case 0:
01643 LOG << "WARNING: unhandled pentium branch if parity with pCond = " << pCond << "\n";
01644 return false;
01645 case 1:
01646 op = opLess;
01647 break;
01648 case 0x40:
01649 op = opEquals;
01650 break;
01651 case 0x41:
01652 op = opLessEq;
01653 break;
01654 default:
01655 op = opWild;
01656 break;
01657 }
01658 pCond = new Binary(op,
01659 flagsParam->getSubExp1()->getSubExp2()->getSubExp1()->clone(),
01660 flagsParam->getSubExp1()->getSubExp2()->getSubExp2()->getSubExp1() ->clone());
01661 return true;
01662 }
01663 default:
01664 break;
01665 }
01666 if (op != opWild) {
01667 pCond = new Binary(op,
01668 pCond->getSubExp2()->getSubExp1()->clone(),
01669 new Const(0));
01670 }
01671 }
01672 else if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "SETFFLAGS", 9) == 0) {
01673
01674 OPER op = opWild;
01675 switch (jtCond) {
01676 case BRANCH_JE: op = opEquals; break;
01677 case BRANCH_JNE: op = opNotEqual; break;
01678 case BRANCH_JMI: op = opLess; break;
01679 case BRANCH_JPOS: op = opGtrEq; break;
01680 case BRANCH_JSL: op = opLess; break;
01681 case BRANCH_JSLE: op = opLessEq; break;
01682 case BRANCH_JSGE: op = opGtrEq; break;
01683 case BRANCH_JSG: op = opGtr; break;
01684 default:
01685 break;
01686 }
01687 if (op != opWild) {
01688 pCond = new Binary(op,
01689 pCond->getSubExp2()->getSubExp1()->clone(),
01690 pCond->getSubExp2()->getSubExp2()->getSubExp1() ->clone());
01691 }
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704 else if (condOp == opEquals || condOp == opNotEqual) {
01705 Exp* left = ((Binary*)pCond)->getSubExp1();
01706 Exp* right = ((Binary*)pCond)->getSubExp2();
01707 bool hasXor40 = false;
01708 if (left->getOper() == opBitXor && right->isIntConst()) {
01709 Exp* r2 = ((Binary*)left)->getSubExp2();
01710 if (r2->isIntConst()) {
01711 int k2 = ((Const*)r2)->getInt();
01712 if (k2 == 0x40) {
01713 hasXor40 = true;
01714 left = ((Binary*)left)->getSubExp1();
01715 }
01716 }
01717 }
01718 if (left->getOper() == opBitAnd && right->isIntConst()) {
01719 Exp* left1 = ((Binary*)left)->getSubExp1();
01720 Exp* left2 = ((Binary*)left)->getSubExp2();
01721 int k = ((Const*)right)->getInt();
01722
01723 k &= 0x41;
01724 if (left1->getOper() == opFlagCall && left2->isIntConst()) {
01725 int mask = ((Const*)left2)->getInt();
01726
01727 mask &= 0x41;
01728 OPER op = opWild;
01729 if (hasXor40) {
01730 assert(k == 0);
01731 op = condOp;
01732 } else {
01733 switch (mask) {
01734 case 1:
01735 if (condOp == opEquals && k == 0 || condOp == opNotEqual && k == 1)
01736 op = opGtrEq;
01737 else
01738 op = opLess;
01739 break;
01740 case 0x40:
01741 if (condOp == opEquals && k == 0 || condOp == opNotEqual && k == 0x40)
01742 op = opNotEqual;
01743 else
01744 op = opEquals;
01745 break;
01746 case 0x41:
01747 switch (k) {
01748 case 0:
01749 if (condOp == opEquals) op = opGtr;
01750 else op = opLessEq;
01751 break;
01752 case 1:
01753 if (condOp == opEquals) op = opLess;
01754 else op = opGtrEq;
01755 break;
01756 case 0x40:
01757 if (condOp == opEquals) op = opEquals;
01758 else op = opNotEqual;
01759 break;
01760 default:
01761 std::cerr << "BranchStatement::simplify: k is " << std::hex << k << "\n";
01762 assert(0);
01763 }
01764 break;
01765 default:
01766 std::cerr << "BranchStatement::simplify: Mask is " << std::hex << mask << "\n";
01767 assert(0);
01768 }
01769 }
01770 if (op != opWild) {
01771 pCond = new Binary(op,
01772 left1->getSubExp2()->getSubExp1(),
01773 left1->getSubExp2()->getSubExp2()->getSubExp1());
01774 return true;
01775 }
01776 }
01777 }
01778 }
01779 return false;
01780 }
01781
01782
01783 void BranchStatement::simplify() {
01784 if (pCond) {
01785 if (condToRelational(pCond, jtCond))
01786 bFloat = true;
01787 }
01788 }
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799 CaseStatement::CaseStatement() :
01800 pSwitchInfo(NULL) {
01801 kind = STMT_CASE;
01802 }
01803
01804
01805
01806
01807
01808
01809
01810
01811 CaseStatement::~CaseStatement() {
01812 if (pSwitchInfo)
01813 ;
01814 }
01815
01816
01817
01818
01819
01820
01821
01822 SWITCH_INFO* CaseStatement::getSwitchInfo() {
01823 return pSwitchInfo;
01824 }
01825
01826
01827
01828
01829
01830
01831
01832 void CaseStatement::setSwitchInfo(SWITCH_INFO* psi) {
01833 pSwitchInfo = psi;
01834 }
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844 bool CaseStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
01845 bool ch = GotoStatement::searchAndReplace(search, replace, cc);
01846 bool ch2 = false;
01847 if (pSwitchInfo && pSwitchInfo->pSwitchVar)
01848 pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->searchReplaceAll(search, replace, ch2);
01849 return ch | ch2;
01850 }
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860 bool CaseStatement::searchAll(Exp* search, std::list<Exp*> &result) {
01861 return GotoStatement::searchAll(search, result) ||
01862 ( pSwitchInfo && pSwitchInfo->pSwitchVar && pSwitchInfo->pSwitchVar->searchAll(search, result) );
01863 }
01864
01865
01866
01867
01868
01869
01870
01871
01872 void CaseStatement::print(std::ostream& os, bool html) {
01873 os << std::setw(4) << std::dec << number << " ";
01874 if (html) {
01875 os << "</td><td>";
01876 os << "<a name=\"stmt" << std::dec << number << "\">";
01877 }
01878 if (pSwitchInfo == NULL) {
01879 os << "CASE [";
01880 if (pDest == NULL)
01881 os << "*no dest*";
01882 else os << pDest;
01883 os << "]";
01884 } else
01885 os << "SWITCH(" << pSwitchInfo->pSwitchVar << ")\n";
01886 if (html)
01887 os << "</a></td>";
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897 Statement* CaseStatement::clone() {
01898 CaseStatement* ret = new CaseStatement();
01899 ret->pDest = pDest->clone();
01900 ret->m_isComputed = m_isComputed;
01901 ret->pSwitchInfo = new SWITCH_INFO;
01902 *ret->pSwitchInfo = *pSwitchInfo;
01903 ret->pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->clone();
01904
01905 ret->pbb = pbb;
01906 ret->proc = proc;
01907 ret->number = number;
01908 return ret;
01909 }
01910
01911
01912 bool CaseStatement::accept(StmtVisitor* visitor) {
01913 return visitor->visit(this);
01914 }
01915
01916 void CaseStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
01917
01918 }
01919
01920 bool CaseStatement::usesExp(Exp *e) {
01921
01922 if (pDest)
01923 return *pDest == *e;
01924
01925 if (pSwitchInfo->pSwitchVar)
01926 return *pSwitchInfo->pSwitchVar == *e;
01927 return false;
01928 }
01929
01930
01931 void CaseStatement::simplify() {
01932 if (pDest)
01933 pDest = pDest->simplify();
01934 else if (pSwitchInfo && pSwitchInfo->pSwitchVar)
01935 pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->simplify();
01936 }
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948 CallStatement::CallStatement(): returnAfterCall(false), calleeReturn(NULL) {
01949 kind = STMT_CALL;
01950 procDest = NULL;
01951 signature = NULL;
01952 }
01953
01954
01955
01956
01957
01958
01959
01960 CallStatement::~CallStatement() {
01961 }
01962
01963
01964 int CallStatement::findDefine(Exp *e) {
01965 StatementList::iterator rr;
01966 int i = 0;
01967 for (rr = defines.begin(); rr != defines.end(); ++rr, ++i) {
01968 Exp* ret = ((Assignment*)*rr)->getLeft();
01969 if (*ret == *e)
01970 return i;
01971 }
01972 return -1;
01973 }
01974
01975 Exp *CallStatement::getProven(Exp *e) {
01976 if (procDest)
01977 return procDest->getProven(e);
01978 return NULL;
01979 }
01980
01981
01982 void CallStatement::localiseComp(Exp* e) {
01983 if (e->isMemOf()) {
01984 ((Location*)e)->setSubExp1(localiseExp(((Location*)e)->getSubExp1()));
01985 }
01986 }
01987
01988
01989
01990 Exp* CallStatement::localiseExp(Exp* e) {
01991 if (!defCol.isInitialised()) return e;
01992 Localiser l(this);
01993 e = e->clone()->accept(&l);
01994
01995 return e;
01996 }
01997
01998
01999
02000
02001 Exp* CallStatement::findDefFor(Exp *e) {
02002 return defCol.findDefFor(e);
02003 }
02004
02005 Type *CallStatement::getArgumentType(int i) {
02006 assert(i < (int)arguments.size());
02007 StatementList::iterator aa = arguments.begin();
02008 my_advance(aa, i);
02009 return ((Assign*)(*aa))->getType();
02010 }
02011
02012
02013
02014
02015
02016
02017
02018 void CallStatement::setArguments(StatementList& args) {
02019 arguments.clear();
02020 arguments.append(args);
02021 StatementList::iterator ll;
02022 for (ll = arguments.begin(); ll != arguments.end(); ++ll) {
02023 ((Assign*)*ll)->setProc(proc);
02024 ((Assign*)*ll)->setBB(pbb);
02025 }
02026 }
02027
02028
02029
02030
02031
02032
02033
02034
02035 void CallStatement::setSigArguments() {
02036 if (signature) return;
02037 if (procDest == NULL)
02038
02039 return;
02040
02041 signature = procDest->getSignature()->clone();
02042 procDest->addCaller(this);
02043
02044 if (!procDest->isLib())
02045 return;
02046 int n = signature->getNumParams();
02047 int i;
02048 arguments.clear();
02049 for (i = 0; i < n; i++) {
02050 Exp *e = signature->getArgumentExp(i);
02051 assert(e);
02052 Location *l = dynamic_cast<Location*>(e);
02053 if (l) {
02054 l->setProc(proc);
02055 }
02056 Assign* as = new Assign(signature->getParamType(i)->clone(), e->clone(), e->clone());
02057 as->setProc(proc);
02058 as->setBB(pbb);
02059 as->setNumber(number);
02060 as->setParent(this);
02061 arguments.append(as);
02062 }
02063
02064
02065
02066 }
02067
02068 bool CallStatement::search(Exp* search, Exp*& result) {
02069 bool found = GotoStatement::search(search, result);
02070 if (found) return true;
02071 StatementList::iterator ss;
02072 for (ss = defines.begin(); ss != defines.end(); ++ss) {
02073 if ((*ss)->search(search, result))
02074 return true;
02075 }
02076 for (ss = arguments.begin(); ss != arguments.end(); ++ss) {
02077 if ((*ss)->search(search, result))
02078 return true;
02079 }
02080 return false;
02081 }
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091 bool CallStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
02092 bool change = GotoStatement::searchAndReplace(search, replace, cc);
02093 StatementList::iterator ss;
02094
02095 for (ss = defines.begin(); ss != defines.end(); ++ss)
02096 change |= (*ss)->searchAndReplace(search, replace, cc);
02097 for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02098 change |= (*ss)->searchAndReplace(search, replace, cc);
02099 if (cc) {
02100 DefCollector::iterator dd;
02101 for (dd = defCol.begin(); dd != defCol.end(); ++dd)
02102 change |= (*dd)->searchAndReplace(search, replace, cc);
02103 }
02104 return change;
02105 }
02106
02107
02108
02109
02110
02111
02112
02113
02114 bool CallStatement::searchAll(Exp* search, std::list<Exp *>& result) {
02115 bool found = GotoStatement::searchAll(search, result);
02116 StatementList::iterator ss;
02117 for (ss = defines.begin(); ss != defines.end(); ++ss) {
02118 if ((*ss)->searchAll(search, result))
02119 found = true;
02120 }
02121 for (ss = arguments.begin(); ss != arguments.end(); ++ss) {
02122 if ((*ss)->searchAll(search, result))
02123 found = true;
02124 }
02125 return found;
02126 }
02127
02128
02129
02130
02131
02132
02133
02134 void CallStatement::print(std::ostream& os, bool html) {
02135 os << std::setw(4) << std::dec << number << " ";
02136 if (html) {
02137 os << "</td><td>";
02138 os << "<a name=\"stmt" << std::dec << number << "\">";
02139 }
02140
02141
02142 if (defines.size()) {
02143 if (defines.size() > 1) os << "{";
02144 StatementList::iterator rr;
02145 bool first = true;
02146 for (rr = defines.begin(); rr != defines.end(); ++rr) {
02147 assert((*rr)->isAssignment());
02148 Assignment *as = (Assignment*)*rr;
02149 if (first)
02150 first = false;
02151 else
02152 os << ", ";
02153 os << "*" << as->getType() << "* " << as->getLeft();
02154 if (as->isAssign())
02155 os << " := " << ((Assign*)as)->getRight();
02156 }
02157 if (defines.size() > 1) os << "}";
02158 os << " := ";
02159 } else if (isChildless()) {
02160 if (html)
02161 os << "<all> := ";
02162 else
02163 os << "<all> := ";
02164 }
02165
02166 os << "CALL ";
02167 if (procDest)
02168 os << procDest->getName();
02169 else if (pDest == NULL)
02170 os << "*no dest*";
02171 else {
02172 if (pDest->isIntConst())
02173 os << "0x" << std::hex << ((Const*)pDest)->getInt();
02174 else
02175 pDest->print(os, html);
02176 }
02177
02178
02179 if (isChildless()) {
02180 if (html)
02181 os << "(<all>)";
02182 else
02183 os << "(<all>)";
02184 } else {
02185 os << "(\n";
02186 StatementList::iterator aa;
02187 for (aa = arguments.begin(); aa != arguments.end(); ++aa) {
02188 os << " ";
02189 ((Assignment*)*aa)->printCompact(os, html);
02190 os << "\n";
02191 }
02192 os << " )";
02193 }
02194
02195 #if 1
02196
02197 if (html)
02198 os << "<br>";
02199 else
02200 os << "\n ";
02201 os << "Reaching definitions: ";
02202 defCol.print(os, html);
02203 if (html)
02204 os << "<br>";
02205 else
02206 os << "\n ";
02207 os << "Live variables: ";
02208 useCol.print(os, html);
02209 #endif
02210
02211 if (html)
02212 os << "</a></td>";
02213 }
02214
02215
02216
02217
02218
02219
02220
02221
02222 void CallStatement::setReturnAfterCall(bool b) {
02223 returnAfterCall = b;
02224 }
02225
02226
02227
02228
02229
02230
02231
02232
02233 bool CallStatement::isReturnAfterCall() {
02234 return returnAfterCall;
02235 }
02236
02237
02238
02239
02240
02241
02242
02243 Statement* CallStatement::clone() {
02244 CallStatement* ret = new CallStatement();
02245 ret->pDest = pDest->clone();
02246 ret->m_isComputed = m_isComputed;
02247 StatementList::iterator ss;
02248 for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02249 ret->arguments.append((*ss)->clone());
02250 for (ss = defines.begin(); ss != defines.end(); ++ss)
02251 ret->defines.append((*ss)->clone());
02252
02253 ret->pbb = pbb;
02254 ret->proc = proc;
02255 ret->number = number;
02256 return ret;
02257 }
02258
02259
02260 bool CallStatement::accept(StmtVisitor* visitor) {
02261 return visitor->visit(this);
02262 }
02263
02264 Proc* CallStatement::getDestProc() {
02265 return procDest;
02266 }
02267
02268 void CallStatement::setDestProc(Proc* dest) {
02269 assert(dest);
02270
02271 procDest = dest;
02272 }
02273
02274 void CallStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
02275
02276 Proc *p = getDestProc();
02277
02278 if (p == NULL && isComputed()) {
02279 hll->AddIndCallStatement(indLevel, pDest, arguments, calcResults());
02280 return;
02281 }
02282 StatementList* results = calcResults();
02283
02284 #if 0
02285 LOG << "call: " << this;
02286 LOG << " in proc " << proc->getName() << "\n";
02287 #endif
02288 assert(p);
02289 if (Boomerang::get()->noDecompile) {
02290 if (procDest->getSignature()->getNumReturns() > 0) {
02291 Assign* as = new Assign(new IntegerType(), new Unary(opRegOf, new Const(24)), new Unary(opRegOf, new Const(24)));
02292 as->setProc(proc);
02293 as->setBB(pbb);
02294 results->append(as);
02295 }
02296
02297
02298 if (std::string(p->getName()) == "printf" ||
02299 std::string(p->getName()) == "scanf") {
02300 for (int i = 1; i < 3; i++) {
02301 Exp *e = signature->getArgumentExp(i);
02302 assert(e);
02303 Location *l = dynamic_cast<Location*>(e);
02304 if (l) {
02305 l->setProc(proc);
02306 }
02307 Assign* as = new Assign(signature->getParamType(i), e->clone(), e->clone());
02308 as->setProc(proc);
02309 as->setBB(pbb);
02310 as->setNumber(number);
02311 arguments.append(as);
02312 }
02313 }
02314 }
02315 if (p->isLib() && *p->getSignature()->getPreferedName()) {
02316 hll->AddCallStatement(indLevel, p, p->getSignature()->getPreferedName(), arguments, results);
02317 } else
02318 hll->AddCallStatement(indLevel, p, p->getName(), arguments, results);
02319 }
02320
02321 void CallStatement::simplify() {
02322 GotoStatement::simplify();
02323 StatementList::iterator ss;
02324 for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02325 (*ss)->simplify();
02326 for (ss = defines.begin(); ss != defines.end(); ++ss)
02327 (*ss)->simplify();
02328 }
02329
02330 bool GotoStatement::usesExp(Exp* e) {
02331 Exp* where;
02332 return (pDest->search(e, where));
02333 }
02334
02335 bool CallStatement::usesExp(Exp *e) {
02336 if (GotoStatement::usesExp(e)) return true;
02337 StatementList::iterator ss;
02338 for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02339 if ((*ss)->usesExp(e)) return true;
02340 for (ss = defines.begin(); ss != defines.end(); ++ss)
02341 if ((*ss)->usesExp(e)) return true;
02342 return false;
02343 }
02344
02345 void CallStatement::getDefinitions(LocationSet &defs) {
02346 StatementList::iterator dd;
02347 for (dd = defines.begin(); dd != defines.end(); ++dd)
02348 defs.insert(((Assignment*)*dd)->getLeft());
02349
02350
02351 if (isChildless() && !Boomerang::get()->assumeABI)
02352 defs.insert(new Terminal(opDefineAll));
02353 }
02354
02355
02356
02357
02358 bool CallStatement::convertToDirect() {
02359 if (!m_isComputed)
02360 return false;
02361 bool convertIndirect = false;
02362 Exp *e = pDest;
02363 if (pDest->isSubscript()) {
02364 Statement* def = ((RefExp*)e)->getDef();
02365 if (def && !def->isImplicit())
02366 return false;
02367 e = ((RefExp*)e)->getSubExp1();
02368 }
02369 if (e->getOper() == opArrayIndex &&
02370 ((Binary*)e)->getSubExp2()->isIntConst() &&
02371 ((Const*)(((Binary*)e)->getSubExp2()))->getInt() == 0)
02372 e = ((Binary*)e)->getSubExp1();
02373
02374 if (e->isSubscript())
02375 e = ((RefExp*)e)->getSubExp1();
02376 if (e->isIntConst()) {
02377
02378
02379
02380 } else if (e->isMemOf()) {
02381
02382 Exp* sub = ((Unary*)e)->getSubExp1();
02383 if (sub->isIntConst()) {
02384
02385 ADDRESS u = (ADDRESS)((Const*)sub)->getInt();
02386 proc->getProg()->globalUsed(u);
02387 const char *nam = proc->getProg()->getGlobalName(u);
02388 e = Location::global(nam, proc);
02389 pDest = new RefExp(e, NULL);
02390 }
02391 }
02392 if (!e->isGlobal()) {
02393 return false;
02394 }
02395 char *nam = ((Const*)e->getSubExp1())->getStr();
02396 Prog* prog = proc->getProg();
02397 ADDRESS gloAddr = prog->getGlobalAddr(nam);
02398 ADDRESS dest = prog->readNative4(gloAddr);
02399
02400
02401 if (dest < prog->getLimitTextLow() || dest > prog->getLimitTextHigh())
02402 return false;
02403 Proc *p = prog->findProc(nam);
02404 bool bNewProc = p == NULL;
02405 if (bNewProc)
02406 p = prog->setNewProc(dest);
02407 if (VERBOSE)
02408 LOG << (bNewProc ? "new" : "existing") << " procedure for call to global '" << nam << " is " << p->getName() <<
02409 "\n";
02410
02411
02412
02413
02414
02415
02416
02417
02418 procDest = p;
02419 Signature *sig = p->getSignature();
02420
02421
02422 pDest = new Const(dest);
02423
02424
02425
02426 proc->fixCallAndPhiRefs();
02427
02428
02429
02430 arguments.clear();
02431 for (unsigned i = 0; i < sig->getNumParams(); i++) {
02432 Exp* a = sig->getParamExp(i);
02433 Assign* as = new Assign(new VoidType(), a->clone(), a->clone());
02434 as->setProc(proc);
02435 as->setBB(pbb);
02436 arguments.append(as);
02437 }
02438
02439
02440
02441
02442
02443
02444
02445
02446 signature = p->getSignature()->clone();
02447
02448
02449 m_isComputed = false;
02450 proc->undoComputedBB(this);
02451 proc->addCallee(procDest);
02452 procDest->printDetailsXML();
02453 convertIndirect = true;
02454
02455 if (VERBOSE)
02456 LOG << "Result of convertToDirect: " << this << "\n";
02457 return convertIndirect;
02458 }
02459
02460 Exp* CallStatement::getArgumentExp(int i)
02461 {
02462 assert(i < (int)arguments.size());
02463 StatementList::iterator aa = arguments.begin();
02464 my_advance(aa, i);
02465 return ((Assign*)*aa)->getRight();
02466 }
02467
02468 void CallStatement::setArgumentExp(int i, Exp *e)
02469 {
02470 assert(i < (int)arguments.size());
02471 StatementList::iterator aa = arguments.begin();
02472 my_advance(aa, i);
02473 Exp*& a = ((Assign*)*aa)->getRightRef();
02474 a = e->clone();
02475 }
02476
02477 int CallStatement::getNumArguments()
02478 {
02479 return arguments.size();
02480 }
02481
02482 void CallStatement::setNumArguments(int n) {
02483 int oldSize = arguments.size();
02484 if (oldSize > n) {
02485 StatementList::iterator aa = arguments.begin();
02486 my_advance(aa, n);
02487 arguments.erase(aa, arguments.end());
02488 }
02489
02490 for (int i = oldSize; i < n; i++) {
02491 Exp* a = procDest->getSignature()->getArgumentExp(i);
02492 Type *ty = procDest->getSignature()->getParamType(i);
02493 if (ty == NULL && oldSize)
02494 ty = procDest->getSignature()->getParamType(oldSize-1);
02495 if (ty == NULL)
02496 ty = new VoidType();
02497 Assign* as = new Assign(ty, a->clone(), a->clone());
02498 as->setProc(proc);
02499 as->setBB(pbb);
02500 arguments.append(as);
02501 }
02502 }
02503
02504 void CallStatement::removeArgument(int i)
02505 {
02506 StatementList::iterator aa = arguments.begin();
02507 my_advance(aa, i);
02508 arguments.erase(aa);
02509 }
02510
02511
02512 Exp *processConstant(Exp *e, Type *t, Prog *prog, UserProc* proc, ADDRESS stmt) {
02513 if (t == NULL) return e;
02514 NamedType *nt = NULL;
02515 if (t->isNamed()) {
02516 nt = (NamedType*)t;
02517 t = ((NamedType*)t)->resolvesTo();
02518 }
02519 if (t == NULL) return e;
02520
02521 if (e->isIntConst()) {
02522 if (nt && nt->getName() == "LPCWSTR") {
02523 ADDRESS u = ((Const*)e)->getAddr();
02524
02525 LOG << "possible wide char string at " << u << "\n";
02526 }
02527 if (t->resolvesToPointer()) {
02528 PointerType *pt = t->asPointer();
02529 Type *points_to = pt->getPointsTo();
02530 if (t->isCString()) {
02531 ADDRESS u = ((Const*)e)->getAddr();
02532 if (u != 0) {
02533 char *str = prog->getStringConstant(u, true);
02534 if (str) {
02535 e = new Const(str);
02536
02537 const char* nam = prog->getGlobalName(u);
02538 if (nam) prog->setGlobalType(nam,
02539 new PointerType(new CharType()));
02540 } else {
02541 proc->getProg()->globalUsed(u);
02542 const char *nam = proc->getProg()->getGlobalName(u);
02543 if (nam)
02544 e = Location::global(nam, proc);
02545 }
02546 }
02547 }
02548 if (points_to->resolvesToFunc()) {
02549 ADDRESS a = ((Const*)e)->getAddr();
02550 if (VERBOSE || 1)
02551 LOG << "found function pointer with constant value " << "of type " << pt->getCtype()
02552 << " in statement at addr " << stmt << ". Decoding address " << a << "\n";
02553
02554 if (a != 0) {
02555 if (!Boomerang::get()->noDecodeChildren)
02556 prog->decodeEntryPoint(a);
02557 Proc *p = prog->findProc(a);
02558 if (p) {
02559 Signature *sig = points_to->asFunc()->getSignature()->clone();
02560 if (sig->getName() == NULL ||
02561 strlen(sig->getName()) == 0 ||
02562 !strcmp(sig->getName(), "<ANON>") ||
02563 prog->findProc(sig->getName()) != NULL)
02564 sig->setName(p->getName());
02565 else
02566 p->setName(sig->getName());
02567 sig->setForced(true);
02568 p->setSignature(sig);
02569 e = Location::global(p->getName(), proc);
02570 }
02571 }
02572 }
02573 } else if (t->resolvesToFloat()) {
02574 e = new Ternary(opItof, new Const(32), new Const(t->getSize()), e);
02575 }
02576 }
02577
02578 return e;
02579 }
02580
02581 Type* Assignment::getTypeFor(Exp* e) {
02582
02583 return type;
02584 }
02585
02586 void Assignment::setTypeFor(Exp* e, Type* ty) {
02587
02588 Type* oldType = type;
02589 type = ty;
02590 if (DEBUG_TA && oldType != ty)
02591 LOG << " changed type of " << this << " (type was " << oldType->getCtype() << ")\n";
02592 }
02593
02594
02595 Type* CallStatement::getTypeFor(Exp* e) {
02596
02597 Assignment* as = defines.findOnLeft(e);
02598 if (as != NULL)
02599 return as->getType();
02600 if (e->isPC())
02601
02602 return new PointerType(new VoidType);
02603 return new VoidType;
02604 }
02605
02606 void CallStatement::setTypeFor(Exp* e, Type* ty) {
02607 Assignment* as = defines.findOnLeft(e);
02608 if (as != NULL)
02609 return as->setType(ty);
02610
02611 Exp* ref = defCol.findDefFor(e);
02612 if (ref == NULL || !ref->isSubscript()) return;
02613 Statement* def = ((RefExp*)ref)->getDef();
02614 if (def == NULL) return;
02615 def->setTypeFor(e, ty);
02616 }
02617
02618
02619
02620
02621
02622 bool CallStatement::ellipsisProcessing(Prog* prog) {
02623
02624
02625 if (getDestProc() == NULL || !signature->hasEllipsis())
02626 return false;
02627
02628 std::string name(getDestProc()->getName());
02629 int format = -1;
02630 if ((name == "printf" || name == "scanf"))
02631 format = 0;
02632 else if (name == "sprintf" || name == "fprintf" || name == "sscanf")
02633 format = 1;
02634 else if (getNumArguments() && getArgumentExp(getNumArguments()-1)->isStrConst())
02635 format = getNumArguments() - 1;
02636 else return false;
02637 if (VERBOSE)
02638 LOG << "ellipsis processing for " << name << "\n";
02639 char* formatStr = NULL;
02640 Exp* formatExp = getArgumentExp(format);
02641
02642 if (formatExp->isAddrOf()) {
02643 formatExp = ((Unary*)formatExp)->getSubExp1();
02644 if (formatExp->isSubscript())
02645 formatExp = ((RefExp*)formatExp)->getSubExp1();
02646 if (formatExp->isMemOf())
02647 formatExp = ((Unary*)formatExp)->getSubExp1();
02648 }
02649 if (formatExp->isSubscript()) {
02650
02651 Statement* def = ((RefExp*)formatExp)->getDef();
02652 if (def == NULL) return false;
02653 if (def->isAssign()) {
02654
02655 Exp* rhs = ((Assign*)def)->getRight();
02656 if (rhs == NULL || !rhs->isStrConst()) return false;
02657 formatStr = ((Const*)rhs)->getStr();
02658 } else if (def->isPhi()) {
02659
02660 PhiAssign* pa = (PhiAssign*)def;
02661 int n = pa->getNumDefs();
02662 for (int i=0; i < n; i++) {
02663 def = pa->getStmtAt(i);
02664 if (def == NULL) continue;
02665 if (!def->isAssign()) continue;
02666 Exp* rhs = ((Assign*)def)->getRight();
02667 if (rhs == NULL || !rhs->isStrConst()) continue;
02668 formatStr = ((Const*)rhs)->getStr();
02669 break;
02670 }
02671 if (formatStr == NULL) return false;
02672 } else return false;
02673 } else if (formatExp->isStrConst()) {
02674 formatStr = ((Const*)formatExp)->getStr();
02675 } else return false;
02676
02677
02678 int n = 1;
02679 char ch;
02680
02681 bool isScanf = name == "scanf" || name.substr(1, 5) == "scanf";
02682 char *p = formatStr;
02683 while ((p = strchr(p, '%'))) {
02684 p++;
02685 bool veryLong = false;
02686 do {
02687 ch = *p++;
02688 switch (ch) {
02689 case '*':
02690
02691 n++;
02692
02693 addSigParam(new IntegerType(), false);
02694 continue;
02695 case '-': case '+': case '#': case ' ':
02696
02697 continue;
02698 case '.':
02699
02700 continue;
02701 case 'h': case 'l':
02702
02703
02704
02705
02706 if (*p == 'l') {
02707
02708 p++;
02709 veryLong = true;
02710 }
02711 continue;
02712 case 'L':
02713
02714
02715 veryLong = true;
02716 continue;
02717 default:
02718 if ('0' <= ch && ch <= '9') continue;
02719 break;
02720 }
02721 break;
02722 } while (1);
02723 if (ch != '%')
02724 n++;
02725 switch (ch) {
02726 case 'd': case 'i':
02727 addSigParam(new IntegerType(veryLong ? 64 : 32), isScanf);
02728 break;
02729 case 'u': case 'x': case 'X': case 'o':
02730 addSigParam(new IntegerType(32, -1), isScanf);
02731 break;
02732 case 'f': case 'g': case 'G': case 'e': case 'E':
02733
02734
02735 addSigParam(new FloatType(veryLong ? 128 : (isScanf ? 32 : 64)), isScanf);
02736
02737 break;
02738 case 's':
02739 addSigParam(new PointerType(new ArrayType(new CharType)), isScanf);
02740 break;
02741 case 'c':
02742 addSigParam(new CharType, isScanf);
02743 break;
02744 case '%':
02745 break;
02746 default:
02747 LOG << "Unhandled format character " << ch << " in format string for call " << this << "\n";
02748 }
02749 }
02750 setNumArguments(format + n);
02751 signature->killEllipsis();
02752 return true;
02753 }
02754
02755
02756 Assign* CallStatement::makeArgAssign(Type* ty, Exp* e) {
02757 Exp* lhs = e->clone();
02758 localiseComp(lhs);
02759 Exp* rhs = localiseExp(e->clone());
02760 Assign* as = new Assign(ty, lhs, rhs);
02761 as->setProc(proc);
02762 as->setBB(pbb);
02763
02764 Cfg* cfg = proc->getCFG();
02765 if (cfg->implicitsDone()) {
02766 ImplicitConverter ic(cfg);
02767 StmtImplicitConverter sm(&ic, cfg);
02768 as->accept(&sm);
02769 }
02770 return as;
02771 }
02772
02773
02774 void CallStatement::addSigParam(Type* ty, bool isScanf) {
02775 if (isScanf) ty = new PointerType(ty);
02776 signature->addParameter(ty);
02777 Exp* paramExp = signature->getParamExp(signature->getNumParams()-1);
02778 if (VERBOSE)
02779 LOG << " ellipsisProcessing: adding parameter " << paramExp << " of type " << ty->getCtype() << "\n";
02780 if (arguments.size() < (unsigned)signature->getNumParams()) {
02781 Assign* as = makeArgAssign(ty, paramExp);
02782 arguments.append(as);
02783 }
02784 }
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796 ReturnStatement::ReturnStatement() : retAddr(NO_ADDRESS) {
02797 kind = STMT_RET;
02798 }
02799
02800
02801
02802
02803
02804
02805
02806 ReturnStatement::~ReturnStatement() {
02807 }
02808
02809
02810
02811
02812
02813
02814
02815 Statement* ReturnStatement::clone() {
02816 ReturnStatement* ret = new ReturnStatement();
02817 iterator rr;
02818 for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
02819 ret->modifieds.append((ImplicitAssign*)(*rr)->clone());
02820 for (rr = returns.begin(); rr != returns.end(); ++rr)
02821 ret->returns.append((Assignment*)(*rr)->clone());
02822 ret->retAddr = retAddr;
02823 ret->col.makeCloneOf(col);
02824
02825 ret->pbb = pbb;
02826 ret->proc = proc;
02827 ret->number = number;
02828 return ret;
02829 }
02830
02831
02832 bool ReturnStatement::accept(StmtVisitor* visitor) {
02833 return visitor->visit(this);
02834 }
02835
02836 void ReturnStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
02837 hll->AddReturnStatement(indLevel, &getReturns());
02838 }
02839
02840 void ReturnStatement::simplify() {
02841 iterator it;
02842 for (it = modifieds.begin(); it != modifieds.end(); it++)
02843 (*it)->simplify();
02844 for (it = returns.begin(); it != returns.end(); it++)
02845 (*it)->simplify();
02846 }
02847
02848
02849 void ReturnStatement::removeReturn(Exp* loc) {
02850 if (loc->isSubscript())
02851 loc = ((Location*)loc)->getSubExp1();
02852 iterator rr;
02853 for (rr = returns.begin(); rr != returns.end(); ++rr) {
02854 if (*((Assignment*)*rr)->getLeft() == *loc) {
02855 returns.erase(rr);
02856 return;
02857 }
02858 }
02859 }
02860
02861 void ReturnStatement::addReturn(Assignment* a) {
02862 returns.append(a);
02863 }
02864
02865
02866 bool ReturnStatement::search(Exp* search, Exp*& result) {
02867 result = NULL;
02868 ReturnStatement::iterator rr;
02869 for (rr = begin(); rr != end(); ++rr) {
02870 if ((*rr)->search(search, result))
02871 return true;
02872 }
02873 return false;
02874 }
02875
02876 bool ReturnStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
02877 bool change = false;
02878 ReturnStatement::iterator rr;
02879 for (rr = begin(); rr != end(); ++rr)
02880 change |= (*rr)->searchAndReplace(search, replace, cc);
02881 if (cc) {
02882 DefCollector::iterator dd;
02883 for (dd = col.begin(); dd != col.end(); ++dd)
02884 change |= (*dd)->searchAndReplace(search, replace);
02885 }
02886 return change;
02887 }
02888
02889 bool ReturnStatement::searchAll(Exp* search, std::list<Exp *>& result) {
02890 bool found = false;
02891 ReturnStatement::iterator rr;
02892 for (rr = begin(); rr != end(); ++rr) {
02893 if ((*rr)->searchAll(search, result))
02894 found = true;
02895 }
02896 return found;
02897 }
02898
02899 bool CallStatement::isDefinition() {
02900 LocationSet defs;
02901 getDefinitions(defs);
02902 return defs.size() != 0;
02903 }
02904
02905 bool ReturnStatement::usesExp(Exp *e) {
02906 Exp *where;
02907 ReturnStatement::iterator rr;
02908 for (rr = begin(); rr != end(); ++rr) {
02909 if ((*rr)->search(e, where))
02910 return true;
02911 }
02912 return false;
02913 }
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927 BoolAssign::BoolAssign(int sz): Assignment(NULL), jtCond((BRANCH_TYPE)0),
02928 pCond(NULL), bFloat(false), size(sz) {
02929 kind = STMT_BOOLASSIGN;
02930 }
02931
02932
02933
02934
02935
02936
02937
02938 BoolAssign::~BoolAssign() {
02939 if (pCond)
02940 ;
02941 }
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953 void BoolAssign::setCondType(BRANCH_TYPE cond, bool usesFloat ) {
02954 jtCond = cond;
02955 bFloat = usesFloat;
02956 setCondExpr(new Terminal(opFlags));
02957 }
02958
02959
02960
02961
02962
02963
02964
02965
02966 void BoolAssign::makeSigned() {
02967
02968 switch (jtCond)
02969 {
02970 case BRANCH_JUL : jtCond = BRANCH_JSL; break;
02971 case BRANCH_JULE: jtCond = BRANCH_JSLE; break;
02972 case BRANCH_JUGE: jtCond = BRANCH_JSGE; break;
02973 case BRANCH_JUG : jtCond = BRANCH_JSG; break;
02974 default:
02975
02976 break;
02977 }
02978 }
02979
02980
02981
02982
02983
02984
02985
02986 Exp* BoolAssign::getCondExpr() {
02987 return pCond;
02988 }
02989
02990
02991
02992
02993
02994
02995
02996 void BoolAssign::setCondExpr(Exp* pss) {
02997 if (pCond) ;
02998 pCond = pss;
02999 }
03000
03001
03002
03003
03004
03005
03006
03007 void BoolAssign::printCompact(std::ostream& os , bool html) {
03008 os << "BOOL ";
03009 lhs->print(os);
03010 os << " := CC(";
03011 switch (jtCond) {
03012 case BRANCH_JE: os << "equals"; break;
03013 case BRANCH_JNE: os << "not equals"; break;
03014 case BRANCH_JSL: os << "signed less"; break;
03015 case BRANCH_JSLE: os << "signed less or equals"; break;
03016 case BRANCH_JSGE: os << "signed greater or equals"; break;
03017 case BRANCH_JSG: os << "signed greater"; break;
03018 case BRANCH_JUL: os << "unsigned less"; break;
03019 case BRANCH_JULE: os << "unsigned less or equals"; break;
03020 case BRANCH_JUGE: os << "unsigned greater or equals"; break;
03021 case BRANCH_JUG: os << "unsigned greater"; break;
03022 case BRANCH_JMI: os << "minus"; break;
03023 case BRANCH_JPOS: os << "plus"; break;
03024 case BRANCH_JOF: os << "overflow"; break;
03025 case BRANCH_JNOF: os << "no overflow"; break;
03026 case BRANCH_JPAR: os << "ev parity"; break;
03027 }
03028 os << ")";
03029 if (bFloat) os << ", float";
03030 if (html)
03031 os << "<br>";
03032 os << std::endl;
03033 if (pCond) {
03034 os << "High level: ";
03035 pCond->print(os, html);
03036 if (html)
03037 os << "<br>";
03038 os << "\n";
03039 }
03040 }
03041
03042
03043
03044
03045
03046
03047
03048 Statement* BoolAssign::clone() {
03049 BoolAssign* ret = new BoolAssign(size);
03050 ret->jtCond = jtCond;
03051 if (pCond) ret->pCond = pCond->clone();
03052 else ret->pCond = NULL;
03053 ret->bFloat = bFloat;
03054 ret->size = size;
03055
03056 ret->pbb = pbb;
03057 ret->proc = proc;
03058 ret->number = number;
03059 return ret;
03060 }
03061
03062
03063 bool BoolAssign::accept(StmtVisitor* visitor) {
03064 return visitor->visit(this);
03065 }
03066
03067 void BoolAssign::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
03068 assert(lhs);
03069 assert(pCond);
03070
03071 Assign as(lhs->clone(), new Ternary(opTern, pCond->clone(),
03072 new Const(1), new Const(0)));
03073 hll->AddAssignmentStatement(indLevel, &as);
03074 }
03075
03076 void BoolAssign::simplify() {
03077 if (pCond)
03078 condToRelational(pCond, jtCond);
03079 }
03080
03081 void BoolAssign::getDefinitions(LocationSet &defs)
03082 {
03083 defs.insert(getLeft());
03084 }
03085
03086 bool BoolAssign::usesExp(Exp *e)
03087 {
03088 assert(lhs && pCond);
03089 Exp *where = 0;
03090 return (pCond->search(e, where) || (lhs->isMemOf() &&
03091 ((Unary*)lhs)->getSubExp1()->search(e, where)));
03092 }
03093
03094 bool BoolAssign::search(Exp *search, Exp *&result)
03095 {
03096 assert(lhs);
03097 if (lhs->search(search, result)) return true;
03098 assert(pCond);
03099 return pCond->search(search, result);
03100 }
03101
03102 bool BoolAssign::searchAll(Exp* search, std::list<Exp*>& result)
03103 {
03104 bool ch = false;
03105 assert(lhs);
03106 if (lhs->searchAll(search, result)) ch = true;
03107 assert(pCond);
03108 return pCond->searchAll(search, result) || ch;
03109 }
03110
03111 bool BoolAssign::searchAndReplace(Exp *search, Exp *replace, bool cc) {
03112 bool chl, chr;
03113 assert(pCond);
03114 assert(lhs);
03115 pCond = pCond->searchReplaceAll(search, replace, chl);
03116 lhs = lhs->searchReplaceAll(search, replace, chr);
03117 return chl | chr;
03118 }
03119
03120
03121 void BoolAssign::setLeftFromList(std::list<Statement*>* stmts) {
03122 assert(stmts->size() == 1);
03123 Assign* first = (Assign*)stmts->front();
03124 assert(first->getKind() == STMT_ASSIGN);
03125 lhs = first->getLeft();
03126 }
03127
03128
03129
03130
03131
03132 Assignment::Assignment(Exp* lhs) : TypingStatement(new VoidType), lhs(lhs) {
03133 if (lhs && lhs->isRegOf()) {
03134 int n = ((Const*)lhs->getSubExp1())->getInt();
03135 if (((Location*)lhs)->getProc()) {
03136 type = new SizeType(((Location*)lhs)->getProc()->getProg()->getRegSize(n));
03137 }
03138 }
03139
03140 }
03141 Assignment::Assignment(Type* ty, Exp* lhs) : TypingStatement(ty), lhs(lhs) {}
03142 Assignment::~Assignment() {}
03143
03144 Assign::Assign(Exp* lhs, Exp* rhs, Exp* guard)
03145 : Assignment(lhs), rhs(rhs), guard(guard) {
03146 kind = STMT_ASSIGN;
03147 }
03148
03149 Assign::Assign(Type* ty, Exp* lhs, Exp* rhs, Exp* guard)
03150 : Assignment(ty, lhs), rhs(rhs), guard(guard)
03151 {
03152 kind = STMT_ASSIGN;
03153 }
03154 Assign::Assign(Assign& o) : Assignment(lhs->clone()) {
03155 kind = STMT_ASSIGN;
03156 rhs = o.rhs->clone();
03157 if (o.type) type = o.type->clone(); else type = NULL;
03158 if (o.guard) guard = o.guard->clone(); else guard = NULL;
03159 }
03160
03161
03162
03163 ImplicitAssign::ImplicitAssign(Exp* lhs) : Assignment(lhs) {
03164 kind = STMT_IMPASSIGN;
03165 }
03166
03167 ImplicitAssign::ImplicitAssign(Type* ty, Exp* lhs) : Assignment(ty, lhs) {
03168 kind = STMT_IMPASSIGN;
03169 }
03170 ImplicitAssign::ImplicitAssign(ImplicitAssign& o) : Assignment(type?type->clone():NULL, lhs->clone()) {
03171 kind = STMT_IMPASSIGN;
03172 }
03173
03174 ImplicitAssign::~ImplicitAssign() { }
03175
03176 Statement* Assign::clone() {
03177 Assign* a = new Assign(type == NULL ? NULL : type->clone(), lhs->clone(), rhs->clone(),
03178 guard == NULL ? NULL : guard->clone());
03179
03180 a->pbb = pbb;
03181 a->proc = proc;
03182 a->number = number;
03183 return a;
03184 }
03185
03186 Statement* PhiAssign::clone() {
03187 PhiAssign* pa = new PhiAssign(type, lhs);
03188 Definitions::iterator dd;
03189 for (dd = defVec.begin(); dd != defVec.end(); dd++) {
03190 PhiInfo pi;
03191 pi.def = dd->def;
03192 pi.e = dd->e->clone();
03193 pa->defVec.push_back(pi);
03194 }
03195 return pa;
03196 }
03197
03198 Statement* ImplicitAssign::clone() {
03199 ImplicitAssign* ia = new ImplicitAssign(type, lhs);
03200 return ia;
03201 }
03202
03203
03204 bool Assign::accept(StmtVisitor* visitor) {
03205 return visitor->visit(this);
03206 }
03207 bool PhiAssign::accept(StmtVisitor* visitor) {
03208 return visitor->visit(this);
03209 }
03210 bool ImplicitAssign::accept(StmtVisitor* visitor) {
03211 return visitor->visit(this);
03212 }
03213
03214 void Assign::simplify() {
03215
03216 OPER leftop = lhs->getOper();
03217 if (Boomerang::get()->noBranchSimplify) {
03218 if (leftop == opZF || leftop == opCF || leftop == opOF || leftop == opNF)
03219 return;
03220 }
03221
03222 lhs = lhs->simplifyArith();
03223 rhs = rhs->simplifyArith();
03224 if (guard) guard = guard->simplifyArith();
03225
03226 lhs = lhs->simplify();
03227 rhs = rhs->simplify();
03228 if (guard) guard = guard->simplify();
03229
03230
03231 if (guard && (guard->isTrue() || guard->isIntConst() && ((Const*)guard)->getInt() == 1))
03232 guard = NULL;
03233
03234 if (lhs->getOper() == opMemOf) {
03235 lhs->setSubExp1(lhs->getSubExp1()->simplifyArith());
03236 }
03237
03238
03239 #if 0
03240 if (DFA_TYPE_ANALYSIS) return;
03241 if (lhs->getOper() == opMemOf && lhs->getSubExp1()->getOper() == opSubscript) {
03242 RefExp *ref = (RefExp*)lhs->getSubExp1();
03243 Statement *phist = ref->getDef();
03244 PhiAssign *phi = NULL;
03245 if (phist )
03246 phi = dynamic_cast<PhiAssign*>(phist);
03247 for (int i = 0; phi && i < phi->getNumDefs(); i++) {
03248 if (phi->getStmtAt(i)) {
03249 Assign *def = dynamic_cast<Assign*>(phi->getStmtAt(i));
03250
03251 if (def && (def->rhs->isIntConst() ||
03252 (def->rhs->getOper() == opMinus &&
03253 def->rhs->getSubExp1()->isSubscript() &&
03254 ((RefExp*)def->rhs->getSubExp1())->isImplicitDef() &&
03255 def->rhs->getSubExp1()->getSubExp1()->isRegOf() &&
03256 def->rhs->getSubExp2()->isIntConst()))) {
03257 Exp *ne = new Unary(opAddrOf, Location::memOf(def->rhs, proc));
03258 if (VERBOSE)
03259 LOG << "replacing " << def->rhs << " with " << ne << " in " << def << "\n";
03260 def->rhs = ne;
03261 }
03262 if (def && def->rhs->getOper() == opAddrOf &&
03263 def->rhs->getSubExp1()->getOper() == opSubscript &&
03264 def->rhs->getSubExp1()->getSubExp1()->getOper() == opGlobal &&
03265
03266 rhs->getOper() != opPhi && rhs->getOper() != opItof &&
03267 rhs->getOper() != opFltConst) {
03268 Type *ty = proc->getProg()->getGlobalType(
03269 ((Const*)def->rhs->getSubExp1()->
03270 getSubExp1()->
03271 getSubExp1())->getStr());
03272 if (ty && ty->isArray()) {
03273 Type *bty = ((ArrayType*)ty)->getBaseType();
03274 if (bty->isFloat()) {
03275 if (VERBOSE)
03276 LOG << "replacing " << rhs << " with ";
03277 rhs = new Ternary(opItof, new Const(32), new Const(bty->getSize()), rhs);
03278 if (VERBOSE)
03279 LOG << rhs << " (assign indicates float type)\n";
03280 }
03281 }
03282 }
03283 }
03284 }
03285 }
03286 #endif
03287 }
03288
03289 void Assign::simplifyAddr() {
03290 lhs = lhs->simplifyAddr();
03291 rhs = rhs->simplifyAddr();
03292 }
03293
03294 void Assignment::simplifyAddr() {
03295 lhs = lhs->simplifyAddr();
03296 }
03297
03298
03299 void Assign::fixSuccessor() {
03300 lhs = lhs->fixSuccessor();
03301 rhs = rhs->fixSuccessor();
03302 }
03303
03304 void Assignment::print(std::ostream& os, bool html) {
03305 os << std::setw(4) << std::dec << number << " ";
03306 if (html) {
03307 os << "</td><td>";
03308 os << "<a name=\"stmt" << std::dec << number << "\">";
03309 }
03310 printCompact(os, html);
03311 if (html)
03312 os << "</a>";
03313 if (!ranges.empty()) {
03314 os << "\n\t\t\tranges: ";
03315 ranges.print(os);
03316 }
03317 }
03318 void Assign::printCompact(std::ostream& os, bool html) {
03319 os << "*" << type << "* ";
03320 if (guard)
03321 os << guard << " => ";
03322 if (lhs) lhs->print(os, html);
03323 os << " := ";
03324 if (rhs) rhs->print(os, html);
03325 }
03326 void PhiAssign::printCompact(std::ostream& os, bool html) {
03327 os << "*" << type << "* ";
03328 if (lhs) lhs->print(os, html);
03329 os << " := phi";
03330
03331
03332 bool simple = true;
03333 int i, n = defVec.size();
03334 if (n != 0) {
03335 for (i = 0; i < n; i++) {
03336
03337 if (defVec[i].e == NULL) continue;
03338 if (! (*defVec[i].e == *lhs)) {
03339
03340 simple = false;
03341 break;
03342 }
03343 }
03344 }
03345 iterator it;
03346 if (simple) {
03347 os << "{" << std::dec;
03348 for (it = defVec.begin(); it != defVec.end(); ) {
03349 if (it->def) {
03350 if (html)
03351 os << "<a href=\"#stmt" << std::dec << it->def->getNumber() << "\">";
03352 os << it->def->getNumber();
03353 if (html)
03354 os << "</a>";
03355 } else
03356 os << "-";
03357 if (++it != defVec.end())
03358 os << " ";
03359 }
03360 os << "}";
03361 } else {
03362 os << "(";
03363 for (it = defVec.begin(); it != defVec.end(); ) {
03364 Exp* e = it->e;
03365 if (e == NULL)
03366 os << "NULL{";
03367 else
03368 os << e << "{";
03369 if (it->def)
03370 os << std::dec << it->def->getNumber();
03371 else
03372 os << "-";
03373 os << "}";
03374 if (++it != defVec.end())
03375 os << " ";
03376 }
03377 os << ")";
03378 }
03379 }
03380 void ImplicitAssign::printCompact(std::ostream& os, bool html) {
03381 os << "*" << type << "* ";
03382 if (lhs) lhs->print(os, html);
03383 os << " := -";
03384 }
03385
03386
03387
03388
03389 void Assignment::getDefinitions(LocationSet &defs) {
03390 if (lhs->getOper() == opAt)
03391 defs.insert(((Ternary*)lhs)->getSubExp1());
03392 else
03393 defs.insert(lhs);
03394
03395 if (lhs->isFlags()) {
03396 defs.insert(new Terminal(opCF));
03397 defs.insert(new Terminal(opZF));
03398 }
03399 }
03400
03401 bool Assign::search(Exp* search, Exp*& result) {
03402 if (lhs->search(search, result))
03403 return true;
03404 return rhs->search(search, result);
03405 }
03406 bool PhiAssign::search(Exp* search, Exp*& result) {
03407 if (lhs->search(search, result))
03408 return true;
03409 iterator it;
03410 for (it = defVec.begin(); it != defVec.end(); ++it) {
03411 if (it->e == NULL) continue;
03412 RefExp* re = new RefExp(it->e, it->def);
03413 if (re->search(search, result))
03414 return true;
03415 }
03416 return false;
03417 }
03418 bool ImplicitAssign::search(Exp* search, Exp*& result) {
03419 return lhs->search(search, result);
03420 }
03421
03422 bool Assign::searchAll(Exp* search, std::list<Exp*>& result) {
03423 bool res;
03424 std::list<Exp*> leftResult;
03425 std::list<Exp*>::iterator it;
03426 res = lhs->searchAll(search, leftResult);
03427
03428 res |= rhs->searchAll(search, result);
03429 for (it = leftResult.begin(); it != leftResult.end(); it++)
03430 result.push_back(*it);
03431 return res;
03432 }
03433
03434 bool PhiAssign::searchAll(Exp* search, std::list<Exp*>& result) {
03435 return lhs->searchAll(search, result);
03436 }
03437 bool ImplicitAssign::searchAll(Exp* search, std::list<Exp*>& result) {
03438 return lhs->searchAll(search, result);
03439 }
03440
03441 bool Assign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
03442 bool chl, chr, chg = false;
03443 lhs = lhs->searchReplaceAll(search, replace, chl);
03444 rhs = rhs->searchReplaceAll(search, replace, chr);
03445 if (guard)
03446 guard = guard->searchReplaceAll(search, replace, chg);
03447 return chl | chr | chg;
03448 }
03449 bool PhiAssign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
03450 bool change;
03451 lhs = lhs->searchReplaceAll(search, replace, change);
03452 std::vector<PhiInfo>::iterator it;
03453 for (it = defVec.begin(); it != defVec.end(); it++) {
03454 if (it->e == NULL) continue;
03455 bool ch;
03456
03457 it->e = it->e->searchReplaceAll(search, replace, ch);
03458 change |= ch;
03459 }
03460 return change;
03461 }
03462 bool ImplicitAssign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
03463 bool change;
03464 lhs = lhs->searchReplaceAll(search, replace, change);
03465 return change;
03466 }
03467
03468 void Assign::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
03469 hll->AddAssignmentStatement(indLevel, this);
03470 }
03471
03472
03473 int Assign::getMemDepth() {
03474 int d1 = lhs->getMemDepth();
03475 int d2 = rhs->getMemDepth();
03476 if (d1 >= d2) return d1;
03477 return d2;
03478 }
03479
03480
03481 bool Assignment::usesExp(Exp* e) {
03482 Exp *where = 0;
03483 return (lhs->isMemOf() || lhs->isRegOf()) && ((Unary*)lhs)->getSubExp1()->search(e, where);
03484 }
03485
03486 bool Assign::usesExp(Exp *e) {
03487 Exp *where = 0;
03488 return (rhs->search(e, where) || ((lhs->isMemOf() || lhs->isRegOf()) &&
03489 ((Unary*)lhs)->getSubExp1()->search(e, where)));
03490 }
03491
03492 #if 0
03493 bool Assign::match(const char *pattern, std::map<std::string, Exp*> &bindings)
03494 {
03495 if (strstr(pattern, ":=") == NULL)
03496 return false;
03497 char *left = strdup(pattern);
03498 char *right = strstr(left, ":=");
03499 *right++ = 0;
03500 right++;
03501 while (*right == ' ')
03502 right++;
03503 char *endleft = left + strlen(left) - 1;
03504 while (*endleft == ' ') {
03505 *endleft = 0;
03506 endleft--;
03507 }
03508
03509 return lhs->match(left, bindings) && rhs->match(right, bindings);
03510 }
03511
03512 void addPhiReferences(StatementSet &stmts, Statement *def);
03513
03514 void addSimpleCopyReferences(StatementSet &stmts, Statement *def)
03515 {
03516 if (!(*((Assign*)def)->getLeft() == *((Assign*)def)->getRight()->getSubExp1()))
03517 return;
03518 Statement *copy = ((RefExp*)((Assign*)def)->getRight())->getDef();
03519 if (!stmts.exists(copy)) {
03520 stmts.insert(copy);
03521 if (copy->isPhi())
03522 addPhiReferences(stmts, copy);
03523 else if (copy->isAssign() && ((Assign*)copy)->getRight()->isSubscript())
03524 addSimpleCopyReferences(stmts, copy);
03525 }
03526 }
03527
03528 void addPhiReferences(StatementSet &stmts, Statement *def)
03529 {
03530 PhiAssign *p = (PhiAssign*)def;
03531 for (PhiAssign::iterator it = p->begin(); it != p->end(); it++) {
03532 if ((*it).def->isPhi() && !stmts.exists((*it).def)) {
03533 stmts.insert((*it).def);
03534 addPhiReferences(stmts, (*it).def);
03535 } else if ((*it).def->isAssign() && ((Assign*)(*it).def)->getRight()->isSubscript()) {
03536 stmts.insert((*it).def);
03537 addSimpleCopyReferences(stmts, (*it).def);
03538 } else
03539 stmts.insert((*it).def);
03540 }
03541 }
03542 #endif
03543
03544 void Assignment::genConstraints(LocationSet& cons) {
03545
03546
03547 if (type)
03548 cons.insert(new Binary(opEquals,
03549 new Unary(opTypeOf,
03550 new RefExp(lhs, this)),
03551 new TypeVal(type)));
03552 }
03553
03554
03555 void Assign::genConstraints(LocationSet& cons) {
03556 Assignment::genConstraints(cons);
03557 Exp* con = rhs->genConstraints(
03558 new Unary(opTypeOf,
03559 new RefExp(lhs->clone(), this)));
03560 if (con) cons.insert(con);
03561 }
03562
03563 void PhiAssign::genConstraints(LocationSet& cons) {
03564
03565
03566 Exp* result = new Unary(opTypeOf, new RefExp(lhs, this));
03567 Definitions::iterator uu;
03568 for (uu = defVec.begin(); uu != defVec.end(); uu++) {
03569 Exp* conjunct = new Binary(opEquals,
03570 result,
03571 new Unary(opTypeOf,
03572 new RefExp(uu->e, uu->def)));
03573 cons.insert(conjunct);
03574 }
03575 }
03576
03577 void CallStatement::genConstraints(LocationSet& cons) {
03578 Proc* dest = getDestProc();
03579 if (dest == NULL) return;
03580 Signature* destSig = dest->getSignature();
03581
03582
03583 StatementList::iterator aa;
03584 int p = 0;
03585 for (aa = arguments.begin(); aa != arguments.end(); ++aa, ++p) {
03586 Exp* arg = ((Assign*)*aa)->getRight();
03587
03588 if (arg->isAddrOf()) {
03589 Exp* sub = arg->getSubExp1();
03590 if (sub->isSubscript())
03591 sub = ((RefExp*)sub)->getSubExp1();
03592 if (sub->isMemOf())
03593 arg = ((Location*)sub)->getSubExp1();
03594 }
03595 if (arg->isRegOf() || arg->isMemOf() || arg->isSubscript() || arg->isLocal() || arg->isGlobal()) {
03596 Exp* con = new Binary(opEquals,
03597 new Unary(opTypeOf, arg->clone()),
03598 new TypeVal(destSig->getParamType(p)->clone()));
03599 cons.insert(con);
03600 }
03601 }
03602
03603 if (dest->isLib()) {
03604
03605 std::string name = dest->getName();
03606
03607
03608 char* str;
03609 Exp* arg0 = ((Assign*)*arguments.begin())->getRight();
03610 if ((name == "printf" || name == "scanf") && (str = arg0->getAnyStrConst()) != NULL) {
03611
03612 int n = 1;
03613 char* p = str;
03614 while ((p = strchr(p, '%'))) {
03615 p++;
03616 Type* t = NULL;
03617 int longness = 0;
03618 bool sign = true;
03619 bool cont;
03620 do {
03621 cont = false;
03622 switch(*p) {
03623 case 'u':
03624 sign = false;
03625 cont = true;
03626 break;
03627 case 'x':
03628 sign = false;
03629
03630 case 'i':
03631 case 'd': {
03632 int size = 32;
03633
03634 if (longness == 2) size = 64;
03635 t = new IntegerType(size, sign);
03636 break;
03637 }
03638 case 'f':
03639 case 'g':
03640 t = new FloatType(64);
03641 break;
03642 case 's':
03643 t = new PointerType(new CharType());
03644 break;
03645 case 'l':
03646 longness++;
03647 cont = true;
03648 break;
03649 case '.':
03650 cont = true;
03651 break;
03652 case '*':
03653 assert(0);
03654 default:
03655 if (*p >= '0' && *p <= '9')
03656 cont = true;
03657 break;
03658 }
03659 p++;
03660 } while (cont);
03661 if (t) {
03662
03663 if (name == "scanf")
03664 t = new PointerType(t);
03665
03666 TypeVal* tv = new TypeVal(t);
03667 StatementList::iterator aa = arguments.begin();
03668 my_advance(aa, n);
03669 Exp* argn = ((Assign*)*aa)->getRight();
03670 Exp* con = argn->genConstraints(tv);
03671 cons.insert(con);
03672 }
03673 n++;
03674 }
03675 }
03676 }
03677 }
03678
03679 void BranchStatement::genConstraints(LocationSet& cons) {
03680 if (pCond == NULL && VERBOSE) {
03681 LOG << "Warning: BranchStatment " << number << " has no condition expression!\n";
03682 return;
03683 }
03684 Type* opsType;
03685 if (bFloat)
03686 opsType = new FloatType(0);
03687 else
03688 opsType = new IntegerType(0);
03689 if ( jtCond == BRANCH_JUGE || jtCond == BRANCH_JULE ||
03690 jtCond == BRANCH_JUG || jtCond == BRANCH_JUL) {
03691 assert(!bFloat);
03692 ((IntegerType*)opsType)->bumpSigned(-1);
03693 } else if (jtCond == BRANCH_JSGE || jtCond == BRANCH_JSLE ||
03694 jtCond == BRANCH_JSG || jtCond == BRANCH_JSL) {
03695 assert(!bFloat);
03696 ((IntegerType*)opsType)->bumpSigned(+1);
03697 }
03698
03699
03700 assert(pCond->getArity() == 2);
03701 Exp* a = ((Binary*)pCond)->getSubExp1();
03702 Exp* b = ((Binary*)pCond)->getSubExp2();
03703
03704
03705 Exp* Ta; Exp* Tb;
03706 if (a->isSizeCast()) {
03707 opsType->setSize(((Const*)((Binary*)a)->getSubExp1())->getInt());
03708 Ta = new Unary(opTypeOf, ((Binary*)a)->getSubExp2());
03709 } else
03710 Ta = new Unary(opTypeOf, a);
03711 if (b->isSizeCast()) {
03712 opsType->setSize(((Const*)((Binary*)b)->getSubExp1())->getInt());
03713 Tb = new Unary(opTypeOf, ((Binary*)b)->getSubExp2());
03714 } else
03715 Tb = new Unary(opTypeOf, b);
03716
03717 Exp* con = new Binary(opEquals, Ta, new TypeVal(opsType));
03718 cons.insert(con);
03719 con = new Binary(opEquals, Tb, new TypeVal(opsType));
03720 cons.insert(con);
03721 }
03722
03723 int Statement::setConscripts(int n) {
03724 StmtConscriptSetter scs(n, false);
03725 accept(&scs);
03726 return scs.getLast();
03727 }
03728
03729 void Statement::clearConscripts() {
03730 StmtConscriptSetter scs(0, true);
03731 accept(&scs);
03732 }
03733
03734
03735 bool Statement::castConst(int num, Type* ty) {
03736 ExpConstCaster ecc(num, ty);
03737 StmtModifier scc(&ecc);
03738 accept(&scc);
03739 return ecc.isChanged();
03740 }
03741
03742 void Statement::stripSizes() {
03743 SizeStripper ss;
03744 StmtModifier sm(&ss);
03745 accept(&sm);
03746 }
03747
03748
03749
03750 bool Assign::accept(StmtExpVisitor* v) {
03751 bool override;
03752 bool ret = v->visit(this, override);
03753 if (override)
03754
03755
03756 return ret;
03757 if (ret && lhs) ret = lhs->accept(v->ev);
03758 if (ret && rhs) ret = rhs->accept(v->ev);
03759 return ret;
03760 }
03761
03762 bool PhiAssign::accept(StmtExpVisitor* v) {
03763 bool override;
03764 bool ret = v->visit(this, override);
03765 if (override) return ret;
03766 if (ret && lhs) ret = lhs->accept(v->ev);
03767 iterator it;
03768 for (it = defVec.begin(); it != defVec.end(); ++it) {
03769 if (it->e == NULL) continue;
03770 RefExp* re = new RefExp(it->e, it->def);
03771 ret = re->accept(v->ev);
03772 if (ret == false) return false;
03773 }
03774 return true;
03775 }
03776
03777 bool ImplicitAssign::accept(StmtExpVisitor* v) {
03778 bool override;
03779 bool ret = v->visit(this, override);
03780 if (override) return ret;
03781 if (ret && lhs) ret = lhs->accept(v->ev);
03782 return ret;
03783 }
03784
03785
03786 bool GotoStatement::accept(StmtExpVisitor* v) {
03787 bool override;
03788 bool ret = v->visit(this, override);
03789 if (override) return ret;
03790 if (ret && pDest)
03791 ret = pDest->accept(v->ev);
03792 return ret;
03793 }
03794
03795 bool BranchStatement::accept(StmtExpVisitor* v) {
03796 bool override;
03797 bool ret = v->visit(this, override);
03798 if (override) return ret;
03799
03800 if (ret && pDest)
03801 ret = pDest->accept(v->ev);
03802 if (ret && pCond)
03803 ret = pCond->accept(v->ev);
03804 return ret;
03805 }
03806
03807 bool CaseStatement::accept(StmtExpVisitor* v) {
03808 bool override;
03809 bool ret = v->visit(this, override);
03810 if (override) return ret;
03811 if (ret && pDest)
03812 ret = pDest->accept(v->ev);
03813 if (ret && pSwitchInfo && pSwitchInfo->pSwitchVar)
03814 ret = pSwitchInfo->pSwitchVar->accept(v->ev);
03815 return ret;
03816 }
03817
03818 bool CallStatement::accept(StmtExpVisitor* v) {
03819 bool override;
03820 bool ret = v->visit(this, override);
03821 if (override) return ret;
03822 if (ret && pDest)
03823 ret = pDest->accept(v->ev);
03824 StatementList::iterator it;
03825 for (it = arguments.begin(); ret && it != arguments.end(); it++)
03826 ret = (*it)->accept(v);
03827
03828 #if 0 // Do we want to accept visits to the defines? Not sure now...
03829 std::vector<ReturnInfo>::iterator rr;
03830 for (rr = defines.begin(); ret && rr != defines.end(); rr++)
03831 if (rr->e)
03832 ret = rr->e->accept(v->ev);
03833 #endif
03834
03835 return ret;
03836 }
03837
03838 bool ReturnStatement::accept(StmtExpVisitor* v) {
03839 bool override;
03840 ReturnStatement::iterator rr;
03841 if (!v->visit(this, override))
03842 return false;
03843 if (override) return true;
03844 if (!v->isIgnoreCol()) {
03845 DefCollector::iterator dd;
03846 for (dd = col.begin(); dd != col.end(); ++dd)
03847 if (!(*dd)->accept(v))
03848 return false;
03849
03850
03851
03852 for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
03853 if (!(*rr)->accept(v))
03854 return false;
03855 }
03856 for (rr = returns.begin(); rr != returns.end(); ++rr)
03857 if (!(*rr)->accept(v))
03858 return false;
03859 return true;
03860 }
03861
03862 bool BoolAssign::accept(StmtExpVisitor* v) {
03863 bool override;
03864 bool ret = v->visit(this, override);
03865 if (override) return ret;
03866 if (ret && pCond)
03867 ret = pCond->accept(v->ev);
03868 return ret;
03869 }
03870
03871
03872
03873 bool Assign::accept(StmtModifier* v) {
03874 bool recur;
03875 v->visit(this, recur);
03876 v->mod->clearMod();
03877 if (recur) lhs = lhs->accept(v->mod);
03878 if (recur) rhs = rhs->accept(v->mod);
03879 if (VERBOSE && v->mod->isMod())
03880 LOG << "Assignment changed: now " << this << "\n";
03881 return true;
03882 }
03883 bool PhiAssign::accept(StmtModifier* v) {
03884 bool recur;
03885 v->visit(this, recur);
03886 v->mod->clearMod();
03887 if (recur) lhs = lhs->accept(v->mod);
03888 if (VERBOSE && v->mod->isMod())
03889 LOG << "PhiAssign changed: now " << this << "\n";
03890 return true;
03891 }
03892
03893 bool ImplicitAssign::accept(StmtModifier* v) {
03894 bool recur;
03895 v->visit(this, recur);
03896 v->mod->clearMod();
03897 if (recur) lhs = lhs->accept(v->mod);
03898 if (VERBOSE && v->mod->isMod())
03899 LOG << "ImplicitAssign changed: now " << this << "\n";
03900 return true;
03901 }
03902
03903 bool BoolAssign::accept(StmtModifier* v) {
03904 bool recur;
03905 v->visit(this, recur);
03906 if (pCond && recur)
03907 pCond = pCond->accept(v->mod);
03908 if (recur && lhs->isMemOf()) {
03909 ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
03910 }
03911 return true;
03912 }
03913
03914
03915 bool GotoStatement::accept(StmtModifier* v) {
03916 bool recur;
03917 v->visit(this, recur);
03918 if (pDest && recur)
03919 pDest = pDest->accept(v->mod);
03920 return true;
03921 }
03922
03923 bool BranchStatement::accept(StmtModifier* v) {
03924 bool recur;
03925 v->visit(this, recur);
03926 if (pDest && recur)
03927 pDest = pDest->accept(v->mod);
03928 if (pCond && recur)
03929 pCond = pCond->accept(v->mod);
03930 return true;
03931 }
03932
03933 bool CaseStatement::accept(StmtModifier* v) {
03934 bool recur;
03935 v->visit(this, recur);
03936 if (pDest && recur)
03937 pDest = pDest->accept(v->mod);
03938 if (pSwitchInfo && pSwitchInfo->pSwitchVar && recur)
03939 pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->accept(v->mod);
03940 return true;
03941 }
03942
03943 bool CallStatement::accept(StmtModifier* v) {
03944 bool recur;
03945 v->visit(this, recur);
03946 if (!recur) return true;
03947 if (pDest)
03948 pDest = pDest->accept(v->mod);
03949 StatementList::iterator it;
03950 for (it = arguments.begin(); recur && it != arguments.end(); it++)
03951 (*it)->accept(v);
03952
03953
03954
03955
03956
03957 if (!v->ignoreCollector()) {
03958 DefCollector::iterator cc;
03959 for (cc = defCol.begin(); cc != defCol.end(); cc++)
03960 (*cc)->accept(v);
03961 }
03962 StatementList::iterator dd;
03963 for (dd = defines.begin(); recur && dd != defines.end(); ++dd)
03964 (*dd)->accept(v);
03965 return true;
03966 }
03967
03968 bool ReturnStatement::accept(StmtModifier* v) {
03969 bool recur;
03970 v->visit(this, recur);
03971 if (!recur) return true;
03972 if (!v->ignoreCollector()) {
03973 DefCollector::iterator dd;
03974 for (dd = col.begin(); dd != col.end(); ++dd)
03975 if (!(*dd)->accept(v))
03976 return false;
03977 }
03978 ReturnStatement::iterator rr;
03979 for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
03980 if (!(*rr)->accept(v))
03981 return false;
03982 for (rr = returns.begin(); rr != returns.end(); ++rr)
03983 if (!(*rr)->accept(v))
03984 return false;
03985 return true;
03986 }
03987
03988
03989
03990 bool Assign::accept(StmtPartModifier* v) {
03991 bool recur;
03992 v->visit(this, recur);
03993 v->mod->clearMod();
03994 if (recur && lhs->isMemOf()) {
03995 ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
03996 }
03997 if (recur) rhs = rhs->accept(v->mod);
03998 if (VERBOSE && v->mod->isMod())
03999 LOG << "Assignment changed: now " << this << "\n";
04000 return true;
04001 }
04002 bool PhiAssign::accept(StmtPartModifier* v) {
04003 bool recur;
04004 v->visit(this, recur);
04005 v->mod->clearMod();
04006 if (recur && lhs->isMemOf()) {
04007 ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
04008 }
04009 if (VERBOSE && v->mod->isMod())
04010 LOG << "PhiAssign changed: now " << this << "\n";
04011 return true;
04012 }
04013
04014 bool ImplicitAssign::accept(StmtPartModifier* v) {
04015 bool recur;
04016 v->visit(this, recur);
04017 v->mod->clearMod();
04018 if (recur && lhs->isMemOf()) {
04019 ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
04020 }
04021 if (VERBOSE && v->mod->isMod())
04022 LOG << "ImplicitAssign changed: now " << this << "\n";
04023 return true;
04024 }
04025
04026
04027 bool GotoStatement::accept(StmtPartModifier* v) {
04028 bool recur;
04029 v->visit(this, recur);
04030 if (pDest && recur)
04031 pDest = pDest->accept(v->mod);
04032 return true;
04033 }
04034
04035 bool BranchStatement::accept(StmtPartModifier* v) {
04036 bool recur;
04037 v->visit(this, recur);
04038 if (pDest && recur)
04039 pDest = pDest->accept(v->mod);
04040 if (pCond && recur)
04041 pCond = pCond->accept(v->mod);
04042 return true;
04043 }
04044
04045 bool CaseStatement::accept(StmtPartModifier* v) {
04046 bool recur;
04047 v->visit(this, recur);
04048 if (pDest && recur)
04049 pDest = pDest->accept(v->mod);
04050 if (pSwitchInfo && pSwitchInfo->pSwitchVar && recur)
04051 pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->accept(v->mod);
04052 return true;
04053 }
04054
04055 bool CallStatement::accept(StmtPartModifier* v) {
04056 bool recur;
04057 v->visit(this, recur);
04058 if (pDest && recur)
04059 pDest = pDest->accept(v->mod);
04060 StatementList::iterator it;
04061 for (it = arguments.begin(); recur && it != arguments.end(); it++)
04062 (*it)->accept(v);
04063
04064
04065
04066
04067 if (!v->ignoreCollector()) {
04068 DefCollector::iterator dd;
04069 for (dd = defCol.begin(); dd != defCol.end(); dd++)
04070 (*dd)->accept(v);
04071 UseCollector::iterator uu;
04072 for (uu = useCol.begin(); uu != useCol.end(); ++uu)
04073
04074 (*uu)->accept(v->mod);
04075 }
04076 StatementList::iterator dd;
04077 for (dd = defines.begin(); recur && dd != defines.end(); dd++)
04078 (*dd)->accept(v);
04079 return true;
04080 }
04081
04082 bool ReturnStatement::accept(StmtPartModifier* v) {
04083 bool recur;
04084 v->visit(this, recur);
04085 ReturnStatement::iterator rr;
04086 for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
04087 if (!(*rr)->accept(v))
04088 return false;
04089 for (rr = returns.begin(); rr != returns.end(); ++rr)
04090 if (!(*rr)->accept(v))
04091 return false;
04092 return true;
04093 }
04094
04095 bool BoolAssign::accept(StmtPartModifier* v) {
04096 bool recur;
04097 v->visit(this, recur);
04098 if (pCond && recur)
04099 pCond = pCond->accept(v->mod);
04100 if (lhs && recur)
04101 lhs = lhs->accept(v->mod);
04102 return true;
04103 }
04104
04105
04106 void Statement::bypass() {
04107 CallBypasser cb(this);
04108 StmtPartModifier sm(&cb);
04109 accept(&sm);
04110 if (cb.isTopChanged())
04111 simplify();
04112 }
04113
04114
04115
04116
04117 void Statement::addUsedLocs(LocationSet& used, bool cc , bool memOnly ) {
04118 UsedLocsFinder ulf(used, memOnly);
04119 UsedLocsVisitor ulv(&ulf, cc);
04120 accept(&ulv);
04121 }
04122
04123 bool Statement::addUsedLocals(LocationSet& used) {
04124 UsedLocalFinder ulf(used, proc);
04125 UsedLocsVisitor ulv(&ulf, false);
04126 accept(&ulv);
04127 return ulf.wasAllFound();
04128 }
04129
04130
04131 void Statement::subscriptVar(Exp* e, Statement* def ) {
04132 ExpSubscripter es(e, def );
04133 StmtSubscripter ss(&es);
04134 accept(&ss);
04135 }
04136
04137
04138 void Statement::findConstants(std::list<Const*>& lc) {
04139 ConstFinder cf(lc);
04140 StmtConstFinder scf(&cf);
04141 accept(&scf);
04142 }
04143
04144
04145
04146
04147 void PhiAssign::convertToAssign(Exp* rhs) {
04148
04149 rhs = rhs->propagateAll();
04150
04151 assert(sizeof(Assign) <= sizeof(PhiAssign));
04152 int n = number;
04153 PBB bb = pbb;
04154 UserProc* p = proc;
04155 Exp* lhs_ = lhs;
04156 Exp* rhs_ = rhs;
04157 Type* type_ = type;
04158 this->~PhiAssign();
04159 Assign* a = new(this) Assign(type_, lhs_, rhs_);
04160 a->setNumber(n);
04161 a->setProc(p);
04162 a->setBB(bb);
04163
04164
04165
04166 }
04167
04168 void PhiAssign::simplify() {
04169 lhs = lhs->simplify();
04170
04171 if (defVec.begin() != defVec.end()) {
04172 Definitions::iterator uu;
04173 bool allSame = true;
04174 uu = defVec.begin();
04175 Statement* first;
04176 for (first = (uu++)->def; uu != defVec.end(); uu++) {
04177 if (uu->def != first) {
04178 allSame = false;
04179 break;
04180 }
04181 }
04182
04183 if (allSame) {
04184 if (VERBOSE)
04185 LOG << "all the same in " << this << "\n";
04186 convertToAssign(new RefExp(lhs, first));
04187 return;
04188 }
04189
04190 bool onlyOneNotThis = true;
04191 Statement *notthis = (Statement*)-1;
04192 for (uu = defVec.begin(); uu != defVec.end(); uu++) {
04193 if (uu->def == NULL || uu->def->isImplicit() || !uu->def->isPhi() || uu->def != this)
04194 if (notthis != (Statement*)-1) {
04195 onlyOneNotThis = false;
04196 break;
04197 } else notthis = uu->def;
04198 }
04199
04200 if (onlyOneNotThis && notthis != (Statement*)-1) {
04201 if (VERBOSE)
04202 LOG << "all but one not this in " << this << "\n";
04203 convertToAssign(new RefExp(lhs, notthis));
04204 return;
04205 }
04206 }
04207 }
04208
04209 void PhiAssign::putAt(int i, Statement* def, Exp* e) {
04210 assert(e);
04211 if (i >= (int)defVec.size())
04212 defVec.resize(i+1);
04213 defVec[i].def = def;
04214 defVec[i].e = e;
04215 }
04216
04217 void CallStatement::setLeftFor(Exp* forExp, Exp* newExp) {
04218 std::cerr << "! Attempt to setLeftFor this call statement! forExp is " << forExp << ", newExp is " << newExp <<
04219 "\n";
04220 assert(0);
04221 }
04222
04223 bool Assignment::definesLoc(Exp* loc) {
04224 if (lhs->getOper() == opAt)
04225 if (*((Ternary*)lhs)->getSubExp1() == *loc) return true;
04226 return *lhs == *loc;
04227 }
04228
04229 bool CallStatement::definesLoc(Exp* loc) {
04230 StatementList::iterator dd;
04231 for (dd = defines.begin(); dd != defines.end(); ++dd) {
04232 Exp* lhs = ((Assign*)*dd)->getLeft();
04233 if (*lhs == *loc)
04234 return true;
04235 }
04236 return false;
04237 }
04238
04239
04240
04241
04242
04243 bool ReturnStatement::definesLoc(Exp* loc) {
04244 iterator it;
04245 for (it = modifieds.begin(); it != modifieds.end(); it++) {
04246 if ((*it)->definesLoc(loc))
04247 return true;
04248 }
04249 return false;
04250 }
04251
04252
04253 void ReturnStatement::getDefinitions(LocationSet& ls) {
04254 iterator rr;
04255 for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
04256 (*rr)->getDefinitions(ls);
04257 }
04258
04259 Type* ReturnStatement::getTypeFor(Exp* e) {
04260 ReturnStatement::iterator rr;
04261 for (rr = modifieds.begin(); rr != modifieds.end(); rr++) {
04262 if (*((Assignment*)*rr)->getLeft() == *e)
04263 return ((Assignment*)*rr)->getType();
04264 }
04265 return NULL;
04266 }
04267
04268 void ReturnStatement::setTypeFor(Exp*e, Type* ty) {
04269 ReturnStatement::iterator rr;
04270 for (rr = modifieds.begin(); rr != modifieds.end(); rr++) {
04271 if (*((Assignment*)*rr)->getLeft() == *e) {
04272 ((Assignment*)*rr)->setType(ty);
04273 break;
04274 }
04275 }
04276 for (rr = returns.begin(); rr != returns.end(); rr++) {
04277 if (*((Assignment*)*rr)->getLeft() == *e) {
04278 ((Assignment*)*rr)->setType(ty);
04279 return;
04280 }
04281 }
04282 }
04283
04284 #define RETSTMT_COLS 120
04285 void ReturnStatement::print(std::ostream& os, bool html) {
04286 os << std::setw(4) << std::dec << number << " ";
04287 if (html) {
04288 os << "</td><td>";
04289 os << "<a name=\"stmt" << std::dec << number << "\">";
04290 }
04291 os << "RET";
04292 iterator it;
04293 bool first = true;
04294 unsigned column = 19;
04295 for (it = returns.begin(); it != returns.end(); ++it) {
04296 std::ostringstream ost;
04297 ((Assignment*)*it)->printCompact(ost, html);
04298 unsigned len = ost.str().length();
04299 if (first) {
04300 first = false;
04301 os << " ";
04302 } else if (column + 4 + len > RETSTMT_COLS) {
04303 if (column != RETSTMT_COLS-1) os << ",";
04304 os << "\n ";
04305 column = 16;
04306 } else {
04307 os << ", ";
04308 column += 4;
04309 }
04310 os << ost.str().c_str();
04311 column += len;
04312 }
04313 if (html)
04314 os << "</a><br>";
04315 else
04316 os << "\n ";
04317 os << "Modifieds: ";
04318 first = true;
04319 column = 25;
04320 for (it = modifieds.begin(); it != modifieds.end(); ++it) {
04321 std::ostringstream ost;
04322 Assign* as = (Assign*)*it;
04323 Type* ty = as->getType();
04324 if (ty)
04325 ost << "*" << ty << "* ";
04326 ost << as->getLeft();
04327 unsigned len = ost.str().length();
04328 if (first)
04329 first = false;
04330 else if (column + 3 + len > RETSTMT_COLS) {
04331 if (column != RETSTMT_COLS-1) os << ",";
04332 os << "\n ";
04333 column = 16;
04334 } else {
04335 os << ", ";
04336 column += 3;
04337 }
04338 os << ost.str().c_str();
04339 column += len;
04340 }
04341 #if 1
04342
04343 if (html)
04344 os << "<br>";
04345 else
04346 os << "\n ";
04347 os << "Reaching definitions: ";
04348 col.print(os, html);
04349 #endif
04350 }
04351
04352
04353 bool lessAssignment::operator()(const Assignment* x, const Assignment* y) const {
04354 Assignment* xx = const_cast<Assignment*>(x);
04355 Assignment* yy = const_cast<Assignment*>(y);
04356 return (*xx->getLeft() < *yy->getLeft());
04357 }
04358
04359
04360 bool lessAssign::operator()(const Assign* x, const Assign* y) const {
04361 Assign* xx = const_cast<Assign*>(x);
04362 Assign* yy = const_cast<Assign*>(y);
04363 return (*xx->getLeft() < *yy->getLeft());
04364 }
04365
04366
04367
04368 void ReturnStatement::updateModifieds() {
04369 Signature* sig = proc->getSignature();
04370 StatementList oldMods(modifieds);
04371 modifieds.clear();
04372
04373 if (pbb->getNumInEdges() == 1 && pbb->getInEdges()[0]->getLastStmt()->isCall()) {
04374 CallStatement *call = (CallStatement*)pbb->getInEdges()[0]->getLastStmt();
04375 if (call->getDestProc() && FrontEnd::noReturnCallDest(call->getDestProc()->getName()))
04376 return;
04377 }
04378
04379
04380
04381 DefCollector::iterator ll;
04382 StatementList::iterator it;
04383 for (ll = col.begin(); ll != col.end(); ++ll) {
04384 bool found = false;
04385 Assign* as = (Assign*)*ll;
04386 Exp* colLhs = as->getLeft();
04387 if (proc->filterReturns(colLhs))
04388 continue;
04389 for (it = oldMods.begin(); it != oldMods.end(); it++) {
04390 Exp* lhs = ((Assign*)*it)->getLeft();
04391 if (*lhs == *colLhs) {
04392 found = true;
04393 break;
04394 }
04395 }
04396 if (!found) {
04397 ImplicitAssign* ias = new ImplicitAssign(
04398 as->getType()->clone(),
04399 as->getLeft()->clone());
04400 ias->setProc(proc);
04401 ias->setBB(pbb);
04402 oldMods.append(ias);
04403 }
04404 }
04405
04406
04407
04408 for (it = oldMods.end(); it != oldMods.begin(); ) {
04409 --it;
04410
04411 Assign* as = (Assign*)*it;
04412 Exp* lhs = as->getLeft();
04413 if (!col.existsOnLeft(lhs))
04414 continue;
04415 if (proc->filterReturns(lhs))
04416 continue;
04417
04418
04419 StatementList::iterator nn;
04420 bool inserted = false;
04421 for (nn = modifieds.begin(); nn != modifieds.end(); ++nn) {
04422 if (sig->returnCompare(*as, *(Assign*)*nn)) {
04423 nn = modifieds.insert(nn, as);
04424 inserted = true;
04425 break;
04426 }
04427 }
04428 if (!inserted)
04429 modifieds.insert(modifieds.end(), as);
04430 }
04431 }
04432
04433
04434
04435 void ReturnStatement::updateReturns() {
04436 Signature* sig = proc->getSignature();
04437 int sp = sig->getStackRegister();
04438 StatementList oldRets(returns);
04439 returns.clear();
04440
04441
04442
04443 StatementList::iterator dd, it;
04444 for (dd = modifieds.begin(); dd != modifieds.end(); ++dd) {
04445 bool found = false;
04446 Exp* loc = ((Assignment*)*dd)->getLeft();
04447 if (proc->filterReturns(loc))
04448 continue;
04449
04450
04451 if (loc->isRegN(sp)) continue;
04452 for (it = oldRets.begin(); it != oldRets.end(); it++) {
04453 Exp* lhs = ((Assign*)*it)->getLeft();
04454 if (*lhs == *loc) {
04455 found = true;
04456 break;
04457 }
04458 }
04459 if (!found) {
04460 Exp* rhs = col.findDefFor(loc);
04461 Assign* as = new Assign(loc->clone(), rhs->clone());
04462 as->setProc(proc);
04463 as->setBB(pbb);
04464 oldRets.append(as);
04465 }
04466 }
04467
04468
04469
04470 for (it = oldRets.end(); it != oldRets.begin(); ) {
04471 --it;
04472
04473 Assign* as = (Assign*)*it;
04474 Exp* lhs = as->getLeft();
04475 if (!modifieds.existsOnLeft(lhs))
04476 continue;
04477 if (proc->filterReturns(lhs))
04478 continue;
04479 #if 1
04480
04481
04482 Exp* rhs = as->getRight();
04483 if (rhs->isSubscript() && ((RefExp*)rhs)->isImplicitDef() && *((RefExp*)rhs)->getSubExp1() == *lhs)
04484 continue;
04485 #endif
04486
04487
04488 StatementList::iterator nn;
04489 bool inserted = false;
04490 for (nn = returns.begin(); nn != returns.end(); ++nn) {
04491 if (sig->returnCompare(*as, *(Assign*)*nn)) {
04492 nn = returns.insert(nn, as);
04493 inserted = true;
04494 break;
04495 }
04496 }
04497 if (!inserted)
04498 returns.insert(returns.end(), as);
04499 }
04500 }
04501
04502
04503 void CallStatement::updateDefines() {
04504 Signature* sig;
04505 if (procDest)
04506
04507 sig = procDest->getSignature();
04508 else
04509
04510 sig = proc->getSignature();
04511
04512 if (procDest && procDest->isLib()) {
04513 sig->setLibraryDefines(&defines);
04514 return;
04515 } else if (Boomerang::get()->assumeABI) {
04516
04517 Signature::setABIdefines(proc->getProg(), &defines);
04518 return;
04519 }
04520
04521
04522 StatementList oldDefines(defines);
04523 StatementList::iterator it;
04524 defines.clear();
04525
04526 if (procDest && calleeReturn) {
04527 StatementList::iterator mm;
04528 StatementList& modifieds = ((UserProc*)procDest)->getModifieds();
04529 for (mm = modifieds.begin(); mm != modifieds.end(); ++mm) {
04530 Assign* as = (Assign*)*mm;
04531 Exp* loc = as->getLeft();
04532 if (proc->filterReturns(loc))
04533 continue;
04534 Type* ty = as->getType();
04535 if (!oldDefines.existsOnLeft(loc))
04536 oldDefines.append(new ImplicitAssign(ty, loc));
04537 }
04538 } else {
04539
04540 LocationSet::iterator ll;
04541 for (ll = useCol.begin(); ll != useCol.end(); ++ll) {
04542 Exp* loc = *ll;
04543 if (proc->filterReturns(loc))
04544 continue;
04545 if (!oldDefines.existsOnLeft(loc)) {
04546 ImplicitAssign* as = new ImplicitAssign(loc->clone());
04547 as->setProc(proc);
04548 as->setBB(pbb);
04549 oldDefines.append(as);
04550 }
04551 }
04552 }
04553
04554 for (it = oldDefines.end(); it != oldDefines.begin(); ) {
04555 --it;
04556
04557 Assign* as = (Assign*)*it;
04558 Exp* lhs = as->getLeft();
04559 if (calleeReturn) {
04560 if (!calleeReturn->definesLoc(lhs))
04561 continue;
04562 } else {
04563 if (!useCol.exists(lhs))
04564 continue;
04565 }
04566 if (proc->filterReturns(lhs))
04567 continue;
04568
04569
04570 StatementList::iterator nn;
04571 bool inserted = false;
04572 for (nn = defines.begin(); nn != defines.end(); ++nn) {
04573 if (sig->returnCompare(*as, *(Assign*)*nn)) {
04574 nn = defines.insert(nn, as);
04575 inserted = true;
04576 break;
04577 }
04578 }
04579 if (!inserted)
04580 defines.insert(defines.end(), as);
04581 }
04582 }
04583
04584
04585
04586 class ArgSourceProvider {
04587 enum Src {SRC_LIB, SRC_CALLEE, SRC_COL};
04588 Src src;
04589 CallStatement* call;
04590 int i, n;
04591 Signature* callSig;
04592 StatementList::iterator pp;
04593 StatementList* calleeParams;
04594 DefCollector::iterator cc;
04595 DefCollector* defCol;
04596 public:
04597 ArgSourceProvider(CallStatement* call);
04598 Exp* nextArgLoc();
04599 Type* curType(Exp* e);
04600 bool exists(Exp* loc);
04601 Exp* localise(Exp* e);
04602 };
04603
04604 ArgSourceProvider::ArgSourceProvider(CallStatement* call) : call(call) {
04605 Proc* procDest = call->getDestProc();
04606 if (procDest && procDest->isLib()) {
04607 src = SRC_LIB;
04608 callSig = call->getSignature();
04609 n = callSig->getNumParams();
04610 i = 0;
04611 } else if (call->getCalleeReturn() != NULL) {
04612 src = SRC_CALLEE;
04613 calleeParams = &((UserProc*)procDest)->getParameters();
04614 pp = calleeParams->begin();
04615 } else {
04616 Signature* destSig = NULL;
04617 if (procDest)
04618 destSig = procDest->getSignature();
04619 if (destSig && destSig->isForced()) {
04620 src = SRC_LIB;
04621 callSig = destSig;
04622 n = callSig->getNumParams();
04623 i = 0;
04624 } else {
04625 src = SRC_COL;
04626 defCol = call->getDefCollector();
04627 cc = defCol->begin();
04628 }
04629 }
04630 }
04631
04632 Exp* ArgSourceProvider::nextArgLoc() {
04633 Exp* s;
04634 bool allZero;
04635 switch(src) {
04636 case SRC_LIB:
04637 if (i == n) return NULL;
04638 s = callSig->getParamExp(i++)->clone();
04639 s->removeSubscripts(allZero);
04640 call->localiseComp(s);
04641 return s;
04642 case SRC_CALLEE:
04643 if (pp == calleeParams->end()) return NULL;
04644 s = ((Assignment*)*pp++)->getLeft()->clone();
04645 s->removeSubscripts(allZero);
04646 call->localiseComp(s);
04647
04648 return s;
04649 case SRC_COL:
04650 if (cc == defCol->end()) return NULL;
04651
04652 return ((Assign*)*cc++)->getLeft();
04653 }
04654 return NULL;
04655 }
04656
04657 Exp* ArgSourceProvider::localise(Exp* e) {
04658 if (src == SRC_COL) {
04659
04660 Exp* ret = ((Assign*)*--cc)->getRight();
04661 ++cc;
04662 return ret;
04663 }
04664
04665 return call->localiseExp(e);
04666 }
04667
04668 Type* ArgSourceProvider::curType(Exp* e) {
04669 switch(src) {
04670 case SRC_LIB:
04671 return callSig->getParamType(i-1);
04672 case SRC_CALLEE: {
04673 Type* ty = ((Assignment*)*--pp)->getType();
04674 pp++;
04675 return ty;
04676 }
04677 case SRC_COL: {
04678
04679 Type* ty = (*--cc)->getType();
04680 ++cc;
04681 return ty;
04682 }
04683 }
04684 return NULL;
04685 }
04686
04687 bool ArgSourceProvider::exists(Exp* e) {
04688 bool allZero;
04689 switch (src) {
04690 case SRC_LIB:
04691 if (callSig->hasEllipsis())
04692
04693 return true;
04694 for (i=0; i < n; i++) {
04695 Exp* sigParam = callSig->getParamExp(i)->clone();
04696 sigParam->removeSubscripts(allZero);
04697 call->localiseComp(sigParam);
04698 if (*sigParam == *e)
04699 return true;
04700 }
04701 return false;
04702 case SRC_CALLEE:
04703 for (pp = calleeParams->begin(); pp != calleeParams->end(); ++pp) {
04704 Exp* par = ((Assignment*)*pp)->getLeft()->clone();
04705 par->removeSubscripts(allZero);
04706 call->localiseComp(par);
04707 if (*par == *e)
04708 return true;
04709 }
04710 return false;
04711 case SRC_COL:
04712 return defCol->existsOnLeft(e);
04713 }
04714 return false;
04715 }
04716
04717 void CallStatement::updateArguments() {
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739
04740 if (EXPERIMENTAL) {
04741 bool convert;
04742 proc->propagateStatements(convert, 88);
04743 }
04744 StatementList oldArguments(arguments);
04745 arguments.clear();
04746 if (EXPERIMENTAL) {
04747
04748 DefCollector::iterator dd;
04749 for (dd = defCol.begin(); dd != defCol.end(); ++dd)
04750 (*dd)->simplify();
04751 }
04752
04753 Signature* sig = proc->getSignature();
04754
04755
04756 ArgSourceProvider asp(this);
04757 Exp* loc;
04758 while ((loc = asp.nextArgLoc()) != NULL) {
04759 if (proc->filterParams(loc))
04760 continue;
04761 if (!oldArguments.existsOnLeft(loc)) {
04762
04763
04764 Exp* rhs;
04765 if (proc->canRename(loc))
04766 rhs = asp.localise(loc->clone());
04767 else
04768 rhs = loc->clone();
04769 Type* ty = asp.curType(loc);
04770 Assign* as = new Assign(ty, loc->clone(), rhs);
04771 as->setNumber(number);
04772 as->setParent(this);
04773 as->setProc(proc);
04774 as->setBB(pbb);
04775 oldArguments.append(as);
04776 }
04777 }
04778
04779 StatementList::iterator it;
04780 for (it = oldArguments.end(); it != oldArguments.begin(); ) {
04781 --it;
04782
04783 Assign* as = (Assign*)*it;
04784 Exp* lhs = as->getLeft();
04785 if (!asp.exists(lhs)) continue;
04786 if (proc->filterParams(lhs))
04787 continue;
04788
04789
04790 StatementList::iterator nn;
04791 bool inserted = false;
04792 for (nn = arguments.begin(); nn != arguments.end(); ++nn) {
04793 if (sig->argumentCompare(*as, *(Assign*)*nn)) {
04794 nn = arguments.insert(nn, as);
04795 inserted = true;
04796 break;
04797 }
04798 }
04799 if (!inserted)
04800 arguments.insert(arguments.end(), as);
04801 }
04802
04803 }
04804
04805
04806
04807
04808 StatementList* CallStatement::calcResults() {
04809 StatementList* ret = new StatementList;
04810 if (procDest) {
04811 Signature* sig = procDest->getSignature();
04812 if (procDest && procDest->isLib()) {
04813 int n = sig->getNumReturns();
04814 for (int i=1; i < n; i++) {
04815 Exp* sigReturn = sig->getReturnExp(i);
04816 #if SYMS_IN_BACK_END
04817
04818
04819 RefExp* wrappedRet = new RefExp(sigReturn, this);
04820 char* locName = proc->findLocal(wrappedRet);
04821 if (locName)
04822 sigReturn = Location::local(locName, proc);
04823 #endif
04824 if (useCol.exists(sigReturn)) {
04825 ImplicitAssign* as = new ImplicitAssign(getTypeFor(sigReturn), sigReturn);
04826 ret->append(as);
04827 }
04828 }
04829 } else {
04830 Exp* rsp = Location::regOf(proc->getSignature()->getStackRegister(proc->getProg()));
04831 StatementList::iterator dd;
04832 for (dd = defines.begin(); dd != defines.end(); ++dd) {
04833 Exp* lhs = ((Assign*)*dd)->getLeft();
04834
04835 if (*lhs == *rsp) continue;
04836 if (useCol.exists(lhs))
04837 ret->append(*dd);
04838 }
04839 }
04840 } else {
04841
04842
04843 UseCollector::iterator rr;
04844 StatementList::iterator nn;
04845 Signature* sig = proc->getSignature();
04846 int sp = sig->getStackRegister();
04847 for (rr = useCol.begin(); rr != useCol.end(); ++rr) {
04848 Exp* loc = *rr;
04849 if (proc->filterReturns(loc)) continue;
04850 if (loc->isRegN(sp)) continue;
04851 ImplicitAssign* as = new ImplicitAssign(loc);
04852 bool inserted = false;
04853 for (nn = ret->begin(); nn != ret->end(); ++nn) {
04854
04855 if (sig->returnCompare(*as, *(Assignment*)*nn)) {
04856 nn = ret->insert(nn, as);
04857 inserted = true;
04858 break;
04859 }
04860 }
04861 if (!inserted)
04862 ret->insert(ret->end(), as);
04863 }
04864 }
04865 return ret;
04866 }
04867
04868 #if 0
04869 void TypingStatement::setType(Type* ty) {
04870 type = ty;
04871 }
04872 #endif
04873
04874 void CallStatement::removeDefine(Exp* e) {
04875 StatementList::iterator ss;
04876 for (ss = defines.begin(); ss != defines.end(); ++ss) {
04877 Assign* as = ((Assign*)*ss);
04878 if (*as->getLeft() == *e) {
04879 defines.erase(ss);
04880 return;
04881 }
04882 }
04883 LOG << "WARNING: could not remove define " << e << " from call " << this << "\n";
04884 }
04885
04886 bool CallStatement::isChildless() {
04887 if (procDest == NULL) return true;
04888 if (procDest->isLib()) return false;
04889
04890 if (((UserProc*)procDest)->isEarlyRecursive())
04891 return true;
04892 return calleeReturn == NULL;
04893 }
04894
04895 Exp* CallStatement::bypassRef(RefExp* r, bool& ch) {
04896 Exp* base = r->getSubExp1();
04897 Exp* proven;
04898 ch = false;
04899 if (procDest && procDest->isLib()) {
04900 Signature* sig = procDest->getSignature();
04901 proven = sig->getProven(base);
04902 if (proven == NULL) {
04903 if (sig->findReturn(base) != -1)
04904 return r;
04905
04906 }
04907 } else {
04908
04909
04910 if (procDest == NULL)
04911 return r;
04912
04913
04914 if (!procDest->isLib() && ((UserProc*)procDest)->isLocalOrParamPattern(base)) {
04915 Exp* ret = localiseExp(base->clone());
04916 ch = true;
04917 if (VERBOSE)
04918 LOG << base << " allowed to bypass call statement " << number << " ignoring aliasing; result " << ret <<
04919 "\n";
04920 return ret;
04921 }
04922
04923 proven = procDest->getProven(base);
04924 }
04925 if (proven == NULL)
04926 return r;
04927 Exp* to = localiseExp(base);
04928 assert(to);
04929 proven = proven->clone();
04930 proven = proven->searchReplaceAll(base, to, ch);
04931 if (ch && VERBOSE)
04932 LOG << "bypassRef() replacing " << r << " with " << proven << "\n";
04933 return proven;
04934 }
04935
04936 void ReturnStatement::removeModified(Exp* loc) {
04937 modifieds.removeDefOf(loc);
04938 returns.removeDefOf(loc);
04939 }
04940
04941 void CallStatement::addDefine(ImplicitAssign* as) {
04942 defines.append(as);
04943 }
04944
04945 TypingStatement::TypingStatement(Type* ty) : type(ty) {
04946 }
04947
04948
04949 void ImpRefStatement::print(std::ostream& os, bool html) {
04950 os << " *";
04951 if (html) {
04952 os << "</td><td>";
04953 os << "<a name=\"stmt" << std::dec << number << "\">";
04954 }
04955 os << type << "* IMP REF " << addressExp;
04956 if (html)
04957 os << "</a></td>";
04958 }
04959
04960 void ImpRefStatement::meetWith(Type* ty, bool& ch) {
04961 type = type->meetWith(ty, ch);
04962 }
04963
04964 Statement* ImpRefStatement::clone() {
04965 return new ImpRefStatement(type->clone(), addressExp->clone());
04966 }
04967 bool ImpRefStatement::accept(StmtVisitor* visitor) {
04968 return visitor->visit(this);
04969 }
04970 bool ImpRefStatement::accept(StmtExpVisitor* v) {
04971 bool override;
04972 bool ret = v->visit(this, override);
04973 if (override)
04974 return ret;
04975 if (ret) ret = addressExp->accept(v->ev);
04976 return ret;
04977 }
04978 bool ImpRefStatement::accept(StmtModifier* v) {
04979 bool recur;
04980 v->visit(this, recur);
04981 v->mod->clearMod();
04982 if (recur) addressExp = addressExp->accept(v->mod);
04983 if (VERBOSE && v->mod->isMod())
04984 LOG << "ImplicitRef changed: now " << this << "\n";
04985 return true;
04986 }
04987 bool ImpRefStatement::accept(StmtPartModifier* v) {
04988 bool recur;
04989 v->visit(this, recur);
04990 v->mod->clearMod();
04991 if (recur) addressExp = addressExp->accept(v->mod);
04992 if (VERBOSE && v->mod->isMod())
04993 LOG << "ImplicitRef changed: now " << this << "\n";
04994 return true;
04995 }
04996 bool ImpRefStatement::search(Exp* search, Exp*& result) {
04997 result = NULL;
04998 return addressExp->search(search, result);
04999 }
05000 bool ImpRefStatement::searchAll(Exp* search, std::list<Exp*, std::allocator<Exp*> >& result) {
05001 return addressExp->searchAll(search, result);
05002 }
05003 bool ImpRefStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
05004 bool change;
05005 addressExp = addressExp->searchReplaceAll(search, replace, change);
05006 return change;
05007 }
05008 void ImpRefStatement::simplify() {addressExp = addressExp->simplify();}
05009
05010 void CallStatement::eliminateDuplicateArgs() {
05011 StatementList::iterator it;
05012 LocationSet ls;
05013 for (it = arguments.begin(); it != arguments.end(); ) {
05014 Exp* lhs = ((Assignment*)*it)->getLeft();
05015 if (ls.exists(lhs)) {
05016
05017 it = arguments.erase(it);
05018 continue;
05019 }
05020 ls.insert(lhs);
05021 ++it;
05022 }
05023 }
05024
05025 void PhiAssign::enumerateParams(std::list<Exp*>& le) {
05026 iterator it;
05027 for (it = begin(); it != end(); ++it) {
05028 if (it->e == NULL) continue;
05029 RefExp* r = new RefExp(it->e, it->def);
05030 le.push_back(r);
05031 }
05032 }
05033
05034
05035 void dumpDestCounts(std::map<Exp*, int, lessExpStar>* destCounts) {
05036 std::map<Exp*, int, lessExpStar>::iterator it;
05037 for (it = destCounts->begin(); it != destCounts->end(); ++it) {
05038 std::cerr << std::setw(4) << std::dec << it->second << " " << it->first << "\n";
05039 }
05040 }
05041
05042 bool JunctionStatement::accept(StmtVisitor* visitor)
05043 {
05044 return true;
05045 }
05046
05047 bool JunctionStatement::accept(StmtExpVisitor* visitor)
05048 {
05049 return true;
05050 }
05051
05052 bool JunctionStatement::accept(StmtModifier* visitor)
05053 {
05054 return true;
05055 }
05056
05057 bool JunctionStatement::accept(StmtPartModifier* visitor)
05058 {
05059 return true;
05060 }
05061
05062 void JunctionStatement::print(std::ostream &os, bool html)
05063 {
05064 os << std::setw(4) << std::dec << number << " ";
05065 if (html) {
05066 os << "</td><td>";
05067 os << "<a name=\"stmt" << std::dec << number << "\">";
05068 }
05069 os << "JUNCTION ";
05070 for (int i = 0; i < pbb->getNumInEdges(); i++) {
05071 os << std::hex << pbb->getInEdges()[i]->getHiAddr() << std::dec;
05072 if (pbb->isBackEdge(i))
05073 os << "*";
05074 os << " ";
05075 }
05076 if (isLoopJunction())
05077 os << "LOOP";
05078 os << "\n\t\t\tranges: ";
05079 ranges.print(os);
05080 if (html)
05081 os << "</a></td>";
05082 }
05083
05084
05085 void Statement::mapRegistersToLocals() {
05086 ExpRegMapper erm(proc);
05087 StmtRegMapper srm(&erm);
05088 accept(&srm);
05089 }
05090
05091 void Statement::insertCasts() {
05092
05093 ExpCastInserter eci(proc);
05094 StmtModifier sm(&eci, true);
05095 accept(&sm);
05096
05097 StmtCastInserter sci;
05098 accept(&sci);
05099 }
05100
05101 void Statement::replaceSubscriptsWithLocals() {
05102 ExpSsaXformer esx(proc);
05103 StmtSsaXformer ssx(&esx, proc);
05104 accept(&ssx);
05105 }
05106
05107 void Statement::dfaMapLocals() {
05108 DfaLocalMapper dlm(proc);
05109 StmtModifier sm(&dlm, true);
05110 accept(&sm);
05111 if (VERBOSE && dlm.change)
05112 LOG << "statement mapped with new local(s): " << number << "\n";
05113 }
05114
05115 void CallStatement::setNumber(int num) {
05116 number = num;
05117
05118
05119 StatementList::iterator aa;
05120 for (aa = arguments.begin(); aa != arguments.end(); ++aa)
05121 (*aa)->setNumber(num);
05122 }