PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/db/statement.cpp

https://github.com/PrototypeX29A/boomerang
C++ | 5122 lines | 3885 code | 366 blank | 871 comment | 1381 complexity | 92b892dc0f15b915633bc027ee5d4e2a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. * Copyright (C) 2002-2006, Trent Waddington and Mike Van Emmerik
  3. *
  4. * See the file "LICENSE.TERMS" for information on usage and
  5. * redistribution of this file, and for a DISCLAIMER OF ALL
  6. * WARRANTIES.
  7. *
  8. */
  9. /*==============================================================================
  10. * FILE: statement.cpp
  11. * OVERVIEW: Implementation of the Statement and related classes.
  12. * (Was dataflow.cpp a long time ago)
  13. *============================================================================*/
  14. /*
  15. * $Revision: 1.234 $ // 1.148.2.38
  16. * 03 Jul 02 - Trent: Created
  17. * 25 Jul 03 - Mike: dataflow.cpp, hrtl.cpp -> statement.cpp
  18. */
  19. /*==============================================================================
  20. * Dependencies.
  21. *============================================================================*/
  22. #include <assert.h>
  23. #include <iomanip> // For setfill etc
  24. #include <sstream>
  25. #include <algorithm>
  26. #include "statement.h"
  27. #include "exp.h"
  28. #include "cfg.h"
  29. #include "proc.h"
  30. #include "prog.h"
  31. #include "boomerang.h"
  32. #include "rtl.h" // For debugging code
  33. #include "util.h"
  34. #include "signature.h"
  35. #include "visitor.h"
  36. #include "dataflow.h"
  37. #include "log.h"
  38. #include <string.h>
  39. extern char debug_buffer[]; // For prints functions
  40. #if defined(_MSC_VER) && _MSC_VER < 1310 // Ugh - MSC 7.0 doesn't have advance
  41. #define my_advance(aa, n) \
  42. for (int zz = 0; zz < n; zz++) \
  43. aa++;
  44. #else
  45. #define my_advance(aa, n) \
  46. advance(aa, n);
  47. #endif
  48. void Statement::setProc(UserProc *p)
  49. {
  50. proc = p;
  51. LocationSet exps;
  52. addUsedLocs(exps);
  53. LocationSet defs;
  54. getDefinitions(defs);
  55. exps.makeUnion(defs);
  56. LocationSet::iterator ll;
  57. for (ll = exps.begin(); ll != exps.end(); ll++) {
  58. Location *l = dynamic_cast<Location*>(*ll);
  59. if (l) {
  60. l->setProc(p);
  61. }
  62. }
  63. }
  64. Exp *Statement::getExpAtLex(unsigned int begin, unsigned int end)
  65. {
  66. return NULL;
  67. }
  68. bool Statement::mayAlias(Exp *e1, Exp *e2, int size) {
  69. if (*e1 == *e2) return true;
  70. // Pass the expressions both ways. Saves checking things like m[exp] vs m[exp+K] and m[exp+K] vs m[exp] explicitly
  71. // (only need to check one of these cases)
  72. bool b = (calcMayAlias(e1, e2, size) && calcMayAlias(e2, e1, size));
  73. if (b && VERBOSE) {
  74. LOG << "May alias: " << e1 << " and " << e2 << " size " << size << "\n";
  75. }
  76. return b;
  77. }
  78. // returns true if e1 may alias e2
  79. bool Statement::calcMayAlias(Exp *e1, Exp *e2, int size) {
  80. // currently only considers memory aliasing..
  81. if (!e1->isMemOf() || !e2->isMemOf()) {
  82. return false;
  83. }
  84. Exp *e1a = e1->getSubExp1();
  85. Exp *e2a = e2->getSubExp1();
  86. // constant memory accesses
  87. if (e1a->isIntConst() && e2a->isIntConst()) {
  88. ADDRESS a1 = ((Const*)e1a)->getAddr();
  89. ADDRESS a2 = ((Const*)e2a)->getAddr();
  90. int diff = a1 - a2;
  91. if (diff < 0) diff = -diff;
  92. if (diff*8 >= size) return false;
  93. }
  94. // same left op constant memory accesses
  95. if (e1a->getArity() == 2 && e1a->getOper() == e2a->getOper() && e1a->getSubExp2()->isIntConst() &&
  96. e2a->getSubExp2()->isIntConst() && *e1a->getSubExp1() == *e2a->getSubExp1()) {
  97. int i1 = ((Const*)e1a->getSubExp2())->getInt();
  98. int i2 = ((Const*)e2a->getSubExp2())->getInt();
  99. int diff = i1 - i2;
  100. if (diff < 0) diff = -diff;
  101. if (diff*8 >= size) return false;
  102. }
  103. // [left] vs [left +/- constant] memory accesses
  104. if ((e2a->getOper() == opPlus || e2a->getOper() == opMinus) && *e1a == *e2a->getSubExp1() &&
  105. e2a->getSubExp2()->isIntConst()) {
  106. int i1 = 0;
  107. int i2 = ((Const*)e2a->getSubExp2())->getInt();
  108. int diff = i1 - i2;
  109. if (diff < 0) diff = -diff;
  110. if (diff*8 >= size) return false;
  111. }
  112. // Don't need [left +/- constant ] vs [left] because called twice with
  113. // args reversed
  114. return true;
  115. }
  116. RangeMap Statement::getInputRanges()
  117. {
  118. if (!isFirstStatementInBB()) {
  119. savedInputRanges = getPreviousStatementInBB()->getRanges();
  120. return savedInputRanges;
  121. }
  122. assert(pbb && pbb->getNumInEdges() <= 1);
  123. RangeMap input;
  124. if (pbb->getNumInEdges() == 0) {
  125. // setup input for start of procedure
  126. Range ra24(1, 0, 0, new Unary(opInitValueOf, Location::regOf(24)));
  127. Range ra25(1, 0, 0, new Unary(opInitValueOf, Location::regOf(25)));
  128. Range ra26(1, 0, 0, new Unary(opInitValueOf, Location::regOf(26)));
  129. Range ra27(1, 0, 0, new Unary(opInitValueOf, Location::regOf(27)));
  130. Range ra28(1, 0, 0, new Unary(opInitValueOf, Location::regOf(28)));
  131. Range ra29(1, 0, 0, new Unary(opInitValueOf, Location::regOf(29)));
  132. Range ra30(1, 0, 0, new Unary(opInitValueOf, Location::regOf(30)));
  133. Range ra31(1, 0, 0, new Unary(opInitValueOf, Location::regOf(31)));
  134. Range rpc(1, 0, 0, new Unary(opInitValueOf, new Terminal(opPC)));
  135. input.addRange(Location::regOf(24), ra24);
  136. input.addRange(Location::regOf(25), ra25);
  137. input.addRange(Location::regOf(26), ra26);
  138. input.addRange(Location::regOf(27), ra27);
  139. input.addRange(Location::regOf(28), ra28);
  140. input.addRange(Location::regOf(29), ra29);
  141. input.addRange(Location::regOf(30), ra30);
  142. input.addRange(Location::regOf(31), ra31);
  143. input.addRange(new Terminal(opPC), rpc);
  144. } else {
  145. PBB pred = pbb->getInEdges()[0];
  146. Statement *last = pred->getLastStmt();
  147. assert(last);
  148. if (pred->getNumOutEdges() != 2) {
  149. input = last->getRanges();
  150. } else {
  151. assert(pred->getNumOutEdges() == 2);
  152. assert(last->isBranch());
  153. input = ((BranchStatement*)last)->getRangesForOutEdgeTo(pbb);
  154. }
  155. }
  156. savedInputRanges = input;
  157. return input;
  158. }
  159. void Statement::updateRanges(RangeMap &output, std::list<Statement*> &execution_paths, bool notTaken)
  160. {
  161. if (!output.isSubset(notTaken ? ((BranchStatement*)this)->getRanges2Ref() : ranges)) {
  162. if (notTaken)
  163. ((BranchStatement*)this)->setRanges2(output);
  164. else
  165. ranges = output;
  166. if (isLastStatementInBB()) {
  167. if (pbb->getNumOutEdges()) {
  168. int arc = 0;
  169. if (isBranch()) {
  170. if (pbb->getOutEdge(0)->getLowAddr() != ((BranchStatement*)this)->getFixedDest())
  171. arc = 1;
  172. if (notTaken)
  173. arc ^= 1;
  174. }
  175. execution_paths.push_back(pbb->getOutEdge(arc)->getFirstStmt());
  176. }
  177. } else
  178. execution_paths.push_back(getNextStatementInBB());
  179. }
  180. }
  181. void Statement::rangeAnalysis(std::list<Statement*> &execution_paths)
  182. {
  183. RangeMap output = getInputRanges();
  184. updateRanges(output, execution_paths);
  185. }
  186. void Assign::rangeAnalysis(std::list<Statement*> &execution_paths)
  187. {
  188. RangeMap output = getInputRanges();
  189. Exp *a_lhs = lhs->clone();
  190. if (a_lhs->isFlags()) {
  191. // special hacks for flags
  192. assert(rhs->isFlagCall());
  193. Exp *a_rhs = rhs->clone();
  194. if (a_rhs->getSubExp2()->getSubExp1()->isMemOf())
  195. a_rhs->getSubExp2()->getSubExp1()->setSubExp1(
  196. output.substInto(a_rhs->getSubExp2()->getSubExp1()->getSubExp1()));
  197. if (!a_rhs->getSubExp2()->getSubExp2()->isTerminal() &&
  198. a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->isMemOf())
  199. a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->setSubExp1(
  200. output.substInto(a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->getSubExp1()));
  201. Range ra(1, 0, 0, a_rhs);
  202. output.addRange(a_lhs, ra);
  203. } else {
  204. if (a_lhs->isMemOf())
  205. a_lhs->setSubExp1(output.substInto(a_lhs->getSubExp1()->clone()));
  206. Exp *a_rhs = output.substInto(rhs->clone());
  207. if (a_rhs->isMemOf() && a_rhs->getSubExp1()->getOper() == opInitValueOf &&
  208. a_rhs->getSubExp1()->getSubExp1()->isRegOfK() &&
  209. ((Const*)a_rhs->getSubExp1()->getSubExp1()->getSubExp1())->getInt() == 28)
  210. a_rhs = new Unary(opInitValueOf, new Terminal(opPC)); // nice hack
  211. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  212. LOG << "a_rhs is " << a_rhs << "\n";
  213. if (a_rhs->isMemOf() && a_rhs->getSubExp1()->isIntConst()) {
  214. ADDRESS c = ((Const*)a_rhs->getSubExp1())->getInt();
  215. if (proc->getProg()->isDynamicLinkedProcPointer(c)) {
  216. char *nam = (char*)proc->getProg()->GetDynamicProcName(c);
  217. if (nam) {
  218. a_rhs = new Const(nam);
  219. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  220. LOG << "a_rhs is a dynamic proc pointer to " << nam << "\n";
  221. }
  222. } else if (proc->getProg()->isReadOnly(c)) {
  223. switch(type->getSize()) {
  224. case 8:
  225. a_rhs = new Const(proc->getProg()->readNative1(c));
  226. break;
  227. case 16:
  228. a_rhs = new Const(proc->getProg()->readNative2(c));
  229. break;
  230. case 32:
  231. a_rhs = new Const(proc->getProg()->readNative4(c));
  232. break;
  233. default:
  234. LOG << "error: unhandled type size " << type->getSize() << " for reading native address\n";
  235. }
  236. } else
  237. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  238. LOG << c << " is not dynamically linked proc pointer or in read only memory\n";
  239. }
  240. if ((a_rhs->getOper() == opPlus || a_rhs->getOper() == opMinus) &&
  241. a_rhs->getSubExp2()->isIntConst() && output.hasRange(a_rhs->getSubExp1())) {
  242. Range &r = output.getRange(a_rhs->getSubExp1());
  243. int c = ((Const*)a_rhs->getSubExp2())->getInt();
  244. if (a_rhs->getOper() == opPlus) {
  245. Range ra(1, r.getLowerBound() != Range::MIN ? r.getLowerBound() + c : Range::MIN,
  246. r.getUpperBound() != Range::MAX? r.getUpperBound() + c : Range::MAX, r.getBase());
  247. output.addRange(a_lhs, ra);
  248. } else {
  249. Range ra(1, r.getLowerBound() != Range::MIN ? r.getLowerBound() - c : Range::MIN,
  250. r.getUpperBound() != Range::MAX ? r.getUpperBound() - c : Range::MAX, r.getBase());
  251. output.addRange(a_lhs, ra);
  252. }
  253. } else {
  254. if (output.hasRange(a_rhs)) {
  255. output.addRange(a_lhs, output.getRange(a_rhs));
  256. } else {
  257. Exp *result;
  258. if (a_rhs->getMemDepth() == 0 && !a_rhs->search(new Unary(opRegOf, new Terminal(opWild)), result) &&
  259. !a_rhs->search(new Unary(opTemp, new Terminal(opWild)), result)) {
  260. if (a_rhs->isIntConst()) {
  261. Range ra(1, ((Const*)a_rhs)->getInt(), ((Const*)a_rhs)->getInt(), new Const(0));
  262. output.addRange(a_lhs, ra);
  263. }
  264. else {
  265. Range ra(1, 0, 0, a_rhs);
  266. output.addRange(a_lhs, ra);
  267. }
  268. } else {
  269. Range empty;
  270. output.addRange(a_lhs, empty);
  271. }
  272. }
  273. }
  274. }
  275. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  276. LOG << "added " << a_lhs << " -> " << output.getRange(a_lhs) << "\n";
  277. updateRanges(output, execution_paths);
  278. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  279. LOG << this << "\n";
  280. }
  281. void BranchStatement::limitOutputWithCondition(RangeMap &output, Exp *e)
  282. {
  283. assert(e);
  284. if (output.hasRange(e->getSubExp1())) {
  285. Range &r = output.getRange(e->getSubExp1());
  286. if (e->getSubExp2()->isIntConst() && r.getBase()->isIntConst() && ((Const*)r.getBase())->getInt() == 0) {
  287. int c = ((Const*)e->getSubExp2())->getInt();
  288. switch(e->getOper()) {
  289. case opLess:
  290. case opLessUns: {
  291. Range ra(r.getStride(), r.getLowerBound() >= c ? c - 1 : r.getLowerBound(),
  292. r.getUpperBound() >= c ? c - 1 : r.getUpperBound(), r.getBase());
  293. output.addRange(e->getSubExp1(), ra);
  294. break;
  295. }
  296. case opLessEq:
  297. case opLessEqUns: {
  298. Range ra(r.getStride(), r.getLowerBound() > c ? c : r.getLowerBound(),
  299. r.getUpperBound() > c ? c : r.getUpperBound(), r.getBase());
  300. output.addRange(e->getSubExp1(), ra);
  301. break;
  302. }
  303. case opGtr:
  304. case opGtrUns: {
  305. Range ra(r.getStride(), r.getLowerBound() <= c ? c + 1 : r.getLowerBound(),
  306. r.getUpperBound() <= c ? c + 1 : r.getUpperBound(), r.getBase());
  307. output.addRange(e->getSubExp1(), ra);
  308. break;
  309. }
  310. case opGtrEq:
  311. case opGtrEqUns: {
  312. Range ra(r.getStride(), r.getLowerBound() < c ? c : r.getLowerBound(),
  313. r.getUpperBound() < c ? c : r.getUpperBound(), r.getBase());
  314. output.addRange(e->getSubExp1(), ra);
  315. break;
  316. }
  317. case opEquals: {
  318. Range ra(r.getStride(), c, c, r.getBase());
  319. output.addRange(e->getSubExp1(), ra);
  320. break;
  321. }
  322. case opNotEqual: {
  323. Range ra(r.getStride(), r.getLowerBound() == c ? c + 1 : r.getLowerBound(),
  324. r.getUpperBound() == c ? c - 1 : r.getUpperBound(), r.getBase());
  325. output.addRange(e->getSubExp1(), ra);
  326. break;
  327. }
  328. default:
  329. break;
  330. }
  331. }
  332. }
  333. }
  334. void BranchStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
  335. {
  336. RangeMap output = getInputRanges();
  337. Exp *e = NULL;
  338. // try to hack up a useful expression for this branch
  339. OPER op = pCond->getOper();
  340. if (op == opLess || op == opLessEq || op == opGtr || op == opGtrEq ||
  341. op == opLessUns || op == opLessEqUns || op == opGtrUns || op == opGtrEqUns ||
  342. op == opEquals || op == opNotEqual) {
  343. if (pCond->getSubExp1()->isFlags() && output.hasRange(pCond->getSubExp1())) {
  344. Range &r = output.getRange(pCond->getSubExp1());
  345. if (r.getBase()->isFlagCall() &&
  346. r.getBase()->getSubExp2()->getOper() == opList &&
  347. r.getBase()->getSubExp2()->getSubExp2()->getOper() == opList) {
  348. e = new Binary(op, r.getBase()->getSubExp2()->getSubExp1()->clone(), r.getBase()->getSubExp2()->getSubExp2()->getSubExp1()->clone());
  349. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  350. LOG << "calculated condition " << e << "\n";
  351. }
  352. }
  353. }
  354. if (e)
  355. limitOutputWithCondition(output, e);
  356. updateRanges(output, execution_paths);
  357. output = getInputRanges();
  358. if (e)
  359. limitOutputWithCondition(output, (new Unary(opNot, e))->simplify());
  360. updateRanges(output, execution_paths, true);
  361. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  362. LOG << this << "\n";
  363. }
  364. void JunctionStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
  365. {
  366. RangeMap input;
  367. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  368. LOG << "unioning {\n";
  369. for (int i = 0; i < pbb->getNumInEdges(); i++) {
  370. Statement *last = pbb->getInEdges()[i]->getLastStmt();
  371. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  372. LOG << " in BB: " << pbb->getInEdges()[i]->getLowAddr() << " " << last << "\n";
  373. if (last->isBranch()) {
  374. input.unionwith(((BranchStatement*)last)->getRangesForOutEdgeTo(pbb));
  375. } else {
  376. if (last->isCall()) {
  377. Proc *d = ((CallStatement*)last)->getDestProc();
  378. if (d && !d->isLib() && ((UserProc*)d)->getCFG()->findRetNode() == NULL) {
  379. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  380. LOG << "ignoring ranges from call to proc with no ret node\n";
  381. } else
  382. input.unionwith(last->getRanges());
  383. } else
  384. input.unionwith(last->getRanges());
  385. }
  386. }
  387. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  388. LOG << "}\n";
  389. if (!input.isSubset(ranges)) {
  390. RangeMap output = input;
  391. if (output.hasRange(Location::regOf(28))) {
  392. Range &r = output.getRange(Location::regOf(28));
  393. if (r.getLowerBound() != r.getUpperBound() && r.getLowerBound() != Range::MIN) {
  394. if (VERBOSE)
  395. LOG << "stack height assumption violated " << r << " my bb: " << pbb->getLowAddr() << "\n";
  396. proc->printToLog();
  397. assert(false);
  398. }
  399. }
  400. if (isLoopJunction()) {
  401. output = ranges;
  402. output.widenwith(input);
  403. }
  404. updateRanges(output, execution_paths);
  405. }
  406. if (VERBOSE && DEBUG_RANGE_ANALYSIS)
  407. LOG << this << "\n";
  408. }
  409. void CallStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
  410. {
  411. RangeMap output = getInputRanges();
  412. if (this->procDest == NULL) {
  413. // note this assumes the call is only to one proc.. could be bad.
  414. Exp *d = output.substInto(getDest()->clone());
  415. if (d->isIntConst() || d->isStrConst()) {
  416. if (d->isIntConst()) {
  417. ADDRESS dest = ((Const*)d)->getInt();
  418. procDest = proc->getProg()->setNewProc(dest);
  419. } else {
  420. procDest = proc->getProg()->getLibraryProc(((Const*)d)->getStr());
  421. }
  422. if (procDest) {
  423. Signature *sig = procDest->getSignature();
  424. pDest = d;
  425. arguments.clear();
  426. for (unsigned i = 0; i < sig->getNumParams(); i++) {
  427. Exp* a = sig->getParamExp(i);
  428. Assign* as = new Assign(new VoidType(), a->clone(), a->clone());
  429. as->setProc(proc);
  430. as->setBB(pbb);
  431. arguments.append(as);
  432. }
  433. signature = procDest->getSignature()->clone();
  434. m_isComputed = false;
  435. proc->undoComputedBB(this);
  436. proc->addCallee(procDest);
  437. LOG << "replaced indirect call with call to " << procDest->getName() << "\n";
  438. }
  439. }
  440. }
  441. if (output.hasRange(Location::regOf(28))) {
  442. Range &r = output.getRange(Location::regOf(28));
  443. int c = 4;
  444. if (procDest == NULL) {
  445. LOG << "using push count hack to guess number of params\n";
  446. Statement *prev = this->getPreviousStatementInBB();
  447. while(prev) {
  448. if (prev->isAssign() && ((Assign*)prev)->getLeft()->isMemOf() &&
  449. ((Assign*)prev)->getLeft()->getSubExp1()->isRegOfK() &&
  450. ((Const*)((Assign*)prev)->getLeft()->getSubExp1()->getSubExp1())->getInt() == 28 &&
  451. ((Assign*)prev)->getRight()->getOper() != opPC) {
  452. c += 4;
  453. }
  454. prev = prev->getPreviousStatementInBB();
  455. }
  456. } else if (procDest->getSignature()->getConvention() == CONV_PASCAL)
  457. c += procDest->getSignature()->getNumParams() * 4;
  458. else if (!strncmp(procDest->getName(), "__imp_", 6)) {
  459. Statement *first = ((UserProc*)procDest)->getCFG()->getEntryBB()->getFirstStmt();
  460. assert(first && first->isCall());
  461. Proc *d = ((CallStatement*)first)->getDestProc();
  462. if (d->getSignature()->getConvention() == CONV_PASCAL)
  463. c += d->getSignature()->getNumParams() * 4;
  464. } else if (!procDest->isLib()) {
  465. UserProc *p = (UserProc*)procDest;
  466. if (VERBOSE) {
  467. LOG << "== checking for number of bytes popped ==\n";
  468. p->printToLog();
  469. LOG << "== end it ==\n";
  470. }
  471. Exp *eq = p->getProven(Location::regOf(28));
  472. if (eq) {
  473. if (VERBOSE)
  474. LOG << "found proven " << eq << "\n";
  475. if (eq->getOper() == opPlus && *eq->getSubExp1() == *Location::regOf(28) &&
  476. eq->getSubExp2()->isIntConst()) {
  477. c = ((Const*)eq->getSubExp2())->getInt();
  478. } else
  479. eq = NULL;
  480. }
  481. PBB retbb = p->getCFG()->findRetNode();
  482. if (retbb && eq == NULL) {
  483. Statement *last = retbb->getLastStmt();
  484. assert(last);
  485. if (last->isReturn()) {
  486. last->setBB(retbb);
  487. last = last->getPreviousStatementInBB();
  488. }
  489. if (last == NULL) {
  490. // call followed by a ret, sigh
  491. for (int i = 0; i < retbb->getNumInEdges(); i++) {
  492. last = retbb->getInEdges()[i]->getLastStmt();
  493. if (last->isCall())
  494. break;
  495. }
  496. if (last->isCall()) {
  497. Proc *d = ((CallStatement*)last)->getDestProc();
  498. if (d && d->getSignature()->getConvention() == CONV_PASCAL)
  499. c += d->getSignature()->getNumParams() * 4;
  500. }
  501. last = NULL;
  502. }
  503. if (last && last->isAssign()) {
  504. //LOG << "checking last statement " << last << " for number of bytes popped\n";
  505. Assign *a = (Assign*)last;
  506. assert(a->getLeft()->isRegOfK() && ((Const*)a->getLeft()->getSubExp1())->getInt() == 28);
  507. Exp *t = a->getRight()->clone()->simplifyArith();
  508. assert(t->getOper() == opPlus &&
  509. t->getSubExp1()->isRegOfK() &&
  510. ((Const*)t->getSubExp1()->getSubExp1())->getInt() == 28);
  511. assert(t->getSubExp2()->isIntConst());
  512. c = ((Const*)t->getSubExp2())->getInt();
  513. }
  514. }
  515. }
  516. Range ra(r.getStride(), r.getLowerBound() == Range::MIN ? Range::MIN : r.getLowerBound() + c,
  517. r.getUpperBound() == Range::MAX ? Range::MAX : r.getUpperBound() + c, r.getBase());
  518. output.addRange(Location::regOf(28), ra);
  519. }
  520. updateRanges(output, execution_paths);
  521. }
  522. bool JunctionStatement::isLoopJunction()
  523. {
  524. for (int i = 0; i < pbb->getNumInEdges(); i++)
  525. if (pbb->isBackEdge(i))
  526. return true;
  527. return false;
  528. }
  529. RangeMap &BranchStatement::getRangesForOutEdgeTo(PBB out)
  530. {
  531. assert(this->getFixedDest() != NO_ADDRESS);
  532. if (out->getLowAddr() == this->getFixedDest())
  533. return ranges;
  534. return ranges2;
  535. }
  536. bool Statement::isFirstStatementInBB()
  537. {
  538. assert(pbb);
  539. assert(pbb->getRTLs());
  540. assert(pbb->getRTLs()->size());
  541. assert(pbb->getRTLs()->front());
  542. assert(pbb->getRTLs()->front()->getList().size());
  543. return this == pbb->getRTLs()->front()->getList().front();
  544. }
  545. bool Statement::isLastStatementInBB()
  546. {
  547. assert(pbb);
  548. return this == pbb->getLastStmt();
  549. }
  550. Statement* Statement::getPreviousStatementInBB()
  551. {
  552. assert(pbb);
  553. std::list<RTL*> *rtls = pbb->getRTLs();
  554. assert(rtls);
  555. Statement *previous = NULL;
  556. for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
  557. RTL *rtl = *rit;
  558. for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
  559. if (*it == this)
  560. return previous;
  561. previous = *it;
  562. }
  563. }
  564. return NULL;
  565. }
  566. Statement *Statement::getNextStatementInBB()
  567. {
  568. assert(pbb);
  569. std::list<RTL*> *rtls = pbb->getRTLs();
  570. assert(rtls);
  571. bool wantNext = false;
  572. for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
  573. RTL *rtl = *rit;
  574. for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
  575. if (wantNext)
  576. return *it;
  577. if (*it == this)
  578. wantNext = true;
  579. }
  580. }
  581. return NULL;
  582. }
  583. /*==============================================================================
  584. * FUNCTION: operator<<
  585. * OVERVIEW: Output operator for Statement*
  586. * Just makes it easier to use e.g. std::cerr << myStmtStar
  587. * PARAMETERS: os: output stream to send to
  588. * p: ptr to Statement to print to the stream
  589. * RETURNS: copy of os (for concatenation)
  590. *============================================================================*/
  591. std::ostream& operator<<(std::ostream& os, Statement* s) {
  592. if (s == NULL) {os << "NULL "; return os;}
  593. s->print(os);
  594. return os;
  595. }
  596. bool Statement::isFlagAssgn() {
  597. if (kind != STMT_ASSIGN)
  598. return false;
  599. OPER op = ((Assign*)this)->getRight()->getOper();
  600. return (op == opFlagCall);
  601. }
  602. char* Statement::prints() {
  603. std::ostringstream ost;
  604. print(ost);
  605. strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
  606. debug_buffer[DEBUG_BUFSIZE-1] = '\0';
  607. return debug_buffer;
  608. }
  609. // This version prints much better in gdb
  610. void Statement::dump() {
  611. print(std::cerr);
  612. std::cerr << "\n";
  613. }
  614. /* This function is designed to find basic flag calls, plus in addition two variations seen with Pentium FP code.
  615. These variations involve ANDing and/or XORing with constants. So it should return true for these values of e:
  616. ADDFLAGS(...)
  617. SETFFLAGS(...) & 0x45
  618. (SETFFLAGS(...) & 0x45) ^ 0x40
  619. FIXME: this may not be needed any more...
  620. */
  621. bool hasSetFlags(Exp* e) {
  622. if (e->isFlagCall()) return true;
  623. OPER op = e->getOper();
  624. if (op != opBitAnd && op != opBitXor) return false;
  625. Exp* left = ((Binary*)e)->getSubExp1();
  626. Exp* right = ((Binary*)e)->getSubExp2();
  627. if (!right->isIntConst()) return false;
  628. if (left->isFlagCall()) {
  629. std::cerr << "hasSetFlags returns true with " << e << "\n";
  630. return true;
  631. }
  632. op = left->getOper();
  633. if (op != opBitAnd && op != opBitXor) return false;
  634. right = ((Binary*)left)->getSubExp2();
  635. left = ((Binary*)left)->getSubExp1();
  636. if (!right->isIntConst()) return false;
  637. bool ret = left->isFlagCall();
  638. if (ret)
  639. std::cerr << "hasSetFlags returns true with " << e << "\n";
  640. return ret;
  641. }
  642. // Return true if can propagate to Exp* e (must be a RefExp to return true)
  643. // Note: does not consider whether e is able to be renamed (from a memory Primitive point of view), only if the
  644. // definition can be propagated TO this stmt
  645. // Note: static member function
  646. bool Statement::canPropagateToExp(Exp*e) {
  647. if (!e->isSubscript()) return false;
  648. if (((RefExp*)e)->isImplicitDef())
  649. // Can't propagate statement "-" or "0" (implicit assignments)
  650. return false;
  651. Statement* def = ((RefExp*)e)->getDef();
  652. // if (def == this)
  653. // Don't propagate to self! Can happen with %pc's (?!)
  654. // return false;
  655. if (def->isNullStatement())
  656. // Don't propagate a null statement! Can happen with %pc's (would have no effect, and would infinitely loop)
  657. return false;
  658. if (!def->isAssign()) return false; // Only propagate ordinary assignments (so far)
  659. Assign* adef = (Assign*)def;
  660. if (adef->getType()->isArray()) {
  661. // Assigning to an array, don't propagate (Could be alias problems?)
  662. return false;
  663. }
  664. return true;
  665. }
  666. // Return true if any change; set convert if an indirect call statement is converted to direct (else unchanged)
  667. // destCounts is a set of maps from location to number of times it is used this proc
  668. // usedByDomPhi is a set of subscripted locations used in phi statements
  669. static int progress = 0;
  670. bool Statement::propagateTo(bool& convert, std::map<Exp*, int, lessExpStar>* destCounts /* = NULL */,
  671. LocationSet* usedByDomPhi /* = NULL */, bool force /* = false */) {
  672. if (++progress > 1000) {
  673. std::cerr << 'p' << std::flush;
  674. progress = 0;
  675. }
  676. bool change;
  677. int changes = 0;
  678. // int sp = proc->getSignature()->getStackRegister(proc->getProg());
  679. // Exp* regSp = Location::regOf(sp);
  680. int propMaxDepth = Boomerang::get()->propMaxDepth;
  681. do {
  682. LocationSet exps;
  683. addUsedLocs(exps, true); // True to also add uses from collectors. For example, want to propagate into
  684. // the reaching definitions of calls. Third parameter defaults to false, to
  685. // find all locations, not just those inside m[...]
  686. LocationSet::iterator ll;
  687. change = false; // True if changed this iteration of the do/while loop
  688. // Example: m[r24{10}] := r25{20} + m[r26{30}]
  689. // exps has r24{10}, r25{30}, m[r26{30}], r26{30}
  690. for (ll = exps.begin(); ll != exps.end(); ll++) {
  691. Exp* e = *ll;
  692. if (!canPropagateToExp(e))
  693. continue;
  694. Assign* def = (Assign*)((RefExp*)e)->getDef();
  695. Exp* rhs = def->getRight();
  696. // If force is true, ignore the fact that a memof should not be propagated (for switch analysis)
  697. if (rhs->containsBadMemof(proc) && !(force && rhs->isMemOf()))
  698. // Must never propagate unsubscripted memofs, or memofs that don't yet have symbols. You could be
  699. // propagating past a definition, thereby invalidating the IR
  700. continue;
  701. Exp* lhs = def->getLeft();
  702. if (EXPERIMENTAL) {
  703. #if 0
  704. // This is the old "don't propagate x=f(x)" heuristic. Hopefully it will work better now that we always
  705. // propagate into memofs etc. However, it might need a "and we're inside the right kind of loop"
  706. // condition
  707. LocationSet used;
  708. def->addUsedLocs(used);
  709. RefExp left(def->getLeft(), (Statement*)-1);
  710. RefExp *right = dynamic_cast<RefExp*>(def->getRight());
  711. // Beware of x := x{something else} (because we do want to do copy propagation)
  712. if (used.exists(&left) && !(right && *right->getSubExp1() == *left.getSubExp1()))
  713. // We have something like eax = eax + 1
  714. continue;
  715. #else
  716. // This is Mike's experimental propagation limiting heuristic. At present, it is:
  717. // for each component of def->rhs
  718. // test if the base expression is in the set usedByDomPhi
  719. // if so, check if this statement OW overwrites a parameter (like ebx = ebx-1)
  720. // if so, check for propagating past this overwriting statement, i.e.
  721. // domNum(def) <= domNum(OW) && dimNum(OW) < domNum(def)
  722. // if so, don't propagate (heuristic takes effect)
  723. if (usedByDomPhi) {
  724. LocationSet rhsComps;
  725. rhs->addUsedLocs(rhsComps);
  726. LocationSet::iterator rcit;
  727. bool doNotPropagate = false;
  728. for (rcit = rhsComps.begin(); rcit != rhsComps.end(); ++rcit) {
  729. if (!(*rcit)->isSubscript()) continue; // Sometimes %pc sneaks in
  730. Exp* rhsBase = ((RefExp*)*rcit)->getSubExp1();
  731. // We don't know the statement number for the one definition in usedInDomPhi that might exist,
  732. // so we use findNS()
  733. Exp* OW = usedByDomPhi->findNS(rhsBase);
  734. if (OW) {
  735. Statement* OWdef = ((RefExp*)OW)->getDef();
  736. if (!OWdef->isAssign()) continue;
  737. Exp* lhsOWdef = ((Assign*)OWdef)->getLeft();
  738. LocationSet OWcomps;
  739. def->addUsedLocs(OWcomps);
  740. LocationSet::iterator cc;
  741. bool isOverwrite = false;
  742. for (cc = OWcomps.begin(); cc != OWcomps.end(); ++cc) {
  743. if (**cc *= *lhsOWdef) {
  744. isOverwrite = true;
  745. break;
  746. }
  747. }
  748. if (isOverwrite) {
  749. // Now check for propagating a component past OWdef
  750. if (def->getDomNumber() <= OWdef->getDomNumber() &&
  751. OWdef->getDomNumber() < dominanceNum)
  752. // The heuristic kicks in
  753. doNotPropagate = true;
  754. break;
  755. }
  756. if (OW) std::cerr << "Ow is " << OW << "\n";
  757. }
  758. }
  759. if (doNotPropagate) {
  760. if (VERBOSE)
  761. LOG << "% propagation of " << def->getNumber() << " into " << number << " prevented by the "
  762. "propagate past overwriting statement in loop heuristic\n";
  763. continue;
  764. }
  765. }
  766. }
  767. #endif
  768. // Check if the -l flag (propMaxDepth) prevents this propagation
  769. if (destCounts && !lhs->isFlags()) { // Always propagate to %flags
  770. std::map<Exp*, int, lessExpStar>::iterator ff = destCounts->find(e);
  771. if (ff != destCounts->end() && ff->second > 1 && rhs->getComplexityDepth(proc) >= propMaxDepth) {
  772. if (!def->getRight()->containsFlags()) {
  773. // This propagation is prevented by the -l limit
  774. continue;
  775. }
  776. }
  777. }
  778. change |= doPropagateTo(e, def, convert);
  779. }
  780. } while (change && ++changes < 10);
  781. // Simplify is very costly, especially for calls. I hope that doing one simplify at the end will not affect any
  782. // result...
  783. simplify();
  784. return changes > 0; // Note: change is only for the last time around the do/while loop
  785. }
  786. // Experimental: may want to propagate flags first, without tests about complexity or the propagation limiting heuristic
  787. bool Statement::propagateFlagsTo() {
  788. bool change = false, convert;
  789. int changes = 0;
  790. do {
  791. LocationSet exps;
  792. addUsedLocs(exps, true);
  793. LocationSet::iterator ll;
  794. for (ll = exps.begin(); ll != exps.end(); ll++) {
  795. Exp* e = *ll;
  796. if (!e->isSubscript()) continue; // e.g. %pc
  797. Assign* def = (Assign*)((RefExp*)e)->getDef();
  798. if (def == NULL || !def->isAssign()) continue;
  799. Exp* base = ((RefExp*)e)->getSubExp1();
  800. if (base->isFlags() || base->isMainFlag()) {
  801. change |= doPropagateTo(e, def, convert);
  802. }
  803. }
  804. } while (change && ++changes < 10);
  805. simplify();
  806. return change;
  807. }
  808. // Parameter convert is set true if an indirect call is converted to direct
  809. // Return true if a change made
  810. // Note: this procedure does not control what part of this statement is propagated to
  811. // Propagate to e from definition statement def.
  812. // Set convert to true if convert a call from indirect to direct.
  813. bool Statement::doPropagateTo(Exp* e, Assign* def, bool& convert) {
  814. // Respect the -p N switch
  815. if (Boomerang::get()->numToPropagate >= 0) {
  816. if (Boomerang::get()->numToPropagate == 0) return false;
  817. Boomerang::get()->numToPropagate--;
  818. }
  819. if (VERBOSE)
  820. LOG << "propagating " << def << "\n" << " into " << this << "\n";
  821. bool change = replaceRef(e, def, convert);
  822. if (VERBOSE) {
  823. LOG << " result " << this << "\n\n";
  824. }
  825. return change;
  826. }
  827. // replace a use of def->getLeft() by def->getRight() in this statement
  828. // return true if change
  829. bool Statement::replaceRef(Exp* e, Assign *def, bool& convert) {
  830. Exp* rhs = def->getRight();
  831. assert(rhs);
  832. Exp* base = ((RefExp*)e)->getSubExp1();
  833. // Could be propagating %flags into %CF
  834. Exp* lhs = def->getLeft();
  835. if (base->getOper() == opCF && lhs->isFlags()) {
  836. if (!rhs->isFlagCall())
  837. return false;
  838. char* str = ((Const*)((Binary*)rhs)->getSubExp1())->getStr();
  839. if (strncmp("SUBFLAGS", str, 8) == 0) {
  840. /* When the carry flag is used bare, and was defined in a subtract of the form lhs - rhs, then CF has
  841. the value (lhs <u rhs). lhs and rhs are the first and second parameters of the flagcall.
  842. Note: the flagcall is a binary, with a Const (the name) and a list of expressions:
  843. defRhs
  844. / \
  845. Const opList
  846. "SUBFLAGS" / \
  847. P1 opList
  848. / \
  849. P2 opList
  850. / \
  851. P3 opNil
  852. */
  853. Exp* relExp = new Binary(opLessUns,
  854. ((Binary*)rhs)->getSubExp2()->getSubExp1(),
  855. ((Binary*)rhs)->getSubExp2()->getSubExp2()->getSubExp1());
  856. searchAndReplace(new RefExp(new Terminal(opCF), def), relExp, true);
  857. return true;
  858. }
  859. }
  860. // need something similar for %ZF
  861. if (base->getOper() == opZF && lhs->isFlags()) {
  862. if (!rhs->isFlagCall())
  863. return false;
  864. char* str = ((Const*)((Binary*)rhs)->getSubExp1())->getStr();
  865. if (strncmp("SUBFLAGS", str, 8) == 0) {
  866. // for zf we're only interested in if the result part of the subflags is equal to zero
  867. Exp* relExp = new Binary(opEquals,
  868. ((Binary*)rhs)->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1(),
  869. new Const(0));
  870. searchAndReplace(new RefExp(new Terminal(opZF), def), relExp, true);
  871. return true;
  872. }
  873. }
  874. // do the replacement
  875. //bool convert = doReplaceRef(re, rhs);
  876. bool ret = searchAndReplace(e, rhs, true); // Last parameter true to change collectors
  877. // assert(ret);
  878. if (ret && isCall()) {
  879. convert |= ((CallStatement*)this)->convertToDirect();
  880. }
  881. return ret;
  882. }
  883. bool Statement::isNullStatement() {
  884. if (kind != STMT_ASSIGN) return false;
  885. Exp* right = ((Assign*)this)->getRight();
  886. if (right->isSubscript()) {
  887. // Must refer to self to be null
  888. return this == ((RefExp*)right)->getDef();
  889. }
  890. else
  891. // Null if left == right
  892. return *((Assign*)this)->getLeft() == *right;
  893. }
  894. bool Statement::isFpush() {
  895. if (kind != STMT_ASSIGN) return false;
  896. return ((Assign*)this)->getRight()->getOper() == opFpush;
  897. }
  898. bool Statement::isFpop() {
  899. if (kind != STMT_ASSIGN) return false;
  900. return ((Assign*)this)->getRight()->getOper() == opFpop;
  901. }
  902. /*
  903. * This code was in hrtl.cpp
  904. * Classes derived from Statement
  905. */
  906. #if defined(_MSC_VER) && _MSC_VER <= 1200
  907. #pragma warning(disable:4786)
  908. #endif
  909. /******************************************************************************
  910. * GotoStatement methods
  911. *****************************************************************************/
  912. /*==============================================================================
  913. * FUNCTION: GotoStatement::GotoStatement
  914. * OVERVIEW: Constructor.
  915. * PARAMETERS: listStmt: a list of Statements (not the same as an RTL)
  916. * to serve as the initial list of statements
  917. * RETURNS: N/a
  918. *============================================================================*/
  919. GotoStatement::GotoStatement()
  920. : pDest(NULL), m_isComputed(false) {
  921. kind = STMT_GOTO;
  922. }
  923. /*==============================================================================
  924. * FUNCTION: GotoStatement::GotoStatement
  925. * OVERVIEW: Construct a jump to a fixed address
  926. * PARAMETERS: uDest: native address of destination
  927. * RETURNS: N/a
  928. *============================================================================*/
  929. GotoStatement::GotoStatement(ADDRESS uDest) : m_isComputed(false) {
  930. kind = STMT_GOTO;
  931. pDest = new Const(uDest);
  932. }
  933. /*==============================================================================
  934. * FUNCTION: GotoStatement::~GotoStatement
  935. * OVERVIEW: Destructor
  936. * PARAMETERS: None
  937. * RETURNS: N/a
  938. *============================================================================*/
  939. GotoStatement::~GotoStatement() {
  940. if (pDest) ;//delete pDest;
  941. }
  942. /*==============================================================================
  943. * FUNCTION: GotoStatement::getFixedDest
  944. * OVERVIEW: Get the fixed destination of this CTI. Assumes destination
  945. * simplication has already been done so that a fixed dest will
  946. * be of the Exp form:
  947. * opIntConst dest
  948. * PARAMETERS: <none>
  949. * RETURNS: Fixed dest or NO_ADDRESS if there isn't one
  950. *============================================================================*/
  951. ADDRESS GotoStatement::getFixedDest() {
  952. if (pDest->getOper() != opIntConst) return NO_ADDRESS;
  953. return ((Const*)pDest)->getAddr();
  954. }
  955. /*==============================================================================
  956. * FUNCTION: GotoStatement::setDest
  957. * OVERVIEW: Set the destination of this jump to be a given expression.
  958. * PARAMETERS: addr - the new fixed address
  959. * RETURNS: Nothing
  960. *============================================================================*/
  961. void GotoStatement::setDest(Exp* pd) {
  962. pDest = pd;
  963. }
  964. /*==============================================================================
  965. * FUNCTION: GotoStatement::setDest
  966. * OVERVIEW: Set the destination of this jump to be a given fixed address.
  967. * PARAMETERS: addr - the new fixed address
  968. * RETURNS: <nothing>
  969. *============================================================================*/
  970. void GotoStatement::setDest(ADDRESS addr) {
  971. // This fails in FrontSparcTest, do you really want it to Mike? -trent
  972. // assert(addr >= prog.limitTextLow && addr < prog.limitTextHigh);
  973. // Delete the old destination if there is one
  974. if (pDest != NULL)
  975. ;//delete pDest;
  976. pDest = new Const(addr);
  977. }
  978. /*==============================================================================
  979. * FUNCTION: GotoStatement::getDest
  980. * OVERVIEW: Returns the destination of this CTI.
  981. * PARAMETERS: None
  982. * RETURNS: Pointer to the SS representing the dest of this jump
  983. *============================================================================*/
  984. Exp* GotoStatement::getDest() {
  985. return pDest;
  986. }
  987. /*==============================================================================
  988. * FUNCTION: GotoStatement::adjustFixedDest
  989. * OVERVIEW: Adjust the destination of this CTI by a given amount. Causes
  990. * an error is this destination is not a fixed destination
  991. * (i.e. a constant offset).
  992. * PARAMETERS: delta - the amount to add to the destination (can be
  993. * negative)
  994. * RETURNS: <nothing>
  995. *============================================================================*/
  996. void GotoStatement::adjustFixedDest(int delta) {
  997. // Ensure that the destination is fixed.
  998. if (pDest == 0 || pDest->getOper() != opIntConst)
  999. LOG << "Can't adjust destination of non-static CTI\n";
  1000. ADDRESS dest = ((Const*)pDest)->getAddr();
  1001. ((Const*)pDest)->setAddr(dest + delta);
  1002. }
  1003. bool GotoStatement::search(Exp* search, Exp*& result) {
  1004. result = NULL;
  1005. if (pDest)
  1006. return pDest->search(search, result);
  1007. return false;
  1008. }
  1009. /*==============================================================================
  1010. * FUNCTION: GotoStatement::searchAndReplace
  1011. * OVERVIEW: Replace all instances of search with replace.
  1012. * PARAMETERS: search - a location to search for
  1013. * replace - the expression with which to replace it
  1014. * cc - ignored
  1015. * RETURNS: True if any change
  1016. *============================================================================*/
  1017. bool GotoStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  1018. bool change = false;
  1019. if (pDest) {
  1020. pDest = pDest->searchReplaceAll(search, replace, change);
  1021. }
  1022. return change;
  1023. }
  1024. /*==============================================================================
  1025. * FUNCTION: GotoStatement::searchAll
  1026. * OVERVIEW: Find all instances of the search expression
  1027. * PARAMETERS: search - a location to search for
  1028. * result - a list which will have any matching exprs
  1029. * appended to it
  1030. * RETURNS: true if there were any matches
  1031. *============================================================================*/
  1032. bool GotoStatement::searchAll(Exp* search, std::list<Exp*> &result) {
  1033. if (pDest) return pDest->searchAll(search, result);
  1034. return false;
  1035. }
  1036. /*==============================================================================
  1037. * FUNCTION: GotoStatement::print
  1038. * OVERVIEW: Display a text reprentation of this RTL to the given stream
  1039. * NOTE: Usually called from RTL::print, in which case the first 9
  1040. * chars of the print have already been output to os
  1041. * PARAMETERS: os: stream to write to
  1042. * RETURNS: Nothing
  1043. *============================================================================*/
  1044. void GotoStatement::print(std::ostream& os, bool html) {
  1045. os << std::setw(4) << std::dec << number << " ";
  1046. if (html) {
  1047. os << "</td><td>";
  1048. os << "<a name=\"stmt" << std::dec << number << "\">";
  1049. }
  1050. os << "GOTO ";
  1051. if (pDest == NULL)
  1052. os << "*no dest*";
  1053. else if (pDest->getOper() != opIntConst)
  1054. pDest->print(os);
  1055. else
  1056. os << "0x" << std::hex << getFixedDest();
  1057. if (html)
  1058. os << "</a></td>";
  1059. }
  1060. /*==============================================================================
  1061. * FUNCTION: GotoStatement::setIsComputed
  1062. * OVERVIEW: Sets the fact that this call is computed.
  1063. * NOTE: This should really be removed, once CaseStatement and
  1064. * HLNwayCall are implemented properly
  1065. * PARAMETERS: <none>
  1066. * RETURNS: <nothing>
  1067. *============================================================================*/
  1068. void GotoStatement::setIsComputed(bool b) {
  1069. m_isComputed = b;
  1070. }
  1071. /*==============================================================================
  1072. * FUNCTION: GotoStatement::isComputed
  1073. * OVERVIEW: Returns whether or not this call is computed.
  1074. * NOTE: This should really be removed, once CaseStatement and HLNwayCall
  1075. * are implemented properly
  1076. * PARAMETERS: <none>
  1077. * RETURNS: this call is computed
  1078. *============================================================================*/
  1079. bool GotoStatement::isComputed() {
  1080. return m_isComputed;
  1081. }
  1082. /*==============================================================================
  1083. * FUNCTION: GotoStatement::clone
  1084. * OVERVIEW: Deep copy clone
  1085. * PARAMETERS: <none>
  1086. * RETURNS: Pointer to a new Statement, a clone of this GotoStatement
  1087. *============================================================================*/
  1088. Statement* GotoStatement::clone() {
  1089. GotoStatement* ret = new GotoStatement();
  1090. ret->pDest = pDest->clone();
  1091. ret->m_isComputed = m_isComputed;
  1092. // Statement members
  1093. ret->pbb = pbb;
  1094. ret->proc = proc;
  1095. ret->number = number;
  1096. return ret;
  1097. }
  1098. // visit this Statement in the RTL
  1099. bool GotoStatement::accept(StmtVisitor* visitor) {
  1100. return visitor->visit(this);
  1101. }
  1102. void GotoStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  1103. // dont generate any code for jumps, they will be handled by the BB
  1104. }
  1105. void GotoStatement::simplify() {
  1106. if (isComputed()) {
  1107. pDest = pDest->simplifyArith();
  1108. pDest = pDest->simplify();
  1109. }
  1110. }
  1111. /**********************************
  1112. * BranchStatement methods
  1113. **********************************/
  1114. /*==============================================================================
  1115. * FUNCTION: BranchStatement::BranchStatement
  1116. * OVERVIEW: Constructor.
  1117. * PARAMETERS: None
  1118. * RETURNS: N/a
  1119. *============================================================================*/
  1120. BranchStatement::BranchStatement() : jtCond((BRANCH_TYPE)0), pCond(NULL), bFloat(false), size(0) {
  1121. kind = STMT_BRANCH;
  1122. }
  1123. /*==============================================================================
  1124. * FUNCTION: BranchStatement::~BranchStatement
  1125. * OVERVIEW: Destructor
  1126. * PARAMETERS: None
  1127. * RETURNS: N/a
  1128. *============================================================================*/
  1129. BranchStatement::~BranchStatement() {
  1130. if (pCond)
  1131. ;//delete pCond;
  1132. }
  1133. /*==============================================================================
  1134. * FUNCTION: BranchStatement::setCondType
  1135. * OVERVIEW: Sets the BRANCH_TYPE of this jcond as well as the flag
  1136. * indicating whether or not the floating point condition codes
  1137. * are used.
  1138. * PARAMETERS: cond - the BRANCH_TYPE
  1139. * usesFloat - this condional jump checks the floating point
  1140. * condition codes
  1141. * RETURNS: a semantic string
  1142. *============================================================================*/
  1143. void BranchStatement::setCondType(BRANCH_TYPE cond, bool usesFloat /*= false*/) {
  1144. jtCond = cond;
  1145. bFloat = usesFloat;
  1146. // set pCond to a high level representation of this type
  1147. Exp* p = NULL;
  1148. switch(cond) {
  1149. case BRANCH_JE:
  1150. p = new Binary(opEquals, new Terminal(opFlags), new Const(0));
  1151. break;
  1152. case BRANCH_JNE:
  1153. p = new Binary(opNotEqual, new Terminal(opFlags), new Const(0));
  1154. break;
  1155. case BRANCH_JSL:
  1156. p = new Binary(opLess, new Terminal(opFlags), new Const(0));
  1157. break;
  1158. case BRANCH_JSLE:
  1159. p = new Binary(opLessEq, new Terminal(opFlags), new Const(0));
  1160. break;
  1161. case BRANCH_JSGE:
  1162. p = new Binary(opGtrEq, new Terminal(opFlags), new Const(0));
  1163. break;
  1164. case BRANCH_JSG:
  1165. p = new Binary(opGtr, new Terminal(opFlags), new Const(0));
  1166. break;
  1167. case BRANCH_JUL:
  1168. p = new Binary(opLessUns, new Terminal(opFlags), new Const(0));
  1169. break;
  1170. case BRANCH_JULE:
  1171. p = new Binary(opLessEqUns, new Terminal(opFlags), new Const(0));
  1172. break;
  1173. case BRANCH_JUGE:
  1174. p = new Binary(opGtrEqUns, new Terminal(opFlags), new Const(0));
  1175. break;
  1176. case BRANCH_JUG:
  1177. p = new Binary(opGtrUns, new Terminal(opFlags), new Const(0));
  1178. break;
  1179. case BRANCH_JMI:
  1180. p = new Binary(opLess, new Terminal(opFlags), new Const(0));
  1181. break;
  1182. case BRANCH_JPOS:
  1183. p = new Binary(opGtr, new Terminal(opFlags), new Const(0));
  1184. break;
  1185. case BRANCH_JOF:
  1186. p = new Binary(opLessUns, new Terminal(opFlags), new Const(0));
  1187. break;
  1188. case BRANCH_JNOF:
  1189. p = new Binary(opGtrUns, new Terminal(opFlags), new Const(0));
  1190. break;
  1191. case BRANCH_JPAR:
  1192. // Can't handle this properly here; leave an impossible expression involving %flags so propagation will
  1193. // still happen, and we can recognise this later in condToRelational()
  1194. // Update: these expressions seem to get ignored ???
  1195. p = new Binary(opEquals, new Terminal(opFlags), new Const(999));
  1196. break;
  1197. }
  1198. // this is such a hack.. preferably we should actually recognise SUBFLAGS32(..,..,..) > 0 instead of just
  1199. // SUBFLAGS32(..,..,..) but I'll leave this in here for the moment as it actually works.
  1200. if (!Boomerang::get()->noDecompile)
  1201. p = new Terminal(usesFloat ? opFflags : opFlags);
  1202. assert(p);
  1203. setCondExpr(p);
  1204. }
  1205. /*==============================================================================
  1206. * FUNCTION: BranchStatement::makeSigned
  1207. * OVERVIEW: Change this from an unsigned to a signed branch
  1208. * PARAMETERS: <none>
  1209. * RETURNS: <nothing>
  1210. *============================================================================*/
  1211. void BranchStatement::makeSigned() {
  1212. // Make this into a signed branch
  1213. switch (jtCond)
  1214. {
  1215. case BRANCH_JUL : jtCond = BRANCH_JSL; break;
  1216. case BRANCH_JULE: jtCond = BRANCH_JSLE; break;
  1217. case BRANCH_JUGE: jtCond = BRANCH_JSGE; break;
  1218. case BRANCH_JUG : jtCond = BRANCH_JSG; break;
  1219. default:
  1220. // Do nothing for other cases
  1221. break;
  1222. }
  1223. }
  1224. /*==============================================================================
  1225. * FUNCTION: BranchStatement::getCondExpr
  1226. * OVERVIEW: Return the SemStr expression containing the HL condition.
  1227. * PARAMETERS: <none>
  1228. * RETURNS: ptr to an expression
  1229. *============================================================================*/
  1230. Exp* BranchStatement::getCondExpr() {
  1231. return pCond;
  1232. }
  1233. /*==============================================================================
  1234. * FUNCTION: BranchStatement::setCondExpr
  1235. * OVERVIEW: Set the SemStr expression containing the HL condition.
  1236. * PARAMETERS: Pointer to Exp to set
  1237. * RETURNS: <nothing>
  1238. *============================================================================*/
  1239. void BranchStatement::setCondExpr(Exp* e) {
  1240. if (pCond) ;//delete pCond;
  1241. pCond = e;
  1242. }
  1243. PBB BranchStatement::getFallBB()
  1244. {
  1245. ADDRESS a = getFixedDest();
  1246. if (a == NO_ADDRESS)
  1247. return NULL;
  1248. if (pbb == NULL)
  1249. return NULL;
  1250. if (pbb->getNumOutEdges() != 2)
  1251. return NULL;
  1252. if (pbb->getOutEdge(0)->getLowAddr() == a)
  1253. return pbb->getOutEdge(1);
  1254. return pbb->getOutEdge(0);
  1255. }
  1256. // not that if you set the taken BB or fixed dest first, you will not be able to set the fall BB
  1257. void BranchStatement::setFallBB(PBB bb)
  1258. {
  1259. ADDRESS a = getFixedDest();
  1260. if (a == NO_ADDRESS)
  1261. return;
  1262. if (pbb == NULL)
  1263. return;
  1264. if (pbb->getNumOutEdges() != 2)
  1265. return;
  1266. if (pbb->getOutEdge(0)->getLowAddr() == a) {
  1267. pbb->getOutEdge(1)->deleteInEdge(pbb);
  1268. pbb->setOutEdge(1, bb);
  1269. bb->addInEdge(pbb);
  1270. } else {
  1271. pbb->getOutEdge(0)->deleteInEdge(pbb);
  1272. pbb->setOutEdge(0, bb);
  1273. bb->addInEdge(pbb);
  1274. }
  1275. }
  1276. PBB BranchStatement::getTakenBB()
  1277. {
  1278. ADDRESS a = getFixedDest();
  1279. if (a == NO_ADDRESS)
  1280. return NULL;
  1281. if (pbb == NULL)
  1282. return NULL;
  1283. if (pbb->getNumOutEdges() != 2)
  1284. return NULL;
  1285. if (pbb->getOutEdge(0)->getLowAddr() == a)
  1286. return pbb->getOutEdge(0);
  1287. return pbb->getOutEdge(1);
  1288. }
  1289. void BranchStatement::setTakenBB(PBB bb)
  1290. {
  1291. ADDRESS a = getFixedDest();
  1292. if (a == NO_ADDRESS)
  1293. return;
  1294. if (pbb == NULL)
  1295. return;
  1296. if (pbb->getNumOutEdges() != 2)
  1297. return;
  1298. if (pbb->getOutEdge(0)->getLowAddr() == a) {
  1299. pbb->getOutEdge(0)->deleteInEdge(pbb);
  1300. pbb->setOutEdge(0, bb);
  1301. bb->addInEdge(pbb);
  1302. } else {
  1303. pbb->getOutEdge(1)->deleteInEdge(pbb);
  1304. pbb->setOutEdge(1, bb);
  1305. bb->addInEdge(pbb);
  1306. }
  1307. }
  1308. bool BranchStatement::search(Exp* search, Exp*& result) {
  1309. if (pCond) return pCond->search(search, result);
  1310. result = NULL;
  1311. return false;
  1312. }
  1313. /*==============================================================================
  1314. * FUNCTION: BranchStatement::searchAndReplace
  1315. * OVERVIEW: Replace all instances of search with replace.
  1316. * PARAMETERS: search - a location to search for
  1317. * replace - the expression with which to replace it
  1318. * cc - ignored
  1319. * RETURNS: True if any change
  1320. *============================================================================*/
  1321. bool BranchStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  1322. GotoStatement::searchAndReplace(search, replace, cc);
  1323. bool change = false;
  1324. if (pCond)
  1325. pCond = pCond->searchReplaceAll(search, replace, change);
  1326. return change;
  1327. }
  1328. /*==============================================================================
  1329. * FUNCTION: BranchStatement::searchAll
  1330. * OVERVIEW: Find all instances of the search expression
  1331. * PARAMETERS: search - a location to search for
  1332. * result - a list which will have any matching exprs
  1333. * appended to it
  1334. * RETURNS: true if there were any matches
  1335. *============================================================================*/
  1336. bool BranchStatement::searchAll(Exp* search, std::list<Exp*> &result) {
  1337. if (pCond) return pCond->searchAll(search, result);
  1338. return false;
  1339. }
  1340. /*==============================================================================
  1341. * FUNCTION: BranchStatement::print
  1342. * OVERVIEW: Write a text representation to the given stream
  1343. * PARAMETERS: os: stream
  1344. * RETURNS: Nothing
  1345. *============================================================================*/
  1346. void BranchStatement::print(std::ostream& os, bool html) {
  1347. os << std::setw(4) << std::dec << number << " ";
  1348. if (html) {
  1349. os << "</td><td>";
  1350. os << "<a name=\"stmt" << std::dec << number << "\">";
  1351. }
  1352. os << "BRANCH ";
  1353. if (pDest == NULL)
  1354. os << "*no dest*";
  1355. else if (!pDest->isIntConst())
  1356. os << pDest;
  1357. else {
  1358. // Really we'd like to display the destination label here...
  1359. os << "0x" << std::hex << getFixedDest();
  1360. }
  1361. os << ", condition ";
  1362. switch (jtCond) {
  1363. case BRANCH_JE: os << "equals"; break;
  1364. case BRANCH_JNE: os << "not equals"; break;
  1365. case BRANCH_JSL: os << "signed less"; break;
  1366. case BRANCH_JSLE: os << "signed less or equals"; break;
  1367. case BRANCH_JSGE: os << "signed greater or equals"; break;
  1368. case BRANCH_JSG: os << "signed greater"; break;
  1369. case BRANCH_JUL: os << "unsigned less"; break;
  1370. case BRANCH_JULE: os << "unsigned less or equals"; break;
  1371. case BRANCH_JUGE: os << "unsigned greater or equals"; break;
  1372. case BRANCH_JUG: os << "unsigned greater"; break;
  1373. case BRANCH_JMI: os << "minus"; break;
  1374. case BRANCH_JPOS: os << "plus"; break;
  1375. case BRANCH_JOF: os << "overflow"; break;
  1376. case BRANCH_JNOF: os << "no overflow"; break;
  1377. case BRANCH_JPAR: os << "parity"; break;
  1378. }
  1379. if (bFloat) os << " float";
  1380. os << std::endl;
  1381. if (pCond) {
  1382. if (html)
  1383. os << "<br>";
  1384. os << "High level: ";
  1385. pCond->print(os, html);
  1386. }
  1387. if (html)
  1388. os << "</a></td>";
  1389. }
  1390. /*==============================================================================
  1391. * FUNCTION: BranchStatement::clone
  1392. * OVERVIEW: Deep copy clone
  1393. * PARAMETERS: <none>
  1394. * RETURNS: Pointer to a new Statement, a clone of this BranchStatement
  1395. *============================================================================*/
  1396. Statement* BranchStatement::clone() {
  1397. BranchStatement* ret = new BranchStatement();
  1398. ret->pDest = pDest->clone();
  1399. ret->m_isComputed = m_isComputed;
  1400. ret->jtCond = jtCond;
  1401. if (pCond) ret->pCond = pCond->clone();
  1402. else ret->pCond = NULL;
  1403. ret->bFloat = bFloat;
  1404. // Statement members
  1405. ret->pbb = pbb;
  1406. ret->proc = proc;
  1407. ret->number = number;
  1408. return ret;
  1409. }
  1410. // visit this stmt
  1411. bool BranchStatement::accept(StmtVisitor* visitor) {
  1412. return visitor->visit(this);
  1413. }
  1414. void BranchStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  1415. // dont generate any code for jconds, they will be handled by the bb
  1416. }
  1417. bool BranchStatement::usesExp(Exp *e) {
  1418. Exp *tmp;
  1419. return pCond && pCond->search(e, tmp);
  1420. }
  1421. // Common to BranchStatement and BoolAssign
  1422. // Return true if this is now a floating point Branch
  1423. bool condToRelational(Exp*& pCond, BRANCH_TYPE jtCond) {
  1424. pCond = pCond->simplifyArith()->simplify();
  1425. std::stringstream os;
  1426. pCond->print(os);
  1427. std::string s = os.str();
  1428. OPER condOp = pCond->getOper();
  1429. if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "SUBFLAGS", 8) == 0) {
  1430. OPER op = opWild;
  1431. // Special for PPC unsigned compares; may be other cases in the future
  1432. bool makeUns = strncmp(((Const*)pCond->getSubExp1())->getStr(), "SUBFLAGSNL", 10) == 0;
  1433. switch (jtCond) {
  1434. case BRANCH_JE: op = opEquals; break;
  1435. case BRANCH_JNE: op = opNotEqual; break;
  1436. case BRANCH_JSL: if (makeUns) op = opLessUns; else op = opLess; break;
  1437. case BRANCH_JSLE: if (makeUns) op = opLessEqUns; else op = opLessEq; break;
  1438. case BRANCH_JSGE: if (makeUns) op = opGtrEqUns; else op = opGtrEq; break;
  1439. case BRANCH_JSG: if (makeUns) op = opGtrUns; else op = opGtr; break;
  1440. case BRANCH_JUL: op = opLessUns; break;
  1441. case BRANCH_JULE: op = opLessEqUns; break;
  1442. case BRANCH_JUGE: op = opGtrEqUns; break;
  1443. case BRANCH_JUG: op = opGtrUns; break;
  1444. case BRANCH_JMI:
  1445. /* pCond
  1446. / \
  1447. Const opList
  1448. "SUBFLAGS" / \
  1449. P1 opList
  1450. / \
  1451. P2 opList
  1452. / \
  1453. P3 opNil */
  1454. pCond = new Binary(opLess, // P3 < 0
  1455. pCond->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1()->clone(),
  1456. new Const(0));
  1457. break;
  1458. case BRANCH_JPOS:
  1459. pCond = new Binary(opGtrEq, // P3 >= 0
  1460. pCond->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1()->clone(),
  1461. new Const(0));
  1462. break;
  1463. case BRANCH_JOF:
  1464. case BRANCH_JNOF:
  1465. case BRANCH_JPAR:
  1466. break;
  1467. }
  1468. if (op != opWild) {
  1469. pCond = new Binary(op,
  1470. pCond->getSubExp2()->getSubExp1()->clone(), // P1
  1471. pCond->getSubExp2()->getSubExp2()->getSubExp1()->clone()); // P2
  1472. }
  1473. }
  1474. else if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "LOGICALFLAGS", 12) == 0) {
  1475. // Exp *e = pCond;
  1476. OPER op = opWild;
  1477. switch (jtCond) {
  1478. case BRANCH_JE: op = opEquals; break;
  1479. case BRANCH_JNE: op = opNotEqual; break;
  1480. case BRANCH_JMI: op = opLess; break;
  1481. case BRANCH_JPOS: op = opGtrEq; break;
  1482. // FIXME: This next set is quite shakey. Really, we should pull all the individual flag definitions out of
  1483. // the flag definitions, and substitute these into the equivalent conditions for the branches (a big, ugly
  1484. // job).
  1485. case BRANCH_JSL: op = opLess; break;
  1486. case BRANCH_JSLE: op = opLessEq; break;
  1487. case BRANCH_JSGE: op = opGtrEq; break;
  1488. case BRANCH_JSG: op = opGtr; break;
  1489. // These next few seem to fluke working fine on architectures like X86, SPARC, and 68K which clear the
  1490. // carry on all logical operations.
  1491. case BRANCH_JUL: op = opLessUns; break; // NOTE: this is equivalent to never branching, since nothing
  1492. // can be unsigned less than zero
  1493. case BRANCH_JULE: op = opLessEqUns; break;
  1494. case BRANCH_JUGE: op = opGtrEqUns; break; // Similarly, this is equivalent to always branching
  1495. case BRANCH_JUG: op = opGtrUns; break;
  1496. case BRANCH_JPAR: {
  1497. // This is pentium specific too; see below for more notes.
  1498. /* pCond
  1499. / \
  1500. Const opList
  1501. "LOGICALFLAGS8" / \
  1502. opBitAnd opNil
  1503. / \
  1504. opFlagCall opIntConst
  1505. / \ mask
  1506. Const opList
  1507. "SETFFLAGS" / \
  1508. P1 opList
  1509. / \
  1510. P2 opNil
  1511. */
  1512. Exp* flagsParam = ((Binary*)((Binary*)pCond)->getSubExp2())->getSubExp1();
  1513. Exp* test = flagsParam;
  1514. if (test->isSubscript())
  1515. test = ((RefExp*)test)->getSubExp1();
  1516. if (test->isTemp())
  1517. return false; // Just not propagated yet
  1518. int mask = 0;
  1519. if (flagsParam->getOper() == opBitAnd) {
  1520. Exp* setFlagsParam = ((Binary*)flagsParam)->getSubExp2();
  1521. if (setFlagsParam->isIntConst())
  1522. mask = ((Const*)setFlagsParam)->getInt();
  1523. }
  1524. // Sometimes the mask includes the 0x4 bit, but we expect that to be off all the time. So effectively
  1525. // the branch is for any one of the (one or two) bits being on. For example, if the mask is 0x41, we
  1526. // are branching of less (0x1) or equal (0x41).
  1527. mask &= 0x41;
  1528. OPER op;
  1529. switch (mask) {
  1530. case 0:
  1531. LOG << "WARNING: unhandled pentium branch if parity with pCond = " << pCond << "\n";
  1532. return false;
  1533. case 1:
  1534. op = opLess;
  1535. break;
  1536. case 0x40:
  1537. op = opEquals;
  1538. break;
  1539. case 0x41:
  1540. op = opLessEq;
  1541. break;
  1542. default:
  1543. op = opWild; // Not possible, but avoid a compiler warning
  1544. break;
  1545. }
  1546. pCond = new Binary(op,
  1547. flagsParam->getSubExp1()->getSubExp2()->getSubExp1()->clone(),
  1548. flagsParam->getSubExp1()->getSubExp2()->getSubExp2()->getSubExp1() ->clone());
  1549. return true; // This is a floating point comparison
  1550. }
  1551. default:
  1552. break;
  1553. }
  1554. if (op != opWild) {
  1555. pCond = new Binary(op,
  1556. pCond->getSubExp2()->getSubExp1()->clone(),
  1557. new Const(0));
  1558. }
  1559. }
  1560. else if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "SETFFLAGS", 9) == 0) {
  1561. // Exp *e = pCond;
  1562. OPER op = opWild;
  1563. switch (jtCond) {
  1564. case BRANCH_JE: op = opEquals; break;
  1565. case BRANCH_JNE: op = opNotEqual; break;
  1566. case BRANCH_JMI: op = opLess; break;
  1567. case BRANCH_JPOS: op = opGtrEq; break;
  1568. case BRANCH_JSL: op = opLess; break;
  1569. case BRANCH_JSLE: op = opLessEq; break;
  1570. case BRANCH_JSGE: op = opGtrEq; break;
  1571. case BRANCH_JSG: op = opGtr; break;
  1572. default:
  1573. break;
  1574. }
  1575. if (op != opWild) {
  1576. pCond = new Binary(op,
  1577. pCond->getSubExp2()->getSubExp1()->clone(),
  1578. pCond->getSubExp2()->getSubExp2()->getSubExp1() ->clone());
  1579. }
  1580. }
  1581. // ICK! This is all PENTIUM SPECIFIC... needs to go somewhere else.
  1582. // Might be of the form (SETFFLAGS(...) & MASK) RELOP INTCONST where MASK could be a combination of 1, 4, and 40,
  1583. // and relop could be == or ~=. There could also be an XOR 40h after the AND
  1584. // From MSVC 6, we can also see MASK = 0x44, 0x41, 0x5 followed by jump if (even) parity (see above)
  1585. // %fflags = 0..0.0 00 >
  1586. // %fflags = 0..0.1 01 <
  1587. // %fflags = 1..0.0 40 =
  1588. // %fflags = 1..1.1 45 not comparable
  1589. // Example: (SETTFLAGS(...) & 1) ~= 0
  1590. // left = SETFFLAGS(...) & 1
  1591. // left1 = SETFFLAGS(...) left2 = int 1, k = 0, mask = 1
  1592. else if (condOp == opEquals || condOp == opNotEqual) {
  1593. Exp* left = ((Binary*)pCond)->getSubExp1();
  1594. Exp* right = ((Binary*)pCond)->getSubExp2();
  1595. bool hasXor40 = false;
  1596. if (left->getOper() == opBitXor && right->isIntConst()) {
  1597. Exp* r2 = ((Binary*)left)->getSubExp2();
  1598. if (r2->isIntConst()) {
  1599. int k2 = ((Const*)r2)->getInt();
  1600. if (k2 == 0x40) {
  1601. hasXor40 = true;
  1602. left = ((Binary*)left)->getSubExp1();
  1603. }
  1604. }
  1605. }
  1606. if (left->getOper() == opBitAnd && right->isIntConst()) {
  1607. Exp* left1 = ((Binary*)left)->getSubExp1();
  1608. Exp* left2 = ((Binary*)left)->getSubExp2();
  1609. int k = ((Const*)right)->getInt();
  1610. // Only interested in 40, 1
  1611. k &= 0x41;
  1612. if (left1->getOper() == opFlagCall && left2->isIntConst()) {
  1613. int mask = ((Const*)left2)->getInt();
  1614. // Only interested in 1, 40
  1615. mask &= 0x41;
  1616. OPER op = opWild;
  1617. if (hasXor40) {
  1618. assert(k == 0);
  1619. op = condOp;
  1620. } else {
  1621. switch (mask) {
  1622. case 1:
  1623. if (condOp == opEquals && k == 0 || condOp == opNotEqual && k == 1)
  1624. op = opGtrEq;
  1625. else
  1626. op = opLess;
  1627. break;
  1628. case 0x40:
  1629. if (condOp == opEquals && k == 0 || condOp == opNotEqual && k == 0x40)
  1630. op = opNotEqual;
  1631. else
  1632. op = opEquals;
  1633. break;
  1634. case 0x41:
  1635. switch (k) {
  1636. case 0:
  1637. if (condOp == opEquals) op = opGtr;
  1638. else op = opLessEq;
  1639. break;
  1640. case 1:
  1641. if (condOp == opEquals) op = opLess;
  1642. else op = opGtrEq;
  1643. break;
  1644. case 0x40:
  1645. if (condOp == opEquals) op = opEquals;
  1646. else op = opNotEqual;
  1647. break;
  1648. default:
  1649. std::cerr << "BranchStatement::simplify: k is " << std::hex << k << "\n";
  1650. assert(0);
  1651. }
  1652. break;
  1653. default:
  1654. std::cerr << "BranchStatement::simplify: Mask is " << std::hex << mask << "\n";
  1655. assert(0);
  1656. }
  1657. }
  1658. if (op != opWild) {
  1659. pCond = new Binary(op,
  1660. left1->getSubExp2()->getSubExp1(),
  1661. left1->getSubExp2()->getSubExp2()->getSubExp1());
  1662. return true; // This is now a float comparison
  1663. }
  1664. }
  1665. }
  1666. }
  1667. return false;
  1668. }
  1669. void BranchStatement::simplify() {
  1670. if (pCond) {
  1671. if (condToRelational(pCond, jtCond))
  1672. bFloat = true;
  1673. }
  1674. }
  1675. /**********************************
  1676. * CaseStatement methods
  1677. **********************************/
  1678. /*==============================================================================
  1679. * FUNCTION: CaseStatement::CaseStatement
  1680. * OVERVIEW: Constructor.
  1681. * PARAMETERS: None
  1682. * RETURNS: N/a
  1683. *============================================================================*/
  1684. CaseStatement::CaseStatement() :
  1685. pSwitchInfo(NULL) {
  1686. kind = STMT_CASE;
  1687. }
  1688. /*==============================================================================
  1689. * FUNCTION: CaseStatement::~CaseStatement
  1690. * OVERVIEW: Destructor
  1691. * NOTE: Don't delete the pSwitchVar; it's always a copy of something else (so don't delete twice)
  1692. * PARAMETERS: None
  1693. * RETURNS: N/a
  1694. *============================================================================*/
  1695. CaseStatement::~CaseStatement() {
  1696. if (pSwitchInfo)
  1697. ;//delete pSwitchInfo;
  1698. }
  1699. /*==============================================================================
  1700. * FUNCTION: CaseStatement::getSwitchInfo
  1701. * OVERVIEW: Return a pointer to a struct with switch information in it
  1702. * PARAMETERS: <none>
  1703. * RETURNS: a semantic string
  1704. *============================================================================*/
  1705. SWITCH_INFO* CaseStatement::getSwitchInfo() {
  1706. return pSwitchInfo;
  1707. }
  1708. /*==============================================================================
  1709. * FUNCTION: CaseStatement::setSwitchInfo
  1710. * OVERVIEW: Set a pointer to a SWITCH_INFO struct
  1711. * PARAMETERS: Pointer to SWITCH_INFO struct
  1712. * RETURNS: <nothing>
  1713. *============================================================================*/
  1714. void CaseStatement::setSwitchInfo(SWITCH_INFO* psi) {
  1715. pSwitchInfo = psi;
  1716. }
  1717. /*==============================================================================
  1718. * FUNCTION: CaseStatement::searchAndReplace
  1719. * OVERVIEW: Replace all instances of search with replace.
  1720. * PARAMETERS: search - a location to search for
  1721. * replace - the expression with which to replace it
  1722. * cc - ignored
  1723. * RETURNS: True if any change
  1724. *============================================================================*/
  1725. bool CaseStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  1726. bool ch = GotoStatement::searchAndReplace(search, replace, cc);
  1727. bool ch2 = false;
  1728. if (pSwitchInfo && pSwitchInfo->pSwitchVar)
  1729. pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->searchReplaceAll(search, replace, ch2);
  1730. return ch | ch2;
  1731. }
  1732. /*==============================================================================
  1733. * FUNCTION: CaseStatement::searchAll
  1734. * OVERVIEW: Find all instances of the search expression
  1735. * PARAMETERS: search - a location to search for
  1736. * result - a list which will have any matching exprs appended to it
  1737. * NOTES: search can't easily be made const
  1738. * RETURNS: true if there were any matches
  1739. *============================================================================*/
  1740. bool CaseStatement::searchAll(Exp* search, std::list<Exp*> &result) {
  1741. return GotoStatement::searchAll(search, result) ||
  1742. ( pSwitchInfo && pSwitchInfo->pSwitchVar && pSwitchInfo->pSwitchVar->searchAll(search, result) );
  1743. }
  1744. /*==============================================================================
  1745. * FUNCTION: CaseStatement::print
  1746. * OVERVIEW: Write a text representation to the given stream
  1747. * PARAMETERS: os: stream
  1748. * indent: number of columns to skip
  1749. * RETURNS: Nothing
  1750. *============================================================================*/
  1751. void CaseStatement::print(std::ostream& os, bool html) {
  1752. os << std::setw(4) << std::dec << number << " ";
  1753. if (html) {
  1754. os << "</td><td>";
  1755. os << "<a name=\"stmt" << std::dec << number << "\">";
  1756. }
  1757. if (pSwitchInfo == NULL) {
  1758. os << "CASE [";
  1759. if (pDest == NULL)
  1760. os << "*no dest*";
  1761. else os << pDest;
  1762. os << "]";
  1763. } else
  1764. os << "SWITCH(" << pSwitchInfo->pSwitchVar << ")\n";
  1765. if (html)
  1766. os << "</a></td>";
  1767. }
  1768. /*==============================================================================
  1769. * FUNCTION: CaseStatement::clone
  1770. * OVERVIEW: Deep copy clone
  1771. * PARAMETERS: <none>
  1772. * RETURNS: Pointer to a new Statement that is a clone of this one
  1773. *============================================================================*/
  1774. Statement* CaseStatement::clone() {
  1775. CaseStatement* ret = new CaseStatement();
  1776. ret->pDest = pDest->clone();
  1777. ret->m_isComputed = m_isComputed;
  1778. ret->pSwitchInfo = new SWITCH_INFO;
  1779. *ret->pSwitchInfo = *pSwitchInfo;
  1780. ret->pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->clone();
  1781. // Statement members
  1782. ret->pbb = pbb;
  1783. ret->proc = proc;
  1784. ret->number = number;
  1785. return ret;
  1786. }
  1787. // visit this stmt
  1788. bool CaseStatement::accept(StmtVisitor* visitor) {
  1789. return visitor->visit(this);
  1790. }
  1791. void CaseStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  1792. // dont generate any code for switches, they will be handled by the bb
  1793. }
  1794. bool CaseStatement::usesExp(Exp *e) {
  1795. // Before a switch statement is recognised, pDest is non null
  1796. if (pDest)
  1797. return *pDest == *e;
  1798. // After a switch statement is recognised, pDest is null, and pSwitchInfo->pSwitchVar takes over
  1799. if (pSwitchInfo->pSwitchVar)
  1800. return *pSwitchInfo->pSwitchVar == *e;
  1801. return false;
  1802. }
  1803. void CaseStatement::simplify() {
  1804. if (pDest)
  1805. pDest = pDest->simplify();
  1806. else if (pSwitchInfo && pSwitchInfo->pSwitchVar)
  1807. pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->simplify();
  1808. }
  1809. /**********************************
  1810. * CallStatement methods
  1811. **********************************/
  1812. /*==============================================================================
  1813. * FUNCTION: CallStatement::CallStatement
  1814. * OVERVIEW: Constructor for a call
  1815. * PARAMETERS: None
  1816. * RETURNS: <nothing>
  1817. *============================================================================*/
  1818. CallStatement::CallStatement(): returnAfterCall(false), calleeReturn(NULL) {
  1819. kind = STMT_CALL;
  1820. procDest = NULL;
  1821. signature = NULL;
  1822. }
  1823. /*==============================================================================
  1824. * FUNCTION: CallStatement::~CallStatement
  1825. * OVERVIEW: Destructor
  1826. * PARAMETERS: BB - the enclosing basic block of this call
  1827. * RETURNS: <nothing>
  1828. *============================================================================*/
  1829. CallStatement::~CallStatement() {
  1830. }
  1831. // Temporarily needed for ad-hoc type analysis
  1832. int CallStatement::findDefine(Exp *e) {
  1833. StatementList::iterator rr;
  1834. int i = 0;
  1835. for (rr = defines.begin(); rr != defines.end(); ++rr, ++i) {
  1836. Exp* ret = ((Assignment*)*rr)->getLeft();
  1837. if (*ret == *e)
  1838. return i;
  1839. }
  1840. return -1;
  1841. }
  1842. Exp *CallStatement::getProven(Exp *e) {
  1843. if (procDest)
  1844. return procDest->getProven(e);
  1845. return NULL;
  1846. }
  1847. // Localise only components of e, i.e. xxx if e is m[xxx]
  1848. void CallStatement::localiseComp(Exp* e) {
  1849. if (e->isMemOf()) {
  1850. ((Location*)e)->setSubExp1(localiseExp(((Location*)e)->getSubExp1()));
  1851. }
  1852. }
  1853. // Substitute the various components of expression e with the appropriate reaching definitions.
  1854. // Used in e.g. fixCallBypass (via the CallBypasser). Locations defined in this call are replaced with their proven
  1855. // values, which are in terms of the initial values at the start of the call (reaching definitions at the call)
  1856. Exp* CallStatement::localiseExp(Exp* e) {
  1857. if (!defCol.isInitialised()) return e; // Don't attempt to subscript if the data flow not started yet
  1858. Localiser l(this);
  1859. e = e->clone()->accept(&l);
  1860. return e;
  1861. }
  1862. // Find the definition for the given expression, using the embedded Collector object
  1863. // Was called findArgument(), and used implicit arguments and signature parameters
  1864. // Note: must only operator on unsubscripted locations, otherwise it is invalid
  1865. Exp* CallStatement::findDefFor(Exp *e) {
  1866. return defCol.findDefFor(e);
  1867. }
  1868. Type *CallStatement::getArgumentType(int i) {
  1869. assert(i < (int)arguments.size());
  1870. StatementList::iterator aa = arguments.begin();
  1871. my_advance(aa, i);
  1872. return ((Assign*)(*aa))->getType();
  1873. }
  1874. /*==============================================================================
  1875. * FUNCTION: CallStatement::setArguments
  1876. * OVERVIEW: Set the arguments of this call.
  1877. * PARAMETERS: arguments - the list of locations to set the arguments to (for testing)
  1878. * RETURNS: <nothing>
  1879. *============================================================================*/
  1880. void CallStatement::setArguments(StatementList& args) {
  1881. arguments.clear();
  1882. arguments.append(args);
  1883. StatementList::iterator ll;
  1884. for (ll = arguments.begin(); ll != arguments.end(); ++ll) {
  1885. ((Assign*)*ll)->setProc(proc);
  1886. ((Assign*)*ll)->setBB(pbb);
  1887. }
  1888. }
  1889. /*==============================================================================
  1890. * FUNCTION: CallStatement::setSigArguments
  1891. * OVERVIEW: Set the arguments of this call based on signature info
  1892. * NOTE: Should only be called for calls to library functions
  1893. * PARAMETERS: None
  1894. * RETURNS: <nothing>
  1895. *============================================================================*/
  1896. void CallStatement::setSigArguments() {
  1897. if (signature) return; // Already done
  1898. if (procDest == NULL)
  1899. // FIXME: Need to check this
  1900. return;
  1901. // Clone here because each call to procDest could have a different signature, modified by ellipsisProcessing
  1902. signature = procDest->getSignature()->clone();
  1903. procDest->addCaller(this);
  1904. if (!procDest->isLib())
  1905. return; // Using dataflow analysis now
  1906. int n = signature->getNumParams();
  1907. int i;
  1908. arguments.clear();
  1909. for (i = 0; i < n; i++) {
  1910. Exp *e = signature->getArgumentExp(i);
  1911. assert(e);
  1912. Location *l = dynamic_cast<Location*>(e);
  1913. if (l) {
  1914. l->setProc(proc); // Needed?
  1915. }
  1916. Assign* as = new Assign(signature->getParamType(i)->clone(), e->clone(), e->clone());
  1917. as->setProc(proc);
  1918. as->setBB(pbb);
  1919. as->setNumber(number); // So fromSSAform will work later. But note: this call is probably not numbered yet!
  1920. as->setParent(this);
  1921. arguments.append(as);
  1922. }
  1923. // initialize returns
  1924. // FIXME: anything needed here?
  1925. }
  1926. bool CallStatement::search(Exp* search, Exp*& result) {
  1927. bool found = GotoStatement::search(search, result);
  1928. if (found) return true;
  1929. StatementList::iterator ss;
  1930. for (ss = defines.begin(); ss != defines.end(); ++ss) {
  1931. if ((*ss)->search(search, result))
  1932. return true;
  1933. }
  1934. for (ss = arguments.begin(); ss != arguments.end(); ++ss) {
  1935. if ((*ss)->search(search, result))
  1936. return true;
  1937. }
  1938. return false;
  1939. }
  1940. /*==============================================================================
  1941. * FUNCTION: CallStatement::searchAndReplace
  1942. * OVERVIEW: Replace all instances of search with replace.
  1943. * PARAMETERS: search - a location to search for
  1944. * replace - the expression with which to replace it
  1945. * cc - true to replace in collectors
  1946. * RETURNS: True if any change
  1947. *============================================================================*/
  1948. bool CallStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  1949. bool change = GotoStatement::searchAndReplace(search, replace, cc);
  1950. StatementList::iterator ss;
  1951. // FIXME: MVE: Check if we ever want to change the LHS of arguments or defines...
  1952. for (ss = defines.begin(); ss != defines.end(); ++ss)
  1953. change |= (*ss)->searchAndReplace(search, replace, cc);
  1954. for (ss = arguments.begin(); ss != arguments.end(); ++ss)
  1955. change |= (*ss)->searchAndReplace(search, replace, cc);
  1956. if (cc) {
  1957. DefCollector::iterator dd;
  1958. for (dd = defCol.begin(); dd != defCol.end(); ++dd)
  1959. change |= (*dd)->searchAndReplace(search, replace, cc);
  1960. }
  1961. return change;
  1962. }
  1963. /*==============================================================================
  1964. * FUNCTION: CallStatement::searchAll
  1965. * OVERVIEW: Find all instances of the search expression
  1966. * PARAMETERS: search - a location to search for
  1967. * result - a list which will have any matching exprs appended to it
  1968. * RETURNS: true if there were any matches
  1969. *============================================================================*/
  1970. bool CallStatement::searchAll(Exp* search, std::list<Exp *>& result) {
  1971. bool found = GotoStatement::searchAll(search, result);
  1972. StatementList::iterator ss;
  1973. for (ss = defines.begin(); ss != defines.end(); ++ss) {
  1974. if ((*ss)->searchAll(search, result))
  1975. found = true;
  1976. }
  1977. for (ss = arguments.begin(); ss != arguments.end(); ++ss) {
  1978. if ((*ss)->searchAll(search, result))
  1979. found = true;
  1980. }
  1981. return found;
  1982. }
  1983. /*==============================================================================
  1984. * FUNCTION: CallStatement::print
  1985. * OVERVIEW: Write a text representation of this RTL to the given stream
  1986. * PARAMETERS: os: stream to write to
  1987. * RETURNS: Nothing
  1988. *============================================================================*/
  1989. void CallStatement::print(std::ostream& os, bool html) {
  1990. os << std::setw(4) << std::dec << number << " ";
  1991. if (html) {
  1992. os << "</td><td>";
  1993. os << "<a name=\"stmt" << std::dec << number << "\">";
  1994. }
  1995. // Define(s), if any
  1996. if (defines.size()) {
  1997. if (defines.size() > 1) os << "{";
  1998. StatementList::iterator rr;
  1999. bool first = true;
  2000. for (rr = defines.begin(); rr != defines.end(); ++rr) {
  2001. assert((*rr)->isAssignment());
  2002. Assignment *as = (Assignment*)*rr;
  2003. if (first)
  2004. first = false;
  2005. else
  2006. os << ", ";
  2007. os << "*" << as->getType() << "* " << as->getLeft();
  2008. if (as->isAssign())
  2009. os << " := " << ((Assign*)as)->getRight();
  2010. }
  2011. if (defines.size() > 1) os << "}";
  2012. os << " := ";
  2013. } else if (isChildless()) {
  2014. if (html)
  2015. os << "&lt;all&gt; := ";
  2016. else
  2017. os << "<all> := ";
  2018. }
  2019. os << "CALL ";
  2020. if (procDest)
  2021. os << procDest->getName();
  2022. else if (pDest == NULL)
  2023. os << "*no dest*";
  2024. else {
  2025. if (pDest->isIntConst())
  2026. os << "0x" << std::hex << ((Const*)pDest)->getInt();
  2027. else
  2028. pDest->print(os, html); // Could still be an expression
  2029. }
  2030. // Print the actual arguments of the call
  2031. if (isChildless()) {
  2032. if (html)
  2033. os << "(&lt;all&gt;)";
  2034. else
  2035. os << "(<all>)";
  2036. } else {
  2037. os << "(\n";
  2038. StatementList::iterator aa;
  2039. for (aa = arguments.begin(); aa != arguments.end(); ++aa) {
  2040. os << " ";
  2041. ((Assignment*)*aa)->printCompact(os, html);
  2042. os << "\n";
  2043. }
  2044. os << " )";
  2045. }
  2046. #if 1
  2047. // Collected reaching definitions
  2048. if (html)
  2049. os << "<br>";
  2050. else
  2051. os << "\n ";
  2052. os << "Reaching definitions: ";
  2053. defCol.print(os, html);
  2054. if (html)
  2055. os << "<br>";
  2056. else
  2057. os << "\n ";
  2058. os << "Live variables: ";
  2059. useCol.print(os, html);
  2060. #endif
  2061. if (html)
  2062. os << "</a></td>";
  2063. }
  2064. /*==============================================================================
  2065. * FUNCTION: CallStatement::setReturnAfterCall
  2066. * OVERVIEW: Sets a bit that says that this call is effectively followed by a return. This happens e.g. on
  2067. * Sparc when there is a restore in the delay slot of the call
  2068. * PARAMETERS: b: true if this is to be set; false to clear the bit
  2069. * RETURNS: <nothing>
  2070. *============================================================================*/
  2071. void CallStatement::setReturnAfterCall(bool b) {
  2072. returnAfterCall = b;
  2073. }
  2074. /*==============================================================================
  2075. * FUNCTION: CallStatement::isReturnAfterCall
  2076. * OVERVIEW: Tests a bit that says that this call is effectively followed by a return. This happens e.g. on
  2077. * Sparc when there is a restore in the delay slot of the call
  2078. * PARAMETERS: none
  2079. * RETURNS: True if this call is effectively followed by a return
  2080. *============================================================================*/
  2081. bool CallStatement::isReturnAfterCall() {
  2082. return returnAfterCall;
  2083. }
  2084. /*==============================================================================
  2085. * FUNCTION: CallStatement::clone
  2086. * OVERVIEW: Deep copy clone
  2087. * PARAMETERS: <none>
  2088. * RETURNS: Pointer to a new Statement, a clone of this CallStatement
  2089. *============================================================================*/
  2090. Statement* CallStatement::clone() {
  2091. CallStatement* ret = new CallStatement();
  2092. ret->pDest = pDest->clone();
  2093. ret->m_isComputed = m_isComputed;
  2094. StatementList::iterator ss;
  2095. for (ss = arguments.begin(); ss != arguments.end(); ++ss)
  2096. ret->arguments.append((*ss)->clone());
  2097. for (ss = defines.begin(); ss != defines.end(); ++ss)
  2098. ret->defines.append((*ss)->clone());
  2099. // Statement members
  2100. ret->pbb = pbb;
  2101. ret->proc = proc;
  2102. ret->number = number;
  2103. return ret;
  2104. }
  2105. // visit this stmt
  2106. bool CallStatement::accept(StmtVisitor* visitor) {
  2107. return visitor->visit(this);
  2108. }
  2109. Proc* CallStatement::getDestProc() {
  2110. return procDest;
  2111. }
  2112. void CallStatement::setDestProc(Proc* dest) {
  2113. assert(dest);
  2114. // assert(procDest == NULL); // No: not convenient for unit testing
  2115. procDest = dest;
  2116. }
  2117. void CallStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  2118. Proc *p = getDestProc();
  2119. if (p == NULL && isComputed()) {
  2120. hll->AddIndCallStatement(indLevel, pDest, arguments, calcResults());
  2121. return;
  2122. }
  2123. StatementList* results = calcResults();
  2124. #if 0
  2125. LOG << "call: " << this;
  2126. LOG << " in proc " << proc->getName() << "\n";
  2127. #endif
  2128. assert(p);
  2129. if (Boomerang::get()->noDecompile) {
  2130. if (procDest->getSignature()->getNumReturns() > 0) {
  2131. Assign* as = new Assign(new IntegerType(), new Unary(opRegOf, new Const(24)), new Unary(opRegOf, new Const(24)));
  2132. as->setProc(proc);
  2133. as->setBB(pbb);
  2134. results->append(as);
  2135. }
  2136. // some hacks
  2137. if (std::string(p->getName()) == "printf" ||
  2138. std::string(p->getName()) == "scanf") {
  2139. for (int i = 1; i < 3; i++) {
  2140. Exp *e = signature->getArgumentExp(i);
  2141. assert(e);
  2142. Location *l = dynamic_cast<Location*>(e);
  2143. if (l) {
  2144. l->setProc(proc); // Needed?
  2145. }
  2146. Assign* as = new Assign(signature->getParamType(i), e->clone(), e->clone());
  2147. as->setProc(proc);
  2148. as->setBB(pbb);
  2149. as->setNumber(number); // So fromSSAform will work later
  2150. arguments.append(as);
  2151. }
  2152. }
  2153. }
  2154. if (p->isLib() && *p->getSignature()->getPreferedName()) {
  2155. hll->AddCallStatement(indLevel, p, p->getSignature()->getPreferedName(), arguments, results);
  2156. } else
  2157. hll->AddCallStatement(indLevel, p, p->getName(), arguments, results);
  2158. }
  2159. void CallStatement::simplify() {
  2160. GotoStatement::simplify();
  2161. StatementList::iterator ss;
  2162. for (ss = arguments.begin(); ss != arguments.end(); ++ss)
  2163. (*ss)->simplify();
  2164. for (ss = defines.begin(); ss != defines.end(); ++ss)
  2165. (*ss)->simplify();
  2166. }
  2167. bool GotoStatement::usesExp(Exp* e) {
  2168. Exp* where;
  2169. return (pDest->search(e, where));
  2170. }
  2171. bool CallStatement::usesExp(Exp *e) {
  2172. if (GotoStatement::usesExp(e)) return true;
  2173. StatementList::iterator ss;
  2174. for (ss = arguments.begin(); ss != arguments.end(); ++ss)
  2175. if ((*ss)->usesExp(e)) return true;
  2176. for (ss = defines.begin(); ss != defines.end(); ++ss)
  2177. if ((*ss)->usesExp(e)) return true;
  2178. return false;
  2179. }
  2180. void CallStatement::getDefinitions(LocationSet &defs) {
  2181. StatementList::iterator dd;
  2182. for (dd = defines.begin(); dd != defines.end(); ++dd)
  2183. defs.insert(((Assignment*)*dd)->getLeft());
  2184. // Childless calls are supposed to define everything. In practice they don't really define things like %pc, so we
  2185. // need some extra logic in getTypeFor()
  2186. if (isChildless() && !Boomerang::get()->assumeABI)
  2187. defs.insert(new Terminal(opDefineAll));
  2188. }
  2189. // Attempt to convert this call, if indirect, to a direct call.
  2190. // NOTE: at present, we igore the possibility that some other statement will modify the global. This is a serious
  2191. // limitation!!
  2192. bool CallStatement::convertToDirect() {
  2193. if (!m_isComputed)
  2194. return false;
  2195. bool convertIndirect = false;
  2196. Exp *e = pDest;
  2197. if (pDest->isSubscript()) {
  2198. Statement* def = ((RefExp*)e)->getDef();
  2199. if (def && !def->isImplicit())
  2200. return false; // If an already defined global, don't convert
  2201. e = ((RefExp*)e)->getSubExp1();
  2202. }
  2203. if (e->getOper() == opArrayIndex &&
  2204. ((Binary*)e)->getSubExp2()->isIntConst() &&
  2205. ((Const*)(((Binary*)e)->getSubExp2()))->getInt() == 0)
  2206. e = ((Binary*)e)->getSubExp1();
  2207. // Can actually have name{0}[0]{0} !!
  2208. if (e->isSubscript())
  2209. e = ((RefExp*)e)->getSubExp1();
  2210. if (e->isIntConst()) {
  2211. // ADDRESS u = (ADDRESS)((Const*)e)->getInt();
  2212. // Just convert it to a direct call!
  2213. // FIXME: to be completed
  2214. } else if (e->isMemOf()) {
  2215. // It might be a global that has not been processed yet
  2216. Exp* sub = ((Unary*)e)->getSubExp1();
  2217. if (sub->isIntConst()) {
  2218. // m[K]: convert it to a global right here
  2219. ADDRESS u = (ADDRESS)((Const*)sub)->getInt();
  2220. proc->getProg()->globalUsed(u);
  2221. const char *nam = proc->getProg()->getGlobalName(u);
  2222. e = Location::global(nam, proc);
  2223. pDest = new RefExp(e, NULL);
  2224. }
  2225. }
  2226. if (!e->isGlobal()) {
  2227. return false;
  2228. }
  2229. char *nam = ((Const*)e->getSubExp1())->getStr();
  2230. Prog* prog = proc->getProg();
  2231. ADDRESS gloAddr = prog->getGlobalAddr(nam);
  2232. ADDRESS dest = prog->readNative4(gloAddr);
  2233. // We'd better do some limit checking on the value. This does not guarantee that it's a valid proc pointer, but it
  2234. // may help
  2235. if (dest < prog->getLimitTextLow() || dest > prog->getLimitTextHigh())
  2236. return false; // Not a valid proc pointer
  2237. Proc *p = prog->findProc(nam);
  2238. bool bNewProc = p == NULL;
  2239. if (bNewProc)
  2240. p = prog->setNewProc(dest);
  2241. if (VERBOSE)
  2242. LOG << (bNewProc ? "new" : "existing") << " procedure for call to global '" << nam << " is " << p->getName() <<
  2243. "\n";
  2244. // we need to:
  2245. // 1) replace the current return set with the return set of the new procDest
  2246. // 2) call fixCallBypass (now fixCallAndPhiRefs) on the enclosing procedure
  2247. // 3) fix the arguments (this will only affect the implicit arguments, the regular arguments should
  2248. // be empty at this point)
  2249. // 3a replace current arguments with those of the new proc
  2250. // 3b copy the signature from the new proc
  2251. // 4) change this to a non-indirect call
  2252. procDest = p;
  2253. Signature *sig = p->getSignature();
  2254. // pDest is currently still global5{-}, but we may as well make it a constant now, since that's how it will be
  2255. // treated now
  2256. pDest = new Const(dest);
  2257. // 1
  2258. // 2
  2259. proc->fixCallAndPhiRefs();
  2260. // 3
  2261. // 3a Do the same with the regular arguments
  2262. arguments.clear();
  2263. for (unsigned i = 0; i < sig->getNumParams(); i++) {
  2264. Exp* a = sig->getParamExp(i);
  2265. Assign* as = new Assign(new VoidType(), a->clone(), a->clone());
  2266. as->setProc(proc);
  2267. as->setBB(pbb);
  2268. arguments.append(as);
  2269. }
  2270. // std::cerr << "Step 3a: arguments now: ";
  2271. // StatementList::iterator xx; for (xx = arguments.begin(); xx != arguments.end(); ++xx) {
  2272. // ((Assignment*)*xx)->printCompact(std::cerr); std::cerr << ", ";
  2273. // } std::cerr << "\n";
  2274. // implicitArguments = newimpargs;
  2275. // assert((int)implicitArguments.size() == sig->getNumImplicitParams());
  2276. // 3b
  2277. signature = p->getSignature()->clone();
  2278. // 4
  2279. m_isComputed = false;
  2280. proc->undoComputedBB(this);
  2281. proc->addCallee(procDest);
  2282. procDest->printDetailsXML();
  2283. convertIndirect = true;
  2284. if (VERBOSE)
  2285. LOG << "Result of convertToDirect: " << this << "\n";
  2286. return convertIndirect;
  2287. }
  2288. Exp* CallStatement::getArgumentExp(int i)
  2289. {
  2290. assert(i < (int)arguments.size());
  2291. StatementList::iterator aa = arguments.begin();
  2292. my_advance(aa, i);
  2293. return ((Assign*)*aa)->getRight();
  2294. }
  2295. void CallStatement::setArgumentExp(int i, Exp *e)
  2296. {
  2297. assert(i < (int)arguments.size());
  2298. StatementList::iterator aa = arguments.begin();
  2299. my_advance(aa, i);
  2300. Exp*& a = ((Assign*)*aa)->getRightRef();
  2301. a = e->clone();
  2302. }
  2303. int CallStatement::getNumArguments()
  2304. {
  2305. return arguments.size();
  2306. }
  2307. void CallStatement::setNumArguments(int n) {
  2308. int oldSize = arguments.size();
  2309. if (oldSize > n) {
  2310. StatementList::iterator aa = arguments.begin();
  2311. my_advance(aa, n);
  2312. arguments.erase(aa, arguments.end());
  2313. }
  2314. // MVE: check if these need extra propagation
  2315. for (int i = oldSize; i < n; i++) {
  2316. Exp* a = procDest->getSignature()->getArgumentExp(i);
  2317. Type *ty = procDest->getSignature()->getParamType(i);
  2318. if (ty == NULL && oldSize)
  2319. ty = procDest->getSignature()->getParamType(oldSize-1);
  2320. if (ty == NULL)
  2321. ty = new VoidType();
  2322. Assign* as = new Assign(ty, a->clone(), a->clone());
  2323. as->setProc(proc);
  2324. as->setBB(pbb);
  2325. arguments.append(as);
  2326. }
  2327. }
  2328. void CallStatement::removeArgument(int i)
  2329. {
  2330. StatementList::iterator aa = arguments.begin();
  2331. my_advance(aa, i);
  2332. arguments.erase(aa);
  2333. }
  2334. // Processes each argument of a CallStatement, and the RHS of an Assign. Ad-hoc type analysis only.
  2335. Exp *processConstant(Exp *e, Type *t, Prog *prog, UserProc* proc, ADDRESS stmt) {
  2336. if (t == NULL) return e;
  2337. NamedType *nt = NULL;
  2338. if (t->isNamed()) {
  2339. nt = (NamedType*)t;
  2340. t = ((NamedType*)t)->resolvesTo();
  2341. }
  2342. if (t == NULL) return e;
  2343. // char* and a constant
  2344. if (e->isIntConst()) {
  2345. if (nt && (nt->getName() == static_cast<std::string>("LPCWSTR"))) {
  2346. ADDRESS u = ((Const*)e)->getAddr();
  2347. // TODO
  2348. LOG << "possible wide char string at " << u << "\n";
  2349. }
  2350. if (t->resolvesToPointer()) {
  2351. PointerType *pt = t->asPointer();
  2352. Type *points_to = pt->getPointsTo();
  2353. if (t->isCString()) {
  2354. ADDRESS u = ((Const*)e)->getAddr();
  2355. if (u != 0) { // can't do anything with NULL
  2356. char *str = prog->getStringConstant(u, true);
  2357. if (str) {
  2358. e = new Const(str);
  2359. // Check if we may have guessed this global incorrectly (usually as an array of char)
  2360. const char* nam = prog->getGlobalName(u);
  2361. if (nam) prog->setGlobalType(nam,
  2362. new PointerType(new CharType()));
  2363. } else {
  2364. proc->getProg()->globalUsed(u);
  2365. const char *nam = proc->getProg()->getGlobalName(u);
  2366. if (nam)
  2367. e = Location::global(nam, proc);
  2368. }
  2369. }
  2370. }
  2371. if (points_to->resolvesToFunc()) {
  2372. ADDRESS a = ((Const*)e)->getAddr();
  2373. if (VERBOSE || 1)
  2374. LOG << "found function pointer with constant value " << "of type " << pt->getCtype()
  2375. << " in statement at addr " << stmt << ". Decoding address " << a << "\n";
  2376. // the address can be zero, i.e., NULL, if so, ignore it.
  2377. if (a != 0) {
  2378. if (!Boomerang::get()->noDecodeChildren)
  2379. prog->decodeEntryPoint(a);
  2380. Proc *p = prog->findProc(a);
  2381. if (p) {
  2382. Signature *sig = points_to->asFunc()->getSignature()->clone();
  2383. if (sig->getName() == NULL ||
  2384. strlen(sig->getName()) == 0 ||
  2385. !strcmp(sig->getName(), "<ANON>") ||
  2386. prog->findProc(sig->getName()) != NULL)
  2387. sig->setName(p->getName());
  2388. else
  2389. p->setName(sig->getName());
  2390. sig->setForced(true);
  2391. p->setSignature(sig);
  2392. e = Location::global(p->getName(), proc);
  2393. }
  2394. }
  2395. }
  2396. } else if (t->resolvesToFloat()) {
  2397. e = new Ternary(opItof, new Const(32), new Const(t->getSize()), e);
  2398. }
  2399. }
  2400. return e;
  2401. }
  2402. Type* Assignment::getTypeFor(Exp* e) {
  2403. // assert(*lhs == *e); // No: local vs base expression
  2404. return type;
  2405. }
  2406. void Assignment::setTypeFor(Exp* e, Type* ty) {
  2407. // assert(*lhs == *e);
  2408. Type* oldType = type;
  2409. type = ty;
  2410. if (DEBUG_TA && oldType != ty)
  2411. LOG << " changed type of " << this << " (type was " << oldType->getCtype() << ")\n";
  2412. }
  2413. // Scan the returns for e. If found, return the type associated with that return
  2414. Type* CallStatement::getTypeFor(Exp* e) {
  2415. // The defines "cache" what the destination proc is defining
  2416. Assignment* as = defines.findOnLeft(e);
  2417. if (as != NULL)
  2418. return as->getType();
  2419. if (e->isPC())
  2420. // Special case: just return void*
  2421. return new PointerType(new VoidType);
  2422. return new VoidType;
  2423. }
  2424. void CallStatement::setTypeFor(Exp* e, Type* ty) {
  2425. Assignment* as = defines.findOnLeft(e);
  2426. if (as != NULL)
  2427. return as->setType(ty);
  2428. // See if it is in our reaching definitions
  2429. Exp* ref = defCol.findDefFor(e);
  2430. if (ref == NULL || !ref->isSubscript()) return;
  2431. Statement* def = ((RefExp*)ref)->getDef();
  2432. if (def == NULL) return;
  2433. def->setTypeFor(e, ty);
  2434. }
  2435. // This function has two jobs. One is to truncate the list of arguments based on the format string.
  2436. // The second is to add parameter types to the signature.
  2437. // If -Td is used, type analysis will be rerun with these changes.
  2438. bool CallStatement::ellipsisProcessing(Prog* prog) {
  2439. // if (getDestProc() == NULL || !getDestProc()->getSignature()->hasEllipsis())
  2440. if (getDestProc() == NULL || !signature->hasEllipsis())
  2441. return false;
  2442. // functions like printf almost always have too many args
  2443. std::string name(getDestProc()->getName());
  2444. int format = -1;
  2445. if ((name == "printf" || name == "scanf"))
  2446. format = 0;
  2447. else if (name == "sprintf" || name == "fprintf" || name == "sscanf")
  2448. format = 1;
  2449. else if (getNumArguments() && getArgumentExp(getNumArguments()-1)->isStrConst())
  2450. format = getNumArguments() - 1;
  2451. else return false;
  2452. if (VERBOSE)
  2453. LOG << "ellipsis processing for " << name << "\n";
  2454. char* formatStr = NULL;
  2455. Exp* formatExp = getArgumentExp(format);
  2456. // We sometimes see a[m[blah{...}]]
  2457. if (formatExp->isAddrOf()) {
  2458. formatExp = ((Unary*)formatExp)->getSubExp1();
  2459. if (formatExp->isSubscript())
  2460. formatExp = ((RefExp*)formatExp)->getSubExp1();
  2461. if (formatExp->isMemOf())
  2462. formatExp = ((Unary*)formatExp)->getSubExp1();
  2463. }
  2464. if (formatExp->isSubscript()) {
  2465. // Maybe it's defined to be a Const string
  2466. Statement* def = ((RefExp*)formatExp)->getDef();
  2467. if (def == NULL) return false; // Not all NULL refs get converted to implicits
  2468. if (def->isAssign()) {
  2469. // This would be unusual; propagation would normally take care of this
  2470. Exp* rhs = ((Assign*)def)->getRight();
  2471. if (rhs == NULL || !rhs->isStrConst()) return false;
  2472. formatStr = ((Const*)rhs)->getStr();
  2473. } else if (def->isPhi()) {
  2474. // More likely. Example: switch_gcc. Only need ONE candidate format string
  2475. PhiAssign* pa = (PhiAssign*)def;
  2476. int n = pa->getNumDefs();
  2477. for (int i=0; i < n; i++) {
  2478. def = pa->getStmtAt(i);
  2479. if (def == NULL) continue;
  2480. if (!def->isAssign()) continue;
  2481. Exp* rhs = ((Assign*)def)->getRight();
  2482. if (rhs == NULL || !rhs->isStrConst()) continue;
  2483. formatStr = ((Const*)rhs)->getStr();
  2484. break;
  2485. }
  2486. if (formatStr == NULL) return false;
  2487. } else return false;
  2488. } else if (formatExp->isStrConst()) {
  2489. formatStr = ((Const*)formatExp)->getStr();
  2490. } else return false;
  2491. // actually have to parse it
  2492. // Format string is: % [flags] [width] [.precision] [size] type
  2493. int n = 1; // Count the format string itself (may also be "format" more arguments)
  2494. char ch;
  2495. // Set a flag if the name of the function is scanf/sscanf/fscanf
  2496. bool isScanf = name == "scanf" || name.substr(1, 5) == "scanf";
  2497. char *p = formatStr;
  2498. while ((p = strchr(p, '%'))) {
  2499. p++; // Point past the %
  2500. bool veryLong = false; // %lld or %L
  2501. do {
  2502. ch = *p++; // Skip size and precisionA
  2503. switch (ch) {
  2504. case '*':
  2505. // Example: printf("Val: %*.*f\n", width, precision, val);
  2506. n++; // There is an extra parameter for the width or precision
  2507. // This extra parameter is of type integer, never int* (so pass false as last argument)
  2508. addSigParam(new IntegerType(), false);
  2509. continue;
  2510. case '-': case '+': case '#': case ' ':
  2511. // Flag. Ignore
  2512. continue;
  2513. case '.':
  2514. // Separates width and precision. Ignore.
  2515. continue;
  2516. case 'h': case 'l':
  2517. // size of half or long. Argument is usually still one word. Ignore.
  2518. // Exception: %llx
  2519. // TODO: handle architectures where l implies two words
  2520. // TODO: at least h has implications for scanf
  2521. if (*p == 'l') {
  2522. // %llx
  2523. p++; // Skip second l
  2524. veryLong = true;
  2525. }
  2526. continue;
  2527. case 'L':
  2528. // long. TODO: handle L for long doubles.
  2529. // n++; // At least chew up one more parameter so later types are correct
  2530. veryLong = true;
  2531. continue;
  2532. default:
  2533. if ('0' <= ch && ch <= '9') continue; // width or precision
  2534. break; // Else must be format type, handled below
  2535. }
  2536. break;
  2537. } while (1);
  2538. if (ch != '%') // Don't count %%
  2539. n++;
  2540. switch (ch) {
  2541. case 'd': case 'i': // Signed integer
  2542. addSigParam(new IntegerType(veryLong ? 64 : 32), isScanf);
  2543. break;
  2544. case 'u': case 'x': case 'X': case 'o': // Unsigned integer
  2545. addSigParam(new IntegerType(32, -1), isScanf);
  2546. break;
  2547. case 'f': case 'g': case 'G': case 'e': case 'E': // Various floating point formats
  2548. // Note that for scanf, %f means float, and %lf means double, whereas for printf, both of these mean
  2549. // double
  2550. addSigParam(new FloatType(veryLong ? 128 : (isScanf ? 32 : 64)), isScanf);// Note: may not be 64 bits
  2551. // for some archs
  2552. break;
  2553. case 's': // String
  2554. addSigParam(new PointerType(new ArrayType(new CharType)), isScanf);
  2555. break;
  2556. case 'c': // Char
  2557. addSigParam(new CharType, isScanf);
  2558. break;
  2559. case '%':
  2560. break; // Ignore %% (emits 1 percent char)
  2561. default:
  2562. LOG << "Unhandled format character " << ch << " in format string for call " << this << "\n";
  2563. }
  2564. }
  2565. setNumArguments(format + n);
  2566. signature->killEllipsis(); // So we don't do this again
  2567. return true;
  2568. }
  2569. // Make an assign suitable for use as an argument from a callee context expression
  2570. Assign* CallStatement::makeArgAssign(Type* ty, Exp* e) {
  2571. Exp* lhs = e->clone();
  2572. localiseComp(lhs); // Localise the components of lhs (if needed)
  2573. Exp* rhs = localiseExp(e->clone());
  2574. Assign* as = new Assign(ty, lhs, rhs);
  2575. as->setProc(proc);
  2576. as->setBB(pbb);
  2577. // It may need implicit converting (e.g. sp{-} -> sp{0})
  2578. Cfg* cfg = proc->getCFG();
  2579. if (cfg->implicitsDone()) {
  2580. ImplicitConverter ic(cfg);
  2581. StmtImplicitConverter sm(&ic, cfg);
  2582. as->accept(&sm);
  2583. }
  2584. return as;
  2585. }
  2586. // Helper function for the above
  2587. void CallStatement::addSigParam(Type* ty, bool isScanf) {
  2588. if (isScanf) ty = new PointerType(ty);
  2589. signature->addParameter(ty);
  2590. Exp* paramExp = signature->getParamExp(signature->getNumParams()-1);
  2591. if (VERBOSE)
  2592. LOG << " ellipsisProcessing: adding parameter " << paramExp << " of type " << ty->getCtype() << "\n";
  2593. if (arguments.size() < (unsigned)signature->getNumParams()) {
  2594. Assign* as = makeArgAssign(ty, paramExp);
  2595. arguments.append(as);
  2596. }
  2597. }
  2598. /**********************************
  2599. * ReturnStatement methods
  2600. **********************************/
  2601. /*==============================================================================
  2602. * FUNCTION: ReturnStatement::ReturnStatement
  2603. * OVERVIEW: Constructor.
  2604. * PARAMETERS: None
  2605. * RETURNS: <nothing>
  2606. *============================================================================*/
  2607. ReturnStatement::ReturnStatement() : retAddr(NO_ADDRESS) {
  2608. kind = STMT_RET;
  2609. }
  2610. /*==============================================================================
  2611. * FUNCTION: ReturnStatement::~ReturnStatement
  2612. * OVERVIEW: Destructor.
  2613. * PARAMETERS: <none>
  2614. * RETURNS: <nothing>
  2615. *============================================================================*/
  2616. ReturnStatement::~ReturnStatement() {
  2617. }
  2618. /*==============================================================================
  2619. * FUNCTION: ReturnStatement::clone
  2620. * OVERVIEW: Deep copy clone
  2621. * PARAMETERS: <none>
  2622. * RETURNS: Pointer to a new Statement, a clone of this ReturnStatement
  2623. *============================================================================*/
  2624. Statement* ReturnStatement::clone() {
  2625. ReturnStatement* ret = new ReturnStatement();
  2626. iterator rr;
  2627. for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
  2628. ret->modifieds.append((ImplicitAssign*)(*rr)->clone());
  2629. for (rr = returns.begin(); rr != returns.end(); ++rr)
  2630. ret->returns.append((Assignment*)(*rr)->clone());
  2631. ret->retAddr = retAddr;
  2632. ret->col.makeCloneOf(col);
  2633. // Statement members
  2634. ret->pbb = pbb;
  2635. ret->proc = proc;
  2636. ret->number = number;
  2637. return ret;
  2638. }
  2639. // visit this stmt
  2640. bool ReturnStatement::accept(StmtVisitor* visitor) {
  2641. return visitor->visit(this);
  2642. }
  2643. void ReturnStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  2644. hll->AddReturnStatement(indLevel, &getReturns());
  2645. }
  2646. void ReturnStatement::simplify() {
  2647. iterator it;
  2648. for (it = modifieds.begin(); it != modifieds.end(); it++)
  2649. (*it)->simplify();
  2650. for (it = returns.begin(); it != returns.end(); it++)
  2651. (*it)->simplify();
  2652. }
  2653. // Remove the return (if any) related to loc. Loc may or may not be subscripted
  2654. void ReturnStatement::removeReturn(Exp* loc) {
  2655. if (loc->isSubscript())
  2656. loc = ((Location*)loc)->getSubExp1();
  2657. iterator rr;
  2658. for (rr = returns.begin(); rr != returns.end(); ++rr) {
  2659. if (*((Assignment*)*rr)->getLeft() == *loc) {
  2660. returns.erase(rr);
  2661. return; // Assume only one definition
  2662. }
  2663. }
  2664. }
  2665. void ReturnStatement::addReturn(Assignment* a) {
  2666. returns.append(a);
  2667. }
  2668. bool ReturnStatement::search(Exp* search, Exp*& result) {
  2669. result = NULL;
  2670. ReturnStatement::iterator rr;
  2671. for (rr = begin(); rr != end(); ++rr) {
  2672. if ((*rr)->search(search, result))
  2673. return true;
  2674. }
  2675. return false;
  2676. }
  2677. bool ReturnStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  2678. bool change = false;
  2679. ReturnStatement::iterator rr;
  2680. for (rr = begin(); rr != end(); ++rr)
  2681. change |= (*rr)->searchAndReplace(search, replace, cc);
  2682. if (cc) {
  2683. DefCollector::iterator dd;
  2684. for (dd = col.begin(); dd != col.end(); ++dd)
  2685. change |= (*dd)->searchAndReplace(search, replace);
  2686. }
  2687. return change;
  2688. }
  2689. bool ReturnStatement::searchAll(Exp* search, std::list<Exp *>& result) {
  2690. bool found = false;
  2691. ReturnStatement::iterator rr;
  2692. for (rr = begin(); rr != end(); ++rr) {
  2693. if ((*rr)->searchAll(search, result))
  2694. found = true;
  2695. }
  2696. return found;
  2697. }
  2698. bool CallStatement::isDefinition() {
  2699. LocationSet defs;
  2700. getDefinitions(defs);
  2701. return defs.size() != 0;
  2702. }
  2703. bool ReturnStatement::usesExp(Exp *e) {
  2704. Exp *where;
  2705. ReturnStatement::iterator rr;
  2706. for (rr = begin(); rr != end(); ++rr) {
  2707. if ((*rr)->search(e, where))
  2708. return true;
  2709. }
  2710. return false;
  2711. }
  2712. /**********************************************************************
  2713. * BoolAssign methods
  2714. * These are for statements that set a destination (usually to 1 or 0)
  2715. * depending in a condition code (e.g. Pentium)
  2716. **********************************************************************/
  2717. /*==============================================================================
  2718. * FUNCTION: BoolAssign::BoolAssign
  2719. * OVERVIEW: Constructor.
  2720. * PARAMETERS: sz: size of the assignment
  2721. * RETURNS: <N/a>
  2722. *============================================================================*/
  2723. BoolAssign::BoolAssign(int sz): Assignment(NULL), jtCond((BRANCH_TYPE)0),
  2724. pCond(NULL), bFloat(false), size(sz) {
  2725. kind = STMT_BOOLASSIGN;
  2726. }
  2727. /*==============================================================================
  2728. * FUNCTION: BoolAssign::~BoolAssign
  2729. * OVERVIEW: Destructor
  2730. * PARAMETERS: None
  2731. * RETURNS: N/a
  2732. *============================================================================*/
  2733. BoolAssign::~BoolAssign() {
  2734. if (pCond)
  2735. ;//delete pCond;
  2736. }
  2737. /*==============================================================================
  2738. * FUNCTION: BoolAssign::setCondType
  2739. * OVERVIEW: Sets the BRANCH_TYPE of this jcond as well as the flag
  2740. * indicating whether or not the floating point condition codes
  2741. * are used.
  2742. * PARAMETERS: cond - the BRANCH_TYPE
  2743. * usesFloat - this condional jump checks the floating point
  2744. * condition codes
  2745. * RETURNS: a semantic string
  2746. *============================================================================*/
  2747. void BoolAssign::setCondType(BRANCH_TYPE cond, bool usesFloat /*= false*/) {
  2748. jtCond = cond;
  2749. bFloat = usesFloat;
  2750. setCondExpr(new Terminal(opFlags));
  2751. }
  2752. /*==============================================================================
  2753. * FUNCTION: BoolAssign::makeSigned
  2754. * OVERVIEW: Change this from an unsigned to a signed branch
  2755. * NOTE: Not sure if this is ever going to be used
  2756. * PARAMETERS: <none>
  2757. * RETURNS: <nothing>
  2758. *============================================================================*/
  2759. void BoolAssign::makeSigned() {
  2760. // Make this into a signed branch
  2761. switch (jtCond)
  2762. {
  2763. case BRANCH_JUL : jtCond = BRANCH_JSL; break;
  2764. case BRANCH_JULE: jtCond = BRANCH_JSLE; break;
  2765. case BRANCH_JUGE: jtCond = BRANCH_JSGE; break;
  2766. case BRANCH_JUG : jtCond = BRANCH_JSG; break;
  2767. default:
  2768. // Do nothing for other cases
  2769. break;
  2770. }
  2771. }
  2772. /*==============================================================================
  2773. * FUNCTION: BoolAssign::getCondExpr
  2774. * OVERVIEW: Return the Exp expression containing the HL condition.
  2775. * PARAMETERS: <none>
  2776. * RETURNS: a semantic string
  2777. *============================================================================*/
  2778. Exp* BoolAssign::getCondExpr() {
  2779. return pCond;
  2780. }
  2781. /*==============================================================================
  2782. * FUNCTION: BoolAssign::setCondExpr
  2783. * OVERVIEW: Set the Exp expression containing the HL condition.
  2784. * PARAMETERS: Pointer to semantic string to set
  2785. * RETURNS: <nothing>
  2786. *============================================================================*/
  2787. void BoolAssign::setCondExpr(Exp* pss) {
  2788. if (pCond) ;//delete pCond;
  2789. pCond = pss;
  2790. }
  2791. /*==============================================================================
  2792. * FUNCTION: BoolAssign::print
  2793. * OVERVIEW: Write a text representation to the given stream
  2794. * PARAMETERS: os: stream
  2795. * RETURNS: <Nothing>
  2796. *============================================================================*/
  2797. void BoolAssign::printCompact(std::ostream& os /*= cout*/, bool html) {
  2798. os << "BOOL ";
  2799. lhs->print(os);
  2800. os << " := CC(";
  2801. switch (jtCond) {
  2802. case BRANCH_JE: os << "equals"; break;
  2803. case BRANCH_JNE: os << "not equals"; break;
  2804. case BRANCH_JSL: os << "signed less"; break;
  2805. case BRANCH_JSLE: os << "signed less or equals"; break;
  2806. case BRANCH_JSGE: os << "signed greater or equals"; break;
  2807. case BRANCH_JSG: os << "signed greater"; break;
  2808. case BRANCH_JUL: os << "unsigned less"; break;
  2809. case BRANCH_JULE: os << "unsigned less or equals"; break;
  2810. case BRANCH_JUGE: os << "unsigned greater or equals"; break;
  2811. case BRANCH_JUG: os << "unsigned greater"; break;
  2812. case BRANCH_JMI: os << "minus"; break;
  2813. case BRANCH_JPOS: os << "plus"; break;
  2814. case BRANCH_JOF: os << "overflow"; break;
  2815. case BRANCH_JNOF: os << "no overflow"; break;
  2816. case BRANCH_JPAR: os << "ev parity"; break;
  2817. }
  2818. os << ")";
  2819. if (bFloat) os << ", float";
  2820. if (html)
  2821. os << "<br>";
  2822. os << std::endl;
  2823. if (pCond) {
  2824. os << "High level: ";
  2825. pCond->print(os, html);
  2826. if (html)
  2827. os << "<br>";
  2828. os << "\n";
  2829. }
  2830. }
  2831. /*==============================================================================
  2832. * FUNCTION: BoolAssign::clone
  2833. * OVERVIEW: Deep copy clone
  2834. * PARAMETERS: <none>
  2835. * RETURNS: Pointer to a new Statement, a clone of this BoolAssign
  2836. *============================================================================*/
  2837. Statement* BoolAssign::clone() {
  2838. BoolAssign* ret = new BoolAssign(size);
  2839. ret->jtCond = jtCond;
  2840. if (pCond) ret->pCond = pCond->clone();
  2841. else ret->pCond = NULL;
  2842. ret->bFloat = bFloat;
  2843. ret->size = size;
  2844. // Statement members
  2845. ret->pbb = pbb;
  2846. ret->proc = proc;
  2847. ret->number = number;
  2848. return ret;
  2849. }
  2850. // visit this Statement
  2851. bool BoolAssign::accept(StmtVisitor* visitor) {
  2852. return visitor->visit(this);
  2853. }
  2854. void BoolAssign::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  2855. assert(lhs);
  2856. assert(pCond);
  2857. // lhs := (pCond) ? 1 : 0
  2858. Assign as(lhs->clone(), new Ternary(opTern, pCond->clone(),
  2859. new Const(1), new Const(0)));
  2860. hll->AddAssignmentStatement(indLevel, &as);
  2861. }
  2862. void BoolAssign::simplify() {
  2863. if (pCond)
  2864. condToRelational(pCond, jtCond);
  2865. }
  2866. void BoolAssign::getDefinitions(LocationSet &defs)
  2867. {
  2868. defs.insert(getLeft());
  2869. }
  2870. bool BoolAssign::usesExp(Exp *e)
  2871. {
  2872. assert(lhs && pCond);
  2873. Exp *where = 0;
  2874. return (pCond->search(e, where) || (lhs->isMemOf() &&
  2875. ((Unary*)lhs)->getSubExp1()->search(e, where)));
  2876. }
  2877. bool BoolAssign::search(Exp *search, Exp *&result)
  2878. {
  2879. assert(lhs);
  2880. if (lhs->search(search, result)) return true;
  2881. assert(pCond);
  2882. return pCond->search(search, result);
  2883. }
  2884. bool BoolAssign::searchAll(Exp* search, std::list<Exp*>& result)
  2885. {
  2886. bool ch = false;
  2887. assert(lhs);
  2888. if (lhs->searchAll(search, result)) ch = true;
  2889. assert(pCond);
  2890. return pCond->searchAll(search, result) || ch;
  2891. }
  2892. bool BoolAssign::searchAndReplace(Exp *search, Exp *replace, bool cc) {
  2893. bool chl, chr;
  2894. assert(pCond);
  2895. assert(lhs);
  2896. pCond = pCond->searchReplaceAll(search, replace, chl);
  2897. lhs = lhs->searchReplaceAll(search, replace, chr);
  2898. return chl | chr;
  2899. }
  2900. // This is for setting up SETcc instructions; see include/decoder.h macro SETS
  2901. void BoolAssign::setLeftFromList(std::list<Statement*>* stmts) {
  2902. assert(stmts->size() == 1);
  2903. Assign* first = (Assign*)stmts->front();
  2904. assert(first->getKind() == STMT_ASSIGN);
  2905. lhs = first->getLeft();
  2906. }
  2907. // // // //
  2908. // Assign //
  2909. // // // //
  2910. Assignment::Assignment(Exp* lhs) : TypingStatement(new VoidType), lhs(lhs) {
  2911. if (lhs && lhs->isRegOf()) {
  2912. int n = ((Const*)lhs->getSubExp1())->getInt();
  2913. if (((Location*)lhs)->getProc()) {
  2914. type = new SizeType(((Location*)lhs)->getProc()->getProg()->getRegSize(n));
  2915. }
  2916. }
  2917. }
  2918. Assignment::Assignment(Type* ty, Exp* lhs) : TypingStatement(ty), lhs(lhs) {}
  2919. Assignment::~Assignment() {}
  2920. Assign::Assign(Exp* lhs, Exp* rhs, Exp* guard)
  2921. : Assignment(lhs), rhs(rhs), guard(guard) {
  2922. kind = STMT_ASSIGN;
  2923. }
  2924. Assign::Assign(Type* ty, Exp* lhs, Exp* rhs, Exp* guard)
  2925. : Assignment(ty, lhs), rhs(rhs), guard(guard)
  2926. {
  2927. kind = STMT_ASSIGN;
  2928. }
  2929. Assign::Assign(Assign& o) : Assignment(lhs->clone()) {
  2930. kind = STMT_ASSIGN;
  2931. rhs = o.rhs->clone();
  2932. if (o.type) type = o.type->clone(); else type = NULL;
  2933. if (o.guard) guard = o.guard->clone(); else guard = NULL;
  2934. }
  2935. // Implicit Assignment
  2936. // Constructor and subexpression
  2937. ImplicitAssign::ImplicitAssign(Exp* lhs) : Assignment(lhs) {
  2938. kind = STMT_IMPASSIGN;
  2939. }
  2940. // Constructor, type, and subexpression
  2941. ImplicitAssign::ImplicitAssign(Type* ty, Exp* lhs) : Assignment(ty, lhs) {
  2942. kind = STMT_IMPASSIGN;
  2943. }
  2944. ImplicitAssign::ImplicitAssign(ImplicitAssign& o) : Assignment(type?type->clone():NULL, lhs->clone()) {
  2945. kind = STMT_IMPASSIGN;
  2946. }
  2947. // The first virtual function (here the destructor) can't be in statement.h file for gcc
  2948. ImplicitAssign::~ImplicitAssign() { }
  2949. Statement* Assign::clone() {
  2950. Assign* a = new Assign(type == NULL ? NULL : type->clone(), lhs->clone(), rhs->clone(),
  2951. guard == NULL ? NULL : guard->clone());
  2952. // Statement members
  2953. a->pbb = pbb;
  2954. a->proc = proc;
  2955. a->number = number;
  2956. return a;
  2957. }
  2958. Statement* PhiAssign::clone() {
  2959. PhiAssign* pa = new PhiAssign(type, lhs);
  2960. Definitions::iterator dd;
  2961. for (dd = defVec.begin(); dd != defVec.end(); dd++) {
  2962. PhiInfo pi;
  2963. pi.def = dd->def; // Don't clone the Statement pointer (never moves)
  2964. pi.e = dd->e->clone(); // Do clone the expression pointer
  2965. pa->defVec.push_back(pi);
  2966. }
  2967. return pa;
  2968. }
  2969. Statement* ImplicitAssign::clone() {
  2970. ImplicitAssign* ia = new ImplicitAssign(type, lhs);
  2971. return ia;
  2972. }
  2973. // visit this Statement
  2974. bool Assign::accept(StmtVisitor* visitor) {
  2975. return visitor->visit(this);
  2976. }
  2977. bool PhiAssign::accept(StmtVisitor* visitor) {
  2978. return visitor->visit(this);
  2979. }
  2980. bool ImplicitAssign::accept(StmtVisitor* visitor) {
  2981. return visitor->visit(this);
  2982. }
  2983. void Assign::simplify() {
  2984. // simplify arithmetic of assignment
  2985. OPER leftop = lhs->getOper();
  2986. if (Boomerang::get()->noBranchSimplify) {
  2987. if (leftop == opZF || leftop == opCF || leftop == opOF || leftop == opNF)
  2988. return;
  2989. }
  2990. lhs = lhs->simplifyArith();
  2991. rhs = rhs->simplifyArith();
  2992. if (guard) guard = guard->simplifyArith();
  2993. // simplify the resultant expression
  2994. lhs = lhs->simplify();
  2995. rhs = rhs->simplify();
  2996. if (guard) guard = guard->simplify();
  2997. // Perhaps the guard can go away
  2998. if (guard && (guard->isTrue() || guard->isIntConst() && ((Const*)guard)->getInt() == 1))
  2999. guard = NULL; // No longer a guarded assignment
  3000. if (lhs->getOper() == opMemOf) {
  3001. lhs->setSubExp1(lhs->getSubExp1()->simplifyArith());
  3002. }
  3003. // this hack finds address constants.. it should go away when Mike writes some decent type analysis.
  3004. #if 0
  3005. if (DFA_TYPE_ANALYSIS) return;
  3006. if (lhs->getOper() == opMemOf && lhs->getSubExp1()->getOper() == opSubscript) {
  3007. RefExp *ref = (RefExp*)lhs->getSubExp1();
  3008. Statement *phist = ref->getDef();
  3009. PhiAssign *phi = NULL;
  3010. if (phist /* && phist->getRight() */) // ?
  3011. phi = dynamic_cast<PhiAssign*>(phist);
  3012. for (int i = 0; phi && i < phi->getNumDefs(); i++) {
  3013. if (phi->getStmtAt(i)) {
  3014. Assign *def = dynamic_cast<Assign*>(phi->getStmtAt(i));
  3015. // Look for rX{-} - K or K
  3016. if (def && (def->rhs->isIntConst() ||
  3017. (def->rhs->getOper() == opMinus &&
  3018. def->rhs->getSubExp1()->isSubscript() &&
  3019. ((RefExp*)def->rhs->getSubExp1())->isImplicitDef() &&
  3020. def->rhs->getSubExp1()->getSubExp1()->isRegOf() &&
  3021. def->rhs->getSubExp2()->isIntConst()))) {
  3022. Exp *ne = new Unary(opAddrOf, Location::memOf(def->rhs, proc));
  3023. if (VERBOSE)
  3024. LOG << "replacing " << def->rhs << " with " << ne << " in " << def << "\n";
  3025. def->rhs = ne;
  3026. }
  3027. if (def && def->rhs->getOper() == opAddrOf &&
  3028. def->rhs->getSubExp1()->getOper() == opSubscript &&
  3029. def->rhs->getSubExp1()->getSubExp1()->getOper() == opGlobal &&
  3030. // MVE: opPhi!!
  3031. rhs->getOper() != opPhi && rhs->getOper() != opItof &&
  3032. rhs->getOper() != opFltConst) {
  3033. Type *ty = proc->getProg()->getGlobalType(
  3034. ((Const*)def->rhs->getSubExp1()->
  3035. getSubExp1()->
  3036. getSubExp1())->getStr());
  3037. if (ty && ty->isArray()) {
  3038. Type *bty = ((ArrayType*)ty)->getBaseType();
  3039. if (bty->isFloat()) {
  3040. if (VERBOSE)
  3041. LOG << "replacing " << rhs << " with ";
  3042. rhs = new Ternary(opItof, new Const(32), new Const(bty->getSize()), rhs);
  3043. if (VERBOSE)
  3044. LOG << rhs << " (assign indicates float type)\n";
  3045. }
  3046. }
  3047. }
  3048. }
  3049. }
  3050. }
  3051. #endif
  3052. }
  3053. void Assign::simplifyAddr() {
  3054. lhs = lhs->simplifyAddr();
  3055. rhs = rhs->simplifyAddr();
  3056. }
  3057. void Assignment::simplifyAddr() {
  3058. lhs = lhs->simplifyAddr();
  3059. }
  3060. void Assign::fixSuccessor() {
  3061. lhs = lhs->fixSuccessor();
  3062. rhs = rhs->fixSuccessor();
  3063. }
  3064. void Assignment::print(std::ostream& os, bool html) {
  3065. os << std::setw(4) << std::dec << number << " ";
  3066. if (html) {
  3067. os << "</td><td>";
  3068. os << "<a name=\"stmt" << std::dec << number << "\">";
  3069. }
  3070. printCompact(os, html);
  3071. if (html)
  3072. os << "</a>";
  3073. if (!ranges.empty()) {
  3074. os << "\n\t\t\tranges: ";
  3075. ranges.print(os);
  3076. }
  3077. }
  3078. void Assign::printCompact(std::ostream& os, bool html) {
  3079. os << "*" << type << "* ";
  3080. if (guard)
  3081. os << guard << " => ";
  3082. if (lhs) lhs->print(os, html);
  3083. os << " := ";
  3084. if (rhs) rhs->print(os, html);
  3085. }
  3086. void PhiAssign::printCompact(std::ostream& os, bool html) {
  3087. os << "*" << type << "* ";
  3088. if (lhs) lhs->print(os, html);
  3089. os << " := phi";
  3090. // Print as lhs := phi{9 17} for the common case where the lhs is the same location as all the referenced
  3091. // locations. When not, print as local4 := phi(r24{9} argc{17})
  3092. bool simple = true;
  3093. int i, n = defVec.size();
  3094. if (n != 0) {
  3095. for (i = 0; i < n; i++) {
  3096. // If e is NULL assume it is meant to match lhs
  3097. if (defVec[i].e == NULL) continue;
  3098. if (! (*defVec[i].e == *lhs)) {
  3099. // One of the phi parameters has a different base expression to lhs. Use non simple print.
  3100. simple = false;
  3101. break;
  3102. }
  3103. }
  3104. }
  3105. iterator it;
  3106. if (simple) {
  3107. os << "{" << std::dec;
  3108. for (it = defVec.begin(); it != defVec.end(); /* no increment */) {
  3109. if (it->def) {
  3110. if (html)
  3111. os << "<a href=\"#stmt" << std::dec << it->def->getNumber() << "\">";
  3112. os << it->def->getNumber();
  3113. if (html)
  3114. os << "</a>";
  3115. } else
  3116. os << "-";
  3117. if (++it != defVec.end())
  3118. os << " ";
  3119. }
  3120. os << "}";
  3121. } else {
  3122. os << "(";
  3123. for (it = defVec.begin(); it != defVec.end(); /* no increment */) {
  3124. Exp* e = it->e;
  3125. if (e == NULL)
  3126. os << "NULL{";
  3127. else
  3128. os << e << "{";
  3129. if (it->def)
  3130. os << std::dec << it->def->getNumber();
  3131. else
  3132. os << "-";
  3133. os << "}";
  3134. if (++it != defVec.end())
  3135. os << " ";
  3136. }
  3137. os << ")";
  3138. }
  3139. }
  3140. void ImplicitAssign::printCompact(std::ostream& os, bool html) {
  3141. os << "*" << type << "* ";
  3142. if (lhs) lhs->print(os, html);
  3143. os << " := -";
  3144. }
  3145. // All the Assignment-derived classes have the same definitions: the lhs
  3146. void Assignment::getDefinitions(LocationSet &defs) {
  3147. if (lhs->getOper() == opAt) // foo@[m:n] really only defines foo
  3148. defs.insert(((Ternary*)lhs)->getSubExp1());
  3149. else
  3150. defs.insert(lhs);
  3151. // Special case: flag calls define %CF (and others)
  3152. if (lhs->isFlags()) {
  3153. defs.insert(new Terminal(opCF));
  3154. defs.insert(new Terminal(opZF));
  3155. }
  3156. }
  3157. bool Assign::search(Exp* search, Exp*& result) {
  3158. if (lhs->search(search, result))
  3159. return true;
  3160. return rhs->search(search, result);
  3161. }
  3162. bool PhiAssign::search(Exp* search, Exp*& result) {
  3163. if (lhs->search(search, result))
  3164. return true;
  3165. iterator it;
  3166. for (it = defVec.begin(); it != defVec.end(); ++it) {
  3167. if (it->e == NULL) continue; // Note: can't match foo{-} because of this
  3168. RefExp* re = new RefExp(it->e, it->def);
  3169. if (re->search(search, result))
  3170. return true;
  3171. }
  3172. return false;
  3173. }
  3174. bool ImplicitAssign::search(Exp* search, Exp*& result) {
  3175. return lhs->search(search, result);
  3176. }
  3177. bool Assign::searchAll(Exp* search, std::list<Exp*>& result) {
  3178. bool res;
  3179. std::list<Exp*> leftResult;
  3180. std::list<Exp*>::iterator it;
  3181. res = lhs->searchAll(search, leftResult);
  3182. // Ugh: searchAll clears the list!
  3183. res |= rhs->searchAll(search, result);
  3184. for (it = leftResult.begin(); it != leftResult.end(); it++)
  3185. result.push_back(*it);
  3186. return res;
  3187. }
  3188. // FIXME: is this the right semantics for searching a phi statement, disregarding the RHS?
  3189. bool PhiAssign::searchAll(Exp* search, std::list<Exp*>& result) {
  3190. return lhs->searchAll(search, result);
  3191. }
  3192. bool ImplicitAssign::searchAll(Exp* search, std::list<Exp*>& result) {
  3193. return lhs->searchAll(search, result);
  3194. }
  3195. bool Assign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  3196. bool chl, chr, chg = false;
  3197. lhs = lhs->searchReplaceAll(search, replace, chl);
  3198. rhs = rhs->searchReplaceAll(search, replace, chr);
  3199. if (guard)
  3200. guard = guard->searchReplaceAll(search, replace, chg);
  3201. return chl | chr | chg;
  3202. }
  3203. bool PhiAssign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  3204. bool change;
  3205. lhs = lhs->searchReplaceAll(search, replace, change);
  3206. std::vector<PhiInfo>::iterator it;
  3207. for (it = defVec.begin(); it != defVec.end(); it++) {
  3208. if (it->e == NULL) continue;
  3209. bool ch;
  3210. // Assume that the definitions will also be replaced
  3211. it->e = it->e->searchReplaceAll(search, replace, ch);
  3212. change |= ch;
  3213. }
  3214. return change;
  3215. }
  3216. bool ImplicitAssign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  3217. bool change;
  3218. lhs = lhs->searchReplaceAll(search, replace, change);
  3219. return change;
  3220. }
  3221. void Assign::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
  3222. hll->AddAssignmentStatement(indLevel, this);
  3223. }
  3224. int Assign::getMemDepth() {
  3225. int d1 = lhs->getMemDepth();
  3226. int d2 = rhs->getMemDepth();
  3227. if (d1 >= d2) return d1;
  3228. return d2;
  3229. }
  3230. // PhiExp and ImplicitExp:
  3231. bool Assignment::usesExp(Exp* e) {
  3232. Exp *where = 0;
  3233. return (lhs->isMemOf() || lhs->isRegOf()) && ((Unary*)lhs)->getSubExp1()->search(e, where);
  3234. }
  3235. bool Assign::usesExp(Exp *e) {
  3236. Exp *where = 0;
  3237. return (rhs->search(e, where) || ((lhs->isMemOf() || lhs->isRegOf()) &&
  3238. ((Unary*)lhs)->getSubExp1()->search(e, where)));
  3239. }
  3240. #if 0
  3241. bool Assign::match(const char *pattern, std::map<std::string, Exp*> &bindings)
  3242. {
  3243. if (strstr(pattern, ":=") == NULL)
  3244. return false;
  3245. char *left = strdup(pattern);
  3246. char *right = strstr(left, ":=");
  3247. *right++ = 0;
  3248. right++;
  3249. while (*right == ' ')
  3250. right++;
  3251. char *endleft = left + strlen(left) - 1;
  3252. while (*endleft == ' ') {
  3253. *endleft = 0;
  3254. endleft--;
  3255. }
  3256. return lhs->match(left, bindings) && rhs->match(right, bindings);
  3257. }
  3258. void addPhiReferences(StatementSet &stmts, Statement *def);
  3259. void addSimpleCopyReferences(StatementSet &stmts, Statement *def)
  3260. {
  3261. if (!(*((Assign*)def)->getLeft() == *((Assign*)def)->getRight()->getSubExp1()))
  3262. return;
  3263. Statement *copy = ((RefExp*)((Assign*)def)->getRight())->getDef();
  3264. if (!stmts.exists(copy)) {
  3265. stmts.insert(copy);
  3266. if (copy->isPhi())
  3267. addPhiReferences(stmts, copy);
  3268. else if (copy->isAssign() && ((Assign*)copy)->getRight()->isSubscript())
  3269. addSimpleCopyReferences(stmts, copy);
  3270. }
  3271. }
  3272. void addPhiReferences(StatementSet &stmts, Statement *def)
  3273. {
  3274. PhiAssign *p = (PhiAssign*)def;
  3275. for (PhiAssign::iterator it = p->begin(); it != p->end(); it++) {
  3276. if ((*it).def->isPhi() && !stmts.exists((*it).def)) {
  3277. stmts.insert((*it).def);
  3278. addPhiReferences(stmts, (*it).def);
  3279. } else if ((*it).def->isAssign() && ((Assign*)(*it).def)->getRight()->isSubscript()) {
  3280. stmts.insert((*it).def);
  3281. addSimpleCopyReferences(stmts, (*it).def);
  3282. } else
  3283. stmts.insert((*it).def);
  3284. }
  3285. }
  3286. #endif
  3287. void Assignment::genConstraints(LocationSet& cons) {
  3288. // Almost every assignment has at least a size from decoding
  3289. // MVE: do/will PhiAssign's have a valid type? Why not?
  3290. if (type)
  3291. cons.insert(new Binary(opEquals,
  3292. new Unary(opTypeOf,
  3293. new RefExp(lhs, this)),
  3294. new TypeVal(type)));
  3295. }
  3296. // generate constraints
  3297. void Assign::genConstraints(LocationSet& cons) {
  3298. Assignment::genConstraints(cons); // Gen constraint for the LHS
  3299. Exp* con = rhs->genConstraints(
  3300. new Unary(opTypeOf,
  3301. new RefExp(lhs->clone(), this)));
  3302. if (con) cons.insert(con);
  3303. }
  3304. void PhiAssign::genConstraints(LocationSet& cons) {
  3305. // Generate a constraints st that all the phi's have to be the same type as
  3306. // result
  3307. Exp* result = new Unary(opTypeOf, new RefExp(lhs, this));
  3308. Definitions::iterator uu;
  3309. for (uu = defVec.begin(); uu != defVec.end(); uu++) {
  3310. Exp* conjunct = new Binary(opEquals,
  3311. result,
  3312. new Unary(opTypeOf,
  3313. new RefExp(uu->e, uu->def)));
  3314. cons.insert(conjunct);
  3315. }
  3316. }
  3317. void CallStatement::genConstraints(LocationSet& cons) {
  3318. Proc* dest = getDestProc();
  3319. if (dest == NULL) return;
  3320. Signature* destSig = dest->getSignature();
  3321. // Generate a constraint for the type of each actual argument to be equal to the type of each formal parameter
  3322. // (hopefully, these are already calculated correctly; if not, we need repeat till no change)
  3323. StatementList::iterator aa;
  3324. int p = 0;
  3325. for (aa = arguments.begin(); aa != arguments.end(); ++aa, ++p) {
  3326. Exp* arg = ((Assign*)*aa)->getRight();
  3327. // Handle a[m[x]]
  3328. if (arg->isAddrOf()) {
  3329. Exp* sub = arg->getSubExp1();
  3330. if (sub->isSubscript())
  3331. sub = ((RefExp*)sub)->getSubExp1();
  3332. if (sub->isMemOf())
  3333. arg = ((Location*)sub)->getSubExp1();
  3334. }
  3335. if (arg->isRegOf() || arg->isMemOf() || arg->isSubscript() || arg->isLocal() || arg->isGlobal()) {
  3336. Exp* con = new Binary(opEquals,
  3337. new Unary(opTypeOf, arg->clone()),
  3338. new TypeVal(destSig->getParamType(p)->clone()));
  3339. cons.insert(con);
  3340. }
  3341. }
  3342. if (dest->isLib()) {
  3343. // A library procedure... check for two special cases
  3344. std::string name = dest->getName();
  3345. // Note: might have to chase back via a phi statement to get a sample
  3346. // string
  3347. char* str;
  3348. Exp* arg0 = ((Assign*)*arguments.begin())->getRight();
  3349. if ((name == "printf" || name == "scanf") && (str = arg0->getAnyStrConst()) != NULL) {
  3350. // actually have to parse it
  3351. int n = 1; // Number of %s plus 1 = number of args
  3352. char* p = str;
  3353. while ((p = strchr(p, '%'))) {
  3354. p++;
  3355. Type* t = NULL;
  3356. int longness = 0;
  3357. bool sign = true;
  3358. bool cont;
  3359. do {
  3360. cont = false;
  3361. switch(*p) {
  3362. case 'u':
  3363. sign = false;
  3364. cont = true;
  3365. break;
  3366. case 'x':
  3367. sign = false;
  3368. // Fall through
  3369. case 'i':
  3370. case 'd': {
  3371. int size = 32;
  3372. // Note: the following only works for 32 bit code or where sizeof(long) == sizeof(int)
  3373. if (longness == 2) size = 64;
  3374. t = new IntegerType(size, sign);
  3375. break;
  3376. }
  3377. case 'f':
  3378. case 'g':
  3379. t = new FloatType(64);
  3380. break;
  3381. case 's':
  3382. t = new PointerType(new CharType());
  3383. break;
  3384. case 'l':
  3385. longness++;
  3386. cont = true;
  3387. break;
  3388. case '.':
  3389. cont = true;
  3390. break;
  3391. case '*':
  3392. assert(0); // Star format not handled yet
  3393. default:
  3394. if (*p >= '0' && *p <= '9')
  3395. cont = true;
  3396. break;
  3397. }
  3398. p++;
  3399. } while (cont);
  3400. if (t) {
  3401. // scanf takes addresses of these
  3402. if (name == "scanf")
  3403. t = new PointerType(t);
  3404. // Generate a constraint for the parameter
  3405. TypeVal* tv = new TypeVal(t);
  3406. StatementList::iterator aa = arguments.begin();
  3407. my_advance(aa, n);
  3408. Exp* argn = ((Assign*)*aa)->getRight();
  3409. Exp* con = argn->genConstraints(tv);
  3410. cons.insert(con);
  3411. }
  3412. n++;
  3413. }
  3414. }
  3415. }
  3416. }
  3417. void BranchStatement::genConstraints(LocationSet& cons) {
  3418. if (pCond == NULL && VERBOSE) {
  3419. LOG << "Warning: BranchStatment " << number << " has no condition expression!\n";
  3420. return;
  3421. }
  3422. Type* opsType;
  3423. if (bFloat)
  3424. opsType = new FloatType(0);
  3425. else
  3426. opsType = new IntegerType(0);
  3427. if ( jtCond == BRANCH_JUGE || jtCond == BRANCH_JULE ||
  3428. jtCond == BRANCH_JUG || jtCond == BRANCH_JUL) {
  3429. assert(!bFloat);
  3430. ((IntegerType*)opsType)->bumpSigned(-1);
  3431. } else if (jtCond == BRANCH_JSGE || jtCond == BRANCH_JSLE ||
  3432. jtCond == BRANCH_JSG || jtCond == BRANCH_JSL) {
  3433. assert(!bFloat);
  3434. ((IntegerType*)opsType)->bumpSigned(+1);
  3435. }
  3436. // Constraints leading from the condition
  3437. assert(pCond->getArity() == 2);
  3438. Exp* a = ((Binary*)pCond)->getSubExp1();
  3439. Exp* b = ((Binary*)pCond)->getSubExp2();
  3440. // Generate constraints for a and b separately (if any). Often only need a size, since we get basic type and
  3441. // signedness from the branch condition (e.g. jump if unsigned less)
  3442. Exp* Ta; Exp* Tb;
  3443. if (a->isSizeCast()) {
  3444. opsType->setSize(((Const*)((Binary*)a)->getSubExp1())->getInt());
  3445. Ta = new Unary(opTypeOf, ((Binary*)a)->getSubExp2());
  3446. } else
  3447. Ta = new Unary(opTypeOf, a);
  3448. if (b->isSizeCast()) {
  3449. opsType->setSize(((Const*)((Binary*)b)->getSubExp1())->getInt());
  3450. Tb = new Unary(opTypeOf, ((Binary*)b)->getSubExp2());
  3451. } else
  3452. Tb = new Unary(opTypeOf, b);
  3453. // Constrain that Ta == opsType and Tb == opsType
  3454. Exp* con = new Binary(opEquals, Ta, new TypeVal(opsType));
  3455. cons.insert(con);
  3456. con = new Binary(opEquals, Tb, new TypeVal(opsType));
  3457. cons.insert(con);
  3458. }
  3459. int Statement::setConscripts(int n) {
  3460. StmtConscriptSetter scs(n, false);
  3461. accept(&scs);
  3462. return scs.getLast();
  3463. }
  3464. void Statement::clearConscripts() {
  3465. StmtConscriptSetter scs(0, true);
  3466. accept(&scs);
  3467. }
  3468. // Cast the constant num to be of type ty. Return true if a change made
  3469. bool Statement::castConst(int num, Type* ty) {
  3470. ExpConstCaster ecc(num, ty);
  3471. StmtModifier scc(&ecc);
  3472. accept(&scc);
  3473. return ecc.isChanged();
  3474. }
  3475. void Statement::stripSizes() {
  3476. SizeStripper ss;
  3477. StmtModifier sm(&ss);
  3478. accept(&sm);
  3479. }
  3480. // Visiting from class StmtExpVisitor
  3481. // Visit all the various expressions in a statement
  3482. bool Assign::accept(StmtExpVisitor* v) {
  3483. bool override;
  3484. bool ret = v->visit(this, override);
  3485. if (override)
  3486. // The visitor has overridden this functionality. This is needed for example in UsedLocFinder, where the lhs of
  3487. // an assignment is not used (but if it's m[blah], then blah is used)
  3488. return ret;
  3489. if (ret && lhs) ret = lhs->accept(v->ev);
  3490. if (ret && rhs) ret = rhs->accept(v->ev);
  3491. return ret;
  3492. }
  3493. bool PhiAssign::accept(StmtExpVisitor* v) {
  3494. bool override;
  3495. bool ret = v->visit(this, override);
  3496. if (override) return ret;
  3497. if (ret && lhs) ret = lhs->accept(v->ev);
  3498. iterator it;
  3499. for (it = defVec.begin(); it != defVec.end(); ++it) {
  3500. if (it->e == NULL) continue;
  3501. RefExp* re = new RefExp(it->e, it->def);
  3502. ret = re->accept(v->ev);
  3503. if (ret == false) return false;
  3504. }
  3505. return true;
  3506. }
  3507. bool ImplicitAssign::accept(StmtExpVisitor* v) {
  3508. bool override;
  3509. bool ret = v->visit(this, override);
  3510. if (override) return ret;
  3511. if (ret && lhs) ret = lhs->accept(v->ev);
  3512. return ret;
  3513. }
  3514. bool GotoStatement::accept(StmtExpVisitor* v) {
  3515. bool override;
  3516. bool ret = v->visit(this, override);
  3517. if (override) return ret;
  3518. if (ret && pDest)
  3519. ret = pDest->accept(v->ev);
  3520. return ret;
  3521. }
  3522. bool BranchStatement::accept(StmtExpVisitor* v) {
  3523. bool override;
  3524. bool ret = v->visit(this, override);
  3525. if (override) return ret;
  3526. // Destination will always be a const for X86, so the below will never be used in practice
  3527. if (ret && pDest)
  3528. ret = pDest->accept(v->ev);
  3529. if (ret && pCond)
  3530. ret = pCond->accept(v->ev);
  3531. return ret;
  3532. }
  3533. bool CaseStatement::accept(StmtExpVisitor* v) {
  3534. bool override;
  3535. bool ret = v->visit(this, override);
  3536. if (override) return ret;
  3537. if (ret && pDest)
  3538. ret = pDest->accept(v->ev);
  3539. if (ret && pSwitchInfo && pSwitchInfo->pSwitchVar)
  3540. ret = pSwitchInfo->pSwitchVar->accept(v->ev);
  3541. return ret;
  3542. }
  3543. bool CallStatement::accept(StmtExpVisitor* v) {
  3544. bool override;
  3545. bool ret = v->visit(this, override);
  3546. if (override) return ret;
  3547. if (ret && pDest)
  3548. ret = pDest->accept(v->ev);
  3549. StatementList::iterator it;
  3550. for (it = arguments.begin(); ret && it != arguments.end(); it++)
  3551. ret = (*it)->accept(v);
  3552. // FIXME: why aren't defines counted?
  3553. #if 0 // Do we want to accept visits to the defines? Not sure now...
  3554. std::vector<ReturnInfo>::iterator rr;
  3555. for (rr = defines.begin(); ret && rr != defines.end(); rr++)
  3556. if (rr->e) // Can be NULL now to line up with other returns
  3557. ret = rr->e->accept(v->ev);
  3558. #endif
  3559. // FIXME: surely collectors should be counted?
  3560. return ret;
  3561. }
  3562. bool ReturnStatement::accept(StmtExpVisitor* v) {
  3563. bool override;
  3564. ReturnStatement::iterator rr;
  3565. if (!v->visit(this, override))
  3566. return false;
  3567. if (override) return true;
  3568. if (!v->isIgnoreCol()) {
  3569. DefCollector::iterator dd;
  3570. for (dd = col.begin(); dd != col.end(); ++dd)
  3571. if (!(*dd)->accept(v))
  3572. return false;
  3573. // EXPERIMENTAL: for now, count the modifieds as if they are a collector (so most, if not all of the time,
  3574. // ignore them). This is so that we can detect better when a definition is used only once, and therefore
  3575. // propagate anything to it
  3576. for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
  3577. if (!(*rr)->accept(v))
  3578. return false;
  3579. }
  3580. for (rr = returns.begin(); rr != returns.end(); ++rr)
  3581. if (!(*rr)->accept(v))
  3582. return false;
  3583. return true;
  3584. }
  3585. bool BoolAssign::accept(StmtExpVisitor* v) {
  3586. bool override;
  3587. bool ret = v->visit(this, override);
  3588. if (override) return ret;
  3589. if (ret && pCond)
  3590. ret = pCond->accept(v->ev);
  3591. return ret;
  3592. }
  3593. // Visiting from class StmtModifier
  3594. // Modify all the various expressions in a statement
  3595. bool Assign::accept(StmtModifier* v) {
  3596. bool recur;
  3597. v->visit(this, recur);
  3598. v->mod->clearMod();
  3599. if (recur) lhs = lhs->accept(v->mod);
  3600. if (recur) rhs = rhs->accept(v->mod);
  3601. if (VERBOSE && v->mod->isMod())
  3602. LOG << "Assignment changed: now " << this << "\n";
  3603. return true;
  3604. }
  3605. bool PhiAssign::accept(StmtModifier* v) {
  3606. bool recur;
  3607. v->visit(this, recur);
  3608. v->mod->clearMod();
  3609. if (recur) lhs = lhs->accept(v->mod);
  3610. if (VERBOSE && v->mod->isMod())
  3611. LOG << "PhiAssign changed: now " << this << "\n";
  3612. return true;
  3613. }
  3614. bool ImplicitAssign::accept(StmtModifier* v) {
  3615. bool recur;
  3616. v->visit(this, recur);
  3617. v->mod->clearMod();
  3618. if (recur) lhs = lhs->accept(v->mod);
  3619. if (VERBOSE && v->mod->isMod())
  3620. LOG << "ImplicitAssign changed: now " << this << "\n";
  3621. return true;
  3622. }
  3623. bool BoolAssign::accept(StmtModifier* v) {
  3624. bool recur;
  3625. v->visit(this, recur);
  3626. if (pCond && recur)
  3627. pCond = pCond->accept(v->mod);
  3628. if (recur && lhs->isMemOf()) {
  3629. ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
  3630. }
  3631. return true;
  3632. }
  3633. bool GotoStatement::accept(StmtModifier* v) {
  3634. bool recur;
  3635. v->visit(this, recur);
  3636. if (pDest && recur)
  3637. pDest = pDest->accept(v->mod);
  3638. return true;
  3639. }
  3640. bool BranchStatement::accept(StmtModifier* v) {
  3641. bool recur;
  3642. v->visit(this, recur);
  3643. if (pDest && recur)
  3644. pDest = pDest->accept(v->mod);
  3645. if (pCond && recur)
  3646. pCond = pCond->accept(v->mod);
  3647. return true;
  3648. }
  3649. bool CaseStatement::accept(StmtModifier* v) {
  3650. bool recur;
  3651. v->visit(this, recur);
  3652. if (pDest && recur)
  3653. pDest = pDest->accept(v->mod);
  3654. if (pSwitchInfo && pSwitchInfo->pSwitchVar && recur)
  3655. pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->accept(v->mod);
  3656. return true;
  3657. }
  3658. bool CallStatement::accept(StmtModifier* v) {
  3659. bool recur;
  3660. v->visit(this, recur);
  3661. if (!recur) return true;
  3662. if (pDest)
  3663. pDest = pDest->accept(v->mod);
  3664. StatementList::iterator it;
  3665. for (it = arguments.begin(); recur && it != arguments.end(); it++)
  3666. (*it)->accept(v);
  3667. // For example: needed for CallBypasser so that a collected definition that happens to be another call gets
  3668. // adjusted
  3669. // I'm thinking no at present... let the bypass and propagate while possible logic take care of it, and leave the
  3670. // collectors as the rename logic set it
  3671. // Well, sort it out with ignoreCollector()
  3672. if (!v->ignoreCollector()) {
  3673. DefCollector::iterator cc;
  3674. for (cc = defCol.begin(); cc != defCol.end(); cc++)
  3675. (*cc)->accept(v);
  3676. }
  3677. StatementList::iterator dd;
  3678. for (dd = defines.begin(); recur && dd != defines.end(); ++dd)
  3679. (*dd)->accept(v);
  3680. return true;
  3681. }
  3682. bool ReturnStatement::accept(StmtModifier* v) {
  3683. bool recur;
  3684. v->visit(this, recur);
  3685. if (!recur) return true;
  3686. if (!v->ignoreCollector()) {
  3687. DefCollector::iterator dd;
  3688. for (dd = col.begin(); dd != col.end(); ++dd)
  3689. if (!(*dd)->accept(v))
  3690. return false;
  3691. }
  3692. ReturnStatement::iterator rr;
  3693. for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
  3694. if (!(*rr)->accept(v))
  3695. return false;
  3696. for (rr = returns.begin(); rr != returns.end(); ++rr)
  3697. if (!(*rr)->accept(v))
  3698. return false;
  3699. return true;
  3700. }
  3701. // Visiting from class StmtPartModifier
  3702. // Modify all the various expressions in a statement, except for the top level of the LHS of assignments
  3703. bool Assign::accept(StmtPartModifier* v) {
  3704. bool recur;
  3705. v->visit(this, recur);
  3706. v->mod->clearMod();
  3707. if (recur && lhs->isMemOf()) {
  3708. ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
  3709. }
  3710. if (recur) rhs = rhs->accept(v->mod);
  3711. if (VERBOSE && v->mod->isMod())
  3712. LOG << "Assignment changed: now " << this << "\n";
  3713. return true;
  3714. }
  3715. bool PhiAssign::accept(StmtPartModifier* v) {
  3716. bool recur;
  3717. v->visit(this, recur);
  3718. v->mod->clearMod();
  3719. if (recur && lhs->isMemOf()) {
  3720. ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
  3721. }
  3722. if (VERBOSE && v->mod->isMod())
  3723. LOG << "PhiAssign changed: now " << this << "\n";
  3724. return true;
  3725. }
  3726. bool ImplicitAssign::accept(StmtPartModifier* v) {
  3727. bool recur;
  3728. v->visit(this, recur);
  3729. v->mod->clearMod();
  3730. if (recur && lhs->isMemOf()) {
  3731. ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
  3732. }
  3733. if (VERBOSE && v->mod->isMod())
  3734. LOG << "ImplicitAssign changed: now " << this << "\n";
  3735. return true;
  3736. }
  3737. bool GotoStatement::accept(StmtPartModifier* v) {
  3738. bool recur;
  3739. v->visit(this, recur);
  3740. if (pDest && recur)
  3741. pDest = pDest->accept(v->mod);
  3742. return true;
  3743. }
  3744. bool BranchStatement::accept(StmtPartModifier* v) {
  3745. bool recur;
  3746. v->visit(this, recur);
  3747. if (pDest && recur)
  3748. pDest = pDest->accept(v->mod);
  3749. if (pCond && recur)
  3750. pCond = pCond->accept(v->mod);
  3751. return true;
  3752. }
  3753. bool CaseStatement::accept(StmtPartModifier* v) {
  3754. bool recur;
  3755. v->visit(this, recur);
  3756. if (pDest && recur)
  3757. pDest = pDest->accept(v->mod);
  3758. if (pSwitchInfo && pSwitchInfo->pSwitchVar && recur)
  3759. pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->accept(v->mod);
  3760. return true;
  3761. }
  3762. bool CallStatement::accept(StmtPartModifier* v) {
  3763. bool recur;
  3764. v->visit(this, recur);
  3765. if (pDest && recur)
  3766. pDest = pDest->accept(v->mod);
  3767. StatementList::iterator it;
  3768. for (it = arguments.begin(); recur && it != arguments.end(); it++)
  3769. (*it)->accept(v);
  3770. // For example: needed for CallBypasser so that a collected definition that happens to be another call gets
  3771. // adjusted
  3772. // But now I'm thinking no, the bypass and propagate while possible logic should take care of it.
  3773. // Then again, what about the use collectors in calls? Best to do it.
  3774. if (!v->ignoreCollector()) {
  3775. DefCollector::iterator dd;
  3776. for (dd = defCol.begin(); dd != defCol.end(); dd++)
  3777. (*dd)->accept(v);
  3778. UseCollector::iterator uu;
  3779. for (uu = useCol.begin(); uu != useCol.end(); ++uu)
  3780. // I believe that these should never change at the top level, e.g. m[esp{30} + 4] -> m[esp{-} - 20]
  3781. (*uu)->accept(v->mod);
  3782. }
  3783. StatementList::iterator dd;
  3784. for (dd = defines.begin(); recur && dd != defines.end(); dd++)
  3785. (*dd)->accept(v);
  3786. return true;
  3787. }
  3788. bool ReturnStatement::accept(StmtPartModifier* v) {
  3789. bool recur;
  3790. v->visit(this, recur);
  3791. ReturnStatement::iterator rr;
  3792. for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
  3793. if (!(*rr)->accept(v))
  3794. return false;
  3795. for (rr = returns.begin(); rr != returns.end(); ++rr)
  3796. if (!(*rr)->accept(v))
  3797. return false;
  3798. return true;
  3799. }
  3800. bool BoolAssign::accept(StmtPartModifier* v) {
  3801. bool recur;
  3802. v->visit(this, recur);
  3803. if (pCond && recur)
  3804. pCond = pCond->accept(v->mod);
  3805. if (lhs && recur)
  3806. lhs = lhs->accept(v->mod);
  3807. return true;
  3808. }
  3809. // Fix references to the returns of call statements
  3810. void Statement::bypass() {
  3811. CallBypasser cb(this);
  3812. StmtPartModifier sm(&cb); // Use the Part modifier so we don't change the top level of LHS of assigns etc
  3813. accept(&sm);
  3814. if (cb.isTopChanged())
  3815. simplify(); // E.g. m[esp{20}] := blah -> m[esp{-}-20+4] := blah
  3816. }
  3817. // Find the locations used by expressions in this Statement.
  3818. // Use the StmtExpVisitor and UsedLocsFinder visitor classes
  3819. // cc = count collectors
  3820. void Statement::addUsedLocs(LocationSet& used, bool cc /* = false */, bool memOnly /*= false */) {
  3821. UsedLocsFinder ulf(used, memOnly);
  3822. UsedLocsVisitor ulv(&ulf, cc);
  3823. accept(&ulv);
  3824. }
  3825. bool Statement::addUsedLocals(LocationSet& used) {
  3826. UsedLocalFinder ulf(used, proc);
  3827. UsedLocsVisitor ulv(&ulf, false);
  3828. accept(&ulv);
  3829. return ulf.wasAllFound();
  3830. }
  3831. // For all expressions in this Statement, replace any e with e{def}
  3832. void Statement::subscriptVar(Exp* e, Statement* def /*, Cfg* cfg */) {
  3833. ExpSubscripter es(e, def /*, cfg*/);
  3834. StmtSubscripter ss(&es);
  3835. accept(&ss);
  3836. }
  3837. // Find all constants in this Statement
  3838. void Statement::findConstants(std::list<Const*>& lc) {
  3839. ConstFinder cf(lc);
  3840. StmtConstFinder scf(&cf);
  3841. accept(&scf);
  3842. }
  3843. // Convert this PhiAssignment to an ordinary Assignment. Hopefully, this is the only place that Statements change from
  3844. // one class to another. All throughout the code, we assume that the addresses of Statement objects do not change,
  3845. // so we need this slight hack to overwrite one object with another
  3846. void PhiAssign::convertToAssign(Exp* rhs) {
  3847. // I believe we always want to propagate to these ex-phi's; check!:
  3848. rhs = rhs->propagateAll();
  3849. // Thanks to tamlin for this cleaner way of implementing this hack
  3850. assert(sizeof(Assign) <= sizeof(PhiAssign));
  3851. int n = number; // These items disappear with the destructor below
  3852. PBB bb = pbb;
  3853. UserProc* p = proc;
  3854. Exp* lhs_ = lhs;
  3855. Exp* rhs_ = rhs;
  3856. Type* type_ = type;
  3857. this->~PhiAssign(); // Explicitly destroy this, but keep the memory allocated.
  3858. Assign* a = new(this) Assign(type_, lhs_, rhs_);// construct in-place. Note that 'a' == 'this'
  3859. a->setNumber(n);
  3860. a->setProc(p);
  3861. a->setBB(bb);
  3862. // RTL* rtl = bb->getRTLWithStatement(this);
  3863. // if (rtl->getAddress() == 0)
  3864. // rtl->setAddress(1); // Strange things happen to real assignments with address 0
  3865. }
  3866. void PhiAssign::simplify() {
  3867. lhs = lhs->simplify();
  3868. if (defVec.begin() != defVec.end()) {
  3869. Definitions::iterator uu;
  3870. bool allSame = true;
  3871. uu = defVec.begin();
  3872. Statement* first;
  3873. for (first = (uu++)->def; uu != defVec.end(); uu++) {
  3874. if (uu->def != first) {
  3875. allSame = false;
  3876. break;
  3877. }
  3878. }
  3879. if (allSame) {
  3880. if (VERBOSE)
  3881. LOG << "all the same in " << this << "\n";
  3882. convertToAssign(new RefExp(lhs, first));
  3883. return;
  3884. }
  3885. bool onlyOneNotThis = true;
  3886. Statement *notthis = (Statement*)-1;
  3887. for (uu = defVec.begin(); uu != defVec.end(); uu++) {
  3888. if (uu->def == NULL || uu->def->isImplicit() || !uu->def->isPhi() || uu->def != this)
  3889. if (notthis != (Statement*)-1) {
  3890. onlyOneNotThis = false;
  3891. break;
  3892. } else notthis = uu->def;
  3893. }
  3894. if (onlyOneNotThis && notthis != (Statement*)-1) {
  3895. if (VERBOSE)
  3896. LOG << "all but one not this in " << this << "\n";
  3897. convertToAssign(new RefExp(lhs, notthis));
  3898. return;
  3899. }
  3900. }
  3901. }
  3902. void PhiAssign::putAt(int i, Statement* def, Exp* e) {
  3903. assert(e); // should be something surely
  3904. if (i >= (int)defVec.size())
  3905. defVec.resize(i+1); // Note: possible to insert uninitialised elements
  3906. defVec[i].def = def;
  3907. defVec[i].e = e;
  3908. }
  3909. void CallStatement::setLeftFor(Exp* forExp, Exp* newExp) {
  3910. std::cerr << "! Attempt to setLeftFor this call statement! forExp is " << forExp << ", newExp is " << newExp <<
  3911. "\n";
  3912. assert(0);
  3913. }
  3914. bool Assignment::definesLoc(Exp* loc) {
  3915. if (lhs->getOper() == opAt) // For foo@[x:y], match of foo==loc OR whole thing == loc
  3916. if (*((Ternary*)lhs)->getSubExp1() == *loc) return true;
  3917. return *lhs == *loc;
  3918. }
  3919. bool CallStatement::definesLoc(Exp* loc) {
  3920. StatementList::iterator dd;
  3921. for (dd = defines.begin(); dd != defines.end(); ++dd) {
  3922. Exp* lhs = ((Assign*)*dd)->getLeft();
  3923. if (*lhs == *loc)
  3924. return true;
  3925. }
  3926. return false;
  3927. }
  3928. // Does a ReturnStatement define anything? Not really, the locations are already defined earlier in the procedure.
  3929. // However, nothing comes after the return statement, so it doesn't hurt to pretend it does, and this is a place to
  3930. // store the return type(s) for example.
  3931. // FIXME: seems it would be cleaner to say that Return Statements don't define anything.
  3932. bool ReturnStatement::definesLoc(Exp* loc) {
  3933. iterator it;
  3934. for (it = modifieds.begin(); it != modifieds.end(); it++) {
  3935. if ((*it)->definesLoc(loc))
  3936. return true;
  3937. }
  3938. return false;
  3939. }
  3940. // FIXME: see above
  3941. void ReturnStatement::getDefinitions(LocationSet& ls) {
  3942. iterator rr;
  3943. for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
  3944. (*rr)->getDefinitions(ls);
  3945. }
  3946. Type* ReturnStatement::getTypeFor(Exp* e) {
  3947. ReturnStatement::iterator rr;
  3948. for (rr = modifieds.begin(); rr != modifieds.end(); rr++) {
  3949. if (*((Assignment*)*rr)->getLeft() == *e)
  3950. return ((Assignment*)*rr)->getType();
  3951. }
  3952. return NULL;
  3953. }
  3954. void ReturnStatement::setTypeFor(Exp*e, Type* ty) {
  3955. ReturnStatement::iterator rr;
  3956. for (rr = modifieds.begin(); rr != modifieds.end(); rr++) {
  3957. if (*((Assignment*)*rr)->getLeft() == *e) {
  3958. ((Assignment*)*rr)->setType(ty);
  3959. break;
  3960. }
  3961. }
  3962. for (rr = returns.begin(); rr != returns.end(); rr++) {
  3963. if (*((Assignment*)*rr)->getLeft() == *e) {
  3964. ((Assignment*)*rr)->setType(ty);
  3965. return;
  3966. }
  3967. }
  3968. }
  3969. #define RETSTMT_COLS 120
  3970. void ReturnStatement::print(std::ostream& os, bool html) {
  3971. os << std::setw(4) << std::dec << number << " ";
  3972. if (html) {
  3973. os << "</td><td>";
  3974. os << "<a name=\"stmt" << std::dec << number << "\">";
  3975. }
  3976. os << "RET";
  3977. iterator it;
  3978. bool first = true;
  3979. unsigned column = 19;
  3980. for (it = returns.begin(); it != returns.end(); ++it) {
  3981. std::ostringstream ost;
  3982. ((Assignment*)*it)->printCompact(ost, html);
  3983. unsigned len = ost.str().length();
  3984. if (first) {
  3985. first = false;
  3986. os << " ";
  3987. } else if (column + 4 + len > RETSTMT_COLS) { // 4 for command 3 spaces
  3988. if (column != RETSTMT_COLS-1) os << ","; // Comma at end of line
  3989. os << "\n ";
  3990. column = 16;
  3991. } else {
  3992. os << ", ";
  3993. column += 4;
  3994. }
  3995. os << ost.str().c_str();
  3996. column += len;
  3997. }
  3998. if (html)
  3999. os << "</a><br>";
  4000. else
  4001. os << "\n ";
  4002. os << "Modifieds: ";
  4003. first = true;
  4004. column = 25;
  4005. for (it = modifieds.begin(); it != modifieds.end(); ++it) {
  4006. std::ostringstream ost;
  4007. Assign* as = (Assign*)*it;
  4008. Type* ty = as->getType();
  4009. if (ty)
  4010. ost << "*" << ty << "* ";
  4011. ost << as->getLeft();
  4012. unsigned len = ost.str().length();
  4013. if (first)
  4014. first = false;
  4015. else if (column + 3 + len > RETSTMT_COLS) { // 3 for comma and 2 spaces
  4016. if (column != RETSTMT_COLS-1) os << ","; // Comma at end of line
  4017. os << "\n ";
  4018. column = 16;
  4019. } else {
  4020. os << ", ";
  4021. column += 3;
  4022. }
  4023. os << ost.str().c_str();
  4024. column += len;
  4025. }
  4026. #if 1
  4027. // Collected reaching definitions
  4028. if (html)
  4029. os << "<br>";
  4030. else
  4031. os << "\n ";
  4032. os << "Reaching definitions: ";
  4033. col.print(os, html);
  4034. #endif
  4035. }
  4036. // A helper class for comparing Assignment*'s sensibly
  4037. bool lessAssignment::operator()(const Assignment* x, const Assignment* y) const {
  4038. Assignment* xx = const_cast<Assignment*>(x);
  4039. Assignment* yy = const_cast<Assignment*>(y);
  4040. return (*xx->getLeft() < *yy->getLeft()); // Compare the LHS expressions
  4041. }
  4042. // Repeat the above for Assign's; sometimes the compiler doesn't (yet) understand that Assign's are Assignment's
  4043. bool lessAssign::operator()(const Assign* x, const Assign* y) const {
  4044. Assign* xx = const_cast<Assign*>(x);
  4045. Assign* yy = const_cast<Assign*>(y);
  4046. return (*xx->getLeft() < *yy->getLeft()); // Compare the LHS expressions
  4047. }
  4048. // Update the modifieds, in case the signature and hence ordering and filtering has changed, or the locations in the
  4049. // collector have changed. Does NOT remove preserveds (deferred until updating returns).
  4050. void ReturnStatement::updateModifieds() {
  4051. Signature* sig = proc->getSignature();
  4052. StatementList oldMods(modifieds); // Copy the old modifieds
  4053. modifieds.clear();
  4054. if (pbb->getNumInEdges() == 1 && pbb->getInEdges()[0]->getLastStmt()->isCall()) {
  4055. CallStatement *call = (CallStatement*)pbb->getInEdges()[0]->getLastStmt();
  4056. if (call->getDestProc() && FrontEnd::noReturnCallDest(call->getDestProc()->getName()))
  4057. return;
  4058. }
  4059. // For each location in the collector, make sure that there is an assignment in the old modifieds, which will
  4060. // be filtered and sorted to become the new modifieds
  4061. // Ick... O(N*M) (N existing modifeds, M collected locations)
  4062. DefCollector::iterator ll;
  4063. StatementList::iterator it;
  4064. for (ll = col.begin(); ll != col.end(); ++ll) {
  4065. bool found = false;
  4066. Assign* as = (Assign*)*ll;
  4067. Exp* colLhs = as->getLeft();
  4068. if (proc->filterReturns(colLhs))
  4069. continue; // Filtered out
  4070. for (it = oldMods.begin(); it != oldMods.end(); it++) {
  4071. Exp* lhs = ((Assign*)*it)->getLeft();
  4072. if (*lhs == *colLhs) {
  4073. found = true;
  4074. break;
  4075. }
  4076. }
  4077. if (!found) {
  4078. ImplicitAssign* ias = new ImplicitAssign(
  4079. as->getType()->clone(),
  4080. as->getLeft()->clone());
  4081. ias->setProc(proc); // Comes from the Collector
  4082. ias->setBB(pbb);
  4083. oldMods.append(ias);
  4084. }
  4085. }
  4086. // Mostly the old modifications will be in the correct order, and inserting will be fastest near the start of the
  4087. // new list. So read the old modifications in reverse order
  4088. for (it = oldMods.end(); it != oldMods.begin(); ) {
  4089. --it; // Becuase we are using a forwards iterator backwards
  4090. // Make sure the LHS is still in the collector
  4091. Assign* as = (Assign*)*it;
  4092. Exp* lhs = as->getLeft();
  4093. if (!col.existsOnLeft(lhs))
  4094. continue; // Not in collector: delete it (don't copy it)
  4095. if (proc->filterReturns(lhs))
  4096. continue; // Filtered out: delete it
  4097. // Insert as, in order, into the existing set of modifications
  4098. StatementList::iterator nn;
  4099. bool inserted = false;
  4100. for (nn = modifieds.begin(); nn != modifieds.end(); ++nn) {
  4101. if (sig->returnCompare(*as, *(Assign*)*nn)) { // If the new assignment is less than the current one
  4102. nn = modifieds.insert(nn, as); // then insert before this position
  4103. inserted = true;
  4104. break;
  4105. }
  4106. }
  4107. if (!inserted)
  4108. modifieds.insert(modifieds.end(), as); // In case larger than all existing elements
  4109. }
  4110. }
  4111. // Update the returns, in case the signature and hence ordering and filtering has changed, or the locations in the
  4112. // modifieds list
  4113. void ReturnStatement::updateReturns() {
  4114. Signature* sig = proc->getSignature();
  4115. int sp = sig->getStackRegister();
  4116. StatementList oldRets(returns); // Copy the old returns
  4117. returns.clear();
  4118. // For each location in the modifieds, make sure that there is an assignment in the old returns, which will
  4119. // be filtered and sorted to become the new returns
  4120. // Ick... O(N*M) (N existing returns, M modifieds locations)
  4121. StatementList::iterator dd, it;
  4122. for (dd = modifieds.begin(); dd != modifieds.end(); ++dd) {
  4123. bool found = false;
  4124. Exp* loc = ((Assignment*)*dd)->getLeft();
  4125. if (proc->filterReturns(loc))
  4126. continue; // Filtered out
  4127. // Special case for the stack pointer: it has to be a modified (otherwise, the changes will bypass the calls),
  4128. // but it is not wanted as a return
  4129. if (loc->isRegN(sp)) continue;
  4130. for (it = oldRets.begin(); it != oldRets.end(); it++) {
  4131. Exp* lhs = ((Assign*)*it)->getLeft();
  4132. if (*lhs == *loc) {
  4133. found = true;
  4134. break;
  4135. }
  4136. }
  4137. if (!found) {
  4138. Exp* rhs = col.findDefFor(loc); // Find the definition that reaches the return statement's collector
  4139. Assign* as = new Assign(loc->clone(), rhs->clone());
  4140. as->setProc(proc);
  4141. as->setBB(pbb);
  4142. oldRets.append(as);
  4143. }
  4144. }
  4145. // Mostly the old returns will be in the correct order, and inserting will be fastest near the start of the
  4146. // new list. So read the old returns in reverse order
  4147. for (it = oldRets.end(); it != oldRets.begin(); ) {
  4148. --it; // Becuase we are using a forwards iterator backwards
  4149. // Make sure the LHS is still in the modifieds
  4150. Assign* as = (Assign*)*it;
  4151. Exp* lhs = as->getLeft();
  4152. if (!modifieds.existsOnLeft(lhs))
  4153. continue; // Not in modifieds: delete it (don't copy it)
  4154. if (proc->filterReturns(lhs))
  4155. continue; // Filtered out: delete it
  4156. #if 1
  4157. // Preserveds are NOT returns (nothing changes, so what are we returning?)
  4158. // Check if it is a preserved location, e.g. r29 := r29{-}
  4159. Exp* rhs = as->getRight();
  4160. if (rhs->isSubscript() && ((RefExp*)rhs)->isImplicitDef() && *((RefExp*)rhs)->getSubExp1() == *lhs)
  4161. continue; // Filter out the preserveds
  4162. #endif
  4163. // Insert as, in order, into the existing set of returns
  4164. StatementList::iterator nn;
  4165. bool inserted = false;
  4166. for (nn = returns.begin(); nn != returns.end(); ++nn) {
  4167. if (sig->returnCompare(*as, *(Assign*)*nn)) { // If the new assignment is less than the current one
  4168. nn = returns.insert(nn, as); // then insert before this position
  4169. inserted = true;
  4170. break;
  4171. }
  4172. }
  4173. if (!inserted)
  4174. returns.insert(returns.end(), as); // In case larger than all existing elements
  4175. }
  4176. }
  4177. // Set the defines to the set of locations modified by the callee, or if no callee, to all variables live at this call
  4178. void CallStatement::updateDefines() {
  4179. Signature* sig;
  4180. if (procDest)
  4181. // The signature knows how to order the returns
  4182. sig = procDest->getSignature();
  4183. else
  4184. // Else just use the enclosing proc's signature
  4185. sig = proc->getSignature();
  4186. if (procDest && procDest->isLib()) {
  4187. sig->setLibraryDefines(&defines); // Set the locations defined
  4188. return;
  4189. } else if (Boomerang::get()->assumeABI) {
  4190. // Risky: just assume the ABI caller save registers are defined
  4191. Signature::setABIdefines(proc->getProg(), &defines);
  4192. return;
  4193. }
  4194. // Move the defines to a temporary list
  4195. StatementList oldDefines(defines); // Copy the old defines
  4196. StatementList::iterator it;
  4197. defines.clear();
  4198. if (procDest && calleeReturn) {
  4199. StatementList::iterator mm;
  4200. StatementList& modifieds = ((UserProc*)procDest)->getModifieds();
  4201. for (mm = modifieds.begin(); mm != modifieds.end(); ++mm) {
  4202. Assign* as = (Assign*)*mm;
  4203. Exp* loc = as->getLeft();
  4204. if (proc->filterReturns(loc))
  4205. continue;
  4206. Type* ty = as->getType();
  4207. if (!oldDefines.existsOnLeft(loc))
  4208. oldDefines.append(new ImplicitAssign(ty, loc));
  4209. }
  4210. } else {
  4211. // Ensure that everything in the UseCollector has an entry in oldDefines
  4212. LocationSet::iterator ll;
  4213. for (ll = useCol.begin(); ll != useCol.end(); ++ll) {
  4214. Exp* loc = *ll;
  4215. if (proc->filterReturns(loc))
  4216. continue; // Filtered out
  4217. if (!oldDefines.existsOnLeft(loc)) {
  4218. ImplicitAssign* as = new ImplicitAssign(loc->clone());
  4219. as->setProc(proc);
  4220. as->setBB(pbb);
  4221. oldDefines.append(as);
  4222. }
  4223. }
  4224. }
  4225. for (it = oldDefines.end(); it != oldDefines.begin(); ) {
  4226. --it; // Becuase we are using a forwards iterator backwards
  4227. // Make sure the LHS is still in the return or collector
  4228. Assign* as = (Assign*)*it;
  4229. Exp* lhs = as->getLeft();
  4230. if (calleeReturn) {
  4231. if (!calleeReturn->definesLoc(lhs))
  4232. continue; // Not in callee returns
  4233. } else {
  4234. if (!useCol.exists(lhs))
  4235. continue; // Not in collector: delete it (don't copy it)
  4236. }
  4237. if (proc->filterReturns(lhs))
  4238. continue; // Filtered out: delete it
  4239. // Insert as, in order, into the existing set of definitions
  4240. StatementList::iterator nn;
  4241. bool inserted = false;
  4242. for (nn = defines.begin(); nn != defines.end(); ++nn) {
  4243. if (sig->returnCompare(*as, *(Assign*)*nn)) { // If the new assignment is less than the current one
  4244. nn = defines.insert(nn, as); // then insert before this position
  4245. inserted = true;
  4246. break;
  4247. }
  4248. }
  4249. if (!inserted)
  4250. defines.insert(defines.end(), as); // In case larger than all existing elements
  4251. }
  4252. }
  4253. // A helper class for updateArguments. It just dishes out a new argument from one of the three sources: the signature,
  4254. // the callee parameters, or the defCollector in the call
  4255. class ArgSourceProvider {
  4256. enum Src {SRC_LIB, SRC_CALLEE, SRC_COL};
  4257. Src src;
  4258. CallStatement* call;
  4259. int i, n; // For SRC_LIB
  4260. Signature* callSig;
  4261. StatementList::iterator pp; // For SRC_CALLEE
  4262. StatementList* calleeParams;
  4263. DefCollector::iterator cc; // For SRC_COL
  4264. DefCollector* defCol;
  4265. public:
  4266. ArgSourceProvider(CallStatement* call);
  4267. Exp* nextArgLoc(); // Get the next location (not subscripted)
  4268. Type* curType(Exp* e); // Get the current location's type
  4269. bool exists(Exp* loc); // True if the given location (not subscripted) exists as a source
  4270. Exp* localise(Exp* e); // Localise to this call if necessary
  4271. };
  4272. ArgSourceProvider::ArgSourceProvider(CallStatement* call) : call(call) {
  4273. Proc* procDest = call->getDestProc();
  4274. if (procDest && procDest->isLib()) {
  4275. src = SRC_LIB;
  4276. callSig = call->getSignature();
  4277. n = callSig->getNumParams();
  4278. i = 0;
  4279. } else if (call->getCalleeReturn() != NULL) {
  4280. src = SRC_CALLEE;
  4281. calleeParams = &((UserProc*)procDest)->getParameters();
  4282. pp = calleeParams->begin();
  4283. } else {
  4284. Signature* destSig = NULL;
  4285. if (procDest)
  4286. destSig = procDest->getSignature();
  4287. if (destSig && destSig->isForced()) {
  4288. src = SRC_LIB;
  4289. callSig = destSig;
  4290. n = callSig->getNumParams();
  4291. i = 0;
  4292. } else {
  4293. src = SRC_COL;
  4294. defCol = call->getDefCollector();
  4295. cc = defCol->begin();
  4296. }
  4297. }
  4298. }
  4299. Exp* ArgSourceProvider::nextArgLoc() {
  4300. Exp* s;
  4301. bool allZero;
  4302. switch(src) {
  4303. case SRC_LIB:
  4304. if (i == n) return NULL;
  4305. s = callSig->getParamExp(i++)->clone();
  4306. s->removeSubscripts(allZero); // e.g. m[sp{-} + 4] -> m[sp + 4]
  4307. call->localiseComp(s);
  4308. return s;
  4309. case SRC_CALLEE:
  4310. if (pp == calleeParams->end()) return NULL;
  4311. s = ((Assignment*)*pp++)->getLeft()->clone();
  4312. s->removeSubscripts(allZero);
  4313. call->localiseComp(s); // Localise the components. Has the effect of translating into
  4314. // the contect of this caller
  4315. return s;
  4316. case SRC_COL:
  4317. if (cc == defCol->end()) return NULL;
  4318. // Give the location, i.e. the left hand side of the assignment
  4319. return ((Assign*)*cc++)->getLeft();
  4320. }
  4321. return NULL; // Suppress warning
  4322. }
  4323. Exp* ArgSourceProvider::localise(Exp* e) {
  4324. if (src == SRC_COL) {
  4325. // Provide the RHS of the current assignment
  4326. Exp* ret = ((Assign*)*--cc)->getRight();
  4327. ++cc;
  4328. return ret;
  4329. }
  4330. // Else just use the call to localise
  4331. return call->localiseExp(e);
  4332. }
  4333. Type* ArgSourceProvider::curType(Exp* e) {
  4334. switch(src) {
  4335. case SRC_LIB:
  4336. return callSig->getParamType(i-1);
  4337. case SRC_CALLEE: {
  4338. Type* ty = ((Assignment*)*--pp)->getType();
  4339. pp++;
  4340. return ty;
  4341. }
  4342. case SRC_COL: {
  4343. // Mostly, there won't be a type here, I would think...
  4344. Type* ty = (*--cc)->getType();
  4345. ++cc;
  4346. return ty;
  4347. }
  4348. }
  4349. return NULL; // Suppress warning
  4350. }
  4351. bool ArgSourceProvider::exists(Exp* e) {
  4352. bool allZero;
  4353. switch (src) {
  4354. case SRC_LIB:
  4355. if (callSig->hasEllipsis())
  4356. // FIXME: for now, just don't check
  4357. return true;
  4358. for (i=0; i < n; i++) {
  4359. Exp* sigParam = callSig->getParamExp(i)->clone();
  4360. sigParam->removeSubscripts(allZero);
  4361. call->localiseComp(sigParam);
  4362. if (*sigParam == *e)
  4363. return true;
  4364. }
  4365. return false;
  4366. case SRC_CALLEE:
  4367. for (pp = calleeParams->begin(); pp != calleeParams->end(); ++pp) {
  4368. Exp* par = ((Assignment*)*pp)->getLeft()->clone();
  4369. par->removeSubscripts(allZero);
  4370. call->localiseComp(par);
  4371. if (*par == *e)
  4372. return true;
  4373. }
  4374. return false;
  4375. case SRC_COL:
  4376. return defCol->existsOnLeft(e);
  4377. }
  4378. return false; // Suppress warning
  4379. }
  4380. void CallStatement::updateArguments() {
  4381. /* If this is a library call, source = signature
  4382. else if there is a callee return, source = callee parameters
  4383. else
  4384. if a forced callee signature, source = signature
  4385. else source is def collector in this call.
  4386. oldArguments = arguments
  4387. clear arguments
  4388. for each arg lhs in source
  4389. if exists in oldArguments, leave alone
  4390. else if not filtered append assignment lhs=lhs to oldarguments
  4391. for each argument as in oldArguments in reverse order
  4392. lhs = as->getLeft
  4393. if (lhs does not exist in source) continue
  4394. if filterParams(lhs) continue
  4395. insert as into arguments, considering sig->argumentCompare
  4396. */
  4397. // Note that if propagations are limited, arguments and collected reaching definitions can be in terms of phi
  4398. // statements that have since been translated to assignments. So propagate through them now
  4399. // FIXME: reconsider! There are problems (e.g. with test/pentium/fromSSA2, test/pentium/fbranch) if you propagate
  4400. // to the expressions in the arguments (e.g. m[esp{phi1}-20]) but don't propagate into ordinary statements that
  4401. // define the actual argument. For example, you might have m[esp{-}-56] in the call, but the actual definition of
  4402. // the printf argument is still m[esp{phi1} -20] = "%d".
  4403. if (EXPERIMENTAL) {
  4404. bool convert;
  4405. proc->propagateStatements(convert, 88);
  4406. }
  4407. StatementList oldArguments(arguments);
  4408. arguments.clear();
  4409. if (EXPERIMENTAL) {
  4410. // I don't really know why this is needed, but I was seeing r28 := ((((((r28{-}-4)-4)-4)-8)-4)-4)-4:
  4411. DefCollector::iterator dd;
  4412. for (dd = defCol.begin(); dd != defCol.end(); ++dd)
  4413. (*dd)->simplify();
  4414. }
  4415. Signature* sig = proc->getSignature();
  4416. // Ensure everything in the callee's signature (if this is a library call), or the callee parameters (if available),
  4417. // or the def collector if not, exists in oldArguments
  4418. ArgSourceProvider asp(this);
  4419. Exp* loc;
  4420. while ((loc = asp.nextArgLoc()) != NULL) {
  4421. if (proc->filterParams(loc))
  4422. continue;
  4423. if (!oldArguments.existsOnLeft(loc)) {
  4424. // Check if the location is renamable. If not, localising won't work, since it relies on definitions
  4425. // collected in the call, and you just get m[...]{-} even if there are definitions.
  4426. Exp* rhs;
  4427. if (proc->canRename(loc))
  4428. rhs = asp.localise(loc->clone());
  4429. else
  4430. rhs = loc->clone();
  4431. Type* ty = asp.curType(loc);
  4432. Assign* as = new Assign(ty, loc->clone(), rhs);
  4433. as->setNumber(number); // Give the assign the same statement number as the call (for now)
  4434. as->setParent(this);
  4435. as->setProc(proc);
  4436. as->setBB(pbb);
  4437. oldArguments.append(as);
  4438. }
  4439. }
  4440. StatementList::iterator it;
  4441. for (it = oldArguments.end(); it != oldArguments.begin(); ) {
  4442. --it; // Becuase we are using a forwards iterator backwards
  4443. // Make sure the LHS is still in the callee signature / callee parameters / use collector
  4444. Assign* as = (Assign*)*it;
  4445. Exp* lhs = as->getLeft();
  4446. if (!asp.exists(lhs)) continue;
  4447. if (proc->filterParams(lhs))
  4448. continue; // Filtered out: delete it
  4449. // Insert as, in order, into the existing set of definitions
  4450. StatementList::iterator nn;
  4451. bool inserted = false;
  4452. for (nn = arguments.begin(); nn != arguments.end(); ++nn) {
  4453. if (sig->argumentCompare(*as, *(Assign*)*nn)) { // If the new assignment is less than the current one
  4454. nn = arguments.insert(nn, as); // then insert before this position
  4455. inserted = true;
  4456. break;
  4457. }
  4458. }
  4459. if (!inserted)
  4460. arguments.insert(arguments.end(), as); // In case larger than all existing elements
  4461. }
  4462. }
  4463. // Calculate results(this) = defines(this) isect live(this)
  4464. // Note: could use a LocationList for this, but then there is nowhere to store the types (for DFA based TA)
  4465. // So the RHS is just ignored
  4466. StatementList* CallStatement::calcResults() {
  4467. StatementList* ret = new StatementList;
  4468. if (procDest) {
  4469. Signature* sig = procDest->getSignature();
  4470. if (procDest && procDest->isLib()) {
  4471. int n = sig->getNumReturns();
  4472. for (int i=1; i < n; i++) { // Ignore first (stack pointer) return
  4473. Exp* sigReturn = sig->getReturnExp(i);
  4474. #if SYMS_IN_BACK_END
  4475. // But we have translated out of SSA form, so some registers have had to have been replaced with locals
  4476. // So wrap the return register in a ref to this and check the locals
  4477. RefExp* wrappedRet = new RefExp(sigReturn, this);
  4478. char* locName = proc->findLocal(wrappedRet); // E.g. r24{16}
  4479. if (locName)
  4480. sigReturn = Location::local(locName, proc); // Replace e.g. r24 with local19
  4481. #endif
  4482. if (useCol.exists(sigReturn)) {
  4483. ImplicitAssign* as = new ImplicitAssign(getTypeFor(sigReturn), sigReturn);
  4484. ret->append(as);
  4485. }
  4486. }
  4487. } else {
  4488. Exp* rsp = Location::regOf(proc->getSignature()->getStackRegister(proc->getProg()));
  4489. StatementList::iterator dd;
  4490. for (dd = defines.begin(); dd != defines.end(); ++dd) {
  4491. Exp* lhs = ((Assign*)*dd)->getLeft();
  4492. // The stack pointer is allowed as a define, so remove it here as a special case non result
  4493. if (*lhs == *rsp) continue;
  4494. if (useCol.exists(lhs))
  4495. ret->append(*dd);
  4496. }
  4497. }
  4498. } else {
  4499. // For a call with no destination at this late stage, use everything live at the call except for the stack
  4500. // pointer register. Needs to be sorted
  4501. UseCollector::iterator rr; // Iterates through reaching definitions
  4502. StatementList::iterator nn; // Iterates through new results
  4503. Signature* sig = proc->getSignature();
  4504. int sp = sig->getStackRegister();
  4505. for (rr = useCol.begin(); rr != useCol.end(); ++rr) {
  4506. Exp* loc = *rr;
  4507. if (proc->filterReturns(loc)) continue; // Ignore filtered locations
  4508. if (loc->isRegN(sp)) continue; // Ignore the stack pointer
  4509. ImplicitAssign* as = new ImplicitAssign(loc); // Create an implicit assignment
  4510. bool inserted = false;
  4511. for (nn = ret->begin(); nn != ret->end(); ++nn) {
  4512. // If the new assignment is less than the current one,
  4513. if (sig->returnCompare(*as, *(Assignment*)*nn)) {
  4514. nn = ret->insert(nn, as); // then insert before this position
  4515. inserted = true;
  4516. break;
  4517. }
  4518. }
  4519. if (!inserted)
  4520. ret->insert(ret->end(), as); // In case larger than all existing elements
  4521. }
  4522. }
  4523. return ret;
  4524. }
  4525. #if 0
  4526. void TypingStatement::setType(Type* ty) {
  4527. type = ty;
  4528. }
  4529. #endif
  4530. void CallStatement::removeDefine(Exp* e) {
  4531. StatementList::iterator ss;
  4532. for (ss = defines.begin(); ss != defines.end(); ++ss) {
  4533. Assign* as = ((Assign*)*ss);
  4534. if (*as->getLeft() == *e) {
  4535. defines.erase(ss);
  4536. return;
  4537. }
  4538. }
  4539. LOG << "WARNING: could not remove define " << e << " from call " << this << "\n";
  4540. }
  4541. bool CallStatement::isChildless() {
  4542. if (procDest == NULL) return true;
  4543. if (procDest->isLib()) return false;
  4544. // Early in the decompile process, recursive calls are treated as childless, so they use and define all
  4545. if (((UserProc*)procDest)->isEarlyRecursive())
  4546. return true;
  4547. return calleeReturn == NULL;
  4548. }
  4549. Exp* CallStatement::bypassRef(RefExp* r, bool& ch) {
  4550. Exp* base = r->getSubExp1();
  4551. Exp* proven;
  4552. ch = false;
  4553. if (procDest && procDest->isLib()) {
  4554. Signature* sig = procDest->getSignature();
  4555. proven = sig->getProven(base);
  4556. if (proven == NULL) { // Not (known to be) preserved
  4557. if (sig->findReturn(base) != -1)
  4558. return r; // Definately defined, it's the return
  4559. // Otherwise, not all that sure. Assume that library calls pass things like local variables
  4560. }
  4561. } else {
  4562. // Was using the defines to decide if something is preserved, but consider sp+4 for stack based machines
  4563. // Have to use the proven information for the callee (if any)
  4564. if (procDest == NULL)
  4565. return r; // Childless callees transmit nothing
  4566. //if (procDest->isLocal(base)) // ICK! Need to prove locals and parameters through calls...
  4567. // FIXME: temporary HACK! Ignores alias issues.
  4568. if (!procDest->isLib() && ((UserProc*)procDest)->isLocalOrParamPattern(base)) {
  4569. Exp* ret = localiseExp(base->clone()); // Assume that it is proved as preserved
  4570. ch = true;
  4571. if (VERBOSE)
  4572. LOG << base << " allowed to bypass call statement " << number << " ignoring aliasing; result " << ret <<
  4573. "\n";
  4574. return ret;
  4575. }
  4576. proven = procDest->getProven(base); // e.g. r28+4
  4577. }
  4578. if (proven == NULL)
  4579. return r; // Can't bypass, since nothing proven
  4580. Exp* to = localiseExp(base); // e.g. r28{17}
  4581. assert(to);
  4582. proven = proven->clone(); // Don't modify the expressions in destProc->proven!
  4583. proven = proven->searchReplaceAll(base, to, ch); // e.g. r28{17} + 4
  4584. if (ch && VERBOSE)
  4585. LOG << "bypassRef() replacing " << r << " with " << proven << "\n";
  4586. return proven;
  4587. }
  4588. void ReturnStatement::removeModified(Exp* loc) {
  4589. modifieds.removeDefOf(loc);
  4590. returns.removeDefOf(loc);
  4591. }
  4592. void CallStatement::addDefine(ImplicitAssign* as) {
  4593. defines.append(as);
  4594. }
  4595. TypingStatement::TypingStatement(Type* ty) : type(ty) {
  4596. }
  4597. // NOTE: ImpRefStatement not yet used
  4598. void ImpRefStatement::print(std::ostream& os, bool html) {
  4599. os << " *"; // No statement number
  4600. if (html) {
  4601. os << "</td><td>";
  4602. os << "<a name=\"stmt" << std::dec << number << "\">";
  4603. }
  4604. os << type << "* IMP REF " << addressExp;
  4605. if (html)
  4606. os << "</a></td>";
  4607. }
  4608. void ImpRefStatement::meetWith(Type* ty, bool& ch) {
  4609. type = type->meetWith(ty, ch);
  4610. }
  4611. Statement* ImpRefStatement::clone() {
  4612. return new ImpRefStatement(type->clone(), addressExp->clone());
  4613. }
  4614. bool ImpRefStatement::accept(StmtVisitor* visitor) {
  4615. return visitor->visit(this);
  4616. }
  4617. bool ImpRefStatement::accept(StmtExpVisitor* v) {
  4618. bool override;
  4619. bool ret = v->visit(this, override);
  4620. if (override)
  4621. return ret;
  4622. if (ret) ret = addressExp->accept(v->ev);
  4623. return ret;
  4624. }
  4625. bool ImpRefStatement::accept(StmtModifier* v) {
  4626. bool recur;
  4627. v->visit(this, recur);
  4628. v->mod->clearMod();
  4629. if (recur) addressExp = addressExp->accept(v->mod);
  4630. if (VERBOSE && v->mod->isMod())
  4631. LOG << "ImplicitRef changed: now " << this << "\n";
  4632. return true;
  4633. }
  4634. bool ImpRefStatement::accept(StmtPartModifier* v) {
  4635. bool recur;
  4636. v->visit(this, recur);
  4637. v->mod->clearMod();
  4638. if (recur) addressExp = addressExp->accept(v->mod);
  4639. if (VERBOSE && v->mod->isMod())
  4640. LOG << "ImplicitRef changed: now " << this << "\n";
  4641. return true;
  4642. }
  4643. bool ImpRefStatement::search(Exp* search, Exp*& result) {
  4644. result = NULL;
  4645. return addressExp->search(search, result);
  4646. }
  4647. bool ImpRefStatement::searchAll(Exp* search, std::list<Exp*, std::allocator<Exp*> >& result) {
  4648. return addressExp->searchAll(search, result);
  4649. }
  4650. bool ImpRefStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
  4651. bool change;
  4652. addressExp = addressExp->searchReplaceAll(search, replace, change);
  4653. return change;
  4654. }
  4655. void ImpRefStatement::simplify() {addressExp = addressExp->simplify();}
  4656. void CallStatement::eliminateDuplicateArgs() {
  4657. StatementList::iterator it;
  4658. LocationSet ls;
  4659. for (it = arguments.begin(); it != arguments.end(); ) {
  4660. Exp* lhs = ((Assignment*)*it)->getLeft();
  4661. if (ls.exists(lhs)) {
  4662. // This is a duplicate
  4663. it = arguments.erase(it);
  4664. continue;
  4665. }
  4666. ls.insert(lhs);
  4667. ++it;
  4668. }
  4669. }
  4670. void PhiAssign::enumerateParams(std::list<Exp*>& le) {
  4671. iterator it;
  4672. for (it = begin(); it != end(); ++it) {
  4673. if (it->e == NULL) continue;
  4674. RefExp* r = new RefExp(it->e, it->def);
  4675. le.push_back(r);
  4676. }
  4677. }
  4678. // For debugging
  4679. void dumpDestCounts(std::map<Exp*, int, lessExpStar>* destCounts) {
  4680. std::map<Exp*, int, lessExpStar>::iterator it;
  4681. for (it = destCounts->begin(); it != destCounts->end(); ++it) {
  4682. std::cerr << std::setw(4) << std::dec << it->second << " " << it->first << "\n";
  4683. }
  4684. }
  4685. bool JunctionStatement::accept(StmtVisitor* visitor)
  4686. {
  4687. return true;
  4688. }
  4689. bool JunctionStatement::accept(StmtExpVisitor* visitor)
  4690. {
  4691. return true;
  4692. }
  4693. bool JunctionStatement::accept(StmtModifier* visitor)
  4694. {
  4695. return true;
  4696. }
  4697. bool JunctionStatement::accept(StmtPartModifier* visitor)
  4698. {
  4699. return true;
  4700. }
  4701. void JunctionStatement::print(std::ostream &os, bool html)
  4702. {
  4703. os << std::setw(4) << std::dec << number << " ";
  4704. if (html) {
  4705. os << "</td><td>";
  4706. os << "<a name=\"stmt" << std::dec << number << "\">";
  4707. }
  4708. os << "JUNCTION ";
  4709. for (int i = 0; i < pbb->getNumInEdges(); i++) {
  4710. os << std::hex << pbb->getInEdges()[i]->getHiAddr() << std::dec;
  4711. if (pbb->isBackEdge(i))
  4712. os << "*";
  4713. os << " ";
  4714. }
  4715. if (isLoopJunction())
  4716. os << "LOOP";
  4717. os << "\n\t\t\tranges: ";
  4718. ranges.print(os);
  4719. if (html)
  4720. os << "</a></td>";
  4721. }
  4722. // Map registers and temporaries to locals
  4723. void Statement::mapRegistersToLocals() {
  4724. ExpRegMapper erm(proc);
  4725. StmtRegMapper srm(&erm);
  4726. accept(&srm);
  4727. }
  4728. void Statement::insertCasts() {
  4729. // First we postvisit expressions using a StmtModifier and an ExpCastInserter
  4730. ExpCastInserter eci(proc);
  4731. StmtModifier sm(&eci, true); // True to ignore collectors
  4732. accept(&sm);
  4733. // Now handle the LHS of assigns that happen to be m[...], using a StmtCastInserter
  4734. StmtCastInserter sci;
  4735. accept(&sci);
  4736. }
  4737. void Statement::replaceSubscriptsWithLocals() {
  4738. ExpSsaXformer esx(proc);
  4739. StmtSsaXformer ssx(&esx, proc);
  4740. accept(&ssx);
  4741. }
  4742. void Statement::dfaMapLocals() {
  4743. DfaLocalMapper dlm(proc);
  4744. StmtModifier sm(&dlm, true); // True to ignore def collector in return statement
  4745. accept(&sm);
  4746. if (VERBOSE && dlm.change)
  4747. LOG << "statement mapped with new local(s): " << number << "\n";
  4748. }
  4749. void CallStatement::setNumber(int num) {
  4750. number = num;
  4751. // Also number any existing arguments. Important for library procedures, since these have arguments set by the front
  4752. // end based in their signature
  4753. StatementList::iterator aa;
  4754. for (aa = arguments.begin(); aa != arguments.end(); ++aa)
  4755. (*aa)->setNumber(num);
  4756. }