bool SgAsmX86Instruction::getBranchTarget(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_absoluteValue(); return true; } default: return false; // do not modify *target } }
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; }