Example #1
0
std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels, bool leaMode) {
    std::string result = "";
    if (expr == NULL) return "BOGUS:NULL";

    switch (expr->variantT()) {
        case V_SgAsmBinaryAdd:
            result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + " + " +
                     unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false);
            break;

        case V_SgAsmBinarySubtract:
            result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + " - " +
                     unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false);
            break;

        case V_SgAsmBinaryMultiply:
            result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + "*" +
                     unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false);
            break;

        case V_SgAsmMemoryReferenceExpression: {
            SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
            if (!leaMode) {
                result += x86TypeToPtrName(mr->get_type()) + " PTR " +
                          (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, false) + ":" : "");
            }
            result += "[" + unparseX86Expression(mr->get_address(), labels, false) + "]";
            break;
        }

        case V_SgAsmx86RegisterReferenceExpression: {
            SgAsmx86RegisterReferenceExpression* rr = isSgAsmx86RegisterReferenceExpression(expr);
            result = unparseX86Register(rr->get_descriptor());
            break;
        }

        case V_SgAsmByteValueExpression:
        case V_SgAsmWordValueExpression:
        case V_SgAsmDoubleWordValueExpression:
        case V_SgAsmQuadWordValueExpression:
        case V_SgAsmIntegerValueExpression: {
            SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr);
            assert(ival!=NULL);
            uint64_t value = ival->get_absolute_value(); // not sign extended
            result = StringUtility::addrToString(value, ival->get_significant_bits(), true/*signed*/);

            // Optional label.  Prefer a label supplied by the caller's LabelMap, but not for single-byte constants.  If
            // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node.
            std::string label;
            if (ival->get_significant_bits()>8)
                label =x86ValToLabel(value, labels);
            if (label.empty())
                label = ival->get_label();
            if (!label.empty())
                result += "<" + label + ">";
            break;
        }

        default: {
            std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl;
            ROSE_ASSERT (false);
        }
    }

    if (expr->get_replacement() != "") {
        result += " <" + expr->get_replacement() + ">";
    }
#if 0
    if (expr->get_bit_size()>0) {
        result += " <@" + StringUtility::numberToString(expr->get_bit_offset()) +
                  "+" + StringUtility::numberToString(expr->get_bit_size()) + ">";
    }
#endif
    return result;
}
Example #2
0
/* Helper function for unparseArmExpression(SgAsmExpression*)
 * 
 * If this function is called for an EXPR node that cannot appear at the top of an ARM instruction operand tree then the node
 * might create two strings: the primary expression return value and an additional string returned through the SUFFIX
 * argument. What to do with the additional string depends on layers higher up in the call stack.
 * 
 * The sign will be prepended to the result if EXPR is a value expression of some sort. */
static std::string unparseArmExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels,
                                        ArmSignForExpressionUnparsing sign, std::string *suffix=NULL)
{
    std::string result, extra;
    if (!isSgAsmValueExpression(expr)) {
        result += unparseArmSign(sign);
    }
    switch (expr->variantT()) {
        case V_SgAsmBinaryMultiply:
            ROSE_ASSERT (isSgAsmByteValueExpression(isSgAsmBinaryExpression(expr)->get_rhs()));
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + "*" +
                     StringUtility::numberToString(isSgAsmByteValueExpression(isSgAsmBinaryExpression(expr)->get_rhs()));
            break;
        case V_SgAsmBinaryLsl:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", lsl " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmBinaryLsr:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", lsr " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmBinaryAsr:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", asr " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmBinaryRor:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", ror " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmUnaryRrx:
            result = unparseArmExpression(isSgAsmUnaryExpression(expr)->get_operand(), labels, arm_sign_none) + ", rrx";
            break;
        case V_SgAsmUnaryArmSpecialRegisterList:
            result += unparseArmExpression(isSgAsmUnaryExpression(expr)->get_operand(), labels, arm_sign_none) + "^";
            break;
        case V_SgAsmExprListExp: {
            SgAsmExprListExp* el = isSgAsmExprListExp(expr);
            const std::vector<SgAsmExpression*>& exprs = el->get_expressions();
            result += "{";
            for (size_t i = 0; i < exprs.size(); ++i) {
                if (i != 0) result += ", ";
                result += unparseArmExpression(exprs[i], labels, arm_sign_none);
            }
            result += "}";
            break;
        }


        case V_SgAsmBinaryAdd: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_plus);
            break;
        }

        case V_SgAsmBinarySubtract: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_minus);
            break;
        }

        case V_SgAsmBinaryAddPreupdate: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_plus);
            extra = "!";
            break;
        }
            
        case V_SgAsmBinarySubtractPreupdate: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_minus);
            extra = "!";
            break;
        }

        case V_SgAsmBinaryAddPostupdate: {
            /* Two styles of syntax depending on whether this is at top-level or inside a memory reference expression. */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            if (suffix) {
                result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none);
                extra = ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_plus);
            } else {
                /* Used by LDM* and STM* instructions outside memory reference expressions. RHS is unused. */
                result = unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + "!";
            }
            break;
        }
            
        case V_SgAsmBinarySubtractPostupdate: {
            /* Two styles of syntax depending on whether this is at top-level or inside a memory reference expression. */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            if (suffix) {
                result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none);
                extra = ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_minus);
            } else {
                /* Used by LDM* and STM* instructions outside memory reference expressions. RHS is unused. */
                result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + "!";
            }
            break;
        }

        case V_SgAsmMemoryReferenceExpression: {
            SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
            SgAsmExpression* addr = mr->get_address();
            switch (addr->variantT()) {
                case V_SgAsmRegisterReferenceExpression:
                case V_SgAsmBinaryAdd:
                case V_SgAsmBinarySubtract:
                case V_SgAsmBinaryAddPreupdate:
                case V_SgAsmBinarySubtractPreupdate:
                case V_SgAsmBinaryAddPostupdate:
                case V_SgAsmBinarySubtractPostupdate:
                    break;
                default: ROSE_ASSERT (!"Bad addressing mode");
            }

            std::string suffix;
            result += "[" + unparseArmExpression(addr, labels, arm_sign_none, &suffix) + "]";
            result += suffix;
            break;
        }

        case V_SgAsmArmRegisterReferenceExpression:
            result += unparseArmRegister(isSgAsmArmRegisterReferenceExpression(expr));
            break;
        case V_SgAsmByteValueExpression:
        case V_SgAsmWordValueExpression:
        case V_SgAsmDoubleWordValueExpression: {
            SgAsmValueExpression *ve = isSgAsmValueExpression(expr);
            assert(ve!=NULL);
            uint64_t v = SageInterface::getAsmConstant(ve);
            result += "#" + unparseArmSign(sign) + StringUtility::numberToString(v);
            if (labels && v!=0) {
                AsmUnparser::LabelMap::const_iterator li=labels->find(v);
                if (li!=labels->end())
                    result += "<" + li->second + ">";
            }
            break;
        }

        default: {
            std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl;
            ROSE_ASSERT (false);
        }
    }

    /* The extra data should be passed back up the call stack so it can be inserted into the ultimate return string. We can't
     * insert it here because the string can't be generated strictly left-to-right. If "suffix" is the null pointer then the
     * caller isn't expecting a suffix and we'll have to just do our best -- the result will not be valid ARM assembly. */
    if (extra.size()>0 && !suffix)
        result = "\"" + result + "\" and \"" + extra + "\"";
    if (suffix)
        *suffix = extra;

    if (expr->get_replacement() != "") {
        result += " <" + expr->get_replacement() + ">";
    }
    return result;
}
Example #3
0
/* Helper for unparsePowerpcExpression(SgAsmExpression*) */
static std::string unparsePowerpcExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels,
                                            const RegisterDictionary *registers, bool useHex) {
    std::string result = "";
    if (expr == NULL) return "BOGUS:NULL";
    switch (expr->variantT()) {
        case V_SgAsmBinaryAdd:
            result = unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " +
                     unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
            break;
        case V_SgAsmMemoryReferenceExpression: {
            SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
            SgAsmExpression* addr = mr->get_address();
            switch (addr->variantT()) {
                case V_SgAsmBinaryAdd: {
                    SgAsmBinaryAdd* a = isSgAsmBinaryAdd(addr);
                    std::string lhs = unparsePowerpcExpression(a->get_lhs(), labels, registers, false);
                    if (isSgAsmValueExpression(a->get_rhs())) {
                        // Sign-extend from 16 bits
                        SgAsmValueExpression *ve = isSgAsmValueExpression(a->get_rhs());
                        ASSERT_not_null(ve);
                        result = boost::lexical_cast<std::string>(
                                   (int64_t)IntegerOps::signExtend<16, 64>(SageInterface::getAsmConstant(ve)));
                        result += "(" + lhs + ")";
                    } else {
                        result = lhs + ", " + unparsePowerpcExpression(a->get_rhs(), labels, registers, false);
                    }
                    break;
                }
                default:
                    result = "(" + unparsePowerpcExpression(addr, labels, registers, false) + ")";
                    break;
            }
            break;
        }
        case V_SgAsmDirectRegisterExpression: {
            SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
            SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr);
            result = unparsePowerpcRegister(insn, rr->get_descriptor(), registers);
            break;
        }
        case V_SgAsmIntegerValueExpression: {
            uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absoluteValue();
            if (useHex) {
                result = StringUtility::intToHex(v);
            } else {
                result = StringUtility::numberToString(v);
            }
            if (expr->get_comment().empty() && labels) {
                AsmUnparser::LabelMap::const_iterator li = labels->find(v);
                if (li!=labels->end())
                    result = StringUtility::appendAsmComment(result, li->second);
            }
            break;
        }
        default: {
            ASSERT_not_reachable("invalid PowerPC expression: " + expr->class_name());
        }
    }
    result = StringUtility::appendAsmComment(result, expr->get_replacement());
    result = StringUtility::appendAsmComment(result, expr->get_comment());
    return result;
}
Example #4
0
std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels,
                                 const RegisterDictionary *registers, bool leaMode) {
    std::string result = "";
    if (expr == NULL) return "BOGUS:NULL";

    switch (expr->variantT()) {
        case V_SgAsmBinaryAdd:
            result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " +
                     unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
            break;

        case V_SgAsmBinarySubtract:
            result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " - " +
                     unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
            break;

        case V_SgAsmBinaryMultiply:
            result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + "*" +
                     unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
            break;

        case V_SgAsmMemoryReferenceExpression: {
            SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
            if (!leaMode) {
                result += x86TypeToPtrName(mr->get_type()) + " " +
                          (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, registers, false) + ":" : "");
            }
            result += "[" + unparseX86Expression(mr->get_address(), labels, registers, false) + "]";
            break;
        }

        case V_SgAsmDirectRegisterExpression: {
            SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
            SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr);
            result = unparseX86Register(insn, rr->get_descriptor(), registers);
            break;
        }

        case V_SgAsmIndirectRegisterExpression: {
            SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
            SgAsmIndirectRegisterExpression* rr = isSgAsmIndirectRegisterExpression(expr);
            result = unparseX86Register(insn, rr->get_descriptor(), registers);
            if (!result.empty() && '0'==result[result.size()-1])
                result = result.substr(0, result.size()-1);
            result += "(" + StringUtility::numberToString(rr->get_index()) + ")";
            break;
        }

        case V_SgAsmIntegerValueExpression: {
            SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr);
            ASSERT_not_null(ival);
            uint64_t value = ival->get_absoluteValue(); // not sign extended

            // If the value looks like it might be an address, then don't bother showing the decimal form.
            if ((32==ival->get_significantBits() || 64==ival->get_significantBits()) &&
                value > 0x0000ffff && value < 0xffff0000) {
                result = StringUtility::addrToString(value, ival->get_significantBits());
            } else {
                result = StringUtility::signedToHex2(value, ival->get_significantBits());
            }

            // Optional label.  Prefer a label supplied by the caller's LabelMap, but not for single-byte constants.  If
            // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node.
            if (expr->get_comment().empty()) {
                std::string label;
                if (label.empty() && ival->get_significantBits()>8)
                    label =x86ValToLabel(value, labels);
                if (label.empty())
                    label = ival->get_label();
                result = StringUtility::appendAsmComment(result, label);
            }
            break;
        }

        default: {
            ASSERT_not_reachable("invalid x86 expression: " + expr->class_name());
        }
    }

    result = StringUtility::appendAsmComment(result, expr->get_replacement());
    result = StringUtility::appendAsmComment(result, expr->get_comment());
    return result;
}
Example #5
0
// Constructor
DataMemberInitializationAttribute::DataMemberInitializationAttribute ( SgAsmInstruction* instruction, SgProject* p )
   {
     ROSE_ASSERT(instruction != NULL);
     printf ("Building a DataMemberInitializationAttribute object for instruction = %s \n",unparseInstructionWithAddress(instruction).c_str());

  // Identify the offset and if this is a stack reference or a global reference.
     SgAsmMemoryReferenceExpression* memoryReferenceExpression = isSgAsmMemoryReferenceExpression(instruction->get_operandList()->get_operands()[0]);
     ROSE_ASSERT(memoryReferenceExpression != NULL);

     SgAsmRegisterReferenceExpression* segmentRegister = isSgAsmRegisterReferenceExpression(memoryReferenceExpression->get_segment());
     ROSE_ASSERT(segmentRegister != NULL);

#ifdef USE_NEW_ISA_INDEPENDENT_REGISTER_HANDLING
  // This is a data member
     isStackVariable  = (segmentRegister->get_register_number() == SgAsmRegisterReferenceExpression::e_ss);

  // This is to test if there is another register being referenced.
     bool isGlobalVariable = (segmentRegister->get_register_number() == SgAsmRegisterReferenceExpression::e_ds);

  // This should be either a stack or global variable (no other allowed).
     ROSE_ASSERT(isStackVariable == true  || isGlobalVariable == true);
     ROSE_ASSERT(isStackVariable == false || isGlobalVariable == false);

     SgAsmBinaryAdd* binaryAdd = isSgAsmBinaryAdd(memoryReferenceExpression->get_address());
     if (binaryAdd != NULL)
        {
       // Case of a non-zero offset into the global scope or the stack frame. 
          ROSE_ASSERT(binaryAdd->get_rhs() != NULL);
          SgAsmValueExpression* offsetExpression = isSgAsmValueExpression(binaryAdd->get_rhs());
          ROSE_ASSERT(offsetExpression != NULL);
          offset = get_value(offsetExpression);
        }
       else
        {
       // Case of zero offset from stack frame (first variable in the stack) 
       // or a global variable with immediate address.
          offset = 0;
          if (isGlobalVariable == true)
             {
             // Handle the case of a global variable.
                ROSE_ASSERT(memoryReferenceExpression != NULL);

                SgAsmValueExpression* offsetExpression = isSgAsmValueExpression(memoryReferenceExpression->get_address());
                if (offsetExpression != NULL)
                   {
                     offset = get_value(offsetExpression);
                   }

#if 0
             // ... finish me ...
                printf ("... finish me ... offset = %p \n",(void*)offset);
                ROSE_ASSERT(false);
#else
                printf ("isGlobalVariable == true: offset = %p \n",(void*)offset);
#endif
             }
        }

     SgAsmValueExpression* valueExpression = isSgAsmValueExpression(instruction->get_operandList()->get_operands()[1]);
     ROSE_ASSERT(valueExpression != NULL);

     value = get_value(valueExpression);

     type = valueExpression->get_type();
     ROSE_ASSERT(type != NULL);

     printf ("   isStackVariable  = %s \n",isStackVariable ? "true" : "false");
     printf ("   isGlobalVariable = %s \n",isGlobalVariable ? "true" : "false");
     printf ("   offset           = %zu \n",offset);
     printf ("   value            = %zu = %p \n",value,(void*)value);
     printf ("   type             = %p = %s \n",type,type->class_name().c_str());
#else
  // DQ (9/2/2013): This allows us to get the existing code compiled and then move to update the code seperately.
     printf ("This code needs to be updated to handle the new register handling (ISA independence) \n");
     ROSE_ASSERT(false);
#endif

#if 0
     printf ("Exiting as a test... \n");
     ROSE_ASSERT(false);
#endif
   }
/************************************************************
 * checks if an instruction has a RegisterReference on the
 * right (bool) or left side.
 * Return value is meaningless if registerReference return value is false.
 ***********************************************************/
std::pair<X86RegisterClass, int>
RoseBin_DataFlowAbstract::check_isRegister(SgGraphNode* node,
                                           SgAsmx86Instruction* inst,
                                           bool rightSide, bool& memoryReference, bool& registerReference ) {
  // bool rightSide specifies
  // true = checking the right side (of instruction operands) for a registerReference
  // false = checking the left side (of instruction operands) for a registerReference
  registerReference = false;
  SgAsmOperandList* opList = inst->get_operandList();
  ROSE_ASSERT(opList);


  SgAsmx86RegisterReferenceExpression* refExpr =NULL;
  std::pair<X86RegisterClass, int>  code = std::make_pair(x86_regclass_gpr, 0); // meaningless
  int counter=0;
  int endCounter=0;
  if (rightSide)
    endCounter=1;

  string operands="";
  // iterate through the operands (for x86 = 2 operands)
  SgAsmExpressionPtrList ptrList = opList->get_operands();
  for (SgAsmExpressionPtrList::iterator it=ptrList.begin(); it!=ptrList.end(); ++it) {
    SgAsmExpression* expr = *it;
    ROSE_ASSERT(expr);
    // skip the iteration if we do not evaluate the correct side
    // counter ==0 (left side) counter==1 (right side)
    if (counter!=endCounter) {
      counter++;
      continue;
    } else
      counter++;

    SgAsmMemoryReferenceExpression* mem = isSgAsmMemoryReferenceExpression(expr);
    if (mem) {
      memoryReference = true;
      SgAsmExpression* memOff = mem->get_address();
        if (isSgAsmx86RegisterReferenceExpression(memOff)) {
          SgAsmx86RegisterReferenceExpression* memRegRef = isSgAsmx86RegisterReferenceExpression(memOff);
          code = std::make_pair((X86RegisterClass)memRegRef->get_descriptor().get_major(), memRegRef->get_descriptor().get_minor());
          registerReference = true;
        }
    }
    refExpr = isSgAsmx86RegisterReferenceExpression(expr);
    if (refExpr) {
      code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor());
      registerReference = true;
    }
  }

#if 0
    refExpr = isSgAsmx86RegisterReferenceExpression(expr);
    if (refExpr) {
      // check if it could be a memory reference
      // changed by tps on 16Jan08

      SgAsmExpression* offset = refExpr->get_offset();
      if (isSgAsmMemoryReferenceExpression(offset)) {
        // is a memory reference
        memoryReference = true;
        SgAsmMemoryReferenceExpression* mem = isSgAsmMemoryReferenceExpression(offset);
        SgAsmExpression* memOff = mem->get_address();
        if (isSgAsmx86RegisterReferenceExpression(memOff)) {
          SgAsmx86RegisterReferenceExpression* memRegRef = isSgAsmx86RegisterReferenceExpression(memOff);
          code = memRegRef->get_identifier();
          registerReference = true;
        }
      } else {
        // is a register reference
        code = refExpr->get_identifier();
        registerReference = true;
        //      }
      }
    }
#endif

  return code;
}
Example #7
0
bool
RoseBin_Emulate::evaluateInstruction( SgAsmx86Instruction* binInst, string& operands) {
  SgAsmOperandList* opList = binInst->get_operandList();
  ROSE_ASSERT(opList);
  //string operands = "";
  bool success = true;

  // ***************************************************************
  // handle special cases
  // handle function calls to cpuid and int
  if (binInst->get_kind() == x86_cpuid) {
    operands += " :: specialOp cpuid";
    //clearRegisters();
    rbx = getRandomValue(100); // example return value
    rcx = getRandomValue(100); // example return value
    rdx = getRandomValue(100); // example return value
    return success;
  }
  else if (binInst->get_kind() == x86_int) {
    operands += " :: specialOp Int";
    //clearRegisters();
    getRegister_val(std::make_pair(x86_regclass_gpr, x86_gpr_ax), RoseBin_support::x86_regpos_qword, rax);
    // should get the values from memory!
    string values = "";
    rose_hash::unordered_map <uint64_t, uint64_t>::iterator it = memory.begin();
    for (;it!=memory.end();++it) {
      uint64_t loc = it->first;
      uint64_t val = it->second;
      string loc_s = RoseBin_support::HexToString(loc);
      string val_s = RoseBin_support::HexToString(val);
      values+= "("+loc_s+":"+val_s+")-";
    }

    //uint64_t rbx_v = getMemory(0x1c);
    //uint64_t rcx_v = getMemory(0x20);
    //uint64_t rdx_v = getMemory(0x24);
    if (rax==4) {
      // sys_write
      //string values = "" + RoseBin_support::HexToString(rbx_v);
      //values += "-" + RoseBin_support::HexToString(rcx_v);
      //values += "-" + RoseBin_support::HexToString(rdx_v);
      operands += " :: syswrite : "+values;
    } else {
      success = false;
    }
    return success;
  }
  // handle call to rdtsc
  else if (binInst->get_kind() == x86_rdtsc) {
    // simulate timer function
    operands += " :: specialOp rdtsc";
    rdx = 0x0ULL;
    rax = getRandomValue(10);
    return success;
  }
  // **************************************************************


  int counter=0;
  SgAsmx86RegisterReferenceExpression* refExpr =NULL;
  std::pair<X86RegisterClass, int>  code ;
  RoseBin_support::X86PositionInRegister pos ;

  // iterate through the operands (for x86 = 2 operands)
  SgAsmExpressionPtrList ptrList = opList->get_operands();
  SgAsmMemoryReferenceExpression* memRef = NULL;
  for (SgAsmExpressionPtrList::iterator it=ptrList.begin(); it!=ptrList.end(); ++it) {
    SgAsmExpression* expr = *it;
    ROSE_ASSERT(expr);
    //string type = "DWORD";
    //string result = unparser->resolveOperand(expr,&type);
    if (counter==0) {
      // left hand side *************************************************************
      refExpr = isSgAsmx86RegisterReferenceExpression(expr);

      // check what it could be
      // ******** 1. its a RegisterReferenceExpression on the left side
      if (refExpr) {
        code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor());
        pos = get_position_in_register(refExpr->get_descriptor());
        operands = "\\nleft :: refExpr ";
        //SgAsmExpression* expression = refExpr->get_offset();
        //memRef = isSgAsmMemoryReferenceExpression(expression);
        //if (memRef)
        //  operands += " :: memoryRefExp ";
        operands += "\\n";
      }

      // ******** 2. Its a BitAndByteInstruction
      else  {
        switch (binInst->get_kind()) {
          case x86_sete: {
            // if the instruction is a sete, then we want to check ZF and set the
            // proper register to 1
            if (ZF) {
              uint64_t qw_val=1;
              assignRegister(code, qw_val);
              ZF=false;
            }
            break;
          }
          case x86_dec: {
            uint64_t left = getRegister(code);
            assignRegister(code, --left);
            break;
          }
          default: {
            success = false;
          }
        }
      }

    } else {
      // right hand side ************************************************************
      SgAsmValueExpression* valExp = isSgAsmValueExpression(expr);
      SgAsmx86RegisterReferenceExpression* refExprR = isSgAsmx86RegisterReferenceExpression(expr);
      uint8_t b_val=0xF;
      uint16_t w_val=0xFF;
      uint32_t dw_val=0xFFFF;
      uint64_t qw_val=0xFFFFFFFF;

      // check what it could be
      // ****** 1. valueExpression
      if (valExp) {
        // value expr
        operands += "right :: valExp ";
        RoseBin_support::resolveValue(valExp, false,
                                      b_val,
                                      w_val,
                                      dw_val,
                                      qw_val);
        uint64_t val = 0xFFFFFFFF;
        if (b_val!=0xF)
          val = uint64_t(b_val);
        else if (w_val!=0xFF)
          val = uint64_t(w_val);
        else if (dw_val!=0xFFFF)
          val = uint64_t(dw_val);
        else if (qw_val!=0xFFFFFFFF)
          val = uint64_t(qw_val);

        if (refExpr) {
          switch (binInst->get_kind()) {
            // mov instruction
            case x86_mov: {
              operands += " :: DataTrans :: Mov ";
              assignRegister(code, pos, b_val,
                             w_val, dw_val,
                             qw_val);
              uint64_t addr_value=0;
              getRegister_val(code, RoseBin_support::x86_regpos_qword, addr_value);
              //string str="";
              //string var = createVariable(addr_value, str, type, description, length);
              //string varHex = RoseBin_support::HexToString(addr_value) ;
              //operands += "\\nVariable : " + var + "("+varHex+")";
              break;
            }

            case x86_and: {
              operands += " :: Logical :: And";
              uint64_t reg = getRegister(code);
              operands+=printRegister("reg",reg);
              operands+=printRegister("val",val);
              reg &= val;
              assignRegister(code, reg);
              if (reg==0)
                ZF = true;
              else ZF=false;
              break;
            }

            case x86_add: {
              operands += " :: Arithm :: Add";
              uint64_t left = getRegister(code);
              uint64_t sum = left+val;
              assignRegister(code, sum);
              break;
            }

            default:
              success = false;
          }

        } // refExp
        else { success = false;}
      } // valExp
      else if (refExprR) {
        // ****** 2. referenceExpression
        // the right hand side is also a register or memory location
        std::pair<X86RegisterClass, int>  codeR ;
        RoseBin_support::X86PositionInRegister posR ;
        codeR = std::make_pair((X86RegisterClass)refExprR->get_descriptor().get_major(), refExprR->get_descriptor().get_minor());
        posR = get_position_in_register(refExprR->get_descriptor());

        operands += "right ::  refExpr ";

        switch (binInst->get_kind()) {
          case x86_mov: {
            operands += " :: DataTrans :: Mov";
            if (memRef) {
              operands += " :: MemRef ";
              SgAsmExpression* mem_loc = memRef->get_address();
              string res = unparseExpression(mem_loc);
              uint64_t pos = 0;
              RoseBin_support::from_string<uint64_t>(pos, res, std::hex);
              uint64_t value = getRegister(codeR);
              assignMemory(pos, value);
              operands += "["+res+"] "+" ("+RoseBin_support::HexToString(pos)+":"+RoseBin_support::HexToString(value)+")";
            } else {
              operands += " :: RegRef ";
              // copy value in right register to left register
              getRegister_val(codeR, posR, b_val,
                              w_val, dw_val,
                              qw_val);
              assignRegister(code, pos, b_val,
                             w_val, dw_val,
                             qw_val);
            }
            break;
          } //mov instruction

          case x86_cmp: {
            operands += " :: Arith :: Cmp";
            uint64_t left = getRegister(code);
            uint64_t right = getRegister(codeR);
            if (left==right)
              ZF=true;
            break;
          }

          default: {
            success =false;
          }
        }

      } //refExprR
      else { success =false;}
    }
    counter++;
  }
  operands += "\\n";
  return success;
}