njmcDecoder.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2001, The University of Queensland
00003  * Copyright (C) 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:       njmcDecoder.cc
00014  * OVERVIEW:   This file contains the machine independent decoding functionality.
00015  *============================================================================*/ 
00016 /*
00017  * $Revision: 1.21 $    // 1.19.2.3
00018  *
00019  * 27 Apr 02 - Mike: Mods for boomerang
00020  */
00021 
00022 #include <assert.h>
00023 #if defined(_MSC_VER) && _MSC_VER <= 1200
00024 #pragma warning(disable:4786)
00025 #endif
00026 
00027 #include <stdarg.h>         // For varargs
00028 #include "rtl.h"
00029 #include "decoder.h"
00030 #include "exp.h"
00031 #include "register.h"
00032 #include "cfg.h"
00033 #include "proc.h"
00034 #include "prog.h"
00035 #include "BinaryFile.h"
00036 #include "boomerang.h"
00037 // For some reason, MSVC 5.00 complains about use of undefined types a lot
00038 #if defined(_MSC_VER) && _MSC_VER <= 1100
00039 #include "signature.h"      // For MSVC 5.00
00040 #endif
00041 
00042 /**********************************
00043  * NJMCDecoder methods.
00044  **********************************/   
00045 
00046 /*==============================================================================
00047  * FUNCTION:       NJMCDecoder::NJMCDecoder
00048  * OVERVIEW:       
00049  * PARAMETERS:     prog: Pointer to the Prog object
00050  * RETURNS:        N/A
00051  *============================================================================*/
00052 NJMCDecoder::NJMCDecoder(Prog* prog) : prog(prog)
00053 {}
00054 
00055 /*==============================================================================
00056  * FUNCTION:       NJMCDecoder::instantiate
00057  * OVERVIEW:       Given an instruction name and a variable list of expressions representing the actual operands of
00058  *                  the instruction, use the RTL template dictionary to return the instantiated RTL representing the
00059  *                  semantics of the instruction.
00060  * PARAMETERS:     pc: native PC
00061  *                 name - instruction name
00062  *                 ... - Semantic String ptrs representing actual operands
00063  * RETURNS:        an instantiated list of Exps
00064  *============================================================================*/
00065 std::list<Statement*>* NJMCDecoder::instantiate(ADDRESS pc, const char* name, ...) {
00066     // Get the signature of the instruction and extract its parts
00067     std::pair<std::string,unsigned> sig = RTLDict.getSignature(name);
00068     std::string opcode = sig.first;
00069     unsigned numOperands = sig.second;
00070 
00071     // Put the operands into a vector
00072     std::vector<Exp*> actuals(numOperands);
00073     va_list args;
00074     va_start(args,name);
00075     for (unsigned i = 0; i < numOperands; i++)
00076         actuals[i] = va_arg(args,Exp*);
00077     va_end(args);
00078 
00079     if (DEBUG_DECODER) {
00080         // Display a disassembly of this instruction if requested
00081         std::cout << std::hex << pc << std::dec << ": " << name << " ";
00082         for (std::vector<Exp*>::iterator itd = actuals.begin(); itd != actuals.end(); itd++) {
00083             if ((*itd)->isIntConst()) {
00084                 int val = ((Const*)(*itd))->getInt();
00085                 if (val > 100 || val < -100)
00086                     std::cout << std::hex << "0x" << val << std::dec;
00087                 else
00088                     std::cout << val;
00089             } else
00090                 (*itd)->print(std::cout);
00091             if (itd != actuals.end()-1)
00092                 std::cout << ", ";
00093         }
00094         std::cout << std::endl;
00095     }
00096 
00097     std::list<Statement*>* instance = RTLDict.instantiateRTL(opcode, pc, actuals);
00098 
00099     return instance;
00100 }
00101 
00102 /*==============================================================================
00103  * FUNCTION:       NJMCDecoder::instantiateNamedParam
00104  * OVERVIEW:       Similarly to the above, given a parameter name and a list of Exp*'s representing sub-parameters,
00105  *                  return a fully substituted Exp for the whole expression
00106  * NOTE:           Caller must delete result
00107  * PARAMETERS:     name - parameter name
00108  *                 ... - Exp* representing actual operands
00109  * RETURNS:        an instantiated list of Exps
00110  *============================================================================*/
00111 Exp* NJMCDecoder::instantiateNamedParam(char* name, ...) {
00112     if (RTLDict.ParamSet.find(name) == RTLDict.ParamSet.end()) {
00113         std::cerr << "No entry for named parameter '" << name << "'\n";
00114         return 0;
00115     }
00116     assert(RTLDict.DetParamMap.find(name) != RTLDict.DetParamMap.end());
00117     ParamEntry &ent = RTLDict.DetParamMap[name];
00118     if (ent.kind != PARAM_ASGN && ent.kind != PARAM_LAMBDA ) {
00119         std::cerr << "Attempt to instantiate expressionless parameter '" << name << "'\n";
00120         return 0;
00121     }
00122     // Start with the RHS
00123     assert(ent.asgn->getKind() == STMT_ASSIGN);
00124     Exp* result = ((Assign*)ent.asgn)->getRight()->clone();
00125 
00126     va_list args;
00127     va_start(args,name);
00128     for( std::list<std::string>::iterator it = ent.params.begin(); it != ent.params.end(); it++ ) {
00129         Exp* formal = new Location(opParam, new Const((char*)it->c_str()), NULL);
00130         Exp* actual = va_arg(args, Exp*);
00131         bool change;
00132         result = result->searchReplaceAll(formal, actual, change);
00133         delete formal;
00134     }
00135     return result;
00136 }
00137 
00138 /*==============================================================================
00139  * FUNCTION:       NJMCDecoder::substituteCallArgs
00140  * OVERVIEW:       In the event that it's necessary to synthesize the call of a named parameter generated with
00141  *                  instantiateNamedParam(), this substituteCallArgs() will substitute the arguments that follow into
00142  *                  the expression.
00143  * NOTE:           Should only be used after instantiateNamedParam(name, ..);
00144  * NOTE:           exp (the pointer) could be changed
00145  * PARAMETERS:     name - parameter name
00146  *                 exp - expression to instantiate into
00147  *                 ... - Exp* representing actual operands
00148  * RETURNS:        an instantiated list of Exps
00149  *============================================================================*/
00150 void NJMCDecoder::substituteCallArgs(char *name, Exp*& exp, ...)
00151 {
00152     if (RTLDict.ParamSet.find(name) == RTLDict.ParamSet.end()) {
00153         std::cerr << "No entry for named parameter '" << name << "'\n";
00154         return;
00155     }
00156     ParamEntry &ent = RTLDict.DetParamMap[name];
00157     /*if (ent.kind != PARAM_ASGN && ent.kind != PARAM_LAMBDA) {
00158         std::cerr << "Attempt to instantiate expressionless parameter '" << name << "'\n";
00159         return;
00160     }*/
00161     
00162     va_list args;
00163     va_start(args, exp);
00164     for (std::list<std::string>::iterator it = ent.funcParams.begin(); it != ent.funcParams.end(); it++) {
00165         Exp* formal = new Location(opParam, new Const((char*)it->c_str()), NULL);
00166         Exp* actual = va_arg(args, Exp*);
00167         bool change;
00168         exp = exp->searchReplaceAll(formal, actual, change);
00169         delete formal;
00170     }
00171 }
00172 
00173 /*==============================================================================
00174  * FUNCTION:       DecodeResult::reset
00175  * OVERVIEW:       Resets the fields of a DecodeResult to their default values.
00176  * PARAMETERS:     <none>
00177  * RETURNS:        <nothing>
00178  *============================================================================*/
00179 void DecodeResult::reset()
00180 {
00181     numBytes = 0;
00182     type = NCT;
00183     valid = true;
00184     rtl = NULL;
00185     reDecode = false;
00186     forceOutEdge = 0;   
00187 }
00188 
00189 /*==============================================================================
00190  * These are functions used to decode instruction operands into
00191  * Exp*s.
00192  *============================================================================*/
00193 
00194 /*==============================================================================
00195  * FUNCTION:        NJMCDecoder::dis_Reg
00196  * OVERVIEW:        Converts a numbered register to a suitable expression.
00197  * PARAMETERS:      reg - the register number, e.g. 0 for eax
00198  * RETURNS:         the Exp* for the register NUMBER (e.g. "int 36" for %f4)
00199  *============================================================================*/
00200 Exp* NJMCDecoder::dis_Reg(int regNum)
00201 {
00202       Exp* expr = Location::regOf(regNum);
00203       return expr;
00204 }
00205 
00206 /*==============================================================================
00207  * FUNCTION:        NJMCDecoder::dis_Num
00208  * OVERVIEW:        Converts a number to a Exp* expression.
00209  * PARAMETERS:      num - a number
00210  * RETURNS:         the Exp* representation of the given number
00211  *============================================================================*/
00212 Exp* NJMCDecoder::dis_Num(unsigned num)
00213 {
00214     Exp* expr = new Const((int)num);
00215     return expr;
00216 }
00217 
00218 /*==============================================================================
00219  * FUNCTION:        NJMCDecoder::unconditionalJump
00220  * OVERVIEW:        Process an unconditional jump instruction
00221  *                  Also check if the destination is a label (MVE: is this done?)
00222  * PARAMETERS:      
00223  * RETURNS:         <none>
00224  *============================================================================*/
00225 void NJMCDecoder::unconditionalJump(const char* name, int size, ADDRESS relocd, int delta, ADDRESS pc,
00226         std::list<Statement*>* stmts, DecodeResult& result) {
00227     result.rtl = new RTL(pc, stmts);
00228     result.numBytes = size;
00229     GotoStatement* jump = new GotoStatement();
00230     jump->setDest(relocd-delta);
00231     result.rtl->appendStmt(jump);
00232     SHOW_ASM(name<<" 0x"<<std::hex<<relocd-delta)
00233 }
00234 
00235 /*==============================================================================
00236  * FUNCTION:        NJMCDecoder::computedJump
00237  * OVERVIEW:        Process an indirect jump instruction
00238  * PARAMETERS:      name: name of instruction (for debugging)
00239  *                  size: size of instruction in bytes
00240  *                  dest: destination Exp*
00241  *                  pc: native pc
00242  *                  stmts: list of statements (?)
00243  *                  result: ref to decoder result object
00244  * RETURNS:         <none>
00245  *============================================================================*/
00246 void NJMCDecoder::computedJump(const char* name, int size, Exp* dest, ADDRESS pc, std::list<Statement*>* stmts,
00247         DecodeResult& result) {
00248     result.rtl = new RTL(pc, stmts);
00249     result.numBytes = size;
00250     GotoStatement* jump = new GotoStatement();
00251     jump->setDest(dest);
00252     jump->setIsComputed(true);
00253     result.rtl->appendStmt(jump);
00254     SHOW_ASM(name<<" "<<dest)
00255 }
00256 
00257 /*==============================================================================
00258  * FUNCTION:        NJMCDecoder::computedCall
00259  * OVERVIEW:        Process an indirect call instruction
00260  * PARAMETERS:      name: name of instruction (for debugging)
00261  *                  size: size of instruction in bytes
00262  *                  dest: destination Exp*
00263  *                  pc: native pc
00264  *                  stmts: list of statements (?)
00265  *                  result: ref to decoder result object
00266  * RETURNS:         <none>
00267  *============================================================================*/
00268 void NJMCDecoder::computedCall(const char* name, int size, Exp* dest, ADDRESS pc, std::list<Statement*>* stmts,
00269         DecodeResult& result) {
00270     result.rtl = new RTL(pc, stmts);
00271     result.numBytes = size;
00272     CallStatement* call = new CallStatement();
00273     call->setDest(dest);
00274     call->setIsComputed(true);
00275     result.rtl->appendStmt(call);
00276     SHOW_ASM(name<<" "<<dest)
00277 }
00278 

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