00001 /* 00002 * Copyright (C) 1998-2001, The University of Queensland 00003 * Copyright (C) 2000-2001, Sun Microsystems, Inc 00004 * Copyright (C) 2002, Trent Waddington 00005 * 00006 * See the file "LICENSE.TERMS" for information on usage and 00007 * redistribution of this file, and for a DISCLAIMER OF ALL 00008 * WARRANTIES. 00009 * 00010 */ 00011 00012 /*============================================================================== 00013 * FILE: frontend/sparcfrontend.cpp 00014 * OVERVIEW: This file contains routines to manage the decoding of sparc instructions and the instantiation to RTLs, 00015 * removing sparc dependent features such as delay slots in the process. These functions replace 00016 * frontend.cpp for decoding sparc instructions. 00017 *============================================================================*/ 00018 00019 /* 00020 * $Revision: 1.44 $ // 1.35.2.5 00021 * 00022 * 17 May 02 - Mike: Mods for boomerang 00023 * 22 Nov 02 - Mike: Added check for invalid instructions; prints opcode 00024 * 12 Dec 02 - Mike: Fixed various bugs in move/call/move (etc) pattern handling 00025 */ 00026 00027 /*============================================================================== 00028 * Dependencies. 00029 *============================================================================*/ 00030 00031 #include <assert.h> 00032 #include <iomanip> // For setfill etc 00033 #include <sstream> 00034 #if defined(_MSC_VER) && _MSC_VER <= 1200 00035 #pragma warning(disable:4786) 00036 #endif 00037 00038 #include "exp.h" 00039 #include "register.h" 00040 #include "rtl.h" 00041 #include "cfg.h" 00042 #include "proc.h" 00043 #include "prog.h" 00044 #include "decoder.h" 00045 #include "sparcdecoder.h" 00046 #include "BinaryFile.h" 00047 #include "frontend.h" 00048 #include "sparcfrontend.h" 00049 #include "BinaryFile.h" // E.g. IsDynamicallyLinkedProc 00050 #include "boomerang.h" 00051 #include "signature.h" 00052 #include "log.h" 00053 00054 /*============================================================================== 00055 * FUNCTION: warnDCTcouple 00056 * OVERVIEW: Emit a warning when encountering a DCTI couple. 00057 * PARAMETERS: uAt - the address of the couple 00058 * uDest - the address of the first DCTI in the couple 00059 * RETURNS: <nothing> 00060 *============================================================================*/ 00061 void SparcFrontEnd::warnDCTcouple(ADDRESS uAt, ADDRESS uDest) 00062 { 00063 std::cerr << "Error: DCTI couple at " << std::hex << uAt << " points to delayed branch at " << uDest << "...\n"; 00064 std::cerr << "Decompilation will likely be incorrect\n"; 00065 } 00066 00067 /*============================================================================== 00068 * FUNCTION: optimise_DelayCopy 00069 * OVERVIEW: Determines if a delay instruction is exactly the same as the instruction immediately preceding the 00070 * destination of a CTI; i.e. has been copied from the real destination to the delay slot as an 00071 * optimisation 00072 * PARAMETERS: src - the logical source address of a CTI 00073 * dest - the logical destination address of the CTI 00074 * delta - used to convert logical to real addresses 00075 * uUpper - first address past the end of the main text section 00076 * SIDE EFFECT: Optionally displays an error message if the target of the branch is the delay slot of another 00077 * delayed CTI 00078 * RETURNS: can optimise away the delay instruction 00079 *============================================================================*/ 00080 bool SparcFrontEnd::optimise_DelayCopy(ADDRESS src, ADDRESS dest, int delta, ADDRESS uUpper) 00081 { 00082 // Check that the destination is within the main test section; may not be when we speculatively decode junk 00083 if ((dest - 4) > uUpper) 00084 return false; 00085 unsigned delay_inst = *((unsigned*)(src+4+delta)); 00086 unsigned inst_before_dest = *((unsigned*)(dest-4+delta)); 00087 return (delay_inst == inst_before_dest); 00088 } 00089 00090 /*============================================================================== 00091 * FUNCTION: optimise_CallReturn 00092 * OVERVIEW: Determines if the given call and delay instruction consitute a call where callee returns to 00093 * the caller's caller. That is: 00094 * ProcA: ProcB: ProcC: 00095 * ... ... ... 00096 * call ProcB call ProcC ret 00097 * ... restore ... 00098 * 00099 * The restore instruction in ProcB will effectively set %o7 to be %i7, the address to which ProcB will 00100 * return. So in effect ProcC will return to ProcA at the position just after the call to ProcB. This 00101 * is equivalent to ProcC returning to ProcB which then immediately returns to ProcA. 00102 * NOTE: We don't set a label at the return, because we also have to force a jump at the call BB, 00103 * and in some cases we don't have the call BB as yet. So these two are up to the caller 00104 * NOTE ALSO: The name of this function is now somewhat irrelevant. The whole function is somewhat irrelevant; 00105 * it dates from the times when you would always find an actual restore in the delay slot. 00106 * With some patterns, this is no longer true. 00107 * PARAMETERS: call - the RTL for the caller (e.g. "call ProcC" above) 00108 * rtl - pointer to the RTL for the call instruction 00109 * delay - the RTL for the delay instruction (e.g. "restore") 00110 * cfg - the CFG of the procedure 00111 * RETURNS: The basic block containing the single return instruction if this optimisation applies, NULL 00112 * otherwise. 00113 *============================================================================*/ 00114 BasicBlock* SparcFrontEnd::optimise_CallReturn(CallStatement* call, RTL* rtl, RTL* delay, UserProc* pProc) { 00115 00116 if (call->isReturnAfterCall()) { 00117 00118 // Constuct the RTLs for the new basic block 00119 std::list<RTL*>* rtls = new std::list<RTL*>(); 00120 00121 // The only RTL in the basic block is a ReturnStatement 00122 std::list<Statement*>* ls = new std::list<Statement*>; 00123 // If the delay slot is a single assignment to %o7, we want to see the semantics for it, so that preservation 00124 // or otherwise of %o7 is correct 00125 if (delay->getNumStmt() == 1 && delay->elementAt(0)->isAssign() && 00126 ((Assign*)delay->elementAt(0))->getLeft()->isRegN(15)) 00127 ls->push_back(delay->elementAt(0)); 00128 ls->push_back(new ReturnStatement); 00129 // rtls->push_back(new RTL(rtl->getAddress() + 1, ls)); 00130 // Cfg* cfg = pProc->getCFG(); 00131 // BasicBlock* returnBB = cfg->newBB(rtls, RET, 0); 00132 BasicBlock* returnBB = createReturnBlock(pProc, rtls, new RTL(rtl->getAddress() + 1, ls)); 00133 return returnBB; 00134 } 00135 else 00136 // May want to put code here that checks whether or not the delay instruction redefines %o7 00137 return NULL; 00138 } 00139 00140 /*============================================================================== 00141 * FUNCTION: handleBranch 00142 * OVERVIEW: Adds the destination of a branch to the queue of address that must be decoded (if this destination 00143 * has not already been visited). 00144 * PARAMETERS: newBB - the new basic block delimited by the branch instruction. May be NULL if this block has been 00145 * built before. 00146 * dest - the destination being branched to 00147 * hiAddress - the last address in the current procedure 00148 * cfg - the CFG of the current procedure 00149 * tq: Object managing the target queue 00150 * RETURNS: <nothing>, but newBB may be changed if the destination of the branch is in the middle of an existing 00151 * BB. It will then be changed to point to a new BB beginning with the dest 00152 *============================================================================*/ 00153 void SparcFrontEnd::handleBranch(ADDRESS dest, ADDRESS hiAddress, BasicBlock*& newBB, Cfg* cfg, TargetQueue& tq) { 00154 if (newBB == NULL) 00155 return; 00156 00157 if (dest < hiAddress) { 00158 tq.visit(cfg, dest, newBB); 00159 cfg->addOutEdge(newBB, dest, true); 00160 } 00161 else 00162 std::cerr << "Error: branch to " << std::hex << dest << " goes beyond section.\n"; 00163 } 00164 00165 /*============================================================================== 00166 * FUNCTION: handleCall 00167 * OVERVIEW: Records the fact that there is a procedure at a given address. Also adds the out edge to the 00168 * lexical successor of the call site (taking into consideration the delay slot and possible UNIMP 00169 * instruction). 00170 * PARAMETERS: dest - the address of the callee 00171 * callBB - the basic block delimited by the call 00172 * cfg - CFG of the enclosing procedure 00173 * address - the address of the call instruction 00174 * offset - the offset from the call instruction to which an outedge must be added. A value of 0 00175 * means no edge is to be added. 00176 * RETURNS: <nothing> 00177 *============================================================================*/ 00178 void SparcFrontEnd::handleCall(UserProc *proc, ADDRESS dest, BasicBlock* callBB, Cfg* cfg, ADDRESS address, 00179 int offset/* = 0*/) 00180 { 00181 if (callBB == NULL) 00182 return; 00183 00184 // If the destination address is the same as this very instruction, we have a call with iDisp30 == 0. Don't treat 00185 // this as the start of a real procedure. 00186 if ((dest != address) && proc->getProg()->findProc(dest) == 0) { 00187 // We don't want to call prog.visitProc just yet, in case this is a speculative decode that failed. Instead, we 00188 // use the set of CallStatements (not in this procedure) that is needed by CSR 00189 if (Boomerang::get()->traceDecoder) 00190 std::cout << "p" << std::hex << dest << "\t"; 00191 } 00192 00193 // Add the out edge if required 00194 if (offset != 0) 00195 cfg->addOutEdge(callBB, address+offset); 00196 00197 } 00198 00199 /*============================================================================== 00200 * FUNCTION: case_unhandled_stub 00201 * OVERVIEW: This is the stub for cases of DCTI couples that we haven't written analysis code for yet. It simply 00202 * displays an informative warning and returns. 00203 * PARAMETERS: addr - the address of the first CTI in the couple 00204 * RETURNS: <nothing> 00205 *============================================================================*/ 00206 void SparcFrontEnd::case_unhandled_stub(ADDRESS addr) 00207 { 00208 std::cerr << "Error: DCTI couple at " << std::hex << addr << std::endl; 00209 } 00210 00211 /*============================================================================== 00212 * FUNCTION: case_CALL 00213 * OVERVIEW: Handles a call instruction 00214 * PARAMETERS: address - the native address of the call instruction 00215 * inst - the info summaries when decoding the call instruction 00216 * delay_inst - the info summaries when decoding the delay instruction 00217 * BB_rtls - the list of RTLs currently built for the BB under construction 00218 * proc - the enclosing procedure 00219 * callList - a list of pointers to CallStatements for procs yet to be processed 00220 * os - output stream for rtls 00221 * isPattern - true if the call is an idiomatic pattern (e.g. a move_call_move pattern) 00222 * SIDE EFFECTS: address may change; BB_rtls may be appended to or set NULL 00223 * RETURNS: true if next instruction is to be fetched sequentially from this one 00224 *============================================================================*/ 00225 bool SparcFrontEnd::case_CALL(ADDRESS& address, DecodeResult& inst, DecodeResult& delay_inst, 00226 std::list<RTL*>*& BB_rtls, UserProc* proc, std::list<CallStatement*>& callList, std::ofstream &os, 00227 bool isPattern/* = false*/) { 00228 00229 // Aliases for the call and delay RTLs 00230 CallStatement* call_stmt = ((CallStatement*)inst.rtl->getList().back()); 00231 RTL* delay_rtl = delay_inst.rtl; 00232 00233 // Emit the delay instruction, unless the delay instruction is a nop, or we have a pattern, or are followed by a 00234 // restore 00235 if ((delay_inst.type != NOP) && !call_stmt->isReturnAfterCall()) { 00236 delay_rtl->updateAddress(address); 00237 BB_rtls->push_back(delay_rtl); 00238 if (Boomerang::get()->printRtl) 00239 delay_rtl->print(os); 00240 } 00241 00242 // Get the new return basic block for the special case where the delay instruction is a restore 00243 BasicBlock* returnBB = optimise_CallReturn(call_stmt, inst.rtl, delay_rtl, proc); 00244 00245 int disp30 = (call_stmt->getFixedDest() - address) >> 2; 00246 // Don't test for small offsets if part of a move_call_move pattern. 00247 // These patterns assign to %o7 in the delay slot, and so can't possibly be used to copy %pc to %o7 00248 // Similarly if followed by a restore 00249 if (!isPattern && (returnBB == NULL) && (disp30 == 2 || disp30 == 3)) { 00250 // This is the idiomatic case where the destination is 1 or 2 instructions after the delayed instruction. 00251 // Only emit the side effect of the call (%o7 := %pc) in this case. Note that the side effect occurs before the 00252 // delay slot instruction (which may use the value of %o7) 00253 emitCopyPC(BB_rtls, address); 00254 address += disp30 << 2; 00255 return true; 00256 } 00257 else { 00258 assert (disp30 != 1); 00259 00260 // First check for helper functions 00261 ADDRESS dest = call_stmt->getFixedDest(); 00262 // Special check for calls to weird PLT entries which don't have symbols 00263 if ((pBF->IsDynamicLinkedProc(dest)) && (pBF->SymbolByAddress(dest) == NULL)) { 00264 // This is one of those. Flag this as an invalid instruction 00265 inst.valid = false; 00266 } 00267 if (helperFunc(dest, address, BB_rtls)) { 00268 address += 8; // Skip call, delay slot 00269 return true; 00270 } 00271 00272 // Emit the call 00273 BB_rtls->push_back(inst.rtl); 00274 00275 // End the current basic block 00276 Cfg* cfg = proc->getCFG(); 00277 BasicBlock* callBB = cfg->newBB(BB_rtls, CALL, 1); 00278 if (callBB == NULL) 00279 return false; 00280 00281 // Add this call site to the set of call sites which need to be analysed later. 00282 // This set will be used later to call prog.visitProc (so the proc will get decoded) 00283 callList.push_back((CallStatement*)inst.rtl->getList().back()); 00284 00285 if (returnBB) { 00286 // Handle the call but don't add any outedges from it just yet. 00287 handleCall(proc, call_stmt->getFixedDest(), callBB, cfg, address); 00288 00289 // Now add the out edge 00290 cfg->addOutEdge(callBB, returnBB); 00291 // Put a label on the return BB; indicate that a jump is reqd 00292 cfg->setLabel(returnBB); 00293 callBB->setJumpReqd(); 00294 00295 address += inst.numBytes; // For coverage 00296 // This is a CTI block that doesn't fall through and so must 00297 // stop sequentially decoding 00298 return false; 00299 } 00300 else { 00301 // Else no restore after this call. An outedge may be added to the lexical successor of the call which 00302 // will be 8 bytes ahead or in the case where the callee returns a struct, 12 bytes ahead. But the problem 00303 // is: how do you know this function returns a struct at decode time? 00304 // If forceOutEdge is set, set offset to 0 and no out-edge will be added yet 00305 int offset = inst.forceOutEdge ? 0 : 00306 //(call_stmt->returnsStruct() ? 12 : 8); 00307 // MVE: FIXME! 00308 8; 00309 00310 bool ret = true; 00311 // Check for _exit; probably should check for other "never return" functions 00312 const char* name = pBF->SymbolByAddress(dest); 00313 if (name && strcmp(name, "_exit") == 0) { 00314 // Don't keep decoding after this call 00315 ret = false; 00316 // Also don't add an out-edge; setting offset to 0 will do this 00317 offset = 0; 00318 // But we have already set the number of out-edges to 1 00319 callBB->updateType(CALL, 0); 00320 } 00321 00322 // Handle the call (register the destination as a proc) and possibly set the outedge. 00323 handleCall(proc, dest, callBB, cfg, address, offset); 00324 00325 if (inst.forceOutEdge) { 00326 // There is no need to force a goto to the new out-edge, since we will continue decoding from there. 00327 // If other edges exist to the outedge, they will generate the required label 00328 cfg->addOutEdge(callBB, inst.forceOutEdge); 00329 address = inst.forceOutEdge; 00330 } 00331 else { 00332 // Continue decoding from the lexical successor 00333 address += offset; 00334 } 00335 BB_rtls = NULL; 00336 00337 return ret; 00338 } 00339 } 00340 } 00341 00342 /*============================================================================== 00343 * FUNCTION: case_SD 00344 * OVERVIEW: Handles a non-call, static delayed (SD) instruction 00345 * PARAMETERS: address - the native address of the SD 00346 * delta - the offset of the above address from the logical address at which the procedure starts 00347 * (i.e. the one given by dis) 00348 * inst - the info summaries when decoding the SD instruction 00349 * delay_inst - the info summaries when decoding the delay instruction 00350 * BB_rtls - the list of RTLs currently built for the BB under construction 00351 * cfg - the CFG of the enclosing procedure 00352 * tq: Object managing the target queue 00353 * os - output stream for rtls 00354 * SIDE EFFECTS: address may change; BB_rtls may be appended to or set NULL 00355 * RETURNS: <nothing> 00356 *============================================================================*/ 00357 void SparcFrontEnd::case_SD(ADDRESS& address, int delta, ADDRESS hiAddress, DecodeResult& inst, 00358 DecodeResult& delay_inst, std::list<RTL*>*& BB_rtls, Cfg* cfg, TargetQueue& tq, std::ofstream &os) { 00359 00360 // Aliases for the SD and delay RTLs 00361 GotoStatement* SD_stmt = static_cast<GotoStatement*>(inst.rtl->getList().back()); 00362 RTL* delay_rtl = delay_inst.rtl; 00363 00364 // Try the "delay instruction has been copied" optimisation, emitting the delay instruction now if the optimisation 00365 // won't apply 00366 if (delay_inst.type != NOP) { 00367 if (optimise_DelayCopy(address, SD_stmt->getFixedDest(), delta, hiAddress)) 00368 SD_stmt->adjustFixedDest(-4); 00369 else { 00370 // Move the delay instruction before the SD. Must update the address in case there is a branch to the SD 00371 delay_rtl->updateAddress(address); 00372 BB_rtls->push_back(delay_rtl); 00373 // Display RTL representation if asked 00374 //if (progOptions.rtl) 00375 if (0) // SETTINGS! 00376 delay_rtl->print(os); 00377 } 00378 } 00379 00380 // Update the address (for coverage) 00381 address += 8; 00382 00383 // Add the SD 00384 BB_rtls->push_back(inst.rtl); 00385 00386 // Add the one-way branch BB 00387 PBB pBB = cfg->newBB(BB_rtls, ONEWAY, 1); 00388 if (pBB == 0) { BB_rtls = NULL; return; } 00389 00390 // Visit the destination, and add the out-edge 00391 ADDRESS uDest = SD_stmt->getFixedDest(); 00392 handleBranch(uDest, hiAddress, pBB, cfg, tq); 00393 BB_rtls = NULL; 00394 } 00395 00396 00397 /*============================================================================== 00398 * FUNCTION: case_DD 00399 * OVERVIEW: Handles all dynamic delayed jumps (jmpl, also dynamic calls) 00400 * PARAMETERS: address - the native address of the DD 00401 * delta - the offset of the above address from the logical address at which the procedure 00402 * starts (i.e. the one given by dis) 00403 * inst - the info summaries when decoding the SD instruction 00404 * delay_inst - the info summaries when decoding the delay instruction 00405 * BB_rtls - the list of RTLs currently built for the BB under construction 00406 * tq: Object managing the target queue 00407 * proc: pointer to the current Proc object 00408 * callSet - a set of pointers to CallStatements for procs yet to be processed 00409 * SIDE EFFECTS: address may change; BB_rtls may be appended to or set NULL 00410 * RETURNS: true if next instruction is to be fetched sequentially from this one 00411 *============================================================================*/ 00412 bool SparcFrontEnd::case_DD(ADDRESS& address, int delta, DecodeResult& inst, DecodeResult& delay_inst, 00413 std::list<RTL*>*& BB_rtls, TargetQueue& tq, UserProc* proc, std::list<CallStatement*>& callList) { 00414 00415 Cfg* cfg = proc->getCFG(); 00416 00417 if (delay_inst.type != NOP) { 00418 // Emit the delayed instruction, unless a NOP 00419 delay_inst.rtl->updateAddress(address); 00420 BB_rtls->push_back(delay_inst.rtl); 00421 } 00422 00423 // Set address past this instruction and delay slot (may be changed later). This in so that we cover the 00424 // jmp/call and delay slot instruction, in case we return false 00425 address += 8; 00426 00427 BasicBlock* newBB; 00428 bool bRet = true; 00429 Statement* lastStmt = inst.rtl->getList().back(); 00430 switch (lastStmt->getKind()) { 00431 case STMT_CALL: 00432 // Will be a computed call 00433 BB_rtls->push_back(inst.rtl); 00434 newBB = cfg->newBB(BB_rtls, COMPCALL, 1); 00435 break; 00436 case STMT_RET: 00437 // newBB = cfg->newBB(BB_rtls, RET, 0); 00438 // proc->setTheReturnAddr((ReturnStatement*)inst.rtl->getList().back(), inst.rtl->getAddress()); 00439 newBB = createReturnBlock(proc, BB_rtls, inst.rtl); 00440 bRet = false; 00441 break; 00442 case STMT_CASE: { 00443 BB_rtls->push_back(inst.rtl); 00444 newBB = cfg->newBB(BB_rtls, COMPJUMP, 0); 00445 bRet = false; 00446 Exp* pDest = ((CaseStatement*)lastStmt)->getDest(); 00447 if (pDest == NULL) { // Happens if already analysed (we are now redecoding) 00448 //SWITCH_INFO* psi = ((CaseStatement*)lastStmt)->getSwitchInfo(); 00449 // processSwitch will update the BB type and number of outedges, decode arms, set out edges, etc 00450 newBB->processSwitch(proc); 00451 } 00452 break; 00453 } 00454 default: 00455 newBB = NULL; 00456 break; 00457 } 00458 if (newBB == NULL) return false; 00459 00460 Statement* last = inst.rtl->getList().back(); 00461 // Do extra processing for for special types of DD 00462 if (last->getKind() == STMT_CALL) { 00463 00464 // Attempt to add a return BB if the delay instruction is a RESTORE 00465 CallStatement* call_stmt = (CallStatement*)(inst.rtl->getList().back()); 00466 BasicBlock* returnBB = optimise_CallReturn(call_stmt, inst.rtl, delay_inst.rtl, proc); 00467 if (returnBB != NULL) { 00468 cfg->addOutEdge(newBB,returnBB); 00469 00470 // We have to set the epilogue for the enclosing procedure (all proc's must have an 00471 // epilogue) and remove the RESTORE in the delay slot that has just been pushed to the list of RTLs 00472 //proc->setEpilogue(new CalleeEpilogue("__dummy",std::list<std::string>())); 00473 // Set the return location; this is now always %o0 00474 //setReturnLocations(proc->getEpilogue(), 8 /* %o0 */); 00475 newBB->getRTLs()->remove(delay_inst.rtl); 00476 00477 // Put a label on the return BB; indicate that a jump is reqd 00478 cfg->setLabel(returnBB); 00479 newBB->setJumpReqd(); 00480 00481 // Add this call to the list of calls to analyse. We won't be able to analyse its callee(s), of course. 00482 callList.push_back(call_stmt); 00483 00484 return false; 00485 } 00486 else { 00487 // Instead, add the standard out edge to original address+8 (now just address) 00488 cfg->addOutEdge(newBB, address); 00489 } 00490 // Add this call to the list of calls to analyse. We won't be able to analyse its callee(s), of course. 00491 callList.push_back(call_stmt); 00492 } 00493 00494 // Set the address of the lexical successor of the call that is to be decoded next and create a new list of 00495 // RTLs for the next basic block. 00496 BB_rtls = NULL; 00497 return bRet; 00498 } 00499 00500 /*============================================================================== 00501 * FUNCTION: case_SCD 00502 * OVERVIEW: Handles all Static Conditional Delayed non-anulled branches 00503 * PARAMETERS: address - the native address of the DD 00504 * delta - the offset of the above address from the logical address at which the procedure starts 00505 * (i.e. the one given by dis) 00506 hiAddress - first address outside this code section 00507 * inst - the info summaries when decoding the SD instruction 00508 * delay_inst - the info summaries when decoding the delay instruction 00509 * BB_rtls - the list of RTLs currently built for the BB under construction 00510 * cfg - the CFG of the enclosing procedure 00511 * tq: Object managing the target queue 00512 * SIDE EFFECTS: address may change; BB_rtls may be appended to or set NULL 00513 * RETURNS: true if next instruction is to be fetched sequentially from this one 00514 *============================================================================*/ 00515 bool SparcFrontEnd::case_SCD(ADDRESS& address, int delta, ADDRESS hiAddress, 00516 DecodeResult& inst, DecodeResult& delay_inst, std::list<RTL*>*& BB_rtls, 00517 Cfg* cfg, TargetQueue& tq) { 00518 GotoStatement* stmt_jump = static_cast<GotoStatement*>(inst.rtl->getList().back()); 00519 ADDRESS uDest = stmt_jump->getFixedDest(); 00520 00521 // Assume that if we find a call in the delay slot, it's actually a pattern such as move/call/move 00522 // MVE: Check this! Only needed for HP PA/RISC 00523 bool delayPattern = delay_inst.rtl->isCall(); 00524 00525 if (delayPattern) { 00526 // Just emit the branch, and decode the instruction immediately following next. 00527 // Assumes the first instruction of the pattern is not used in the true leg 00528 BB_rtls->push_back(inst.rtl); 00529 PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 00530 if (pBB == 0) return false; 00531 handleBranch(uDest, hiAddress, pBB, cfg, tq); 00532 // Add the "false" leg 00533 cfg->addOutEdge(pBB, address+4); 00534 address += 4; // Skip the SCD only 00535 // Start a new list of RTLs for the next BB 00536 BB_rtls = NULL; 00537 std::cerr << "Warning: instruction at " << std::hex << address << 00538 " not copied to true leg of preceeding branch\n"; 00539 return true; 00540 } 00541 00542 if (!delay_inst.rtl->areFlagsAffected()) { 00543 // SCD; flags not affected. Put delay inst first 00544 if (delay_inst.type != NOP) { 00545 // Emit delay instr 00546 BB_rtls->push_back(delay_inst.rtl); 00547 // This is in case we have an in-edge to the branch. If the BB is split, we want the split to happen 00548 // here, so this delay instruction is active on this path 00549 delay_inst.rtl->updateAddress(address); 00550 } 00551 // Now emit the branch 00552 BB_rtls->push_back(inst.rtl); 00553 PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 00554 if (pBB == 0) return false; 00555 handleBranch(uDest, hiAddress, pBB, cfg, tq); 00556 // Add the "false" leg; skips the NCT 00557 cfg->addOutEdge(pBB, address+8); 00558 // Skip the NCT/NOP instruction 00559 address += 8; 00560 } 00561 else if (optimise_DelayCopy(address, uDest, delta, hiAddress)) { 00562 // We can just branch to the instr before uDest. Adjust the destination of the branch 00563 stmt_jump->adjustFixedDest(-4); 00564 // Now emit the branch 00565 BB_rtls->push_back(inst.rtl); 00566 PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 00567 if (pBB == 0) return false; 00568 handleBranch(uDest-4, hiAddress, pBB, cfg, tq); 00569 // Add the "false" leg: point to the delay inst 00570 cfg->addOutEdge(pBB, address+4); 00571 address += 4; // Skip branch but not delay 00572 } 00573 else // The CCs are affected, and we can't use the copy delay slot trick 00574 { 00575 // SCD, must copy delay instr to orphan 00576 // Copy the delay instruction to the dest of the branch, as an orphan. First add the branch. 00577 BB_rtls->push_back(inst.rtl); 00578 // Make a BB for the current list of RTLs. We want to do this first, else ordering can go silly 00579 PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 00580 if (pBB == 0) return false; 00581 // Visit the target of the branch 00582 tq.visit(cfg, uDest, pBB); 00583 std::list<RTL*>* pOrphan = new std::list<RTL*>; 00584 pOrphan->push_back(delay_inst.rtl); 00585 // Change the address to 0, since this code has no source address (else we may branch to here when we want 00586 // to branch to the real BB with this instruction). 00587 // Note that you can't use an address that is a fixed function of the destination addr, because there can 00588 // be several jumps to the same destination that all require an orphan. The instruction in the orphan will 00589 // often but not necessarily be the same, so we can't use the same orphan BB. newBB knows to consider BBs 00590 // with address 0 as being in the map, so several BBs can exist with address 0 00591 delay_inst.rtl->updateAddress(0); 00592 // Add a branch from the orphan instruction to the dest of the branch. Again, we can't even give the jumps 00593 // a special address like 1, since then the BB would have this getLowAddr. 00594 std::list<Statement*>* gl = new std::list<Statement*>; 00595 gl->push_back(new GotoStatement(uDest)); 00596 pOrphan->push_back(new RTL(0, gl)); 00597 PBB pOrBB = cfg->newBB(pOrphan, ONEWAY, 1); 00598 // Add an out edge from the orphan as well 00599 cfg->addOutEdge(pOrBB, uDest, true); 00600 // Add an out edge from the current RTL to the orphan. Put a label at the orphan 00601 cfg->addOutEdge(pBB, pOrBB, true); 00602 // Add the "false" leg to the NCT 00603 cfg->addOutEdge(pBB, address+4); 00604 // Don't skip the delay instruction, so it will be decoded next. 00605 address += 4; 00606 } 00607 // Start a new list of RTLs for the next BB 00608 BB_rtls = NULL; 00609 return true; 00610 } 00611 00612 /*============================================================================== 00613 * FUNCTION: case_SCDAN 00614 * OVERVIEW: Handles all static conditional delayed anulled branches followed by an NCT (but not NOP) 00615 * instruction. 00616 * PARAMETERS: address - the native address of the DD 00617 * delta - the offset of the above address from the logical 00618 * address at which the procedure starts (i.e. the one given by dis) 00619 hiAddress - first address outside this code section 00620 * inst - the info summaries when decoding the SD instruction 00621 * delay_inst - the info summaries when decoding the delay instruction 00622 * BB_rtls - the list of RTLs currently built for the BB under construction 00623 * cfg - the CFG of the enclosing procedure 00624 * tq: Object managing the target queue 00625 * SIDE EFFECTS: address may change; BB_rtls may be appended to or set NULL 00626 * RETURNS: true if next instruction is to be fetched sequentially from this one 00627 *============================================================================*/ 00628 bool SparcFrontEnd::case_SCDAN(ADDRESS& address, int delta, ADDRESS hiAddress, 00629 DecodeResult& inst, DecodeResult& delay_inst, std::list<RTL*>*& BB_rtls, 00630 Cfg* cfg, TargetQueue& tq) { 00631 00632 // We may have to move the delay instruction to an orphan BB, which then branches to the target of the jump. 00633 // Instead of moving the delay instruction to an orphan BB, we may have a duplicate of the delay instruction just 00634 // before the target; if so, we can branch to that and not need the orphan. We do just a binary comparison; that 00635 // may fail to make this optimisation if the instr has relative fields. 00636 GotoStatement* stmt_jump = static_cast<GotoStatement*>(inst.rtl->getList().back()); 00637 ADDRESS uDest = stmt_jump->getFixedDest(); 00638 PBB pBB; 00639 if (optimise_DelayCopy(address, uDest, delta, hiAddress)) { 00640 // Adjust the destination of the branch 00641 stmt_jump->adjustFixedDest(-4); 00642 // Now emit the branch 00643 BB_rtls->push_back(inst.rtl); 00644 pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 00645 if (pBB == 0) return false; 00646 handleBranch(uDest-4, hiAddress, pBB, cfg, tq); 00647 } 00648 else { // SCDAN; must move delay instr to orphan. Assume it's not a NOP (though if it is, no harm done) 00649 // Move the delay instruction to the dest of the branch, as an orphan. First add the branch. 00650 BB_rtls->push_back(inst.rtl); 00651 // Make a BB for the current list of RTLs. We want to do this first, else ordering can go silly 00652 pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 00653 if (pBB == 0) return false; 00654 // Visit the target of the branch 00655 tq.visit(cfg, uDest, pBB); 00656 std::list<RTL*>* pOrphan = new std::list<RTL*>; 00657 pOrphan->push_back(delay_inst.rtl); 00658 // Change the address to 0, since this code has no source address (else we may branch to here when we want to 00659 // branch to the real BB with this instruction). 00660 delay_inst.rtl->updateAddress(0); 00661 // Add a branch from the orphan instruction to the dest of the branch 00662 std::list<Statement*>* gl = new std::list<Statement*>; 00663 gl->push_back(new GotoStatement(uDest)); 00664 pOrphan->push_back(new RTL(0, gl)); 00665 PBB pOrBB = cfg->newBB(pOrphan, ONEWAY, 1); 00666 // Add an out edge from the orphan as well. Set a label there. 00667 cfg->addOutEdge(pOrBB, uDest, true); 00668 // Add an out edge from the current RTL to 00669 // the orphan. Set a label there. 00670 cfg->addOutEdge(pBB, pOrBB, true); 00671 } 00672 // Both cases (orphan or not) 00673 // Add the "false" leg: point past delay inst. Set a label there (see below) 00674 cfg->addOutEdge(pBB, address+8, true); 00675 // Could need a jump to the following BB, e.g. if uDest is the delay slot instruction itself! e.g. beq,a $+8 00676 pBB->setJumpReqd(); 00677 address += 8; // Skip branch and delay 00678 BB_rtls = NULL; // Start new BB return true; 00679 return true; 00680 } 00681 00682 std::vector<Exp*> &SparcFrontEnd::getDefaultParams() { 00683 static std::vector<Exp*> params; 00684 if (params.size() == 0) { 00685 // init arguments and return set to be all 31 machine registers 00686 // Important: because o registers are save in i registers, and 00687 // i registers have higher register numbers (e.g. i1=r25, o1=r9) 00688 // it helps the prover to process higher register numbers first! 00689 // But do r30 first (%i6, saves %o6, the stack pointer) 00690 params.push_back(Location::regOf(30)); 00691 params.push_back(Location::regOf(31)); 00692 for (int r=29; r>0; r--) { 00693 params.push_back(Location::regOf(r)); 00694 } 00695 } 00696 return params; 00697 } 00698 00699 std::vector<Exp*> &SparcFrontEnd::getDefaultReturns() 00700 { 00701 static std::vector<Exp*> returns; 00702 if (returns.size() == 0) { 00703 returns.push_back(Location::regOf(30)); 00704 returns.push_back(Location::regOf(31)); 00705 for (int r=29; r>0; r--) { 00706 returns.push_back(Location::regOf(r)); 00707 } 00708 } 00709 return returns; 00710 } 00711 00712 /*============================================================================== 00713 * FUNCTION: SparcFrontEnd::processProc 00714 * OVERVIEW: Builds the CFG for a procedure out of the RTLs constructed 00715 * during decoding. The semantics of delayed CTIs are 00716 * transformed into CTIs that aren't delayed. 00717 * NOTE: This function overrides (and replaces) the function with 00718 * the same name in class FrontEnd. The required actions 00719 * are so different that the base class implementation 00720 * can't be re-used 00721 * PARAMETERS: address - the native address at which the procedure starts 00722 * proc - the procedure object 00723 * os - output stream for rtl output 00724 * spec - if true, this is a speculative decode 00725 * RETURNS: True if a good decode 00726 *============================================================================*/ 00727 bool SparcFrontEnd::processProc(ADDRESS address, UserProc* proc, std::ofstream &os, bool fragment /* = false */, 00728 bool spec /* = false */) { 00729 00730 // Declare an object to manage the queue of targets not yet processed yet. 00731 // This has to be individual to the procedure! (so not a global) 00732 TargetQueue targetQueue; 00733 00734 // Similarly, we have a set of CallStatement pointers. These may be 00735 // disregarded if this is a speculative decode that fails (i.e. an illegal 00736 // instruction is found). If not, this set will be used to add to the set 00737 // of calls to be analysed in the cfg, and also to call prog.visitProc() 00738 std::list<CallStatement*> callList; 00739 00740 // Indicates whether or not the next instruction to be decoded is the 00741 // lexical successor of the current one. Will be true for all NCTs and for 00742 // CTIs with a fall through branch. 00743 bool sequentialDecode = true; 00744 00745 // The control flow graph of the current procedure 00746 Cfg* cfg = proc->getCFG(); 00747 00748 // If this is a speculative decode, the second time we decode the same 00749 // address, we get no cfg. Else an error. 00750 if (spec && (cfg == 0)) 00751 return false; 00752 assert(cfg); 00753 00754 // Initialise the queue of control flow targets that have yet to be decoded. 00755 targetQueue.initial(address); 00756 00757 // Get the next address from which to continue decoding and go from 00758 // there. Exit the loop if there are no more addresses or they all 00759 // correspond to locations that have been decoded. 00760 while ((address = targetQueue.nextAddress(cfg)) != NO_ADDRESS) { 00761 00762 // The list of RTLs for the current basic block 00763 std::list<RTL*>* BB_rtls = new std::list<RTL*>(); 00764 00765 // Keep decoding sequentially until a CTI without a fall through branch 00766 // is decoded 00767 //ADDRESS start = address; 00768 DecodeResult inst; 00769 while (sequentialDecode) { 00770 00771 if (Boomerang::get()->traceDecoder) 00772 LOG << "*" << address << "\t"; 00773 00774 // Check if this is an already decoded jump instruction (from a previous pass with propagation etc) 00775 // If so, we don't need to decode this instruction 00776 std::map<ADDRESS, RTL*>::iterator ff = previouslyDecoded.find(address); 00777 if (ff != previouslyDecoded.end()) { 00778 inst.rtl = ff->second; 00779 inst.valid = true; 00780 inst.type = DD; // E.g. decode the delay slot instruction 00781 } 00782 else 00783 inst = decodeInstruction(address); 00784 00785 // If invalid and we are speculating, just exit 00786 if (spec && !inst.valid) 00787 return false; 00788 00789 // Check for invalid instructions 00790 if (!inst.valid) { 00791 std::cerr << "Invalid instruction at " << std::hex << address << ": "; 00792 std::cerr << std::setfill('0') << std::setw(2); 00793 int delta = pBF->getTextDelta(); 00794 for (int j=0; j<inst.numBytes; j++) 00795 std::cerr << std::setfill('0') << std::setw(2) << (unsigned)*(unsigned char*)(address+delta + j) << 00796 " " << std::setfill(' ') << std::setw(0) << "\n"; 00797 return false; 00798 } 00799 00800 // Don't display the RTL here; do it after the switch statement in case the delay slot instruction is moved 00801 // before this one 00802 00803 // Need to construct a new list of RTLs if a basic block has just been finished but decoding is continuing 00804 // from its lexical successor 00805 if (BB_rtls == NULL) 00806 BB_rtls = new std::list<RTL*>(); 00807 00808 // Define aliases to the RTLs so that they can be treated as a high level types where appropriate. 00809 RTL* rtl = inst.rtl; 00810 GotoStatement* stmt_jump = NULL; 00811 Statement* last = NULL; 00812 std::list<Statement*>& slist = rtl->getList(); 00813 if (slist.size()) { 00814 last = slist.back(); 00815 stmt_jump = static_cast<GotoStatement*>(last); 00816 } 00817 00818 #define BRANCH_DS_ERROR 0 // If set, a branch to the delay slot of a delayed 00819 // CTI instruction is flagged as an error 00820 #if BRANCH_DS_ERROR 00821 if ((last->getKind() == JUMP_RTL) || 00822 (last->getKind() == STMT_CALL) || 00823 (last->getKind() == JCOND_RTL) || 00824 (last->getKind() == STMT_RET)) { 00825 ADDRESS dest = stmt_jump->getFixedDest(); 00826 if ((dest != NO_ADDRESS) && (dest < hiAddress)){ 00827 unsigned inst_before_dest = *((unsigned*)(dest-4+pBF->getTextDelta())); 00828 00829 unsigned bits31_30 = inst_before_dest >> 30; 00830 unsigned bits23_22 = (inst_before_dest >> 22) & 3; 00831 unsigned bits24_19 = (inst_before_dest >> 19) & 0x3f; 00832 unsigned bits29_25 = (inst_before_dest >> 25) & 0x1f; 00833 if ((bits31_30 == 0x01) || // Call 00834 ((bits31_30 == 0x02) && (bits24_19 == 0x38)) || // Jmpl 00835 ((bits31_30 == 0x00) && (bits23_22 == 0x02) && 00836 (bits29_25 != 0x18))) {// Branch, but not (f)ba,a 00837 // The above test includes floating point branches 00838 std::cerr << "Target of branch at " << std::hex << 00839 rtl->getAddress() << 00840 " is delay slot of CTI at " << dest-4 << std::endl; 00841 } 00842 } 00843 } 00844 #endif 00845 00846 switch (inst.type) { 00847 case NOP: 00848 // Always put the NOP into the BB. It may be needed if it is the 00849 // the destinsation of a branch. Even if not the start of a BB, 00850 // some other branch may be discovered to it later. 00851 BB_rtls->push_back(rtl); 00852 00853 // Then increment the native address pointer 00854 address = address + 4; 00855 break; 00856 00857 case NCT: 00858 // Ordinary instruction. Add it to the list of RTLs this BB 00859 BB_rtls->push_back(rtl); 00860 address += inst.numBytes; 00861 // Ret/restore epilogues are handled as ordinary RTLs now 00862 if (last->getKind() == STMT_RET) 00863 sequentialDecode = false; 00864 break; 00865 00866 case SKIP: { 00867 // We can't simply ignore the skipped delay instruction as there 00868 // will most likely be a branch to it so we simply set the jump 00869 // to go to one past the skipped instruction. 00870 stmt_jump->setDest(address+8); 00871 BB_rtls->push_back(rtl); 00872 00873 // Construct the new basic block and save its destination 00874 // address if it hasn't been visited already 00875 PBB pBB = cfg->newBB(BB_rtls, ONEWAY, 1); 00876 handleBranch(address+8, pBF->getLimitTextHigh(), pBB, cfg, targetQueue); 00877 00878 // There is no fall through branch. 00879 sequentialDecode = false; 00880 address += 8; // Update address for coverage 00881 break; 00882 } 00883 00884 case SU: { 00885 // Ordinary, non-delay branch. 00886 BB_rtls->push_back(inst.rtl); 00887 00888 PBB pBB = cfg->newBB(BB_rtls, ONEWAY, 1); 00889 handleBranch(stmt_jump->getFixedDest(), pBF->getLimitTextHigh(), pBB, 00890 cfg, targetQueue); 00891 00892 // There is no fall through branch. 00893 sequentialDecode = false; 00894 address += 8; // Update address for coverage 00895 break; 00896 } 00897 00898 case SD: { 00899 // This includes "call" and "ba". If a "call", it might be a move_call_move idiom, or a call to .stret4 00900 DecodeResult delay_inst = decodeInstruction(address+4); 00901 if (Boomerang::get()->traceDecoder) 00902 LOG << "*" << address+4 << "\t\n"; 00903 if (last->getKind() == STMT_CALL) { 00904 // Check the delay slot of this call. First case of interest is when the instruction is a restore, 00905 // e.g. 00906 // 142c8: 40 00 5b 91 call exit 00907 // 142cc: 91 e8 3f ff restore %g0, -1, %o0 00908 if (((SparcDecoder*)decoder)->isRestore(address+4+pBF->getTextDelta())) { 00909 // Give the address of the call; I think that this is actually important, if faintly annoying 00910 delay_inst.rtl->updateAddress(address); 00911 BB_rtls->push_back(delay_inst.rtl); 00912 // The restore means it is effectively followed by a return (since the resore semantics chop 00913 // off one level of return address) 00914 ((CallStatement*)last)->setReturnAfterCall(true); 00915 sequentialDecode = false; 00916 case_CALL(address, inst, nop_inst, BB_rtls, proc, callList, os, true); 00917 break; 00918 } 00919 // Next class of interest is if it assigns to %o7 (could be a move, add, and possibly others). E.g.: 00920 // 14e4c: 82 10 00 0f mov %o7, %g1 00921 // 14e50: 7f ff ff 60 call blah 00922 // 14e54: 9e 10 00 01 mov %g1, %o7 00923 // Note there could be an unrelated instruction between the first move and the call 00924 // (move/x/call/move in UQBT terms). In boomerang, we leave the semantics of the moves there 00925 // (to be likely removed by dataflow analysis) and merely insert a return BB after the call 00926 int nd = delay_inst.rtl->getNumStmt(); 00927 // Note that if an add, there may be an assignment to a temp register first. So look at last RT 00928 Statement* a = delay_inst.rtl->elementAt(nd-1); // Look at last 00929 if (a && a->isAssign()) { 00930 Exp* lhs = ((Assign*)a)->getLeft(); 00931 if (lhs->isRegN(15)) { // %o7 is r[15] 00932 // If it's an add, this is special. Example: 00933 // call foo 00934 // add %o7, K, %o7 00935 // is equivalent to call foo / ba .+K 00936 Exp* rhs = ((Assign*)a)->getRight(); 00937 Location *o7 = Location::regOf(15); 00938 if (rhs->getOper() == opPlus && 00939 (((Binary*)rhs)->getSubExp2()->getOper() == opIntConst) && 00940 (*((Binary*)rhs)->getSubExp1() == *o7)) { 00941 // Get the constant 00942 int K = ((Const*)((Binary*)rhs)->getSubExp2()) ->getInt(); 00943 case_CALL(address, inst, delay_inst, BB_rtls, proc, callList, os, true); 00944 // We don't generate a goto; instead, we just decode from the new address 00945 // Note: the call to case_CALL has already incremented address by 8, so don't do again 00946 address += K; 00947 break; 00948 } else { 00949 // We assume this is some sort of move/x/call/move pattern. The overall effect is to 00950 // pop one return address, we we emit a return after this call 00951 ((CallStatement*)last)->setReturnAfterCall(true); 00952 sequentialDecode = false; 00953 case_CALL(address, inst, delay_inst, BB_rtls, proc, callList, os, true); 00954 break; 00955 } 00956 } 00957 } 00958 } 00959 RTL* delay_rtl = delay_inst.rtl; 00960 00961 switch(delay_inst.type) { 00962 case NOP: 00963 case NCT: { 00964 // Ordinary delayed instruction. Since NCT's can't affect unconditional jumps, we put the delay 00965 // instruction before the jump or call 00966 if (last->getKind() == STMT_CALL) { 00967 00968 // This is a call followed by an NCT/NOP 00969 sequentialDecode = case_CALL(address, inst, delay_inst, BB_rtls, proc, callList, os); 00970 } 00971 else { 00972 // This is a non-call followed by an NCT/NOP 00973 case_SD(address, pBF->getTextDelta(), pBF->getLimitTextHigh(), inst, delay_inst, BB_rtls, cfg, 00974 targetQueue, os); 00975 00976 // There is no fall through branch. 00977 sequentialDecode = false; 00978 } 00979 if (spec && (inst.valid == false)) 00980 return false; 00981 break; 00982 } 00983 00984 case SKIP: 00985 case_unhandled_stub(address); 00986 address += 8; 00987 break; 00988 00989 case SU: { 00990 // SD/SU. 00991 // This will be either BA or CALL followed by BA,A. Our interpretation is that it is as if the SD 00992 // (i.e. the BA or CALL) now takes the destination of the SU (i.e. the BA,A). For example: 00993 // call 1000, ba,a 2000 00994 // is really like: 00995 // call 2000. 00996 00997 // Just so that we can check that our interpretation is correct the first time we hit this case... 00998 case_unhandled_stub(address); 00999 01000 // Adjust the destination of the SD and emit it. 01001 GotoStatement* delay_jump = static_cast<GotoStatement*>(delay_rtl->getList().back()); 01002 int dest = 4+address+delay_jump->getFixedDest(); 01003 stmt_jump->setDest(dest); 01004 BB_rtls->push_back(inst.rtl); 01005 01006 // Create the appropriate BB 01007 if (last->getKind() == STMT_CALL) { 01008 handleCall(proc, dest, cfg->newBB(BB_rtls,CALL, 1), cfg, address, 8); 01009 01010 // Set the address of the lexical successor of the call that is to be decoded next. Set RTLs 01011 // to NULL so that a new list of RTLs will be created for the next BB. 01012 BB_rtls = NULL; 01013 address = address + 8; 01014 01015 // Add this call site to the set of call sites which need to be analysed later. 01016 callList.push_back((CallStatement*)inst.rtl->getList().back()); 01017 } 01018 else { 01019 PBB pBB = cfg->newBB(BB_rtls,ONEWAY, 1); 01020 handleBranch(dest, pBF->getLimitTextHigh(), pBB, cfg, targetQueue); 01021 01022 // There is no fall through branch. 01023 sequentialDecode = false; 01024 } 01025 break; 01026 } 01027 default: 01028 case_unhandled_stub(address); 01029 address += 8; // Skip the pair 01030 break; 01031 } 01032 break; 01033 } 01034 01035 case DD: { 01036 DecodeResult delay_inst; 01037 if (inst.numBytes == 4) { 01038 // Ordinary instruction. Look at the delay slot 01039 delay_inst = decodeInstruction(address+4); 01040 } 01041 else { 01042 // Must be a prologue or epilogue or something. 01043 delay_inst = nop_inst; 01044 // Should be no need to adjust the coverage; the number of bytes should take care of it 01045 } 01046 01047 RTL* delay_rtl = delay_inst.rtl; 01048 01049 // Display RTL representation if asked 01050 if (Boomerang::get()->printRtl && delay_rtl != NULL) 01051 delay_rtl->print(os); 01052 01053 switch(delay_inst.type) { 01054 case NOP: 01055 case NCT: { 01056 sequentialDecode = case_DD(address, pBF->getTextDelta(), inst, delay_inst, BB_rtls, targetQueue, 01057 proc, callList); 01058 break; 01059 } 01060 default: 01061 case_unhandled_stub(address); 01062 break; 01063 } 01064 break; 01065 } 01066 01067 case SCD: { 01068 // Always execute the delay instr, and branch if condition is met. 01069 // Normally, the delayed instruction moves in front of the branch. But if it affects the condition 01070 // codes, we may have to duplicate it as an orphan in the true leg of the branch, and fall through to 01071 // the delay instruction in the "false" leg. 01072 // Instead of moving the delay instruction to an orphan BB, we may have a duplicate of the delay 01073 // instruction just before the target; if so, we can branch to that and not need the orphan. We do 01074 // just a binary comparison; that may fail to make this optimisation if the instr has relative fields. 01075 01076 DecodeResult delay_inst = decodeInstruction(address+4); 01077 RTL* delay_rtl = delay_inst.rtl; 01078 01079 // Display low level RTL representation if asked 01080 if (Boomerang::get()->printRtl && delay_rtl != NULL) 01081 delay_rtl->print(os); 01082 01083 switch(delay_inst.type) { 01084 case NOP: 01085 case NCT: { 01086 sequentialDecode = case_SCD(address, pBF->getTextDelta(), 01087 pBF->getLimitTextHigh(), inst, delay_inst, BB_rtls, cfg, 01088 targetQueue); 01089 break; 01090 } 01091 default: 01092 if (delay_inst.rtl->getList().back()->getKind() == STMT_CALL) { 01093 // Assume it's the move/call/move pattern 01094 sequentialDecode = case_SCD(address, pBF->getTextDelta(), pBF->getLimitTextHigh(), inst, 01095 delay_inst, BB_rtls, cfg, targetQueue); 01096 break; 01097 } 01098 case_unhandled_stub(address); 01099 break; 01100 } 01101 break; 01102 } 01103 01104 case SCDAN: 01105 { 01106 // Execute the delay instruction if the branch is taken; skip (anull) the delay instruction if branch 01107 // not taken. 01108 DecodeResult delay_inst = decodeInstruction(address+4); 01109 RTL* delay_rtl = delay_inst.rtl; 01110 01111 // Display RTL representation if asked 01112 if (Boomerang::get()->printRtl && delay_rtl != NULL) 01113 delay_rtl->print(os); 01114 01115 switch(delay_inst.type) { 01116 case NOP: { 01117 // This is an ordinary two-way branch. Add the branch to the list of RTLs for this BB 01118 BB_rtls->push_back(rtl); 01119 // Create the BB and add it to the CFG 01120 PBB pBB = cfg->newBB(BB_rtls, TWOWAY, 2); 01121 if (pBB == 0) { 01122 sequentialDecode = false; 01123 break; 01124 } 01125 // Visit the destination of the branch; add "true" leg 01126 ADDRESS uDest = stmt_jump->getFixedDest(); 01127 handleBranch(uDest, pBF->getLimitTextHigh(), pBB, cfg, targetQueue); 01128 // Add the "false" leg: point past the delay inst 01129 cfg->addOutEdge(pBB, address+8); 01130 address += 8; // Skip branch and delay 01131 BB_rtls = NULL; // Start new BB 01132 break; 01133 } 01134 01135 case NCT: 01136 { 01137 sequentialDecode = case_SCDAN(address, pBF->getTextDelta(), pBF->getLimitTextHigh(), inst, 01138 delay_inst, BB_rtls, cfg, targetQueue); 01139 break; 01140 } 01141 01142 default: 01143 case_unhandled_stub(address); 01144 address = address + 8; 01145 break; 01146 } 01147 break; 01148 } 01149 default: // Others are non sparc cases 01150 break; 01151 } 01152 01153 // If sequentially decoding, check if the next address happens to be the start of an existing BB. If so, 01154 // finish off the current BB (if any RTLs) as a fallthrough, and no need to decode again (unless it's an 01155 // incomplete BB, then we do decode it). In fact, mustn't decode twice, because it will muck up the 01156 // coverage, but also will cause subtle problems like add a call to the list of calls to be processed, then 01157 // delete the call RTL (e.g. Pentium 134.perl benchmark) 01158 if (sequentialDecode && cfg->existsBB(address)) { 01159 // Create the fallthrough BB, if there are any RTLs at all 01160 if (BB_rtls) { 01161 PBB pBB = cfg->newBB(BB_rtls, FALL, 1); 01162 // Add an out edge to this address 01163 if (pBB) { 01164 cfg->addOutEdge(pBB, address); 01165 BB_rtls = NULL; // Need new list of RTLs 01166 } 01167 } 01168 // Pick a new address to decode from, if the BB is complete 01169 if (!cfg->isIncomplete(address)) 01170 sequentialDecode = false; 01171 } 01172 01173 } // while (sequentialDecode) 01174 01175 // Add this range to the coverage 01176 //proc->addRange(start, address); 01177 01178 // Must set sequentialDecode back to true 01179 sequentialDecode = true; 01180 } // End huge while loop 01181 01182 01183 // Add the callees to the set of CallStatements to proces for parameter recovery, and also to the Prog object 01184 for (std::list<CallStatement*>::iterator it = callList.begin(); it != callList.end(); it++) { 01185 ADDRESS dest = (*it)->getFixedDest(); 01186 // Don't speculatively decode procs that are outside of the main text section, apart from dynamically linked 01187 // ones (in the .plt) 01188 if (pBF->IsDynamicLinkedProc(dest) || !spec || (dest < pBF->getLimitTextHigh())) { 01189 cfg->addCall(*it); 01190 // Don't visit the destination of a register call 01191 //if (dest != NO_ADDRESS) newProc(proc->getProg(), dest); 01192 if (dest != NO_ADDRESS) proc->getProg()->setNewProc(dest); 01193 } 01194 } 01195 01196 // MVE: Not 100% sure this is the right place for this 01197 proc->setEntryBB(); 01198 01199 return true; 01200 } 01201 01202 /*============================================================================== 01203 * FUNCTION: emitNop 01204 * OVERVIEW: Emit a null RTL with the given address. 01205 * PARAMETERS: pRtls - List of RTLs to append this instruction to 01206 * uAddr - Native address of this instruction 01207 * RETURNS: <nothing> 01208 *============================================================================*/ 01209 void SparcFrontEnd::emitNop(std::list<RTL*>* pRtls, ADDRESS uAddr) 01210 { 01211 // Emit a null RTL with the given address. Required to cope with 01212 // SKIP instructions. Yes, they really happen, e.g. /usr/bin/vi 2.5 01213 RTL* pRtl = new RTL; 01214 pRtl->updateAddress(uAddr); 01215 pRtls->push_back(pRtl); 01216 } 01217 01218 /*============================================================================== 01219 * FUNCTION: emitCopyPC 01220 * OVERVIEW: Emit the RTL for a call $+8 instruction, which is merely %o7 = %pc 01221 * NOTE: Assumes that the delay slot RTL has already been pushed; we must push the semantics BEFORE that RTL, 01222 * since the delay slot instruction may use %o7. Example: 01223 * CALL $+8 ! This code is common in startup code 01224 * ADD %o7, 20, %o0 01225 * PARAMETERS: pRtls - list of RTLs to append to 01226 * uAddr - native address for the RTL 01227 * RETURNS: <nothing> 01228 *============================================================================*/ 01229 void SparcFrontEnd::emitCopyPC(std::list<RTL*>* pRtls, ADDRESS uAddr) 01230 { 01231 // Emit %o7 = %pc 01232 Assign* a = new Assign( 01233 Location::regOf(15), // %o7 == r[15] 01234 new Terminal(opPC)); 01235 // Add the Exp to an RTL 01236 RTL* pRtl = new RTL(uAddr); 01237 pRtl->appendStmt(a); 01238 // Add the RTL to the list of RTLs, but to the second last position 01239 pRtls->insert(--pRtls->end(), pRtl); 01240 } 01241 01242 /*============================================================================== 01243 * FUNCTION: helperFunc 01244 * OVERVIEW: Checks for sparc specific helper functions like .urem, which have specific sematics. 01245 * NOTE: This needs to be handled in a resourcable way. 01246 * PARAMETERS: dest: destination of the call (native address) 01247 * addr: address of current instruction (native addr) 01248 * lrtl: list of RTL* for current BB 01249 * RETURNS: True if a helper function was found and handled; false 01250 * otherwise 01251 *============================================================================*/ 01252 // Append one assignment to a list of RTLs 01253 void SparcFrontEnd::appendAssignment(Exp* lhs, Exp* rhs, Type* type, ADDRESS addr, std::list<RTL*>* lrtl) { 01254 Assign* a = new Assign(type, lhs, rhs); 01255 // Create an RTL with this one Statement 01256 std::list<Statement*>* lrt = new std::list<Statement*>; 01257 lrt->push_back(a); 01258 RTL* rtl = new RTL(addr, lrt); 01259 // Append this RTL to the list of RTLs for this BB 01260 lrtl->push_back(rtl); 01261 } 01262 01263 /* Small helper function to build an expression with 01264 * *128* m[m[r[14]+64]] = m[r[8]] OP m[r[9]] */ 01265 void SparcFrontEnd::quadOperation(ADDRESS addr, std::list<RTL*>* lrtl, OPER op) 01266 { 01267 Exp* lhs = Location::memOf(Location::memOf(new Binary(opPlus, 01268 Location::regOf(14), 01269 new Const(64)))); 01270 Exp* rhs = new Binary(op, 01271 Location::memOf(Location::regOf(8)), 01272 Location::memOf(Location::regOf(9))); 01273 appendAssignment(lhs, rhs, new FloatType(128), addr, lrtl); 01274 } 01275 01276 // Determine if this is a helper function, e.g. .mul. If so, append the appropriate RTLs to lrtl, and return true 01277 bool SparcFrontEnd::helperFunc(ADDRESS dest, ADDRESS addr, std::list<RTL*>* lrtl) { 01278 if (!pBF->IsDynamicLinkedProc(dest)) return false; 01279 const char* p = pBF->SymbolByAddress(dest); 01280 if (p == NULL) { 01281 std::cerr << "Error: Can't find symbol for PLT address " << std::hex << dest << std::endl; 01282 return false; 01283 } 01284 std::string name(p); 01285 //if (progOptions.fastInstr == false) 01286 if (0) // SETTINGS! 01287 return helperFuncLong(dest, addr, lrtl, name); 01288 Exp* rhs; 01289 if (name == ".umul") { 01290 // %o0 * %o1 01291 rhs = new Binary(opMult, 01292 Location::regOf(8), 01293 Location::regOf(9)); 01294 } else if (name == ".mul") { 01295 // %o0 *! %o1 01296 rhs = new Binary(opMults, 01297 Location::regOf(8), 01298 Location::regOf(9)); 01299 } else if (name == ".udiv") { 01300 // %o0 / %o1 01301 rhs = new Binary(opDiv, 01302 Location::regOf(8), 01303 Location::regOf(9)); 01304 } else if (name == ".div") { 01305 // %o0 /! %o1 01306 rhs = new Binary(opDivs, 01307 Location::regOf(8), 01308 Location::regOf(9)); 01309 } else if (name == ".urem") { 01310 // %o0 % %o1 01311 rhs = new Binary(opMod, 01312 Location::regOf(8), 01313 Location::regOf(9)); 01314 } else if (name == ".rem") { 01315 // %o0 %! %o1 01316 rhs = new Binary(opMods, 01317 Location::regOf(8), 01318 Location::regOf(9)); 01319 // } else if (name.substr(0, 6) == ".stret") { 01320 // // No operation. Just use %o0 01321 // rhs->push(idRegOf); rhs->push(idIntConst); rhs->push(8); 01322 } else if (name == "_Q_mul") { 01323 // Pointers to args are in %o0 and %o1; ptr to result at [%sp+64] 01324 // So semantics is m[m[r[14]] = m[r[8]] *f m[r[9]] 01325 quadOperation(addr, lrtl, opFMult); 01326 return true; 01327 } else if (name == "_Q_div") { 01328 quadOperation(addr, lrtl, opFDiv); 01329 return true; 01330 } else if (name == "_Q_add") { 01331 quadOperation(addr, lrtl, opFPlus); 01332 return true; 01333 } else if (name == "_Q_sub") { 01334 quadOperation(addr, lrtl, opFMinus); 01335 return true; 01336 } else { 01337 // Not a (known) helper function 01338 return false; 01339 } 01340 // Need to make an RTAssgn with %o0 = rhs 01341 Exp* lhs = Location::regOf(8); 01342 Assign* a = new Assign(lhs, rhs); 01343 // Create an RTL with this one Exp 01344 std::list<Statement*>* lrt = new std::list<Statement*>; 01345 lrt->push_back(a); 01346 RTL* rtl = new RTL(addr, lrt); 01347 // Append this RTL to the list of RTLs for this BB 01348 lrtl->push_back(rtl); 01349 return true; 01350 } 01351 01352 /* Another small helper function to generate either (for V9): 01353 *64* tmp[tmpl] = sgnex(32, 64, r8) op sgnex(32, 64, r9) 01354 *32* r8 = truncs(64, 32, tmp[tmpl]) 01355 *32* r9 = r[tmpl]@32:63 01356 or for v8: 01357 *32* r[tmp] = r8 op r9 01358 *32* r8 = r[tmp] 01359 *32* r9 = %Y 01360 */ 01361 void SparcFrontEnd::gen32op32gives64(OPER op, std::list<RTL*>* lrtl, ADDRESS addr) { 01362 std::list<Statement*>* ls = new std::list<Statement*>; 01363 #ifdef V9_ONLY 01364 // tmp[tmpl] = sgnex(32, 64, r8) op sgnex(32, 64, r9) 01365 Statement* a = new Assign(64, 01366 Location::tempOf(new Const("tmpl")), 01367 new Binary(op, // opMult or opMults 01368 new Ternary(opSgnEx, Const(32), Const(64), 01369 Location::regOf(8)), 01370 new Ternary(opSgnEx, Const(32), Const(64), 01371 Location::regOf(9)))); 01372 ls->push_back(a); 01373 // r8 = truncs(64, 32, tmp[tmpl]); 01374 a = new Assign(32, 01375 Location::regOf(8), 01376 new Ternary(opTruncs, new Const(64), new Const(32), 01377 Location::tempOf(new Const("tmpl")))); 01378 ls->push_back(a); 01379 // r9 = r[tmpl]@32:63; 01380 a = new Assign(32, 01381 Location::regOf(9), 01382 new Ternary(opAt, Location::tempOf(new Const("tmpl")), 01383 new Const(32), new Const(63))); 01384 ls->push_back(a); 01385 #else 01386 // BTL: The .umul and .mul support routines are used in V7 code. We implsment these using the V8 UMUL and SMUL 01387 // instructions. 01388 // BTL: In SPARC V8, UMUL and SMUL perform 32x32 -> 64 bit multiplies. 01389 // The 32 high-order bits are written to %Y and the 32 low-order bits are written to r[rd]. This is also true 01390 // on V9 although the high-order bits are also written into the 32 high-order bits of the 64 bit r[rd]. 01391 01392 // r[tmp] = r8 op r9 01393 Assign* a = new Assign( 01394 Location::tempOf(new Const("tmp")), 01395 new Binary(op, // opMult or opMults 01396 Location::regOf(8), 01397 Location::regOf(9))); 01398 ls->push_back(a); 01399 // r8 = r[tmp]; /* low-order bits */ 01400 a = new Assign( 01401 Location::regOf(8), 01402 Location::tempOf(new Const("tmp"))); 01403 ls->push_back(a); 01404 // r9 = %Y; /* high-order bits */ 01405 a = new Assign( 01406 Location::regOf(8), 01407 new Unary(opMachFtr, new Const("%Y"))); 01408 ls->push_back(a); 01409 #endif /* V9_ONLY */ 01410 RTL* rtl = new RTL(addr, ls); 01411 lrtl->push_back(rtl); 01412 delete ls; 01413 } 01414 01415 // This is the long version of helperFunc (i.e. -f not used). This does the complete 64 bit semantics 01416 bool SparcFrontEnd::helperFuncLong(ADDRESS dest, ADDRESS addr, std::list<RTL*>* lrtl, std::string& name) { 01417 Exp* rhs; 01418 Exp* lhs; 01419 if (name == ".umul") { 01420 gen32op32gives64(opMult, lrtl, addr); 01421 return true; 01422 } else if (name == ".mul") { 01423 gen32op32gives64(opMults, lrtl, addr); 01424 return true; 01425 } else if (name == ".udiv") { 01426 // %o0 / %o1 01427 rhs = new Binary(opDiv, 01428 Location::regOf(8), 01429 Location::regOf(9)); 01430 } else if (name == ".div") { 01431 // %o0 /! %o1 01432 rhs = new Binary(opDivs, 01433 Location::regOf(8), 01434 Location::regOf(9)); 01435 } else if (name == ".urem") { 01436 // %o0 % %o1 01437 rhs = new Binary(opMod, 01438 Location::regOf(8), 01439 Location::regOf(9)); 01440 } else if (name == ".rem") { 01441 // %o0 %! %o1 01442 rhs = new Binary(opMods, 01443 Location::regOf(8), 01444 Location::regOf(9)); 01445 // } else if (name.substr(0, 6) == ".stret") { 01446 // // No operation. Just use %o0 01447 // rhs->push(idRegOf); rhs->push(idIntConst); rhs->push(8); 01448 } else if (name == "_Q_mul") { 01449 // Pointers to args are in %o0 and %o1; ptr to result at [%sp+64] 01450 // So semantics is m[m[r[14]] = m[r[8]] *f m[r[9]] 01451 quadOperation(addr, lrtl, opFMult); 01452 return true; 01453 } else if (name == "_Q_div") { 01454 quadOperation(addr, lrtl, opFDiv); 01455 return true; 01456 } else if (name == "_Q_add") { 01457 quadOperation(addr, lrtl, opFPlus); 01458 return true; 01459 } else if (name == "_Q_sub") { 01460 quadOperation(addr, lrtl, opFMinus); 01461 return true; 01462 } else { 01463 // Not a (known) helper function 01464 return false; 01465 } 01466 // Need to make an RTAssgn with %o0 = rhs 01467 lhs = Location::regOf(8); 01468 appendAssignment(lhs, rhs, new IntegerType(32), addr, lrtl); 01469 return true; 01470 } 01471 01472 01473 /*============================================================================== 01474 * FUNCTION: construct 01475 * OVERVIEW: Construct a new instance of SparcFrontEnd 01476 * PARAMETERS: Same as the FrontEnd constructor, except decoder is ** 01477 * RETURNS: <nothing> 01478 *============================================================================*/ 01479 #ifdef DYNAMIC 01480 extern "C" { 01481 SparcFrontEnd* construct(Prog *prog, NJMCDecoder** decoder) { 01482 SparcFrontEnd *fe = new SparcFrontEnd(prog); 01483 *decoder = fe->getDecoder(); 01484 return fe; 01485 } 01486 } 01487 #endif 01488 01489 /*============================================================================== 01490 * FUNCTION: SparcFrontEnd::SparcFrontEnd 01491 * OVERVIEW: SparcFrontEnd constructor 01492 * PARAMETERS: Same as the FrontEnd constructor 01493 * RETURNS: <N/A> 01494 *============================================================================*/ 01495 SparcFrontEnd::SparcFrontEnd(BinaryFile *pBF, Prog* prog, BinaryFileFactory* pbff) : FrontEnd(pBF, prog, pbff) { 01496 decoder = new SparcDecoder(prog); 01497 nop_inst.numBytes = 0; // So won't disturb coverage 01498 nop_inst.type = NOP; 01499 nop_inst.valid = true; 01500 nop_inst.rtl = new RTL(); 01501 } 01502 01503 // destructor 01504 SparcFrontEnd::~SparcFrontEnd() 01505 { 01506 } 01507 01508 /*============================================================================== 01509 * FUNCTION: GetMainEntryPoint 01510 * OVERVIEW: Locate the starting address of "main" in the code section 01511 * PARAMETERS: None 01512 * RETURNS: Native pointer if found; NO_ADDRESS if not 01513 *============================================================================*/ 01514 ADDRESS SparcFrontEnd::getMainEntryPoint( bool &gotMain ) 01515 { 01516 gotMain = true; 01517 ADDRESS start = pBF->GetMainEntryPoint(); 01518 if( start != NO_ADDRESS ) return start; 01519 01520 start = pBF->GetEntryPoint(); 01521 gotMain = false; 01522 if( start == NO_ADDRESS ) return NO_ADDRESS; 01523 01524 gotMain = true; 01525 return start; 01526 }