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 }