void AST_BIN_Traversal::visit(SgNode* n) { if (n) { nrOfInstructions++; std::string name = ""; if (isSgAsmInstruction(n)) name = unparseInstruction(isSgAsmInstruction(n)); SgNode* parent = n->get_parent(); // node std::string add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=yellow,fontname=\"7x13bold\",fontcolor=black,style=filled"; if (isSgAsmFunction(n)) { add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=purple,fontname=\"7x13bold\",fontcolor=black,style=filled"; name = isSgAsmFunction(n)->get_name(); } if (isSgAsmX86Instruction(n) && isSgAsmX86Instruction(n)->get_kind() == x86_call) add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=red,fontname=\"7x13bold\",fontcolor=black,style=filled"; if (isSgAsmValueExpression(n)) add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=lightgreen,fontname=\"7x13bold\",fontcolor=black,style=filled"; if (isSgAsmMemoryReferenceExpression(n)) add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=lightblue,fontname=\"7x13bold\",fontcolor=black,style=filled"; if (isSgAsmBinaryExpression(n)) add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=orange,fontname=\"7x13bold\",fontcolor=black,style=filled"; if (isSgAsmRegisterReferenceExpression(n)) { SgAsmRegisterReferenceExpression* rr = isSgAsmRegisterReferenceExpression(n); std::string exprName = unparseX86Register(rr->get_descriptor(), NULL); name += " "+exprName; add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=green,fontname=\"7x13bold\",fontcolor=black,style=filled"; } if (isSgAsmOperandList(n)) add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=white,fontname=\"7x13bold\",fontcolor=black,style=filled"; myfile << "\"" << n << "\"[label=\"" << name << "\\n" << n->class_name() << "\"" << add << " ];\n"; if (parent) { // edge myfile << "\"" << parent << "\" -> \"" << n << "\" [label=\"" << n->class_name() << "\" ];\n"; } } }
/* 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; }
/* 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(ve!=NULL); 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_SgAsmPowerpcRegisterReferenceExpression: { SgAsmPowerpcRegisterReferenceExpression* rr = isSgAsmPowerpcRegisterReferenceExpression(expr); result = unparsePowerpcRegister(rr->get_descriptor(), registers); break; } case V_SgAsmIntegerValueExpression: { uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absolute_value(); if (useHex) { result = StringUtility::intToHex(v); } else { result = StringUtility::numberToString(v); } if (labels) { AsmUnparser::LabelMap::const_iterator li = labels->find(v); if (li!=labels->end()) result = StringUtility::appendAsmComment(result, li->second); } break; } default: { std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl; ROSE_ASSERT (false); } } result = StringUtility::appendAsmComment(result, expr->get_replacement()); return result; }