Skip to content

Commit

Permalink
1. Add an architecture-independent interface to check whether a regis…
Browse files Browse the repository at this point in the history
…ter represents a flag

2. In jump table analysis, perform shift-left operations if both operands are constant and use architecture-independent interface
  • Loading branch information
mxz297 committed Oct 4, 2016
1 parent 010df64 commit 3a8715b
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
1 change: 1 addition & 0 deletions common/h/dyn_regs.h
Expand Up @@ -106,6 +106,7 @@ namespace Dyninst
bool isStackPointer() const;
bool isSyscallNumberReg() const;
bool isSyscallReturnValueReg() const;
bool isFlag() const;

void getROSERegister(int &c, int &n, int &p);

Expand Down
17 changes: 17 additions & 0 deletions common/src/dyn_regs.C
Expand Up @@ -478,6 +478,23 @@ bool MachRegister::isSyscallReturnValueReg() const
);
}

bool MachRegister::isFlag() const
{
int regC = regClass();
switch (getArchitecture())
{
case Arch_x86:
return regC == x86::FLAG;
case Arch_x86_64:
return regC == x86_64::FLAG;
case Arch_aarch64:
return regC == aarch64::FLAG;
default:
assert(!"Not implemented!");
}
return false;
}

COMMON_EXPORT bool Dyninst::isSegmentRegister(int regClass)
{
return 0 != (regClass & x86::SEG);
Expand Down
1 change: 1 addition & 0 deletions parseAPI/src/BoundFactCalculator.C
Expand Up @@ -320,6 +320,7 @@ static bool IsConditionalJump(Instruction::Ptr insn) {
id == e_jb_jnaej_j || id == e_jnb_jae_j ||
id == e_jle || id == e_jl ||
id == e_jnl || id == e_jnle) return true;
if (id == aarch64_op_b_cond) return true;
return false;
}

Expand Down
16 changes: 11 additions & 5 deletions parseAPI/src/BoundFactData.C
Expand Up @@ -1146,6 +1146,7 @@ bool BoundFact::ConditionalJumpBound(Instruction::Ptr insn, EdgeTypeEnum type) {
}
break;
}
case aarch64_op_b_cond:
case e_jnbe: {
if (pred.e1->getID() == AST::V_ConstantAST) {
if (pred.e2->getID() == AST::V_ConstantAST) {
Expand Down Expand Up @@ -1315,14 +1316,19 @@ void BoundFact::SetPredicate(Assignment::Ptr assign,std::pair<AST::Ptr, bool> ex
}
AST::Ptr simplifiedAST = expandRet.first;
parsing_printf("\t\t semanic expansions: %s\n", simplifiedAST->format().c_str());

ComparisonVisitor cv;
expandRet.first->accept(&cv);
pred.e1 = cv.subtrahend;
pred.e2 = cv.minuend;
pred.id = id;
if (pred.e1 != AST::Ptr() && pred.e2 != AST::Ptr()) {
return;
}

switch (id) {
case e_cmp:
case e_sub: {
ComparisonVisitor cv;
expandRet.first->accept(&cv);
pred.e1 = cv.subtrahend;
pred.e2 = cv.minuend;
pred.id = id;
// The effect of the subtraction can only
// be evaluated when there is a conditional jump
// after it. Currently, we do not know anything.
Expand Down
8 changes: 8 additions & 0 deletions parseAPI/src/IndirectASTVisitor.C
Expand Up @@ -113,6 +113,14 @@ AST::Ptr SimplifyRoot(AST::Ptr ast, uint64_t insnSize) {
else
return RoseAST::create(ROSEOperation(ROSEOperation::derefOp), ast->child(0));
break;
case ROSEOperation::shiftLOp:
if (roseAST->child(0)->getID() == AST::V_ConstantAST && roseAST->child(1)->getID() == AST::V_ConstantAST) {
ConstantAST::Ptr child0 = boost::static_pointer_cast<ConstantAST>(roseAST->child(0));
ConstantAST::Ptr child1 = boost::static_pointer_cast<ConstantAST>(roseAST->child(1));
return ConstantAST::create(Constant(child0->val().val << child1->val().val, 64));
}
break;

default:
break;

Expand Down
11 changes: 6 additions & 5 deletions parseAPI/src/JumpTablePred.C
Expand Up @@ -91,7 +91,7 @@ static void BuildEdges(SliceNode::Ptr curNode,

static bool AssignIsZF(Assignment::Ptr a) {
return a->out().absloc().type() == Absloc::Register &&
(a->out().absloc().reg() == x86::zf || a->out().absloc().reg() == x86_64::zf);
(a->out().absloc().reg() == MachRegister::getZeroFlag(a->out().absloc().reg().getArchitecture()));
}

static bool IsPushAndChangeSP(Assignment::Ptr a) {
Expand Down Expand Up @@ -184,11 +184,12 @@ bool JumpTablePred::addNodeCallback(AssignmentPtr ap, set<ParseAPI::Edge*> &visi
if (currentAssigns.find(ap) != currentAssigns.end()) return true;
if (currentAssigns.size() > 50) return false;
// For flags, we only analyze zf
if (ap->out().absloc().type() == Absloc::Register && ap->out().absloc().reg().regClass() == (unsigned int)x86::FLAG &&
ap->out().absloc().reg() != x86::zf && ap->out().absloc().reg() != x86_64::zf) {
return true;
if (ap->out().absloc().type() == Absloc::Register) {
MachRegister reg = ap->out().absloc().reg();
if (reg.isFlag() && reg != MachRegister::getZeroFlag(reg.getArchitecture())) {
return true;
}
}

pair<AST::Ptr, bool> expandRet = ExpandAssignment(ap);

currentAssigns.insert(ap);
Expand Down

0 comments on commit 3a8715b

Please sign in to comment.