Skip to content

Commit

Permalink
1. Change the DYNINST_DEBUG_PARSING from a flag to a debug log name p…
Browse files Browse the repository at this point in the history
…refix.

   In parallel parsing, we need different threads to output to different files

2. Change the jump table analysis to eliminate non-determinisitic behaviors
2.1. Do not rely on the order of node in slice
2.2. Add a fix-point analysis to allow jump table analysis to redo analysis,
     discover new out-going edges due to new in-cominging edges, and continue
     parsing
  • Loading branch information
mxz297 committed Oct 9, 2018
1 parent e945427 commit 0ca00fa
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 78 deletions.
2 changes: 1 addition & 1 deletion parseAPI/src/CFGModifier.C
Expand Up @@ -349,7 +349,7 @@ bool CFGModifier::remove(Function *f) {
InsertedRegion *CFGModifier::insert(CodeObject *obj,
Address base, void *data,
unsigned size) {
parsing_cerr << "Inserting new code: " << hex << (unsigned) (*((unsigned *)data)) << dec << endl;
parsing_printf("Inserting new code: %lx\n", (unsigned) (*((unsigned *)data)));

// As per Nate's suggestion, we're going to add this data as a new
// Region in the CodeObject.
Expand Down
6 changes: 3 additions & 3 deletions parseAPI/src/IA_IAPI.C
Expand Up @@ -279,17 +279,17 @@ size_t IA_IAPI::getSize() const

bool IA_IAPI::hasCFT() const
{
parsing_cerr << "hasCFT called" << endl;
parsing_printf("hasCFT called\n");
if(hascftstatus.first) {
parsing_cerr << "\t Returning cached entry: " << hascftstatus.second << endl;
parsing_printf("\t Returning cached entry: %d\n",hascftstatus.second);
return hascftstatus.second;
}
InsnCategory c = curInsn().getCategory();
hascftstatus.second = false;
if(c == c_BranchInsn ||
c == c_ReturnInsn) {
if ( likely ( ! (_obj->defensiveMode() && isNopJump()) ) ) {
parsing_cerr << "\t branch or return, ret true" << endl;
parsing_printf("\t branch or return, ret true\n");
hascftstatus.second = true;
}
}
Expand Down
29 changes: 26 additions & 3 deletions parseAPI/src/JumpTableFormatPred.C
Expand Up @@ -70,7 +70,7 @@ void JumpTableFormatPred::FindTOC() {
parsing_printf("\t find TOC address %lx in R2\n", toc_address);
return;
}
parsing_printf("\tDid not find TOC\n");
parsing_printf("\tDid not find TOC for function at %lx\n", func->addr());
}

static int CountInDegree(SliceNode::Ptr n) {
Expand Down Expand Up @@ -202,6 +202,7 @@ bool JumpTableFormatPred::modifyCurrentFrame(Slicer::SliceFrame &frame, Graph::P
// We start plug in ASTs from predecessors
n->ins(nbegin, nend);
map<AST::Ptr, AST::Ptr> inputs;
map<AST::Ptr, Address> input_addr;
if (block->obj()->cs()->getArch() == Arch_ppc64) {
inputs.insert(make_pair(VariableAST::create(Variable(AbsRegion(Absloc(ppc64::r2)))),
ConstantAST::create(Constant(toc_address, 64))));
Expand All @@ -212,18 +213,38 @@ bool JumpTableFormatPred::modifyCurrentFrame(Slicer::SliceFrame &frame, Graph::P
exp = SymbolicExpression::SubstituteAnAST(exp, inputs);
inputs.clear();
}
parsing_printf("JumpTableFormatPred: analyze %s at %lx\n", n->assign()->format().c_str(), n->assign()->addr());
for (; nbegin != nend; ++nbegin) {
SliceNode::Ptr p = boost::static_pointer_cast<SliceNode>(*nbegin);

if (exprs.find(p->assign()) == exprs.end()) {
parsing_printf("\tWARNING: For %s, its predecessor %s does not have an expression\n", n->assign()->format().c_str(), p->assign()->format().c_str());
jumpTableFormat = false;
return false;
}
AST::Ptr rhs = exprs[p->assign()];
AST::Ptr lhs = VariableAST::create(Variable(p->assign()->out()));
// TODO: there may be more than one expression for a single variable
inputs.insert(make_pair(lhs, rhs));
bool find = false;
for (auto iit = inputs.begin(); iit != inputs.end(); ++iit)
if (*(iit->first) == *lhs) {
find = true;
if (p->assign()->addr() < input_addr[iit->first]) {
inputs[iit->first] = rhs;
input_addr[iit->first] = p->assign()->addr();
}
break;
}
if (!find) {
inputs[lhs] = rhs;
input_addr[lhs] = p->assign()->addr();
}
parsing_printf("\t\t pred %s at %lx, lhs %s, rhs %s\n", p->assign()->format().c_str(), p->assign()->addr(), lhs->format().c_str(), rhs->format().c_str());

}
parsing_printf("Input map:\n");
for (auto iit = inputs.begin(); iit != inputs.end(); ++iit) {
parsing_printf("\t %s %s\n", iit->first->format().c_str(), iit->second->format().c_str());
}
if (g->isExitNode(n)) {
// Here we try to detect the case where there are multiple
// paths to the indirect jump, and on some of the paths, the jump
Expand Down Expand Up @@ -265,6 +286,8 @@ bool JumpTableFormatPred::modifyCurrentFrame(Slicer::SliceFrame &frame, Graph::P
// TODO: need to consider thunk
exp = SymbolicExpression::SubstituteAnAST(exp, inputs);
exprs[n->assign()] = exp;
parsing_printf("\t expression %s\n", exp->format().c_str());

// Enumerate every successor and add them to the working list
n->outs(nbegin, nend);
for (; nbegin != nend; ++nbegin) {
Expand Down
1 change: 1 addition & 0 deletions parseAPI/src/ParseData.h
Expand Up @@ -139,6 +139,7 @@ class ParseFrame : public boost::lockable_adapter<boost::recursive_mutex> {
CodeRegion * codereg;

ParseWorkElem * seed; // stored for cleanup
std::vector<Block*> value_driven_jump_tables;

ParseFrame(Function * f,ParseData *pd) :
curAddr(0),
Expand Down

0 comments on commit 0ca00fa

Please sign in to comment.