/** * Build a CFG on top of the BPatch_flowGraph that matches * the original, but with an extra entry block and using * dominatorBB's instead of BPatch_basicBlocks. **/ void dominatorBB::dominatorPredAndSucc() { unsigned i; if (!bpatchBlock) return; //Predecessors BPatch_Vector<BPatch_basicBlock*> blocks; bpatchBlock->getSources(blocks); for (i=0; i<blocks.size(); i++) { dominatorBB *p = dom_cfg->bpatchToDomBB(blocks[i]); assert(p); pred.push_back(p); } if (bpatchBlock->isEntryBlock() || !blocks.size()) { dom_cfg->entryBlock->succ.push_back(this); pred.push_back(dom_cfg->entryBlock); } //Successors blocks.clear(); bpatchBlock->getTargets(blocks); for (i=0; i<blocks.size(); i++) { dominatorBB *s = dom_cfg->bpatchToDomBB(blocks[i]); assert(s); succ.push_back(s); } }
void test_thread_2_Mutator::dumpVars() { BPatch_Vector<BPatch_variableExpr *> vars; appImage->getVariables(vars); for (unsigned int i = 0; i < vars.size(); ++i) { logerror("\t%s\n", vars[i]->getName()); } }
/* * BPatch_image::getProcedures * * Returns a list of all procedures in the image upon success, and NULL * upon failure. */ BPatch_Vector<BPatch_variableExpr *> *BPatch_image::getGlobalVariablesInt() { BPatch_variableExpr *var; BPatch_Vector<BPatch_variableExpr *> *varlist = new BPatch_Vector<BPatch_variableExpr *>; if (varlist == NULL) return NULL; // XXX - should this stuff really be by image ??? jkh 3/19/99 BPatch_Vector<BPatch_module *> *mods = getModules(); //BPatch_type *type; for (unsigned int m = 0; m < mods->size(); m++) { BPatch_module *module = (*mods)[m]; char name[255]; module->getName(name, sizeof(name)); pdvector<pdstring> keys = module->getModuleTypes()->globalVarsByName.keys(); int limit = keys.size(); for (int j = 0; j < limit; j++) { pdstring name = keys[j]; var = createVarExprByName(module, name.c_str()); if (var != NULL) varlist->push_back(var); } } return varlist; }
BPatch_function* getMutateeFunction(const char *name) { BPatch_Vector<BPatch_function *> funcs; mainImg->findFunction(name, funcs, true, true, true); if (funcs.size() != 1) return NULL; return funcs.at(0); }
/** a basic block is instrumented if it is one of the leaf nodes * in the immediate dominator tree of the control flow graph * or it has an outgoing edge to a basic block that it does * not dominate */ bool FCUseDominator::validateBasicBlock(BPatch_basicBlock* bb){ bool ret = false; BPatch_Vector<BPatch_basicBlock*> immediateDominates; bb->getImmediateDominates(immediateDominates); /** if it is a leaf node */ if(!immediateDominates.size()) ret = true; else{ /** or it has outgoing edge to basic block * it does not dominate */ BPatch_Set<BPatch_basicBlock*> allDom; bb->getAllDominates(allDom); BPatch_Vector<BPatch_basicBlock*> targets; bb->getTargets(targets); for(unsigned int j=0;j<targets.size();j++) if(!allDom.contains(targets[j])){ /** target is not in the set * basic block dominates */ ret = true; break; } } return ret; }
/* * BPatch_image::findType * * Returns a BPatch_type* representing the named type. If no such type * exists, returns NULL. * * name The name of type to look up. */ BPatch_type *BPatch_image::findTypeInt(const char *name) { BPatch_type *type; assert(BPatch::bpatch != NULL); // XXX - should this stuff really be by image ??? jkh 3/19/99 BPatch_Vector<BPatch_module *> *mods = getModules(); for (int m = mods->size() -1; m >= 0; m--) { BPatch_module *module = (*mods)[m]; type = module->getModuleTypes()->findType(name); if (type) { return type; } } // check the default base types type = BPatch::bpatch->stdTypes->findType(name); if (type) { return type; } // check the API types of last resort type = BPatch::bpatch->APITypes->findType(name); return type; }
void BPatch_basicBlock::getImmediatePostDominates(BPatch_Vector<BPatch_basicBlock*>& imds){ flowGraph->fillPostDominatorInfo(); if(!immediatePostDominates) return; imds.insert(imds.end(), immediatePostDominates->begin(), immediatePostDominates->end()); return; }
void Instrumentcall (BPatch_image *appImage, BPatch_process *appProcess) { unsigned insertion = 0; unsigned i = 0; BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (true); cout << vfunctions->size() << " functions found in binary " << endl; cout << "Parsing functions " << flush; while (i < vfunctions->size()) { char name[1024], sharedlibname[1024]; BPatch_function *f = (*vfunctions)[i]; (f->getModule())->getFullName (sharedlibname, 1024); f->getName (name, 1024); BPatch_Vector<BPatch_point *> *vpoints = f->findPoint (BPatch_subroutine); unsigned j = 0; while (j < vpoints->size()) { BPatch_function *called = ((*vpoints)[j])->getCalledFunction(); if (NULL != called) { char calledname[1024]; called->getName (calledname, 1024); if (strcmp (calledname, "functionB") == 0) { string s = "functionA"; BPatch_function *patch = getRoutine (s, appImage); if (patch != NULL) { bool replaced = appProcess->replaceFunctionCall (*((*vpoints)[j]), *patch); if (replaced) cout << "call to functionA has been successfully replaced by a call to functionB" << endl; else cout << "call to functionA failed to replace a call to functionB" << endl; insertion++; } } } j++; } i++; } cout << endl; cout << "insertion = " << insertion << endl; }
BPatchSnippetHandle *BPatch_addressSpace::insertSnippet(const BPatch_snippet &expr, BPatch_point &point, BPatch_callWhen when, BPatch_snippetOrder order) { BPatch_Vector<BPatch_point *> points; points.push_back(&point); return insertSnippet(expr, points, when, order); }
BPatch_Vector<BPatch_function *> *pd_image::getIncludedFunctions() { BPatch_Vector<BPatch_function *> *ret = new BPatch_Vector<BPatch_function *>(); for (unsigned int i = 0; i < some_mods.size(); ++i) { BPatch_Vector<BPatch_function *> *temp; temp = getIncludedFunctions(some_mods[i]->get_dyn_module()); if (NULL == temp) continue; for (unsigned j = 0; j < temp->size(); j++) { ret->push_back((*temp)[j]); } } return ret; }
static BPatch_function *findFunction40(const char *fname, BPatch_image *appImage) { BPatch_Vector<BPatch_function *> bpfv; if (NULL == appImage->findFunction(fname, bpfv) || (bpfv.size() != 1)) { logerror("**Failed test #40 (monitor call sites)\n"); logerror(" Expected 1 functions matching %s, got %d\n", fname, bpfv.size()); return NULL; } return bpfv[0]; }
BPatch_Vector<BPatch_point*>* BPatch_memoryAccess::filterPoints( const BPatch_Vector<BPatch_point *> &points, unsigned int numMAs) { BPatch_Vector<BPatch_point*> *result = new BPatch_Vector<BPatch_point *>; for(unsigned int i = 0; i < points.size(); ++i) { const BPatch_memoryAccess *ma = points[i]->getMemoryAccess(); if(ma) if(ma->getNumberOfAccesses() >= numMAs) result->push_back(points[i]); } return result; }
/* * BPatch_localVarCollection::getAllVars() * this function returns all the local variables in the collection. */ BPatch_Vector<BPatch_localVar *> *BPatch_localVarCollection::getAllVars() { dictionary_hash_iter<pdstring, BPatch_localVar *> li(localVariablesByName); pdstring name; BPatch_localVar *localVar; BPatch_Vector<BPatch_localVar *> *localVarVec = new BPatch_Vector<BPatch_localVar *>; // get all local vars in the localVariablesByName collection while (li.next(name, localVar)) localVarVec->push_back(localVar); return localVarVec; }
// // Start Test Case #1 - (zero arg function call) // test_results_t test1_1_Mutator::executeTest() { const char *funcName = "test1_1_func1_1"; const char* testName = "zero arg function call"; int testNo = 1; // Find the entry point to the procedure "func1_1" BPatch_Vector<BPatch_function *> found_funcs; if ((NULL == appImage->findFunction(funcName, found_funcs)) || !found_funcs.size()) { logerror(" Unable to find function %s\n", funcName); return FAILED; } if (1 < found_funcs.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), funcName); } BPatch_Vector<BPatch_point *> *point1_1 = found_funcs[0]->findPoint(BPatch_entry); if (!point1_1 || ((*point1_1).size() == 0)) { logerror("**Failed** test #%d (%s)\n", testNo,testName); logerror(" Unable to find entry point to \"%s.\"\n", funcName); return FAILED; } BPatch_Vector<BPatch_function *> bpfv; const char *fn = "test1_1_call1_1"; if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size() || NULL == bpfv[0]){ logerror("**Failed** test #%d (%s)\n", testNo, testName); logerror(" Unable to find function %s\n", fn); return FAILED; } BPatch_function *call1_func = bpfv[0]; BPatch_Vector<BPatch_snippet *> call1_args; BPatch_funcCallExpr call1Expr(*call1_func, call1_args); checkCost(call1Expr); if(!appAddrSpace->insertSnippet(call1Expr, *point1_1)) return FAILED; dprintf("Inserted snippet\n"); return PASSED; } // test1_1_Mutator::executeTest()
bool instrumentFunctionExit(dynHandle *dh, BPatch_function *func) { BPatch_Vector<BPatch_point *> *points; BPatchSnippetHandle *handle; BPatch_snippet incSnippet; sendMsg(config.outfd, ID_INST_FUNC_EXIT, VERB2); if (! generateInstrumentation (dh, func, &incSnippet)) goto fail; sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3); points = func->findPoint(BPatch_exit); if (!points) { sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3, ID_FAIL, "Failure in BPatch_function::findPoint(BPatch_exit)"); goto fail; } else if (points->size() == 0) { sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3, ID_WARN, "No instrumentation points found in function"); goto fail; } else { sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3, ID_PASS); } sendMsg(config.outfd, ID_INST_INSERT_CODE, VERB3); if (shouldInsert()) { handle = dh->addSpace->insertSnippet(incSnippet, *points); if (!handle) { sendMsg(config.outfd, ID_INST_INSERT_CODE, VERB3, ID_FAIL, "Failure in BPatch_process::insertSnippet()"); goto fail; } else sendMsg(config.outfd, ID_INST_INSERT_CODE, VERB3, ID_PASS); } if (trace_fd) insertTraceSnippet(dh, func, points); sendMsg(config.outfd, ID_INST_FUNC_EXIT, VERB2, ID_PASS); return true; fail: sendMsg(config.outfd, ID_INST_FUNC_EXIT, VERB2, ID_WARN, "Failure while instrumenting function exit."); return false; }
/** the execution counts of the basic block given and the basic blocks * whose execution can be deduced from the given basic block is updated. * If a is immediate dominator of b and if b is executed then we can * deduce a is also executed. So this method iteratively updates * execution counts of the basic blocks through the path towards the root * of the immediate dominator tree starting from the basic block given */ int FCUseDominator::updateExecutionCounts(BPatch_basicBlock* bb,int ec){ for(BPatch_basicBlock* id = bb; id != NULL; id = id->getImmediateDominator()) { if(!executionCounts[id->getBlockNumber()]){ BPatch_Vector<BPatch_sourceBlock*> sb; id->getSourceBlocks(sb); for(unsigned int i=0;i<sb.size();i++) updateLinesCovered(sb[i]); } executionCounts[id->getBlockNumber()] += ec; } return Error_OK; }
static void ShowFunctions (BPatch_image *appImage) { BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false); cout << PACKAGE_NAME << ": " << vfunctions->size() << " functions found in binary " << endl; unsigned i = 0; while (i < vfunctions->size()) { char name[1024]; BPatch_function *f = (*vfunctions)[i]; f->getName (name, 1024); if (VerboseLevel) { char mname[1024], tname[1024], modname[1024]; f->getMangledName (mname, 1024); f->getTypedName (tname, 1024); f->getModuleName (modname, 1024); cout << " * " << i+1 << " of " << vfunctions->size() << ", Name: " << name << endl << " Mangled Name: " << mname << endl << " Typed Name : " << tname << endl << " Module name : " << modname << endl << " Base address: " << f->getBaseAddr() << endl << " Instrumentable? " << (f->isInstrumentable()?"yes":"no") << endl << " In shared library? " << (f->isSharedLib()?"yes":"no") << endl << " Number of BB: " << getBasicBlocksSize(f) << endl; if (f->isSharedLib()) { char sharedlibname[1024]; BPatch_module *mod = f->getModule(); mod->getFullName (sharedlibname, 1024); cout << " Full library name: " << sharedlibname << endl; } cout << endl; } else { cout << name << endl; } i++; } }
void BPatch_basicBlock::getOutgoingEdges(BPatch_Vector<BPatch_edge*>& out) { std::set<BPatch_edge*>::iterator outIter = outgoingEdges.begin(); while (outIter != outgoingEdges.end()) { out.push_back(*outIter); outIter++; } }
void BPatch_basicBlock::getIncomingEdges(BPatch_Vector<BPatch_edge*>& inc) { std::set<BPatch_edge*>::iterator incIter = incomingEdges.begin(); while (incIter != incomingEdges.end()) { inc.push_back(*incIter); incIter++; } }
ostream& operator<<(ostream& os,BPatch_basicBlock& bb) { unsigned i; os << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; os << "Basic Block : " << bb.blockNo() <<" : [ "; os << ostream::hex << bb.getStartAddress() << " , "; os << ostream::hex << bb.getLastInsnAddress() << " | "; os << ostream::dec << bb.getEndAddress() - bb.getStartAddress() << " ]\n"; if(bb.isEntryBlock()) os <<"Type : ENTRY TO CFG\n"; else if(bb.isExitBlock()) os <<"Type : EXIT FROM CFG\n"; cout << "Pred :\n"; BPatch_Vector<BPatch_basicBlock *> elements; bb.getSources(elements); for (i=0; i<elements.size(); i++) os << "\t<- " << elements[i]->blockNo() << "\n"; cout << "Succ:\n"; elements.clear(); bb.getTargets(elements); for (i=0; i<elements.size(); i++) os << "\t-> " << elements[i]->blockNo() << "\n"; os << "Immediate Dominates: "; if(bb.immediateDominates){ for (std::set<BPatch_basicBlock *>::iterator iter = bb.immediateDominates->begin(); iter != bb.immediateDominates->end(); ++iter) { os << (*iter)->blockNo() << " "; } } os << "\n"; os << "Immediate Dominator: "; if(!bb.immediateDominator) os << "None\n"; else os << bb.immediateDominator->blockNo() << "\n"; os << "\n"; os << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; return os; }
void source_helper(ParseAPI::Edge* e, BPatch_Vector<BPatch_basicBlock*>& srcs, BPatch_flowGraph* flowGraph, func_instance* func) { BPatch_basicBlock* b = flowGraph->findBlock(func->obj()->findBlock(e->src())); assert(b); srcs.push_back(b); }
bool BPatch_loopTreeNode::getCalleesInt(BPatch_Vector<BPatch_function *> &v, BPatch_process *p) { for (unsigned i=0; i<callees.size(); i++) { BPatch_function *f = p->func_map->get(callees[i]); v.push_back(f); } return true; }
bool BPatch_loopTreeNode::getCallees(BPatch_Vector<BPatch_function *> &v, BPatch_addressSpace *p) { for (unsigned i=0; i<callees.size(); i++) { // get() will not allocate a NULL entry in the map BPatch_function *f = p->findOrCreateBPFunc(callees[i], NULL); v.push_back(f); } return true; }
static bool hasBackEdge(BPatch_basicBlock *bb, std::set<int> visited) { if (visited.find(bb->getBlockNumber()) != visited.end()) return true; visited.insert(bb->getBlockNumber()); BPatch_Vector<BPatch_basicBlock*> targets; bb->getTargets(targets); unsigned int i; for (i = 0; i < targets.size(); i++) { if (hasBackEdge(targets[i], visited)) return true; } return false; }
static void ShowFunctions (BPatch_image *appImage) { BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false); cout << PACKAGE_NAME << ": " << vfunctions->size() << " functions found in binary " << endl; unsigned i = 0; while (i < vfunctions->size()) { char name[1024]; BPatch_function *f = (*vfunctions)[i]; f->getName (name, 1024); char mname[1024], tname[1024], modname[1024]; f->getMangledName (mname, 1024); f->getTypedName (tname, 1024); f->getModuleName (modname, 1024); cout << " * " << i+1 << " of " << vfunctions->size() << ", Name: " << name << endl << " Mangled Name: " << mname << endl << " Typed Name : " << tname << endl << " Module name : " << modname << endl << " Base address: " << f->getBaseAddr() << endl << " Instrumentable? " << (f->isInstrumentable()?"yes":"no") << endl << " In shared library? " << (f->isSharedLib()?"yes":"no") << endl; if (f->isSharedLib()) { //Old Dyninst API < 9.x //char sharedlibname[1024]; //mod->getFullName (sharedlibname, 1024); BPatch_module *mod = f->getModule(); string sharedlibname; sharedlibname = mod->getObject()->name(); cout << " Full library name: " << sharedlibname << endl; } cout << endl; i++; } }
static BPatch_point *findPoint(BPatch_function *f, BPatch_procedureLocation loc, int testno, const char *testname) { assert(f); BPatch_Vector<BPatch_point *> *pts = f->findPoint(loc); if (!pts) { logerror("%s[%d]: failed to find point\n", FILE__, __LINE__); FAIL_MES(TESTNAME, TESTDESC); return NULL; } if (pts->size() != 1) { logerror("%s[%d]: failed to find point: found too many\n", FILE__, __LINE__); FAIL_MES(TESTNAME, TESTDESC); return NULL; } return (*pts)[0]; }
bool BPatch_basicBlock::getLineNumbers(unsigned int &_startLine, unsigned int &_endLine) { BPatch_Vector<BPatch_sourceBlock *> sbvec; getSourceBlocks(sbvec); if (!sbvec.size()) return false; unsigned int temp_start = UINT_MAX, temp_end = 0; _startLine = UINT_MAX; _endLine = 0; // Loop through all source blocks and accumulate the smallest start line // and the largest end line. (is there a better way? -- don't we know this a priori?) for (unsigned int i = 0; i < sbvec.size(); ++i) { sbvec[i]->getLineNumbers(temp_start, temp_end); if (temp_start < _startLine) _startLine = temp_start; if (temp_end > _endLine) _endLine = temp_end; } return true; }
/* This function should be deprecated. */ bool BPatch_module::getLineToAddrInt( unsigned int lineNo, BPatch_Vector< unsigned long > & buffer, bool ) { if (hasBeenRemoved_) return false; std::vector< std::pair< Address, Address > > ranges; if( ! getAddressRangesInt( NULL, lineNo, ranges ) ) { return false; } for( unsigned int i = 0; i < ranges.size(); ++i ) { buffer.push_back( ranges[i].first ); } return true; } /* end getLineToAddr() */
bool BPatch_module::getVariablesInt(BPatch_Vector<BPatch_variableExpr *> &vars) { if (hasBeenRemoved_) return false; BPatch_variableExpr *var; parseTypesIfNecessary(); pdvector<pdstring> keys = moduleTypes->globalVarsByName.keys(); int limit = keys.size(); for (int j = 0; j < limit; j++) { pdstring name = keys[j]; var = img->createVarExprByName(this, name.c_str()); if (var != NULL) vars.push_back(var); } if (limit) return true; // We may not have top-level (debugging derived) variable info. // If not, go into the low-level code. const pdvector<int_variable *> &allVars = mod->getAllVariables(); for (unsigned i = 0; i < allVars.size(); i++) { BPatch_variableExpr *var = img->createVarExprByName(this, allVars[i]->symTabName().c_str()); if (var) vars.push_back(var); } if (vars.size()) return true; #ifdef IBM_BPATCH_COMPAT // IBM getVariables can be successful while returning an empty set of vars return true; #else return false; #endif }
//returns the successors of the basic block in a set void BPatch_basicBlock::getTargets(BPatch_Vector<BPatch_basicBlock*>& tgrts){ BPatch_basicBlock *b; pdvector<block_instance *> out_blocks; const PatchBlock::edgelist &itrgs = iblock->targets(); for (PatchBlock::edgelist::const_iterator iter = itrgs.begin(); iter != itrgs.end(); ++iter) { edge_instance* iedge = SCAST_EI(*iter); // We don't include interprocedural predecessors in the BPatch layer if (iedge->interproc() || iedge->sinkEdge()) continue; b = flowGraph->findBlock(iedge->trg()); if (b) tgrts.push_back(b); } }