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 }