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 #include <assert.h>
00033 #if defined(_MSC_VER) && _MSC_VER <= 1100
00034 #include "signature.h"
00035 #endif
00036
00037 #include "decoder.h"
00038 #include "exp.h"
00039 #include "prog.h"
00040 #include "proc.h"
00041 #include "sparcdecoder.h"
00042 #include "rtl.h"
00043 #include "BinaryFile.h"
00044 #include "boomerang.h"
00045
00046 #define DIS_ROI (dis_RegImm(roi))
00047 #define DIS_ADDR (dis_Eaddr(addr))
00048 #define DIS_RD (dis_RegLhs(rd))
00049 #define DIS_RDR (dis_RegRhs(rd))
00050 #define DIS_RS1 (dis_RegRhs(rs1))
00051 #define DIS_FS1S (dis_RegRhs(fs1s+32))
00052 #define DIS_FS2S (dis_RegRhs(fs2s+32))
00053
00054
00055 #define DIS_FDS (dis_RegLhs(fds+32))
00056 #define DIS_FS1D (dis_RegRhs((fs1d>>1)+64))
00057 #define DIS_FS2D (dis_RegRhs((fs2d>>1)+64))
00058 #define DIS_FDD (dis_RegLhs((fdd>>1)+64))
00059 #define DIS_FDQ (dis_RegLhs((fdq>>2)+80))
00060 #define DIS_FS1Q (dis_RegRhs((fs1q>>2)+80))
00061 #define DIS_FS2Q (dis_RegRhs((fs2q>>2)+80))
00062
00063
00064
00065
00066
00067
00068
00069 void SparcDecoder::unused(int x)
00070 {}
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 RTL* SparcDecoder::createBranchRtl(ADDRESS pc, std::list<Statement*>* stmts, const char* name) {
00081 RTL* res = new RTL(pc, stmts);
00082 BranchStatement* br = new BranchStatement();
00083 res->appendStmt(br);
00084 if (name[0] == 'F') {
00085
00086
00087
00088 if (name[2] == 'U')
00089 name++;
00090 switch (name[2]) {
00091 case 'E':
00092 br->setCondType(BRANCH_JE, true);
00093 break;
00094 case 'L':
00095 if (name[3] == 'G')
00096 br->setCondType(BRANCH_JNE, true);
00097 else if (name[3] == 'E')
00098 br->setCondType(BRANCH_JSLE, true);
00099 else
00100 br->setCondType(BRANCH_JSL, true);
00101 break;
00102 case 'G':
00103 if (name[3] == 'E')
00104 br->setCondType(BRANCH_JSGE, true);
00105 else
00106 br->setCondType(BRANCH_JSG, true);
00107 break;
00108 case 'N':
00109 if (name[3] == 'E')
00110 br->setCondType(BRANCH_JNE, true);
00111
00112 break;
00113 default:
00114 std::cerr << "unknown float branch " << name << std::endl;
00115 delete res;
00116 res = NULL;
00117 }
00118 return res;
00119 }
00120
00121
00122
00123
00124 switch(name[1]) {
00125 case 'E':
00126 br->setCondType(BRANCH_JE);
00127 break;
00128 case 'L':
00129 if (name[2] == 'E') {
00130 if (name[3] == 'U')
00131 br->setCondType(BRANCH_JULE);
00132 else
00133 br->setCondType(BRANCH_JSLE);
00134 }
00135 else
00136 br->setCondType(BRANCH_JSL);
00137 break;
00138 case 'N':
00139
00140 if (name[3] == 'G')
00141 br->setCondType(BRANCH_JMI);
00142 else
00143 br->setCondType(BRANCH_JNE);
00144 break;
00145 case 'C':
00146
00147 if (name[2] == 'C')
00148 br->setCondType(BRANCH_JUGE);
00149 else
00150 br->setCondType(BRANCH_JUL);
00151 break;
00152 case 'V':
00153
00154 if (name[2] == 'C')
00155 std::cerr << "Decoded BVC instruction\n";
00156 else
00157 std::cerr << "Decoded BVS instruction\n";
00158 break;
00159 case 'G':
00160
00161 if (name[2] == 'E')
00162 br->setCondType(BRANCH_JSGE);
00163 else if (name[2] == 'U')
00164 br->setCondType(BRANCH_JUG);
00165 else
00166 br->setCondType(BRANCH_JSG);
00167 break;
00168 case 'P':
00169 if (name[2] == 'O') {
00170 br->setCondType(BRANCH_JPOS);
00171 break;
00172 }
00173
00174
00175
00176
00177 char temp;
00178 temp = 'B';
00179 strcpy(temp+1, name+2);
00180 delete res;
00181 return createBranchRtl(pc, stmts, temp);
00182 default:
00183 std::cerr << "unknown non-float branch " << name << std::endl;
00184 }
00185 return res;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 DecodeResult& SparcDecoder::decodeInstruction (ADDRESS pc, int delta) {
00203 static DecodeResult result;
00204 ADDRESS hostPC = pc+delta;
00205
00206
00207 result.reset();
00208
00209
00210 std::list<Statement*>* stmts = NULL;
00211
00212 ADDRESS nextPC = NO_ADDRESS;
00213
00214 match hostPC to
00215
00216 | call__(addr) =>
00217
00218
00219
00220 CallStatement* newCall = new CallStatement;
00221
00222
00223 ADDRESS nativeDest = addr - delta;
00224 newCall->setDest(nativeDest);
00225 Proc* destProc = prog->setNewProc(nativeDest);
00226 if (destProc == (Proc*)-1) destProc = NULL;
00227 newCall->setDestProc(destProc);
00228 result.rtl = new RTL(pc, stmts);
00229 result.rtl->appendStmt(newCall);
00230 result.type = SD;
00231 SHOW_ASM("call__ " << std::hex << (nativeDest))
00232 DEBUG_STMTS
00233
00234 | call_(addr) =>
00235
00236
00237
00238 CallStatement* newCall = new CallStatement;
00239
00240
00241 newCall->setIsComputed();
00242
00243
00244 newCall->setDest(dis_Eaddr(addr));
00245 result.rtl = new RTL(pc, stmts);
00246 result.rtl->appendStmt(newCall);
00247 result.type = DD;
00248
00249 SHOW_ASM("call_ " << dis_Eaddr(addr))
00250 DEBUG_STMTS
00251
00252
00253 | ret() =>
00254
00255
00256
00257 result.rtl = new RTL(pc, stmts);
00258 result.rtl->appendStmt(new ReturnStatement);
00259 result.type = DD;
00260 SHOW_ASM("ret_")
00261 DEBUG_STMTS
00262
00263 | retl() =>
00264
00265
00266
00267 result.rtl = new RTL(pc, stmts);
00268 result.rtl->appendStmt(new ReturnStatement);
00269 result.type = DD;
00270 SHOW_ASM("retl_")
00271 DEBUG_STMTS
00272
00273 | branch^",a" (tgt) [name] =>
00274
00275
00276
00277
00278
00279
00280 if (name[0] == 'C') {
00281 result.valid = false;
00282 result.rtl = new RTL;
00283 result.numBytes = 4;
00284 return result;
00285 }
00286
00287
00288 GotoStatement* jump = 0;
00289 RTL* rtl = NULL;
00290 if (strcmp(name,"BA,a") == 0 || strcmp(name,"BN,a") == 0) {
00291 jump = new GotoStatement;
00292 rtl = new RTL(pc, stmts);
00293 rtl->appendStmt(jump);
00294 } else if (strcmp(name,"BVS,a") == 0 || strcmp(name,"BVC,a") == 0) {
00295 jump = new GotoStatement;
00296 rtl = new RTL(pc, stmts);
00297 rtl->appendStmt(jump);
00298 } else {
00299 rtl = createBranchRtl(pc, stmts, name);
00300 jump = (GotoStatement*) rtl->getList().back();
00301 }
00302
00303
00304
00305 result.type = SCDAN;
00306 if ((strcmp(name,"BA,a") == 0) || (strcmp(name, "BVC,a") == 0)) {
00307 result.type = SU;
00308 } else {
00309 result.type = SKIP;
00310 }
00311
00312 result.rtl = rtl;
00313 jump->setDest(tgt - delta);
00314 SHOW_ASM(name << " " << std::hex << tgt-delta)
00315 DEBUG_STMTS
00316
00317 | pbranch^",a" (cc01, tgt) [name] =>
00318
00319
00320
00321
00322
00323
00324 if (cc01 != 0) {
00325 result.valid = false;
00326 result.rtl = new RTL;
00327 result.numBytes = 4;
00328 return result;
00329 }
00330 GotoStatement* jump = 0;
00331 RTL* rtl = NULL;
00332 if (strcmp(name,"BPA,a") == 0 || strcmp(name,"BPN,a") == 0) {
00333 jump = new GotoStatement;
00334 rtl = new RTL(pc, stmts);
00335 rtl->appendStmt(jump);
00336 } else if (strcmp(name,"BPVS,a") == 0 || strcmp(name,"BPVC,a") == 0) {
00337 jump = new GotoStatement;
00338 rtl = new RTL(pc, stmts);
00339 rtl->appendStmt(jump);
00340 } else {
00341 rtl = createBranchRtl(pc, stmts, name);
00342 jump = (GotoStatement*) rtl->getList().back();
00343 }
00344
00345
00346
00347 result.type = SCDAN;
00348 if ((strcmp(name,"BPA,a") == 0) || (strcmp(name, "BPVC,a") == 0)) {
00349 result.type = SU;
00350 } else {
00351 result.type = SKIP;
00352 }
00353
00354 result.rtl = rtl;
00355 jump->setDest(tgt - delta);
00356 SHOW_ASM(name << " " << std::hex << tgt-delta)
00357 DEBUG_STMTS
00358
00359 | branch (tgt) =>
00360
00361
00362
00363
00364
00365 if (name[0] == 'C') {
00366 result.valid = false;
00367 result.rtl = new RTL;
00368 result.numBytes = 4;
00369 return result;
00370 }
00371
00372
00373 GotoStatement* jump = 0;
00374 RTL* rtl = NULL;
00375 if (strcmp(name,"BA") == 0 || strcmp(name,"BN") == 0) {
00376 jump = new GotoStatement;
00377 rtl = new RTL(pc, stmts);
00378 rtl->appendStmt(jump);
00379 } else if (strcmp(name,"BVS") == 0 || strcmp(name,"BVC") == 0) {
00380 jump = new GotoStatement;
00381 rtl = new RTL(pc, stmts);
00382 rtl->appendStmt(jump);
00383 } else {
00384 rtl = createBranchRtl(pc, stmts, name);
00385 jump = (BranchStatement*) rtl->getList().back();
00386 }
00387
00388
00389
00390 result.type = SCD;
00391 if ((strcmp(name,"BA") == 0) || (strcmp(name, "BVC") == 0))
00392 result.type = SD;
00393 if ((strcmp(name,"BN") == 0) || (strcmp(name, "BVS") == 0))
00394 result.type = NCT;
00395
00396 result.rtl = rtl;
00397 jump->setDest(tgt - delta);
00398 SHOW_ASM(name << " " << std::hex << tgt-delta)
00399 DEBUG_STMTS
00400
00401 | BPA (cc01, tgt) =>
00402 unused(cc01);
00403 GotoStatement* jump = new GotoStatement;
00404
00405 result.type = SD;
00406 result.rtl = new RTL(pc, stmts);
00407 result.rtl->appendStmt(jump);
00408 jump->setDest(tgt - delta);
00409 SHOW_ASM("BPA " << std::hex << tgt-delta)
00410 DEBUG_STMTS
00411
00412 | pbranch (cc01, tgt) =>
00413 if (cc01 != 0) {
00414 result.valid = false;
00415 result.rtl = new RTL;
00416 result.numBytes = 4;
00417 return result;
00418 }
00419 GotoStatement* jump = 0;
00420 RTL* rtl = NULL;
00421 if (strcmp(name,"BPN") == 0) {
00422 jump = new GotoStatement;
00423 rtl = new RTL(pc, stmts);
00424 rtl->appendStmt(jump);
00425 } else if (strcmp(name,"BPVS") == 0 || strcmp(name,"BPVC") == 0) {
00426 jump = new GotoStatement;
00427 rtl = new RTL(pc, stmts);
00428 rtl->appendStmt(jump);
00429 } else {
00430 rtl = createBranchRtl(pc, stmts, name);
00431
00432 jump = (GotoStatement*)rtl->getList().back();
00433 }
00434
00435
00436
00437
00438 result.type = SCD;
00439 if (strcmp(name, "BPVC") == 0)
00440 result.type = SD;
00441 if ((strcmp(name,"BPN") == 0) || (strcmp(name, "BPVS") == 0))
00442 result.type = NCT;
00443
00444 result.rtl = rtl;
00445 jump->setDest(tgt - delta);
00446 SHOW_ASM(name << " " << std::hex << tgt-delta)
00447 DEBUG_STMTS
00448
00449 | JMPL (addr, rd) =>
00450
00451
00452
00453
00454 CaseStatement* jump = new CaseStatement;
00455
00456 jump->setIsComputed();
00457 result.rtl = new RTL(pc, stmts);
00458 result.rtl->appendStmt(jump);
00459 result.type = DD;
00460 jump->setDest(dis_Eaddr(addr));
00461 unused(rd);
00462 SHOW_ASM("JMPL ")
00463 DEBUG_STMTS
00464
00465
00466
00467
00468
00469
00470
00471
00472 | SAVE (rs1, roi, rd) =>
00473
00474
00475
00476 stmts = instantiate(pc, "SAVE", DIS_RS1, DIS_ROI, DIS_RD);
00477
00478 | RESTORE (rs1, roi, rd) =>
00479
00480 stmts = instantiate(pc, "RESTORE", DIS_RS1, DIS_ROI, DIS_RD);
00481
00482 | NOP =>
00483 result.type = NOP;
00484 stmts = instantiate(pc, name);
00485
00486 | sethi(imm22, rd) =>
00487 stmts = instantiate(pc, "sethi", dis_Num(imm22), DIS_RD);
00488
00489 | load_greg(addr, rd) =>
00490 stmts = instantiate(pc, name, DIS_ADDR, DIS_RD);
00491
00492 | LDF (addr, fds) =>
00493 stmts = instantiate(pc, name, DIS_ADDR, DIS_FDS);
00494
00495 | LDDF (addr, fdd) =>
00496 stmts = instantiate(pc, name, DIS_ADDR, DIS_FDD);
00497
00498 | load_asi (addr, asi, rd) =>
00499 unused(asi);
00500 stmts = instantiate(pc, name, DIS_RD, DIS_ADDR);
00501
00502 | sto_greg(rd, addr) =>
00503
00504 stmts = instantiate(pc, name, DIS_RDR, DIS_ADDR);
00505
00506 | STF (fds, addr) =>
00507 stmts = instantiate(pc, name, DIS_FDS, DIS_ADDR);
00508
00509 | STDF (fdd, addr) =>
00510 stmts = instantiate(pc, name, DIS_FDD, DIS_ADDR);
00511
00512 | sto_asi (rd, addr, asi) =>
00513 unused(asi);
00514 stmts = instantiate(pc, name, DIS_RDR, DIS_ADDR);
00515
00516 | LDFSR(addr) =>
00517 stmts = instantiate(pc, name, DIS_ADDR);
00518
00519 | LDCSR(addr) =>
00520 stmts = instantiate(pc, name, DIS_ADDR);
00521
00522 | STFSR(addr) =>
00523 stmts = instantiate(pc, name, DIS_ADDR);
00524
00525 | STCSR(addr) =>
00526 stmts = instantiate(pc, name, DIS_ADDR);
00527
00528 | STDFQ(addr) =>
00529 stmts = instantiate(pc, name, DIS_ADDR);
00530
00531 | STDCQ(addr) =>
00532 stmts = instantiate(pc, name, DIS_ADDR);
00533
00534 | RDY(rd) =>
00535 stmts = instantiate(pc, name, DIS_RD);
00536
00537 | RDPSR(rd) =>
00538 stmts = instantiate(pc, name, DIS_RD);
00539
00540 | RDWIM(rd) =>
00541 stmts = instantiate(pc, name, DIS_RD);
00542
00543 | RDTBR(rd) =>
00544 stmts = instantiate(pc, name, DIS_RD);
00545
00546 | WRY(rs1,roi) =>
00547 stmts = instantiate(pc, name, DIS_RS1, DIS_ROI);
00548
00549 | WRPSR(rs1, roi) =>
00550 stmts = instantiate(pc, name, DIS_RS1, DIS_ROI);
00551
00552 | WRWIM(rs1, roi) =>
00553 stmts = instantiate(pc, name, DIS_RS1, DIS_ROI);
00554
00555 | WRTBR(rs1, roi) =>
00556 stmts = instantiate(pc, name, DIS_RS1, DIS_ROI);
00557
00558 | alu (rs1, roi, rd) =>
00559 stmts = instantiate(pc, name, DIS_RS1, DIS_ROI, DIS_RD);
00560
00561 | float2s (fs2s, fds) =>
00562 stmts = instantiate(pc, name, DIS_FS2S, DIS_FDS);
00563
00564 | float3s (fs1s, fs2s, fds) =>
00565 stmts = instantiate(pc, name, DIS_FS1S, DIS_FS2S, DIS_FDS);
00566
00567 | float3d (fs1d, fs2d, fdd) =>
00568 stmts = instantiate(pc, name, DIS_FS1D, DIS_FS2D, DIS_FDD);
00569
00570 | float3q (fs1q, fs2q, fdq) =>
00571 stmts = instantiate(pc, name, DIS_FS1Q, DIS_FS2Q, DIS_FDQ);
00572
00573 | fcompares (fs1s, fs2s) =>
00574 stmts = instantiate(pc, name, DIS_FS1S, DIS_FS2S);
00575
00576 | fcompared (fs1d, fs2d) =>
00577 stmts = instantiate(pc, name, DIS_FS1D, DIS_FS2D);
00578
00579 | fcompareq (fs1q, fs2q) =>
00580 stmts = instantiate(pc, name, DIS_FS1Q, DIS_FS2Q);
00581
00582 | FTOs (fs2s, fds) =>
00583 stmts = instantiate(pc, name, DIS_FS2S, DIS_FDS);
00584
00585
00586 | FiTOd (fs2s, fdd) =>
00587 stmts = instantiate(pc, name, DIS_FS2S, DIS_FDD);
00588 | FdTOi (fs2d, fds) =>
00589 stmts = instantiate(pc, name, DIS_FS2D, DIS_FDS);
00590
00591 | FiTOq (fs2s, fdq) =>
00592 stmts = instantiate(pc, name, DIS_FS2S, DIS_FDQ);
00593 | FqTOi (fs2q, fds) =>
00594 stmts = instantiate(pc, name, DIS_FS2Q, DIS_FDS);
00595
00596 | FsTOd (fs2s, fdd) =>
00597 stmts = instantiate(pc, name, DIS_FS2S, DIS_FDD);
00598 | FdTOs (fs2d, fds) =>
00599 stmts = instantiate(pc, name, DIS_FS2D, DIS_FDS);
00600
00601 | FsTOq (fs2s, fdq) =>
00602 stmts = instantiate(pc, name, DIS_FS2S, DIS_FDQ);
00603 | FqTOs (fs2q, fds) =>
00604 stmts = instantiate(pc, name, DIS_FS2Q, DIS_FDS);
00605
00606 | FdTOq (fs2d, fdq) =>
00607 stmts = instantiate(pc, name, DIS_FS2D, DIS_FDQ);
00608 | FqTOd (fs2q, fdd) =>
00609 stmts = instantiate(pc, name, DIS_FS2Q, DIS_FDD);
00610
00611
00612 | FSQRTd (fs2d, fdd) =>
00613 stmts = instantiate(pc, name, DIS_FS2D, DIS_FDD);
00614
00615 | FSQRTq (fs2q, fdq) =>
00616 stmts = instantiate(pc, name, DIS_FS2Q, DIS_FDQ);
00617
00618
00619
00620
00621 | RETURN (addr) =>
00622 stmts = instantiate(pc, name, DIS_ADDR);
00623 result.rtl = new RTL(pc, stmts);
00624 result.rtl->appendStmt(new ReturnStatement);
00625 result.type = DD;
00626
00627 | trap (addr) =>
00628 stmts = instantiate(pc, name, DIS_ADDR);
00629
00630 | UNIMP (n) =>
00631 unused(n);
00632 stmts = NULL;
00633 result.valid = false;
00634
00635 | inst = n =>
00636
00637 unused(n);
00638 result.valid = false;
00639 stmts = NULL;
00640
00641 else
00642 stmts = NULL;
00643 result.valid = false;
00644 result.numBytes = 4;
00645 endmatch
00646
00647 result.numBytes = nextPC - hostPC;
00648 if (result.valid && result.rtl == 0)
00649 result.rtl = new RTL(pc, stmts);
00650
00651 return result;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 Exp* SparcDecoder::dis_RegLhs(unsigned r)
00667 {
00668 return Location::regOf(r);
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 Exp* SparcDecoder::dis_RegRhs(unsigned r)
00680 {
00681 if (r == 0)
00682 return new Const(0);
00683 return Location::regOf(r);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693 Exp* SparcDecoder::dis_RegImm(unsigned pc)
00694 {
00695
00696 match pc to
00697 | imode(i) =>
00698 Exp* expr = new Const(i);
00699 return expr;
00700 | rmode(rs2) =>
00701 return dis_RegRhs(rs2);
00702 endmatch
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 Exp* SparcDecoder::dis_Eaddr(ADDRESS pc, int ignore )
00714 {
00715 Exp* expr;
00716
00717 match pc to
00718 | indirectA(rs1) =>
00719 expr = Location::regOf(rs1);
00720 | indexA(rs1, rs2) =>
00721 expr = new Binary(opPlus,
00722 Location::regOf(rs1),
00723 Location::regOf(rs2));
00724 | absoluteA(i) =>
00725 expr = new Const((int)i);
00726 | dispA(rs1,i) =>
00727 expr = new Binary(opPlus,
00728 Location::regOf(rs1),
00729 new Const((int)i));
00730 endmatch
00731
00732 return expr;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742 bool SparcDecoder::isFuncPrologue(ADDRESS hostPC)
00743 {
00744 #if 0 // Can't do this without patterns. It was a bit of a hack anyway
00745 int hiVal, loVal, reg, locals;
00746 if ((InstructionPatterns::new_reg_win(prog.csrSrc,hostPC, locals)) != NULL)
00747 return true;
00748 if ((InstructionPatterns::new_reg_win_large(prog.csrSrc, hostPC,
00749 hiVal, loVal, reg)) != NULL)
00750 return true;
00751 if ((InstructionPatterns::same_reg_win(prog.csrSrc, hostPC, locals))
00752 != NULL)
00753 return true;
00754 if ((InstructionPatterns::same_reg_win_large(prog.csrSrc, hostPC,
00755 hiVal, loVal, reg)) != NULL)
00756 return true;
00757 #endif
00758
00759 return false;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768 bool SparcDecoder::isRestore(ADDRESS hostPC) {
00769 match hostPC to
00770 | RESTORE(a, b, c) =>
00771 unused(a);
00772 unused(b);
00773 unused(c);
00774 return true;
00775 else
00776 return false;
00777 endmatch
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 DWord SparcDecoder::getDword(ADDRESS lc)
00791 {
00792 Byte* p = (Byte*)lc;
00793 return (p[0] << 24) + (p << 16) + (p[2] << 8) + p;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802 SparcDecoder::SparcDecoder(Prog* prog) : NJMCDecoder(prog)
00803 {
00804 std::string file = Boomerang::get()->getProgPath() + "frontend/machine/sparc/sparc.ssl";
00805 RTLDict.readSSLFile(file.c_str());
00806 }
00807
00808
00809 int SparcDecoder::decodeAssemblyInstruction(unsigned, int)
00810 { return 0; }
00811