void visit(SgNode *node) { SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(node); if (rre) { size_t nbits = rre->get_descriptor().get_nbits(); double v = log(nbits) / M_LN2; sum += do_variance ? (v-mean)*(v-mean) : v; ++n; } }
// see base class bool SgAsmMipsInstruction::is_function_return(const std::vector<SgAsmInstruction*> &insns) { if (insns.empty()) return false; SgAsmMipsInstruction *last = isSgAsmMipsInstruction(insns.back()); if (!last) return false; if (last->get_kind()!=mips_jr) return false; const SgAsmExpressionPtrList &args = last->get_operandList()->get_operands(); if (args.size()<1) return false; SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(args[0]); if (!rre) return false; if (rre->get_descriptor().get_major()!=mips_regclass_gpr || rre->get_descriptor().get_minor()!=31) return false; return true; // this is a "JR ra" instruction. }
/** HashAST::visit * * Called by traverse. Gets the whatever data is of interest and puts * it in the hash. * * @param[in] node to submit to hash **/ void AstHash::visit(SgNode* node) { //Always include the type of each node in the hash VariantT vType = node->variantT(); hasher_.insert(vType); //If it's an instruction, include the mnemonic, and maybe the address SgAsmInstruction* asmInstruction = isSgAsmInstruction(node); if(asmInstruction != NULL) { std::string mnemonic = asmInstruction->get_mnemonic(); hasher_.insert(mnemonic); if(includeAddresses) { rose_addr_t addr = asmInstruction->get_address(); hasher_.insert(addr); } return; } //Always include register references SgAsmRegisterReferenceExpression* regRef = isSgAsmRegisterReferenceExpression(node); if(regRef != NULL) { unsigned regHash = regRef->get_descriptor().hash(); hasher_.insert(regHash); return; } //Maybe inlcude constants (integers, floats, pointers) if(includeConstants) { SgAsmConstantExpression* constExpr = isSgAsmConstantExpression(node); if(constExpr != NULL) { std::string mnemonic = constExpr->get_bitVector().toHex(); hasher_.insert(mnemonic); return; } } }
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"; } } }
/** Return control flow successors. See base class for full documentation. */ BinaryAnalysis::Disassembler::AddressSet SgAsmArmInstruction::getSuccessors(bool *complete) { BinaryAnalysis::Disassembler::AddressSet retval; const std::vector<SgAsmExpression*> &exprs = get_operandList()->get_operands(); *complete = true; /*assume retval is the complete set of successors for now*/ switch (get_kind()) { case arm_b: case arm_bl: case arm_blx: case arm_bx: { /* Branch target */ ROSE_ASSERT(exprs.size()==1); SgAsmExpression *dest = exprs[0]; if (isSgAsmValueExpression(dest)) { rose_addr_t target_va = SageInterface::getAsmConstant(isSgAsmValueExpression(dest)); retval.insert(target_va); } else { /* Could also be a register reference expression, but we don't know the successor in that case. */ *complete = false; } /* Fall-through address */ if (get_condition()!=arm_cond_al) retval.insert(get_address()+4); break; } case arm_bxj: { /* First argument is the register that holds the next instruction pointer value to use in the case that Jazelle is * not available. We only know the successor if the register is the instruction pointer, in which case the * successor is the fall-through address. */ ROSE_ASSERT(exprs.size()==1); SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(exprs[0]); ROSE_ASSERT(rre); if (rre->get_descriptor().get_major()==arm_regclass_gpr && rre->get_descriptor().get_minor()==15) { retval.insert(get_address()+4); } else { *complete = false; } break; } case arm_cmn: case arm_cmp: case arm_teq: case arm_tst: /* Comparison and test instructions don't ever affect the instruction pointer; they only fall through */ retval.insert(get_address()+4); break; case arm_bkpt: case arm_swi: case arm_undefined: case arm_unknown_instruction: /* No known successors for interrupt-generating instructions */ break; default: if (!modifies_ip(this) || get_condition()!=arm_cond_al) { retval.insert(get_address()+4); } else { *complete = false; } break; } return retval; }
/* Returns true if the instruction modifies the instruction pointer (r15). */ static bool modifies_ip(SgAsmArmInstruction *insn) { switch (insn->get_kind()) { /* Branch instructions */ case arm_b: case arm_bl: case arm_blx: case arm_bx: case arm_bxj: return true; /* Comparison instructions */ case arm_cmn: case arm_cmp: case arm_teq: case arm_tst: return false; /* Load multiple registers instructions. Second argument is the set of registers to load. If the instruction * pointer (r15) can be one of them. */ case arm_ldm: case arm_ldmda: case arm_ldmdb: case arm_ldmia: case arm_ldmib: { const std::vector<SgAsmExpression*> &exprs = insn->get_operandList()->get_operands(); ROSE_ASSERT(exprs.size()>=2); SgAsmExprListExp *elist = isSgAsmExprListExp(exprs[1]); if (!elist) { SgAsmUnaryArmSpecialRegisterList *rlist = isSgAsmUnaryArmSpecialRegisterList(exprs[1]); ROSE_ASSERT(rlist); elist = isSgAsmExprListExp(rlist->get_operand()); ROSE_ASSERT(elist); } for (size_t i=0; i<elist->get_expressions().size(); i++) { SgAsmRegisterReferenceExpression *reg = isSgAsmRegisterReferenceExpression(elist->get_expressions()[i]); ROSE_ASSERT(reg); if (reg->get_descriptor().get_major()==arm_regclass_gpr && reg->get_descriptor().get_minor()==15) { return true; } } return false; } /* Interrupt-causing instructions */ case arm_bkpt: case arm_swi: case arm_undefined: return true; /* Other instructions modify the instruction pointer if it's the first (destination) argument. */ default: { const std::vector<SgAsmExpression*> &exprs = insn->get_operandList()->get_operands(); if (exprs.size()>=1) { SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(exprs[0]); if (rre && rre->get_descriptor().get_major()==arm_regclass_gpr && rre->get_descriptor().get_minor()==15) { return true; } } } } return false; }