00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <assert.h>
00030 #if defined(_MSC_VER) && _MSC_VER <= 1200
00031 #pragma warning(disable:4786)
00032 #endif
00033
00034 #include <sstream>
00035 #include "types.h"
00036 #include "BinaryFile.h"
00037 #include "frontend.h"
00038 #include "pentiumfrontend.h"
00039 #include "rtl.h"
00040 #include "decoder.h"
00041 #include "pentiumdecoder.h"
00042 #include "register.h"
00043 #include "type.h"
00044 #include "cfg.h"
00045 #include "exp.h"
00046 #include "proc.h"
00047 #include "signature.h"
00048 #include "prog.h"
00049 #include "BinaryFile.h"
00050 #include "boomerang.h"
00051 #include "log.h"
00052
00053
00054
00055
00056
00057 #define FSW 40 // Numeric registers
00058 #define AH 12
00059
00060
00061
00062
00063
00064
00065
00066
00067 bool PentiumFrontEnd::isStoreFsw(Statement* s) {
00068 if (!s->isAssign()) return false;
00069 Exp* rhs = ((Assign*)s)->getRight();
00070 Exp* result;
00071 bool res = rhs->search(Location::regOf(FSW), result);
00072 return res;
00073 }
00074
00075
00076
00077
00078
00079
00080 bool PentiumFrontEnd::isDecAh(RTL* r) {
00081
00082 if (r->getNumStmt() != 3) return false;
00083 Statement* mid = r->elementAt(1);
00084 if (!mid->isAssign()) return false;
00085 Assign* asgn = (Assign*)mid;
00086 Exp* rhs = asgn->getRight();
00087 Binary ahm1(opMinus,
00088 new Binary(opSize,
00089 new Const(8),
00090 Location::regOf(12)),
00091 new Const(1));
00092 return *rhs == ahm1;
00093 }
00094
00095
00096
00097
00098
00099
00100 bool PentiumFrontEnd::isSetX(Statement* s) {
00101
00102
00103 if (!s->isAssign()) return false;
00104 Assign* asgn = (Assign*)s;
00105 Exp* lhs = asgn->getLeft();
00106
00107 if (!lhs->isRegOf()) return false;
00108 Exp* rhs = asgn->getRight();
00109 if (rhs->getOper() != opTern) return false;
00110 Exp* s2 = ((Ternary*)rhs)->getSubExp2();
00111 Exp* s3 = ((Ternary*)rhs)->getSubExp3();
00112 if (!s2->isIntConst() || s3->isIntConst()) return false;
00113 return ((Const*)s2)->getInt() == 1 && ((Const*)s3)->getInt() == 0;
00114 }
00115
00116
00117
00118
00119
00120
00121 bool PentiumFrontEnd::isAssignFromTern(Statement* s) {
00122 if (!s->isAssign()) return false;
00123 Assign* asgn = (Assign*)s;
00124 Exp* rhs = asgn->getRight();
00125 return rhs->getOper() == opTern;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 void PentiumFrontEnd::bumpRegisterAll(Exp* e, int min, int max, int delta, int mask) {
00142 std::list<Exp**> li;
00143 std::list<Exp**>::iterator it;
00144 Exp* exp = e;
00145
00146
00147 Exp::doSearch(Location::regOf(new Terminal(opWild)), exp, li, false);
00148 for (it = li.begin(); it != li.end(); it++) {
00149 int reg = ((Const*)((Unary*)**it)->getSubExp1())->getInt();
00150 if ((min <= reg) && (reg <= max)) {
00151
00152
00153 Const* K = (Const*)((Unary*)**it)->getSubExp1();
00154 K->setInt(min + (reg - min + delta & mask));
00155 }
00156 }
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 bool PentiumFrontEnd::processProc(ADDRESS uAddr, UserProc* pProc, std::ofstream &os, bool frag ,
00169 bool spec ) {
00170
00171
00172 if (!FrontEnd::processProc(uAddr, pProc, os, frag, spec))
00173 return false;
00174
00175
00176
00177
00178 Cfg* pCfg = pProc->getCFG();
00179 pCfg->unTraverse();
00180
00181 pProc->setEntryBB();
00182
00183 processFloatCode(pCfg);
00184
00185 int tos = 0;
00186 processFloatCode(pProc->getEntryBB(), tos, pCfg);
00187
00188
00189 processStringInst(pProc);
00190
00191
00192 processOverlapped(pProc);
00193
00194 return true;
00195 }
00196
00197 std::vector<Exp*> &PentiumFrontEnd::getDefaultParams()
00198 {
00199 static std::vector<Exp*> params;
00200 if (params.size() == 0) {
00201 params.push_back(Location::regOf(24));
00202 params.push_back(Location::regOf(25));
00203 params.push_back(Location::regOf(26));
00204 params.push_back(Location::regOf(27));
00205 params.push_back(Location::regOf(28));
00206 params.push_back(Location::regOf(29));
00207 params.push_back(Location::regOf(30));
00208 params.push_back(Location::regOf(31));
00209 params.push_back(Location::memOf(Location::regOf(28)));
00210 }
00211 return params;
00212 }
00213
00214 std::vector<Exp*> &PentiumFrontEnd::getDefaultReturns()
00215 {
00216 static std::vector<Exp*> returns;
00217 if (returns.size() == 0) {
00218 returns.push_back(Location::regOf(24));
00219 returns.push_back(Location::regOf(25));
00220 returns.push_back(Location::regOf(26));
00221 returns.push_back(Location::regOf(27));
00222 returns.push_back(Location::regOf(28));
00223 returns.push_back(Location::regOf(29));
00224 returns.push_back(Location::regOf(30));
00225 returns.push_back(Location::regOf(31));
00226 returns.push_back(Location::regOf(32));
00227 returns.push_back(Location::regOf(33));
00228 returns.push_back(Location::regOf(34));
00229 returns.push_back(Location::regOf(35));
00230 returns.push_back(Location::regOf(36));
00231 returns.push_back(Location::regOf(37));
00232 returns.push_back(Location::regOf(38));
00233 returns.push_back(Location::regOf(39));
00234 returns.push_back(new Terminal(opPC));
00235 }
00236 return returns;
00237 }
00238
00239 void PentiumFrontEnd::processFloatCode(Cfg* pCfg)
00240 {
00241 BB_IT it;
00242 for (PBB pBB = pCfg->getFirstBB(it); pBB; pBB = pCfg->getNextBB(it)) {
00243 std::list<RTL*>::iterator rit;
00244 Statement* st;
00245
00246
00247 std::list<RTL*>* BB_rtls = pBB->getRTLs();
00248 if (BB_rtls == 0) {
00249
00250 return;
00251 }
00252 rit = BB_rtls->begin();
00253 while (rit != BB_rtls->end()) {
00254 for (int i=0; i < (*rit)->getNumStmt(); i++) {
00255
00256 st = (*rit)->elementAt(i);
00257 if (st->isFpush()) {
00258 (*rit)->insertStmt(new Assign(new FloatType(80),
00259 Location::tempOf(new Const("tmpD9")),
00260 Location::regOf(39)), i++);
00261 (*rit)->insertStmt(new Assign(new FloatType(80),
00262 Location::regOf(39),
00263 Location::regOf(38)), i++);
00264 (*rit)->insertStmt(new Assign(new FloatType(80),
00265 Location::regOf(38),
00266 Location::regOf(37)), i++);
00267 (*rit)->insertStmt(new Assign(new FloatType(80),
00268 Location::regOf(37),
00269 Location::regOf(36)), i++);
00270 (*rit)->insertStmt(new Assign(new FloatType(80),
00271 Location::regOf(36),
00272 Location::regOf(35)), i++);
00273 (*rit)->insertStmt(new Assign(new FloatType(80),
00274 Location::regOf(35),
00275 Location::regOf(34)), i++);
00276 (*rit)->insertStmt(new Assign(new FloatType(80),
00277 Location::regOf(34),
00278 Location::regOf(33)), i++);
00279 (*rit)->insertStmt(new Assign(new FloatType(80),
00280 Location::regOf(33),
00281 Location::regOf(32)), i++);
00282 (*rit)->insertStmt(new Assign(new FloatType(80),
00283 Location::regOf(32),
00284 Location::tempOf(new Const("tmpD9"))), i++);
00285
00286 (*rit)->deleteStmt(i);
00287 i--;
00288 continue;
00289 }
00290 else if (st->isFpop()) {
00291 (*rit)->insertStmt(new Assign(new FloatType(80),
00292 Location::tempOf(new Const("tmpD9")),
00293 Location::regOf(32)), i++);
00294 (*rit)->insertStmt(new Assign(new FloatType(80),
00295 Location::regOf(32),
00296 Location::regOf(33)), i++);
00297 (*rit)->insertStmt(new Assign(new FloatType(80),
00298 Location::regOf(33),
00299 Location::regOf(34)), i++);
00300 (*rit)->insertStmt(new Assign(new FloatType(80),
00301 Location::regOf(34),
00302 Location::regOf(35)), i++);
00303 (*rit)->insertStmt(new Assign(new FloatType(80),
00304 Location::regOf(35),
00305 Location::regOf(36)), i++);
00306 (*rit)->insertStmt(new Assign(new FloatType(80),
00307 Location::regOf(36),
00308 Location::regOf(37)), i++);
00309 (*rit)->insertStmt(new Assign(new FloatType(80),
00310 Location::regOf(37),
00311 Location::regOf(38)), i++);
00312 (*rit)->insertStmt(new Assign(new FloatType(80),
00313 Location::regOf(38),
00314 Location::regOf(39)), i++);
00315 (*rit)->insertStmt(new Assign(new FloatType(80),
00316 Location::regOf(39),
00317 Location::tempOf(new Const("tmpD9"))), i++);
00318
00319 (*rit)->deleteStmt(i);
00320 i--;
00321 continue;
00322 }
00323 }
00324 rit++;
00325 }
00326 }
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 void PentiumFrontEnd::processFloatCode(PBB pBB, int& tos, Cfg* pCfg)
00342 {
00343 std::list<RTL*>::iterator rit;
00344 Statement* st;
00345
00346
00347 std::list<RTL*>* BB_rtls = pBB->getRTLs();
00348 if (BB_rtls == 0) {
00349
00350 return;
00351 }
00352 rit = BB_rtls->begin();
00353 while (rit != BB_rtls->end()) {
00354
00355 if ((*rit)->isCall()) {
00356
00357
00358 tos = 0;
00359 }
00360 if ((*rit)->getNumStmt() == 0) { rit++; continue; }
00361 #if PROCESS_FNSTSW
00362
00363 if (isStoreFsw((*rit)->elementAt(0))) {
00364
00365 Exp* lhs = ((Assign*)(*rit)->elementAt(0))->getLeft();
00366 Exp* ax = Location::regOf(0);
00367 assert(*lhs == *ax);
00368 delete ax;
00369
00370
00371 if (processStsw(rit, BB_rtls, pBB, pCfg)) {
00372
00373 break;
00374 }
00375
00376
00377 continue;
00378 }
00379 #endif
00380 for (int i=0; i < (*rit)->getNumStmt(); i++) {
00381
00382 st = (*rit)->elementAt(i);
00383 if (!st->isFlagAssgn()) {
00384
00385
00386 if (st->isFpush()) {
00387 tos = (tos - 1) & 7;
00388
00389 (*rit)->deleteStmt(i);
00390 i--;
00391 continue;
00392 }
00393 else if (st->isFpop()) {
00394 tos = (tos + 1) & 7;
00395
00396 (*rit)->deleteStmt(i);
00397 i--;
00398 continue;
00399 }
00400 else if (st->isAssign()) {
00401 Assign* asgn = (Assign*)st;
00402 Exp* lhs = asgn->getLeft();
00403 Exp* rhs = asgn->getRight();
00404 if (tos != 0) {
00405
00406
00407 bumpRegisterAll(lhs, 32, 39, tos, 7);
00408 bumpRegisterAll(rhs, 32, 39, tos, 7);
00409 }
00410 }
00411 }
00412 else {
00413
00414
00415 Binary* cur;
00416 for (cur = (Binary*)((Assign*)st)->getRight(); !cur->isNil(); cur = (Binary*)cur->getSubExp2()) {
00417
00418
00419
00420
00421
00422 Exp* s = cur->getSubExp1();
00423 if (s->isRegOfK()) {
00424 Const* c = (Const*)((Unary*)s)->getSubExp1();
00425 int K = c->getInt();
00426
00427 if ((K >= 32) && (K <= 39))
00428 s->setSubExp1(new Const(32 + (K - 32 + tos & 7)));
00429 }
00430 }
00431
00432 }
00433 }
00434 rit++;
00435 }
00436 pBB->setTraversed(true);
00437
00438
00439 const std::vector<PBB>& outs = pBB->getOutEdges();
00440 unsigned n;
00441 do {
00442 n = outs.size();
00443 for (unsigned o=0; o<n; o++) {
00444 PBB anOut = outs[o];
00445 if (!anOut->isTraversed()) {
00446 processFloatCode(anOut, tos, pCfg);
00447 if (outs.size() != n)
00448
00449
00450 break;
00451 }
00452 }
00453 } while (outs.size() != n);
00454 }
00455
00456
00457
00458
00459
00460 void PentiumFrontEnd::emitSet(std::list<RTL*>* BB_rtls, std::list<RTL*>::iterator& rit, ADDRESS uAddr, Exp* lhs,
00461 Exp* cond) {
00462
00463 Statement* asgn = new Assign(
00464 lhs,
00465 new Ternary(opTern,
00466 cond,
00467 new Const(1),
00468 new Const(0)));
00469 RTL* pRtl = new RTL(uAddr);
00470 pRtl->appendStmt(asgn);
00471
00472
00473 BB_rtls->insert(rit, pRtl);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 bool PentiumFrontEnd::helperFunc(ADDRESS dest, ADDRESS addr, std::list<RTL*>* lrtl)
00486 {
00487 if (dest == NO_ADDRESS) return false;
00488
00489 const char* p = pBF->SymbolByAddress(dest);
00490 if (p == NULL) return false;
00491 std::string name(p);
00492
00493 if (name == "__xtol" || name == "_ftol" || name == "_ftol2") {
00494
00495
00496
00497
00498
00499 Statement* a = new Assign(new IntegerType(64),
00500 Location::tempOf(new Const("tmpl")),
00501 new Ternary(opFtoi,
00502 new Const(64),
00503 new Const(32),
00504 Location::regOf(32)));
00505 RTL* pRtl = new RTL(addr);
00506 pRtl->appendStmt(a);
00507 a = new Assign(
00508 Location::regOf(24),
00509 new Ternary(opTruncs,
00510 new Const(64),
00511 new Const(32),
00512 Location::tempOf(new Const("tmpl"))));
00513 pRtl->appendStmt(a);
00514 a = new Assign(
00515 Location::regOf(26),
00516 new Binary(opShiftR,
00517 Location::tempOf(new Const("tmpl")),
00518 new Const(32)));
00519 pRtl->appendStmt(a);
00520
00521 lrtl->push_back(pRtl);
00522
00523 return true;
00524
00525 } else if (name == "__mingw_allocstack") {
00526 RTL* pRtl = new RTL(addr);
00527 Statement* a = new Assign(
00528 Location::regOf(28),
00529 new Binary(opMinus,
00530 Location::regOf(28),
00531 Location::regOf(24)));
00532 pRtl->appendStmt(a);
00533 lrtl->push_back(pRtl);
00534 prog->removeProc(name.c_str());
00535 return true;
00536 } else if (name == "__mingw_frame_init" || name == "__mingw_cleanup_setup" || name == "__mingw_frame_end") {
00537 LOG << "found removable call to static lib proc " << name << " at " << addr << "\n";
00538 prog->removeProc(name.c_str());
00539 return true;
00540 } else {
00541
00542 }
00543 return false;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552 #ifdef DYNAMIC
00553 extern "C" {
00554 PentiumFrontEnd* construct(Prog *prog, NJMCDecoder** decoder) {
00555 PentiumFrontEnd *fe = new PentiumFrontEnd(prog);
00556 *decoder = fe->getDecoder();
00557 return fe;
00558 }
00559 }
00560 #endif
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 PentiumFrontEnd::PentiumFrontEnd(BinaryFile *pBF, Prog* prog, BinaryFileFactory* pbff) : FrontEnd(pBF, prog, pbff),
00571 idPF(-1) {
00572 decoder = new PentiumDecoder(prog);
00573 }
00574
00575
00576 PentiumFrontEnd::~PentiumFrontEnd()
00577 {
00578 }
00579
00580
00581
00582
00583
00584
00585
00586 ADDRESS PentiumFrontEnd::getMainEntryPoint(bool& gotMain) {
00587 gotMain = true;
00588 ADDRESS start = pBF->GetMainEntryPoint();
00589 if( start != NO_ADDRESS ) return start;
00590
00591 gotMain = false;
00592 start = pBF->GetEntryPoint();
00593 if (start == 0 || start == NO_ADDRESS)
00594 return NO_ADDRESS;
00595
00596 int instCount = 100;
00597 int conseq = 0;
00598 ADDRESS addr = start;
00599
00600
00601
00602
00603 ADDRESS dest;
00604 do {
00605 DecodeResult inst = decodeInstruction(addr);
00606 if (inst.rtl == NULL)
00607
00608 break;
00609 CallStatement* cs = NULL;
00610 if (inst.rtl->getList().size())
00611 cs = (CallStatement*)(inst.rtl->getList().back());
00612 if (cs && cs->getKind() == STMT_CALL &&
00613 cs->getDest()->getOper() == opMemOf &&
00614 cs->getDest()->getSubExp1()->getOper() == opIntConst &&
00615 pBF->IsDynamicLinkedProcPointer(((Const*)cs->getDest() ->getSubExp1())->getAddr()) &&
00616 !strcmp(pBF->GetDynamicProcName(((Const*)cs->getDest()->getSubExp1())->getAddr()), "GetModuleHandleA"))
00617 {
00618 #if 0
00619 std::cerr << "consider " << std::hex << addr << " " <<
00620 pBF->GetDynamicProcName(((Const*)cs->getDest()->getSubExp1())->getAddr()) << std::endl;
00621 #endif
00622 int oNumBytes = inst.numBytes;
00623 inst = decodeInstruction(addr + oNumBytes);
00624 if (inst.valid && inst.rtl->getNumStmt() == 2) {
00625 Assign* a = dynamic_cast<Assign*>(inst.rtl->elementAt(1));
00626 if (a && *a->getRight() == *Location::regOf(24)) {
00627 #if 0
00628 std::cerr << "is followed by push eax.. " << "good" << std::endl;
00629 #endif
00630 inst = decodeInstruction(addr + oNumBytes + inst.numBytes);
00631 if (inst.rtl->getList().size()) {
00632 CallStatement *toMain = dynamic_cast<CallStatement*>(inst.rtl->getList().back());
00633 if (toMain && toMain->getFixedDest() != NO_ADDRESS) {
00634 pBF->AddSymbol(toMain->getFixedDest(), "WinMain");
00635 gotMain = true;
00636 return toMain->getFixedDest();
00637 }
00638 }
00639 }
00640 }
00641 }
00642 if ((cs && cs->getKind() == STMT_CALL) && ((dest = (cs->getFixedDest())) != NO_ADDRESS)) {
00643 if (++conseq == 3 && 0) {
00644
00645 gotMain = true;
00646 return cs->getFixedDest();
00647 }
00648 if (pBF->SymbolByAddress(dest) &&
00649 strcmp(pBF->SymbolByAddress(dest), "__libc_start_main") == 0) {
00650
00651
00652
00653 inst = decodeInstruction(addr-5);
00654 assert(inst.valid);
00655 assert(inst.rtl->getNumStmt() == 2);
00656 Assign* a = (Assign*) inst.rtl->elementAt(0);
00657 Exp* rhs = a->getRight();
00658 assert(rhs->isIntConst());
00659 gotMain = true;
00660 return (ADDRESS)((Const*)rhs)->getInt();
00661 }
00662 }
00663 else
00664 conseq = 0;
00665 GotoStatement* gs = (GotoStatement*)cs;
00666 if (gs && gs->getKind() == STMT_GOTO)
00667
00668
00669 addr = gs->getFixedDest();
00670 else
00671 addr += inst.numBytes;
00672 } while (--instCount);
00673
00674
00675 ADDRESS umain = pBF->GetAddressByName("_main");
00676 if (umain != NO_ADDRESS) return umain;
00677
00678
00679 std::cerr << "main function not found\n";
00680
00681 this->AddSymbol(start, "_start");
00682
00683 return start;
00684 }
00685
00686 void toBranches(ADDRESS a, bool lastRtl, Cfg* cfg, RTL* rtl, PBB bb, BB_IT& it)
00687 {
00688 BranchStatement* br1 = new BranchStatement;
00689 assert(rtl->getList().size() >= 4);
00690 Statement* s1 = *rtl->getList().begin();
00691 Statement* s6 = *(--rtl->getList().end());
00692 if (s1->isAssign())
00693 br1->setCondExpr(((Assign*)s1)->getRight());
00694 else
00695 br1->setCondExpr(NULL);
00696 br1->setDest(a+2);
00697 BranchStatement* br2 = new BranchStatement;
00698 if (s6->isAssign())
00699 br2->setCondExpr(((Assign*)s6)->getRight());
00700 else
00701 br2->setCondExpr(NULL);
00702 br2->setDest(a);
00703 cfg->splitForBranch(bb, rtl, br1, br2, it);
00704 }
00705
00706 void PentiumFrontEnd::processStringInst(UserProc* proc) {
00707 Cfg::iterator it;
00708 Cfg* cfg = proc->getCFG();
00709
00710 for (it = cfg->begin(); it != cfg->end(); ) {
00711 bool noinc = false;
00712 PBB bb = *it;
00713 std::list<RTL*> *rtls = bb->getRTLs();
00714 if (rtls == NULL)
00715 break;
00716 ADDRESS prev, addr = 0;
00717 bool lastRtl = true;
00718
00719 for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
00720 RTL *rtl = *rit;
00721 prev = addr;
00722 addr = rtl->getAddress();
00723 if (rtl->getList().size()) {
00724 Statement* firstStmt = *rtl->getList().begin();
00725 if (firstStmt->isAssign()) {
00726 Exp* lhs = ((Assign*)firstStmt)->getLeft();
00727 if (lhs->isMachFtr()) {
00728 Const* sub = (Const*)((Unary*)lhs)->getSubExp1();
00729 char* str = sub->getStr();
00730 if (strncmp(str, "%SKIP", 5) == 0) {
00731 toBranches(addr, lastRtl, cfg, rtl, bb, it);
00732 noinc = true;
00733
00734
00735 break;
00736 }
00737 else
00738 LOG << "Unhandled machine feature " << str << "\n";
00739 }
00740 }
00741 }
00742 lastRtl = false;
00743 }
00744 if (!noinc) it++;
00745 }
00746 }
00747
00748 void PentiumFrontEnd::processOverlapped(UserProc* proc) {
00749
00750
00751 std::set<int> usedRegs;
00752 StatementList stmts;
00753 proc->getStatements(stmts);
00754 StatementList::iterator it;
00755 for (it = stmts.begin(); it != stmts.end(); it++) {
00756 Statement* s = *it;
00757 LocationSet locs;
00758 s->addUsedLocs(locs);
00759 for (LocationSet::iterator li = locs.begin(); li != locs.end(); li++) {
00760 Exp *l = *li;
00761 if (!l->isRegOfK())
00762 continue;
00763 int n = ((Const*)l->getSubExp1())->getInt();
00764 usedRegs.insert(n);
00765 }
00766 }
00767
00768 std::set<PBB> bbs;
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 for (it = stmts.begin(); it != stmts.end(); it++) {
00785 Statement* s = *it;
00786 if (s->getBB()->overlappedRegProcessingDone)
00787 continue;
00788 bbs.insert(s->getBB());
00789 if (!s->isAssignment()) continue;
00790 Exp* lhs = ((Assignment*)s)->getLeft();
00791 if (!lhs->isRegOf()) continue;
00792 Const* c = (Const*)((Location*)lhs)->getSubExp1();
00793 assert(c->isIntConst());
00794 int r = c->getInt();
00795 int off = r&3;
00796 int off_mod8 = r&7;
00797 Assign* a;
00798 switch (r) {
00799 case 24: case 25: case 26: case 27:
00800
00801
00802 if (usedRegs.find(off) != usedRegs.end()) {
00803 a = new Assign(
00804 new IntegerType(16),
00805 Location::regOf(off),
00806 new Ternary(opTruncu,
00807 new Const(32),
00808 new Const(16),
00809 Location::regOf(24+off)));
00810 proc->insertStatementAfter(s, a);
00811 }
00812
00813
00814 if (usedRegs.find(8+off) != usedRegs.end()) {
00815 a = new Assign(
00816 new IntegerType(8),
00817 Location::regOf(8+off),
00818 new Ternary(opTruncu,
00819 new Const(32),
00820 new Const(8),
00821 Location::regOf(24+off)));
00822 proc->insertStatementAfter(s, a);
00823 }
00824
00825
00826 if (usedRegs.find(12+off) != usedRegs.end()) {
00827 a = new Assign(
00828 new IntegerType(8),
00829 Location::regOf(12+off),
00830 new Ternary(opAt,
00831 Location::regOf(24+off),
00832 new Const(15),
00833 new Const(8)));
00834 proc->insertStatementAfter(s, a);
00835 }
00836 break;
00837
00838 case 0: case 1: case 2: case 3:
00839
00840
00841 if (usedRegs.find(24+off) != usedRegs.end()) {
00842 a = new Assign(
00843 new IntegerType(32),
00844 Location::regOf(24+off),
00845 new Binary(opBitOr,
00846 new Ternary(opAt,
00847 Location::regOf(24+off),
00848 new Const(31),
00849 new Const(16)),
00850 new Ternary(opZfill,
00851 new Const(16),
00852 new Const(32),
00853 Location::regOf(off))));
00854 proc->insertStatementAfter(s, a);
00855 }
00856
00857
00858 if (usedRegs.find(8+off) != usedRegs.end()) {
00859 a = new Assign(
00860 new IntegerType(8),
00861 Location::regOf(8+off),
00862 new Ternary(opTruncu,
00863 new Const(16),
00864 new Const(8),
00865 Location::regOf(24+off)));
00866 proc->insertStatementAfter(s, a);
00867 }
00868
00869
00870 if (usedRegs.find(12+off) != usedRegs.end()) {
00871 a = new Assign(
00872 new IntegerType(8),
00873 Location::regOf(12+off),
00874 new Ternary(opAt,
00875 Location::regOf(off),
00876 new Const(15),
00877 new Const(8)));
00878 proc->insertStatementAfter(s, a);
00879 }
00880 break;
00881
00882
00883 case 8: case 9: case 10: case 11:
00884
00885
00886 if (usedRegs.find(24+off) != usedRegs.end()) {
00887 a = new Assign(
00888 new IntegerType(32),
00889 Location::regOf(24+off),
00890 new Binary(opBitOr,
00891 new Ternary(opAt,
00892 Location::regOf(24+off),
00893 new Const(31),
00894 new Const(8)),
00895 new Ternary(opZfill,
00896 new Const(8),
00897 new Const(32),
00898 Location::regOf(8+off))));
00899 proc->insertStatementAfter(s, a);
00900 }
00901
00902
00903 if (usedRegs.find(off) != usedRegs.end()) {
00904 a = new Assign(
00905 new IntegerType(16),
00906 Location::regOf(off),
00907 new Binary(opBitOr,
00908 new Ternary(opAt,
00909 Location::regOf(off),
00910 new Const(15),
00911 new Const(8)),
00912 new Ternary(opZfill,
00913 new Const(8),
00914 new Const(16),
00915 Location::regOf(8+off))));
00916 proc->insertStatementAfter(s, a);
00917 }
00918 break;
00919
00920 case 12: case 13: case 14: case 15:
00921
00922
00923
00924 if (usedRegs.find(24+off) != usedRegs.end()) {
00925 a = new Assign(
00926 new IntegerType(32),
00927 Location::regOf(24+off),
00928 new Binary(opBitOr,
00929 Location::regOf(24+off),
00930 new Binary(opShiftL,
00931 Location::regOf(12+off),
00932 new Const(8))));
00933 proc->insertStatementAfter(s, a);
00934 a = new Assign(
00935 new IntegerType(32),
00936 Location::regOf(24+off),
00937 new Binary(opBitAnd,
00938 Location::regOf(24+off),
00939 new Const(0xFFFF00FF)));
00940 proc->insertStatementAfter(s, a);
00941 }
00942
00943
00944
00945 if (usedRegs.find(off) != usedRegs.end()) {
00946 a = new Assign(
00947 new IntegerType(16),
00948 Location::regOf(off),
00949 new Binary(opBitOr,
00950 Location::regOf(off),
00951 new Binary(opShiftL,
00952 Location::regOf(12+off),
00953 new Const(8))));
00954 proc->insertStatementAfter(s, a);
00955 a = new Assign(
00956 new IntegerType(16),
00957 Location::regOf(off),
00958 new Binary(opBitAnd,
00959 Location::regOf(off),
00960 new Const(0x00FF)));
00961 proc->insertStatementAfter(s, a);
00962 }
00963 break;
00964
00965 case 5: case 6: case 7:
00966
00967
00968 if (usedRegs.find(24+off_mod8) != usedRegs.end()) {
00969 a = new Assign(
00970 new IntegerType(32),
00971 Location::regOf(24+off_mod8),
00972 new Binary(opBitOr,
00973 new Ternary(opAt,
00974 Location::regOf(24+off_mod8),
00975 new Const(31),
00976 new Const(16)),
00977 new Ternary(opZfill,
00978 new Const(16),
00979 new Const(32),
00980 Location::regOf(off_mod8))));
00981 proc->insertStatementAfter(s, a);
00982 }
00983 break;
00984
00985 case 29: case 30: case 31:
00986
00987
00988 if (usedRegs.find(off_mod8) != usedRegs.end()) {
00989 a = new Assign(
00990 new IntegerType(16),
00991 Location::regOf(off_mod8),
00992 new Ternary(opTruncu,
00993 new Const(32),
00994 new Const(16),
00995 Location::regOf(24+off_mod8)));
00996 proc->insertStatementAfter(s, a);
00997 }
00998 break;
00999 }
01000 }
01001
01002
01003 for (std::set<PBB>::iterator bit = bbs.begin(); bit != bbs.end(); bit++)
01004 (*bit)->overlappedRegProcessingDone = true;
01005 }
01006
01007 DecodeResult& PentiumFrontEnd::decodeInstruction(ADDRESS pc)
01008 {
01009 int n = pBF->readNative1(pc);
01010 if (n == (int)(char)0xee) {
01011
01012 static DecodeResult r;
01013 r.reset();
01014 r.numBytes = 1;
01015 r.valid = true;
01016 r.type = NCT;
01017 r.reDecode = false;
01018 r.rtl = new RTL(pc);
01019 Exp *dx = Location::regOf(decoder->getRTLDict().RegMap["%dx"]);
01020 Exp *al = Location::regOf(decoder->getRTLDict().RegMap["%al"]);
01021 CallStatement *call = new CallStatement();
01022 call->setDestProc(prog->getLibraryProc("outp"));
01023 call->setArgumentExp(0, dx);
01024 call->setArgumentExp(1, al);
01025 r.rtl->appendStmt(call);
01026 return r;
01027 }
01028 if (n == (int)(char)0x0f && pBF->readNative1(pc+1) == (int)(char)0x0b) {
01029 static DecodeResult r;
01030 r.reset();
01031 r.numBytes = 2;
01032 r.valid = true;
01033 r.type = NCT;
01034 r.reDecode = false;
01035 r.rtl = new RTL(pc);
01036 CallStatement *call = new CallStatement();
01037 call->setDestProc(prog->getLibraryProc("invalid_opcode"));
01038 r.rtl->appendStmt(call);
01039 return r;
01040 }
01041 return FrontEnd::decodeInstruction(pc);
01042 }
01043
01044
01045 void PentiumFrontEnd::extraProcessCall(CallStatement *call, std::list<RTL*> *BB_rtls)
01046 {
01047 if (call->getDestProc()) {
01048
01049
01050 Signature *calledSig = call->getDestProc()->getSignature();
01051 for (unsigned int i = 0; i < calledSig->getNumParams(); i++) {
01052
01053 Type *paramType = calledSig->getParamType(i);
01054 Type *points_to;
01055 CompoundType *compound = NULL;
01056 bool paramIsFuncPointer = false, paramIsCompoundWithFuncPointers = false;
01057 if (paramType->resolvesToPointer()) {
01058 points_to = paramType->asPointer()->getPointsTo();
01059 if (points_to->resolvesToFunc())
01060 paramIsFuncPointer = true;
01061 else if (points_to->resolvesToCompound()) {
01062 compound = points_to->asCompound();
01063 for (unsigned int n = 0; n < compound->getNumTypes(); n++) {
01064 if ( compound->getType(n)->resolvesToPointer() &&
01065 compound->getType(n)->asPointer()->getPointsTo()->resolvesToFunc())
01066 paramIsCompoundWithFuncPointers = true;
01067 }
01068 }
01069 }
01070 if (paramIsFuncPointer == false && paramIsCompoundWithFuncPointers == false)
01071 continue;
01072
01073
01074 Exp *found = NULL;
01075 std::list<RTL*>::reverse_iterator itr;
01076 unsigned int pushcount = 0;
01077 for (itr = BB_rtls->rbegin(); itr != BB_rtls->rend() && !found; itr++) {
01078 RTL *rtl = *itr;
01079 for (int n = rtl->getNumStmt() - 1; n >= 0; n--) {
01080 Statement *stmt = rtl->elementAt(n);
01081 if (stmt->isAssign()) {
01082 Assign *asgn = (Assign*)stmt;
01083 if (asgn->getLeft()->isRegN(28) && asgn->getRight()->getOper() == opMinus)
01084 pushcount++;
01085 else if (pushcount == i + 2 && asgn->getLeft()->isMemOf() &&
01086 asgn->getLeft()->getSubExp1()->getOper() == opMinus &&
01087 asgn->getLeft()->getSubExp1()->getSubExp1()->isRegN(28) &&
01088 asgn->getLeft()->getSubExp1()->getSubExp2()->isIntConst()) {
01089 found = asgn->getRight();
01090 break;
01091 }
01092 }
01093 }
01094 }
01095 if (found == NULL)
01096 continue;
01097
01098 ADDRESS a;
01099 if (found->isIntConst())
01100 a = ((Const*)found)->getInt();
01101 else if (found->isAddrOf() && found->getSubExp1()->isGlobal()) {
01102 const char *name = ((Const*)found->getSubExp1()->getSubExp1())->getStr();
01103 if (prog->getGlobal((char*)name) == NULL)
01104 continue;
01105 a = prog->getGlobalAddr((char*)name);
01106 } else
01107 continue;
01108
01109
01110 if (paramIsFuncPointer) {
01111 if (VERBOSE)
01112 LOG << "found a new procedure at address " << a << " from inspecting parameters of call to " <<
01113 call->getDestProc()->getName() << ".\n";
01114 Proc *proc = prog->setNewProc(a);
01115 Signature *sig = paramType->asPointer()->getPointsTo()->asFunc()->getSignature()->clone();
01116 sig->setName(proc->getName());
01117 sig->setForced(true);
01118 proc->setSignature(sig);
01119 continue;
01120 }
01121
01122
01123
01124
01125
01126
01127 for (unsigned int n = 0; n < compound->getNumTypes(); n++) {
01128 if (compound->getType(n)->resolvesToPointer() &&
01129 compound->getType(n)->asPointer()->getPointsTo()->resolvesToFunc()) {
01130 ADDRESS d = pBF->readNative4(a);
01131 if (VERBOSE)
01132 LOG << "found a new procedure at address " << d << " from inspecting parameters of call to " <<
01133 call->getDestProc()->getName() << ".\n";
01134 Proc *proc = prog->setNewProc(d);
01135 Signature *sig = compound->getType(n)->asPointer()->getPointsTo()->asFunc()->getSignature()->
01136 clone();
01137 sig->setName(proc->getName());
01138 sig->setForced(true);
01139 proc->setSignature(sig);
01140 }
01141 a += compound->getType(n)->getSize() / 8;
01142 }
01143 }
01144
01145
01146 if (calledSig->hasEllipsis()) {
01147
01148 bool found = false;
01149 std::list<RTL*>::reverse_iterator itr;
01150 int pushcount = 0;
01151 for (itr = BB_rtls->rbegin(); itr != BB_rtls->rend() && !found; itr++) {
01152 RTL *rtl = *itr;
01153 for (int n = rtl->getNumStmt() - 1; n >= 0; n--) {
01154 Statement *stmt = rtl->elementAt(n);
01155 if (stmt->isAssign()) {
01156 Assign *asgn = (Assign*)stmt;
01157 if (asgn->getLeft()->isRegN(28) && asgn->getRight()->getOper() == opMinus)
01158 pushcount++;
01159 else if (asgn->getLeft()->isMemOf() &&
01160 asgn->getLeft()->getSubExp1()->getOper() == opMinus &&
01161 asgn->getLeft()->getSubExp1()->getSubExp1()->isRegN(28) &&
01162 asgn->getLeft()->getSubExp1()->getSubExp2()->isIntConst()) {
01163 if (asgn->getRight()->isIntConst()) {
01164 int n = ((Const*)asgn->getRight())->getInt();
01165 if (n == 0) {
01166 found = true;
01167 break;
01168 }
01169 }
01170 }
01171 }
01172 }
01173 }
01174 if (found && pushcount > 1) {
01175 call->setSigArguments();
01176 call->setNumArguments(pushcount - 1);
01177 }
01178 }
01179 }
01180 }