sparcfrontend.cpp

Go to the documentation of this file.
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 }

Generated on Tue Sep 19 21:18:32 2006 for Boomerang by  doxygen 1.4.6