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 
00030 
00031 
00032 
00033 
00034 #include <assert.h>
00035 #if defined(_MSC_VER) && _MSC_VER <= 1200
00036 #pragma warning(disable:4786)
00037 #endif 
00038 
00039 #include <algorithm>    
00040 #include "types.h"
00041 #include "statement.h"
00042 #include "exp.h"
00043 #include "register.h"
00044 #include "type.h"
00045 #include "rtl.h"
00046 #include "cfg.h"
00047 #include "proc.h"
00048 #include "prog.h"
00049 #include "sslparser.h"
00050 #include "boomerang.h"
00051 
00052 #if defined(_MSC_VER) && _MSC_VER <= 1100
00053 #include "signature.h"      
00054 #endif
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 TableEntry::TableEntry() { flags = 0; }
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 TableEntry::TableEntry(std::list<std::string>& p, RTL& r) : rtl(r)
00075 { 
00076     for (std::list<std::string>::iterator it = p.begin(); it != p.end(); it++)
00077         params.push_back(*it);
00078     flags = 0; 
00079 }
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 void TableEntry::setParam(std::list<std::string>& p) { params = p; }
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 void TableEntry::setRTL(RTL& r) {
00096     rtl = r;
00097 }
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 const TableEntry& TableEntry::operator=(const TableEntry& other) {
00107     for (std::list<std::string>::const_iterator it = other.params.begin(); it != other.params.end(); it++)
00108         params.push_back(*it);
00109     rtl = *(new RTL(other.rtl));
00110     return *this;
00111 }
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 int TableEntry::appendRTL(std::list<std::string>& p, RTL& r) {
00121     bool match = (p.size() == params.size());
00122     std::list<std::string>::iterator a, b;
00123     for (a = params.begin(), b = p.begin(); match && (a != params.end()) && (b != p.end());
00124             match = (*a == *b), a++, b++)
00125         ;
00126     if (match) {
00127         rtl.appendRTL(r);
00128         return 0;
00129     }
00130     return -1;
00131 }
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 int RTLInstDict::appendToDict(std::string &n, std::list<std::string>& p, RTL& r)
00142 {
00143     char *opcode = new char[n.size() + 1];
00144     strcpy(opcode, n.c_str());
00145     upperStr(opcode, opcode);
00146     std::remove(opcode, opcode+strlen(opcode)+1,'.');
00147     std::string s(opcode);
00148     
00149    
00150     if (idict.find(s) == idict.end()) {
00151         idict[s] = TableEntry(p, r);
00152     } else {
00153         return idict[s].appendRTL(p, r);
00154     }
00155     return 0;
00156 }
00157 
00158 RTLInstDict::RTLInstDict()
00159 {
00160 }
00161 
00162 RTLInstDict::~RTLInstDict()
00163 {
00164 }
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 bool RTLInstDict::readSSLFile(const std::string& SSLFileName)
00174 {
00175     
00176     idict.erase(idict.begin(),idict.end());
00177     
00178     reset();
00179     
00180     
00181     SSLParser theParser(SSLFileName,
00182 #ifdef DEBUG_SSLPARSER
00183     true
00184 #else
00185     false
00186 #endif
00187 );
00188     if (theParser.theScanner == NULL)
00189         return false;
00190     addRegister( "%CTI", -1, 1, false );
00191     addRegister( "%NEXT", -1, 32, false );
00192     
00193     theParser.yyparse(*this);
00194 
00195     fixupParams();
00196 
00197     if (Boomerang::get()->debugDecoder) {
00198         std::cout << "\n=======Expanded RTL template dictionary=======\n";
00199         print();
00200         std::cout << "\n==============================================\n\n";
00201     }
00202     
00203     return true;
00204 }
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 void RTLInstDict::addRegister( const char *name, int id, int size, bool flt )
00213 {
00214     RegMap[name] = id;
00215     if( id == -1 ) {
00216         SpecialRegMap[name].s_name(name);
00217         SpecialRegMap[name].s_size(size);
00218         SpecialRegMap[name].s_float(flt);
00219         SpecialRegMap[name].s_address(NULL);
00220         SpecialRegMap[name].s_mappedIndex(-1);
00221         SpecialRegMap[name].s_mappedOffset(-1);
00222     } else {
00223         DetRegMap[id].s_name(name);
00224         DetRegMap[id].s_size(size);
00225         DetRegMap[id].s_float(flt);
00226         DetRegMap[id].s_address(NULL);
00227         DetRegMap[id].s_mappedIndex(-1);
00228         DetRegMap[id].s_mappedOffset(-1);
00229     }    
00230 }
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 void RTLInstDict::print(std::ostream& os )
00240 {
00241     for (std::map<std::string, TableEntry>::iterator p = idict.begin();
00242       p != idict.end(); p++) {
00243         
00244         os << (*p).first << "  ";
00245 
00246         
00247         std::list<std::string>& params = (*p).second.params;
00248         int i = params.size();
00249         for (std::list<std::string>::iterator s = params.begin(); s != params.end(); s++,i--)
00250             os << *s << (i != 1 ? "," : "");
00251         os << "\n";
00252     
00253         
00254         RTL& rtlist = (*p).second.rtl;
00255         rtlist.print(os);
00256         os << "\n";
00257     }
00258 
00259 #if 0
00260     
00261     os << "\nDetailed register map\n";
00262     std::map<int, Register, std::less<int> >::iterator rr;
00263     for (rr = DetRegMap.begin(); rr != DetRegMap.end(); rr++) {
00264         int n = rr->first;
00265         Register* pr = &rr->second;
00266         os << "number " << n <<
00267           " name " << pr->g_name() <<
00268           " size " << std::dec << pr->g_size() <<
00269           " address 0x" << std::hex << (unsigned)pr->g_address() <<
00270           " mappedIndex " << std::dec << pr->g_mappedIndex() <<
00271           " mappedOffset " << pr->g_mappedOffset() <<
00272           " flt " << pr->isFloat() << "\n";
00273     }
00274 #endif
00275 }
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 void RTLInstDict::fixupParams( )
00285 {
00286     std::map<std::string,ParamEntry>::iterator param;
00287     int mark = 1;
00288     for( param = DetParamMap.begin(); param != DetParamMap.end(); param++ ) {
00289         param->second.mark = 0;
00290     }
00291     for( param = DetParamMap.begin(); param != DetParamMap.end(); param++ ) {
00292         std::list<std::string> funcParams;
00293         bool haveCount = false;
00294         if( param->second.kind == PARAM_VARIANT ) {
00295             fixupParamsSub( param->first, funcParams, haveCount, mark++ );
00296         }
00297     }
00298 }
00299 
00300 void RTLInstDict::fixupParamsSub( std::string s, std::list<std::string>& funcParams, bool& haveCount, int mark )
00301 {
00302     ParamEntry ¶m = DetParamMap[s];
00303 
00304     if( param.params.size() == 0 ) {
00305         std::cerr << "Error in SSL File: Variant operand " << s << " has no branches. Well that's really useful...\n";
00306         return;
00307     }
00308     if( param.mark == mark )
00309         return; 
00310     
00311     param.mark = mark;
00312     
00313     for( std::list<std::string>::iterator it = param.params.begin();
00314          it != param.params.end(); it++ ) {
00315         ParamEntry &sub = DetParamMap[*it];
00316         if (sub.kind == PARAM_VARIANT ) {
00317             fixupParamsSub(*it, funcParams, haveCount, mark );
00318             if (!haveCount) { 
00319                 continue;
00320             }
00321         } else if (!haveCount ) {
00322             haveCount = true;
00323             char buf[10];
00324             for (unsigned i=1; i <= sub.funcParams.size(); i++ ) {
00325                 sprintf( buf, "__lp%d", i );
00326                 funcParams.push_back(buf);
00327             }
00328         }
00329 
00330         if (funcParams.size() != sub.funcParams.size() ) {
00331             std::cerr << "Error in SSL File: Variant operand " << s << " does not have a fixed number of functional "
00332                 "parameters:\n" << "Expected " << funcParams.size() << ", but branch " << *it << " has " <<
00333                 sub.funcParams.size() << ".\n";
00334         } else if (funcParams != sub.funcParams && sub.asgn != NULL ) {
00335             
00336             std::list<std::string>::iterator i,j;
00337             for( i = funcParams.begin(), j = sub.funcParams.begin(); i != funcParams.end(); i++, j++ ) {
00338                 Exp* match = Location::param(j->c_str());
00339                 Exp* replace = Location::param(i->c_str());
00340                 sub.asgn->searchAndReplace( match, replace );
00341             }
00342             sub.funcParams = funcParams;
00343         }
00344     }
00345 
00346 
00347 
00348 
00349     param.funcParams = funcParams;
00350 }
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 std::pair<std::string,unsigned> RTLInstDict::getSignature(const char* name) {
00359     
00360     char *opcode = new char[strlen(name) + 1];
00361     upperStr(name, opcode);
00362 
00363     std::remove(opcode,opcode+strlen(opcode)+1,'.');
00364 
00365     
00366     std::map<std::string,TableEntry>::iterator it = idict.find(opcode);
00367     if (it == idict.end()) {
00368         std::cerr << "Error: no entry for `" << name << "' in RTL dictionary\n";
00369         it = idict.find("NOP");     
00370     } 
00371 
00372     std::pair<std::string, unsigned> ret;
00373     ret = std::pair<std::string,unsigned>(opcode,(it->second).params.size());
00374     
00375     return ret;
00376 }
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 bool RTLInstDict::partialType(Exp* exp, Type& ty)
00388 {
00389     if (exp->isSizeCast()) {
00390         ty = IntegerType(((Const*)((Binary*)exp)->getSubExp1())->getInt());
00391         return true;
00392     }
00393     if (exp->isFltConst()) {
00394         ty = FloatType(64);
00395         return true;
00396     }
00397     return false;
00398 }
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 std::list<Statement*>* RTLInstDict::instantiateRTL(std::string& name, ADDRESS natPC, std::vector<Exp*>& actuals) {
00409     
00410     const std::string* lname = &name;
00411     
00412 
00413 if (0) {
00414         std::map<std::string, std::string>::iterator itf = fastMap.find(name);
00415         if (itf != fastMap.end()) 
00416             lname = &itf->second;
00417     }
00418     
00419     if ( idict.find(*lname) == idict.end() ) { 
00420         std::cerr << "ERROR: unknown instruction " << *lname << " at 0x" << std::hex << natPC << ", ignoring.\n";
00421         return NULL;
00422     }
00423     TableEntry& entry = idict[*lname];
00424 
00425     return instantiateRTL( entry.rtl, natPC, entry.params, actuals );
00426 }
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 std::list<Statement*>* RTLInstDict::instantiateRTL(RTL& rtl, ADDRESS natPC, std::list<std::string>& params,
00438         std::vector<Exp*>& actuals) {
00439     assert(params.size() == actuals.size());
00440 
00441     
00442     std::list<Statement*>* newList = new std::list<Statement*>();
00443     rtl.deepCopyList(*newList);
00444 
00445     
00446     std::list<Statement*>::iterator ss;
00447     for (ss = newList->begin(); ss != newList->end(); ss++) {
00448         
00449         std::list<std::string>::iterator param = params.begin();
00450         std::vector<Exp*>::const_iterator actual = actuals.begin();
00451         for (; param != params.end(); param++, actual++) {
00452             
00453             Exp* formal = Location::param(param->c_str());
00454             (*ss)->searchAndReplace(formal, *actual);
00455             
00456         }
00457         (*ss)->fixSuccessor();
00458         if (Boomerang::get()->debugDecoder)
00459             std::cout << "          " << *ss << "\n";
00460     }
00461 
00462     transformPostVars( newList, true );
00463 
00464     
00465     for (ss = newList->begin(); ss != newList->end(); ss++) {
00466         (*ss)->simplify();
00467     }
00468 
00469     return newList;
00470 }
00471 
00472 
00473 class transPost {
00474 public:
00475     bool used;      
00476                     
00477                     
00478     bool isNew;     
00479     Exp* tmp;       
00480     Exp* post;      
00481     Exp* base;      
00482     Type* type;     
00483 };
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 std::list<Statement*>* RTLInstDict::transformPostVars(std::list<Statement*>* rts, bool optimise) {
00494     std::list<Statement*>::iterator rt;
00495 
00496     
00497     std::map<Exp*,transPost,lessExpStar> vars;
00498     int tmpcount = 1;       
00499     
00500 
00501 #ifdef DEBUG_POSTVAR
00502     std::cout << "Transforming from:\n";
00503     for (Exp_CIT p = rts->begin(); p != rts->end(); p++) {
00504         std::cout << setw(8) << " ";
00505         (*p)->print(std::cout);
00506         std::cout << "\n";
00507     }
00508 #endif
00509     
00510     
00511     for( rt = rts->begin(); rt != rts->end(); rt++ ) {
00512         
00513         
00514         Binary* ss;
00515         if( (*rt)->isAssign()) {
00516             Exp* lhs = ((Assign*)*rt)->getLeft();
00517             Exp* rhs = ((Assign*)*rt)->getRight();
00518 
00519             
00520             if (lhs && lhs->isPostVar()) {
00521                 if( vars.find(lhs) == vars.end() ) {
00522                     
00523                     transPost& el = vars[lhs];
00524                     el.used = false;
00525                     el.type = ((Assign*)*rt)->getType();
00526                     
00527                     
00528                     
00529                     std::string tmpname = el.type->getTempName() + (tmpcount++) + "post" ;
00530                     el.tmp = Location::tempOf(new Const((char*)tmpname.c_str()));
00531 
00532                     
00533                     el.base = lhs->getSubExp1();
00534                     el.post = lhs;     
00535                     el.isNew = true;
00536 
00537                     
00538                     
00539                     if( !optimise ) {
00540                         el.used = true;
00541                         el.isNew = false;
00542                     }
00543                     
00544                 }
00545             }
00546             
00547             
00548             ss = new Binary(opList,
00549                 lhs->clone(),
00550                 new Binary(opList,
00551                     rhs->clone(),
00552                     new Terminal(opNil)));
00553         } else if( (*rt)->isFlagAssgn()) {
00554             
00555             ss = (Binary*) ((Binary*)*rt)->getSubExp2();
00556         } else
00557             ss = NULL;
00558 
00559         
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567         for (std::map<Exp*,transPost,lessExpStar>::iterator sr = vars.begin();
00568              sr != vars.end(); sr++ ) {
00569             if( sr->second.isNew ) {
00570                 
00571                 sr->second.isNew = false;
00572                 continue;
00573             }
00574             Binary* cur;
00575             for (cur = ss; !cur->isNil(); cur = (Binary*)cur->getSubExp2()) {
00576                 if( sr->second.used )
00577                     break;      
00578                 Exp* s = cur->getSubExp1();
00579                 if( !s ) continue;
00580                 if( *s == *sr->second.base ) {
00581                     sr->second.used = true;
00582                     break;
00583                 }
00584                 std::list<Exp*> res1, res2;
00585                 s->searchAll( sr->second.base, res1 );
00586                 s->searchAll( sr->second.post, res2 );
00587                 
00588                 
00589                 if (res1.size() > res2.size())
00590                     sr->second.used = true;
00591             }
00592         }
00593     }
00594 
00595     
00596     for ( rt = rts->begin(); rt != rts->end(); rt++ ) {
00597         for (std::map<Exp*,transPost,lessExpStar>::iterator sr = vars.begin();
00598           sr != vars.end(); sr++ ) {
00599             if( sr->second.used ) {
00600                 (*rt)->searchAndReplace(sr->first, sr->second.tmp);
00601             } else {
00602                 (*rt)->searchAndReplace(sr->first, sr->second.base);
00603             }
00604         }
00605     }
00606 
00607     
00608     
00609     
00610     for( std::map<Exp*,transPost,lessExpStar>::iterator sr = vars.begin();
00611       sr != vars.end(); sr++ ) {
00612         if( sr->second.used ) {
00613             Assign* te = new Assign(sr->second.type,
00614                     sr->second.base->clone(),
00615                     sr->second.tmp);
00616             rts->push_back( te );
00617         } else {
00618             
00619             
00620         }
00621     }
00622 
00623 #ifdef DEBUG_POSTVAR
00624     std::cout << "\nTo =>\n";
00625     for (std::list<Exp*>::iterator p = rts->begin(); p != rts->end(); p++) {
00626         std::cout << setw(8) << " ";
00627         (*p)->print(std::cout);
00628         std::cout << "\n";
00629     }
00630     std::cout << "\n";
00631 #endif
00632 
00633     return rts;
00634 }
00635 
00636 
00637 void RTLInstDict::reset() {
00638     RegMap.clear();
00639     DetRegMap.clear();
00640     SpecialRegMap.clear();
00641     ParamSet.clear();
00642     DetParamMap.clear();
00643     FlagFuncs.clear();
00644     DefMap.clear();
00645     AliasMap.clear();
00646     fastMap.clear();
00647     idict.clear();
00648     fetchExecCycle = 0;
00649 }