bool SgAsmx86Instruction::get_branch_target(rose_addr_t *target) { // Treats far destinations as "unknown" switch (get_kind()) { case x86_call: case x86_farcall: case x86_jmp: case x86_ja: case x86_jae: case x86_jb: case x86_jbe: case x86_jcxz: case x86_jecxz: case x86_jrcxz: case x86_je: case x86_jg: case x86_jge: case x86_jl: case x86_jle: case x86_jne: case x86_jno: case x86_jns: case x86_jo: case x86_jpe: case x86_jpo: case x86_js: case x86_loop: case x86_loopnz: case x86_loopz: { const SgAsmExpressionPtrList &args = get_operandList()->get_operands(); if (args.size()!=1) return false; SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[0]); if (!ival) return false; if (target) *target = ival->get_absolute_value(); return true; } default: return false; // do not modify *target } }
bool SgAsmMipsInstruction::get_branch_target(rose_addr_t *target) { SgAsmExpressionPtrList &args = get_operandList()->get_operands(); switch (get_kind()) { case mips_j: case mips_jal: case mips_jalx: { // target address stored in first argument assert(args.size()>=1); if (target) { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[0]); assert(ival!=NULL); *target = ival->get_absolute_value(); } return true; } case mips_bgez: case mips_bgezal: case mips_bgezall: case mips_bgezl: case mips_bgtz: case mips_bgtzl: case mips_blez: case mips_blezl: case mips_bltz: case mips_bltzal: case mips_bltzall: case mips_bltzl: { // target address stored in the second argument assert(args.size()>=2); if (target) { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[1]); assert(ival!=NULL); *target = ival->get_absolute_value(); } return true; } case mips_beq: case mips_beql: case mips_bne: case mips_bnel: { // target address stored in the third argument assert(args.size()>=3); if (target) { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(args[2]); assert(ival!=NULL); *target = ival->get_absolute_value(); } return true; } default: // no known target; do not modify *target return false; } }
SgAsmIntegerValueExpression* makeQWordValue(uint64_t val) { SgAsmIntegerValueExpression* v = new SgAsmIntegerValueExpression(val, 64); ROSE_ASSERT (v); v->set_type(SgAsmTypeQuadWord::createType()); return v; }
SgAsmIntegerValueExpression* makeDWordValue(uint32_t val) { SgAsmIntegerValueExpression* v = new SgAsmIntegerValueExpression(val, 32); ROSE_ASSERT (v); v->set_type(SgAsmTypeDoubleWord::createType()); return v; }
SgAsmIntegerValueExpression* makeByteValue(uint8_t val) { SgAsmIntegerValueExpression* v = new SgAsmIntegerValueExpression(val, 8); ROSE_ASSERT (v); v->set_type(SgAsmTypeByte::createType()); return v; }
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; }
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; }