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 #include <assert.h>
00026 #if defined(_MSC_VER) && _MSC_VER <= 1100
00027 #include "signature.h"
00028 #endif
00029
00030 #include "exp.h"
00031 #include "prog.h"
00032 #include "proc.h"
00033 #include "decoder.h"
00034 #include "ppcdecoder.h"
00035 #include "rtl.h"
00036 #include "BinaryFile.h"
00037 #include "boomerang.h"
00038 #include <iostream>
00039
00040 Exp* crBit(int bitNum);
00041
00042 #define DIS_UIMM (new Const(uimm))
00043 #define DIS_SIMM (new Const(simm))
00044 #define DIS_RS (dis_Reg(rs))
00045 #define DIS_RD (dis_Reg(rd))
00046
00047 #define DIS_CRFD (new Const(crfd))
00048 #define DIS_RDR (dis_Reg(rd))
00049 #define DIS_RA (dis_Reg(ra))
00050 #define DIS_RAZ (dis_RAmbz(ra)) // As above, but May Be constant Zero
00051 #define DIS_RB (dis_Reg(rb))
00052 #define DIS_D (new Const(d))
00053 #define DIS_NZRA (dis_Reg(ra))
00054 #define DIS_NZRB (dis_Reg(rb))
00055 #define DIS_ADDR (new Const(addr))
00056 #define DIS_RELADDR (new Const(reladdr - delta))
00057 #define DIS_CRBD (crBit(crbD))
00058 #define DIS_CRBA (crBit(crbA))
00059 #define DIS_CRBB (crBit(crbB))
00060 #define DIS_DISP (new Binary(opPlus, dis_RAmbz(ra), new Const(d)))
00061 #define DIS_INDEX (new Binary(opPlus, DIS_RAZ, DIS_NZRB))
00062 #define DIS_BICR (new Const(BIcr))
00063 #define DIS_RS_NUM (new Const(rs))
00064 #define DIS_RD_NUM (new Const(rd))
00065 #define DIS_BEG (new Const(beg))
00066 #define DIS_END (new Const(end))
00067 #define DIS_FD (dis_Reg(fd+32))
00068 #define DIS_FS (dis_Reg(fs+32))
00069 #define DIS_FA (dis_Reg(fa+32))
00070 #define DIS_FB (dis_Reg(fb+32))
00071
00072 #define PPC_COND_JUMP(name, size, relocd, cond, BIcr) \
00073 result.rtl = new RTL(pc, stmts); \
00074 BranchStatement* jump = new BranchStatement; \
00075 result.rtl->appendStmt(jump); \
00076 result.numBytes = size; \
00077 jump->setDest(relocd-delta); \
00078 jump->setCondType(cond); \
00079 SHOW_ASM(name<<" "<<BIcr<<", 0x"<<std::hex<<relocd-delta)
00080
00081
00082
00083
00084
00085
00086
00087 void PPCDecoder::unused(int x)
00088 {}
00089 void unused(char* x) {}
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 DecodeResult& PPCDecoder::decodeInstruction (ADDRESS pc, int delta) {
00110 static DecodeResult result;
00111 ADDRESS hostPC = pc+delta;
00112
00113
00114 result.reset();
00115
00116
00117 std::list<Statement*>* stmts = NULL;
00118
00119 ADDRESS nextPC = NO_ADDRESS;
00120
00121 match hostPC to
00122 | XO_ ( rd, ra, rb) =>
00123 stmts = instantiate(pc, name, DIS_RD, DIS_RA, DIS_RB);
00124 | XOb_ ( rd, ra) =>
00125 stmts = instantiate(pc, name, DIS_RD, DIS_RA);
00126 | Xsax_^Rc (rd, ra) =>
00127 stmts = instantiate(pc, name, DIS_RD, DIS_RA);
00128
00129
00130
00131 | Dsad_ (rs, d, ra) =>
00132 if (strcmp(name, "stmw") == 0) {
00133
00134 stmts = instantiate(pc, name, DIS_RS, DIS_DISP, DIS_RS_NUM);
00135 } else
00136 stmts = instantiate(pc, name, DIS_RS, DIS_DISP, DIS_NZRA);
00137
00138 | Dsaui_ (rd, ra, uimm) =>
00139 stmts = instantiate(pc, name, DIS_RD, DIS_RA, DIS_UIMM);
00140 | Ddasi_ (rd, ra, simm) =>
00141 if (strcmp(name, "addi") == 0 || strcmp(name, "addis") == 0) {
00142
00143 stmts = instantiate(pc, name, DIS_RD, DIS_RAZ, DIS_SIMM);
00144 } else
00145 stmts = instantiate(pc, name, DIS_RD, DIS_RA , DIS_SIMM);
00146 | Xsabx_^Rc (rd, ra, rb) =>
00147 stmts = instantiate(pc, name, DIS_RD, DIS_RA, DIS_RB);
00148 | Xdab_ (rd, ra, rb) =>
00149 stmts = instantiate(pc, name, DIS_RD, DIS_INDEX);
00150 | Xsab_ (rd, ra, rb) =>
00151 stmts = instantiate(pc, name, DIS_RD, DIS_INDEX);
00152
00153 | Ddad_ (rd, d, ra) =>
00154 if (strcmp(name, "lmw") == 0) {
00155
00156 stmts = instantiate(pc, name, DIS_RD, DIS_DISP, DIS_RD_NUM);
00157 } else
00158 stmts = instantiate(pc, name, DIS_RD, DIS_DISP, DIS_NZRA);
00159
00160 #if BCCTR_LONG // Prefer to see bltctr instead of bcctr 12,0
00161
00162
00163 stmts = instantiate(pc, name);
00164 result.rtl = new RTL(pc, stmts);
00165 result.rtl->appendStmt(new ReturnStatement);
00166 unused(b0);
00167 unused(b1);
00168 #endif
00169 | XLc_ (crbD, crbA, crbB) =>
00170 stmts = instantiate(pc, name, DIS_CRBD, DIS_CRBA, DIS_CRBB);
00171
00172 | mfspr (rd, uimm) =>
00173 stmts = instantiate(pc, name, DIS_RD, DIS_UIMM);
00174 | mtspr (uimm, rs) =>
00175 switch (uimm) {
00176 case 1:
00177 stmts = instantiate(pc, "MTXER" , DIS_RS); break;
00178 case 8:
00179 stmts = instantiate(pc, "MTLR" , DIS_RS); break;
00180 case 9:
00181 stmts = instantiate(pc, "MTCTR" , DIS_RS); break;
00182 default:
00183 std::cerr << "ERROR: MTSPR instruction with invalid S field: " << uimm << "\n";
00184 }
00185 ::unused(name);
00186
00187 | Xd_ (rd) =>
00188 stmts = instantiate(pc, name, DIS_RD);
00189
00190 | M_^Rc(ra, rs, uimm, beg, end) =>
00191 stmts = instantiate(pc, name, DIS_RA, DIS_RS, DIS_UIMM, DIS_BEG, DIS_END);
00192
00193
00194 | bl (reladdr) =>
00195 Exp* dest = DIS_RELADDR;
00196 stmts = instantiate(pc, name, dest);
00197 CallStatement* newCall = new CallStatement;
00198
00199 newCall->setIsComputed(false);
00200
00201 newCall->setDest(dest);
00202 result.rtl = new RTL(pc, stmts);
00203 result.rtl->appendStmt(newCall);
00204 Proc* destProc = prog->setNewProc(reladdr-delta);
00205 if (destProc == (Proc*)-1) destProc = NULL;
00206 newCall->setDestProc(destProc);
00207
00208 | b (reladdr) =>
00209 unconditionalJump("b", 4, reladdr, delta, pc, stmts, result);
00210
00211 | ball (BIcr, reladdr) =>
00212 if (reladdr - delta - pc == 4) {
00213
00214 Assign* as = new Assign(
00215 new IntegerType,
00216 new Unary(opMachFtr, new Const("%LR")),
00217 new Const(pc+4));
00218 stmts = new std::list<Statement*>;
00219 stmts->push_back(as);
00220 SHOW_ASM(name<<" "<<BIcr<<", .+4"<<" %LR = %pc+4")
00221 } else {
00222 Exp* dest = DIS_RELADDR;
00223 stmts = instantiate(pc, name, dest);
00224 CallStatement* newCall = new CallStatement;
00225
00226 newCall->setIsComputed(false);
00227
00228 newCall->setDest(dest);
00229 result.rtl = new RTL(pc, stmts);
00230 result.rtl->appendStmt(newCall);
00231 }
00232 unused(BIcr);
00233
00234 | Xcmp_ (crfd, l, ra, rb) =>
00235 stmts = instantiate(pc, name, DIS_CRFD, DIS_NZRA, DIS_NZRB);
00236 unused(l);
00237 | cmpi (crfd, l, ra, simm) =>
00238 stmts = instantiate(pc, name, DIS_CRFD, DIS_NZRA, DIS_SIMM);
00239 unused(l);
00240 | cmpli (crfd, l, ra, uimm) =>
00241 stmts = instantiate(pc, name, DIS_CRFD, DIS_NZRA, DIS_UIMM);
00242 unused(l);
00243
00244 | Ddaf_(fd, d, ra) =>
00245 stmts = instantiate(pc, name, DIS_FD, DIS_DISP, DIS_RA);
00246
00247 | Xdaf_(fd, ra, rb) =>
00248 stmts = instantiate(pc, name, DIS_FD, DIS_INDEX, DIS_RA);
00249
00250 | Dsaf_(fs, d, ra) =>
00251 stmts = instantiate(pc, name, DIS_FS, DIS_DISP, DIS_RA);
00252
00253 | Xsaf_(fs, ra, rb) =>
00254 stmts = instantiate(pc, name, DIS_FS, DIS_INDEX, DIS_RA);
00255
00256
00257 | Xcab_(crfd, fa, fb) =>
00258 stmts = instantiate(pc, name, DIS_CRFD, DIS_FA, DIS_FB);
00259
00260 | Xdbx_^Rc(fd, fb) =>
00261 stmts = instantiate(pc, name, DIS_FD, DIS_FB);
00262
00263 | Ac_^Rc(fd, fa, fb) =>
00264 stmts = instantiate(pc, name, DIS_FD, DIS_FA, DIS_FB);
00265
00266
00267
00268
00269
00270
00271 | blt(BIcr, reladdr) =>
00272 PPC_COND_JUMP(name, 4, reladdr, BRANCH_JSL, BIcr);
00273 | ble(BIcr, reladdr) =>
00274 PPC_COND_JUMP(name, 4, reladdr, BRANCH_JSLE, BIcr);
00275 | beq(BIcr, reladdr) =>
00276 PPC_COND_JUMP(name, 4, reladdr, BRANCH_JE, BIcr);
00277 | bge(BIcr, reladdr) =>
00278 PPC_COND_JUMP(name, 4, reladdr, BRANCH_JSGE, BIcr);
00279 | bgt(BIcr, reladdr) =>
00280 PPC_COND_JUMP(name, 4, reladdr, BRANCH_JSG, BIcr);
00281
00282
00283 | bne(BIcr, reladdr) =>
00284 PPC_COND_JUMP(name, 4, reladdr, BRANCH_JNE, BIcr);
00285
00286
00287 | bso(BIcr, reladdr) =>
00288 PPC_COND_JUMP(name, 4, reladdr, (BRANCH_TYPE)0, BIcr);
00289 | bns(BIcr, reladdr) =>
00290 PPC_COND_JUMP(name, 4, reladdr, (BRANCH_TYPE)0, BIcr);
00291
00292
00293
00294
00295
00296 | balctr(BIcr) =>
00297 computedJump(name, 4, new Unary(opMachFtr, new Const("%CTR")), pc, stmts, result);
00298 unused(BIcr);
00299
00300 | balctrl(BIcr) =>
00301 computedCall(name, 4, new Unary(opMachFtr, new Const("%CTR")), pc, stmts, result);
00302 unused(BIcr);
00303
00304 | bal(BIcr, reladdr) =>
00305 unconditionalJump("bal", 4, reladdr, delta, pc, stmts, result);
00306 unused(BIcr);
00307
00308
00309
00310 | bltlr(BIcr) =>
00311 PPC_COND_JUMP(name, 4, hostPC+4, BRANCH_JSGE, BIcr);
00312 result.rtl->appendStmt(new ReturnStatement);
00313
00314 | blelr(BIcr) =>
00315 PPC_COND_JUMP(name, 4, hostPC+4, BRANCH_JSG, BIcr);
00316 result.rtl->appendStmt(new ReturnStatement);
00317
00318 | beqlr(BIcr) =>
00319 PPC_COND_JUMP(name, 4, hostPC+4, BRANCH_JNE, BIcr);
00320 result.rtl->appendStmt(new ReturnStatement);
00321
00322 | bgelr(BIcr) =>
00323 PPC_COND_JUMP(name, 4, hostPC+4, BRANCH_JSL, BIcr);
00324 result.rtl->appendStmt(new ReturnStatement);
00325
00326 | bgtlr(BIcr) =>
00327 PPC_COND_JUMP(name, 4, hostPC+4, BRANCH_JSLE, BIcr);
00328 result.rtl->appendStmt(new ReturnStatement);
00329
00330 | bnelr(BIcr) =>
00331 PPC_COND_JUMP(name, 4, hostPC+4, BRANCH_JE, BIcr);
00332 result.rtl->appendStmt(new ReturnStatement);
00333
00334 | bsolr(BIcr) =>
00335 PPC_COND_JUMP(name, 4, hostPC+4, (BRANCH_TYPE)0, BIcr);
00336 result.rtl->appendStmt(new ReturnStatement);
00337
00338 | bnslr(BIcr) =>
00339 PPC_COND_JUMP(name, 4, hostPC+4, (BRANCH_TYPE)0, BIcr);
00340 result.rtl->appendStmt(new ReturnStatement);
00341
00342 | ballr(BIcr) =>
00343 result.rtl = new RTL(pc, stmts);
00344 result.rtl->appendStmt(new ReturnStatement);
00345 SHOW_ASM(name<<"\n");
00346 unused(BIcr);
00347
00348
00349 | srawi(ra, rs, uimm) =>
00350 stmts = instantiate(pc, name, DIS_RA, DIS_RS, DIS_UIMM);
00351 | srawiq(ra, rs, uimm) =>
00352 stmts = instantiate(pc, name, DIS_RA, DIS_RS, DIS_UIMM);
00353
00354 else
00355 stmts = NULL;
00356 result.valid = false;
00357 result.numBytes = 4;
00358 endmatch
00359
00360 result.numBytes = nextPC - hostPC;
00361 if (result.valid && result.rtl == 0)
00362 result.rtl = new RTL(pc, stmts);
00363
00364 return result;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 Exp* PPCDecoder::dis_Reg(unsigned r)
00380 {
00381 return Location::regOf(r);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 Exp* PPCDecoder::dis_RAmbz(unsigned r)
00391 {
00392 if (r == 0)
00393 return new Const(0);
00394 return Location::regOf(r);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 bool PPCDecoder::isFuncPrologue(ADDRESS hostPC)
00407 {
00408
00409 return false;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 DWord PPCDecoder::getDword(ADDRESS lc)
00424 {
00425 Byte* p = (Byte*)lc;
00426 return (p[0] << 24) + (p << 16) + (p[2] << 8) + p;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435 PPCDecoder::PPCDecoder(Prog* prog) : NJMCDecoder(prog)
00436 {
00437 std::string file = Boomerang::get()->getProgPath() + "frontend/machine/ppc/ppc.ssl";
00438 RTLDict.readSSLFile(file.c_str());
00439 }
00440
00441
00442 int PPCDecoder::decodeAssemblyInstruction(unsigned, int)
00443 { return 0; }
00444
00445
00446
00447 Exp* crBit(int bitNum) {
00448 int crNum = bitNum / 4;
00449 bitNum = bitNum & 3;
00450 return new Ternary(opAt,
00451 Location::regOf(64 + crNum),
00452 new Const(bitNum),
00453 new Const(bitNum));
00454 }
00455