BPatch_snippet * snip_ref_shlib_var_Mutator::doVarArrayAssign( const char *to, const char *from, unsigned idx) { BPatch_variableExpr *to_v = appImage->findVariable(to); if (!to_v) { logerror("%s[%d]: failed to find var %s\n", FILE__, __LINE__, to); return NULL; } BPatch_variableExpr *from_v = appImage->findVariable(from); if (!from_v) { logerror("%s[%d]: failed to find var %s\n", FILE__, __LINE__, from); return NULL; } BPatch_snippet *ret; ret = new BPatch_arithExpr(BPatch_assign, BPatch_arithExpr(BPatch_ref, *to_v, BPatch_constExpr(idx)), *from_v); assert(ret); return ret; }
test_results_t test1_8_Mutator::executeTest() { // Find the entry point to the procedure "test1_8_func1" const char *funcName = "test1_8_func1"; 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 *> *point8_1 = found_funcs[0]->findPoint(BPatch_entry); if (!point8_1 || ((*point8_1).size() == 0)) { logerror("Unable to find entry point to \"%s\".\n", funcName); return FAILED; } BPatch_Vector<BPatch_snippet*> vect8_1; const char *globalVar = "test1_8_globalVariable1"; BPatch_variableExpr *expr8_1 = findVariable(appImage, globalVar, point8_1); if (!expr8_1) { logerror("**Failed** test #3 (passing variables)\n"); logerror(" Unable to locate variable %s\n", globalVar); return FAILED; } BPatch_arithExpr arith8_1 (BPatch_assign, *expr8_1, BPatch_arithExpr(BPatch_plus, BPatch_arithExpr(BPatch_plus, BPatch_arithExpr(BPatch_plus, BPatch_constExpr(81), BPatch_constExpr(82)), BPatch_arithExpr(BPatch_plus, BPatch_constExpr(83), BPatch_constExpr(84))), BPatch_arithExpr(BPatch_plus, BPatch_arithExpr(BPatch_plus, BPatch_constExpr(85), BPatch_constExpr(86)), BPatch_arithExpr(BPatch_plus, BPatch_constExpr(87), BPatch_constExpr(88))))); vect8_1.push_back(&arith8_1); checkCost(BPatch_sequence(vect8_1)); if(!appAddrSpace->insertSnippet( BPatch_sequence(vect8_1), *point8_1)) return FAILED; return PASSED; }
static int genVRelTest(BPatch_image *appImage, BPatch_Vector<BPatch_snippet*> &vect7_1, BPatch_relOp op, BPatch_variableExpr *r1, BPatch_variableExpr *r2, const char *var1) { const char *funcName = "test1_7_func2"; 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 -1; } 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 *> *point7_1 = found_funcs[0]->findPoint(BPatch_entry); if (!point7_1 || ((*point7_1).size() == 0)) { logerror("Unable to find entry point to \"%s\".\n", funcName); return -1; } BPatch_variableExpr *expr1_1 = findVariable(appImage, var1, point7_1); if (!expr1_1) { logerror("**Failed** test #7 (relational operators)\n"); logerror(" Unable to locate variable %s\n", var1); return -1; } BPatch_ifExpr *tempExpr1 = new BPatch_ifExpr( BPatch_boolExpr(op, *r1, *r2), BPatch_arithExpr(BPatch_assign, *expr1_1, BPatch_constExpr(74))); vect7_1.push_back(tempExpr1); return 0; }
test_results_t test1_5_Mutator::executeTest() { // Find the entry point to the procedure "func5_2" const char *funcName = "test1_5_func2"; 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 *> *point5_1 = found_funcs[0]->findPoint(BPatch_entry); if (!point5_1 || ((*point5_1).size() == 0)) { logerror("Unable to find entry point to \"%s\".\n", funcName); return FAILED; } const char *funcName2 = "test1_5_func1"; BPatch_Vector<BPatch_function *> found_funcs2; if ((NULL == appImage->findFunction(funcName2, found_funcs2)) || !found_funcs2.size()) { logerror(" Unable to find function %s\n", funcName2); return FAILED; } if (1 < found_funcs2.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs2.size(), funcName2); } BPatch_Vector<BPatch_point *> *point5_2 = found_funcs2[0]->findPoint(BPatch_subroutine); if (!point5_2 || ((*point5_2).size() == 0)) { logerror("Unable to find subroutine call points in \"%s\".\n", funcName2); return FAILED; } const char *globalVar1 = "test1_5_globalVariable5_1"; const char *globalVar2 = "test1_5_globalVariable5_2"; BPatch_variableExpr *expr5_1 = findVariable (appImage, globalVar1, point5_1); BPatch_variableExpr *expr5_2 = findVariable (appImage, globalVar2, point5_1); if (!expr5_1 || !expr5_2) { logerror("**Failed** test #5 (1f w.o. else)\n"); logerror(" Unable to locate variable %s or ", globalVar1); logerror(" variable %s\n", globalVar2); return FAILED; } BPatch_Vector<BPatch_snippet*> vect5_1; // if (0 == 1) globalVariable5_1 = 52; BPatch_ifExpr expr5_3(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0), BPatch_constExpr(1)), BPatch_arithExpr(BPatch_assign, *expr5_1, BPatch_constExpr(52))); // if (1 == 1) globalVariable5_2 = 53; BPatch_ifExpr expr5_4(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(1), BPatch_constExpr(1)), BPatch_arithExpr(BPatch_assign, *expr5_2, BPatch_constExpr(53))); vect5_1.push_back(&expr5_3); vect5_1.push_back(&expr5_4); BPatch_sequence expr5_5(vect5_1); checkCost(expr5_5); appAddrSpace->insertSnippet(expr5_5, *point5_1); return PASSED; }
test_results_t test1_25_Mutator::executeTest() { // Used as hack for Fortran to allow assignment of a pointer to an int BPatch::bpatch->setTypeChecking (false); // First verify that we can find a local variable in test1_25_call1 const char *funcName = "test1_25_call1"; 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 *> *point25_1 = found_funcs[0]->findPoint(BPatch_entry); assert(point25_1); // assert(point25_1 && (point25_1->size() == 1)); BPatch_variableExpr *gvar[8]; for (int i=1; i <= 7; i++) { char name[80]; sprintf (name, "test1_25_globalVariable%d", i); gvar [i] = findVariable (appImage, name, point25_1); if (!gvar[i]) { logerror("**Failed** test #25 (unary operaors)\n"); logerror(" can't find variable %s\n", name); return FAILED; } } // globalVariable25_2 = &globalVariable25_1 #if !defined(rs6000_ibm_aix4_1_test) \ && !defined(i386_unknown_linux2_0_test) \ && !defined(x86_64_unknown_linux2_4_test) /* Blind duplication - Ray */ \ && !defined(ppc64_linux_test) \ && !defined(i386_unknown_nt4_0_test) \ && !defined(os_freebsd_test) // without type info need to inform BPatch_type *type = appImage->findType("void *"); assert(type); gvar[2]->setType(type); #endif BPatch_arithExpr assignment1(BPatch_assign, *gvar[2], BPatch_arithExpr(BPatch_addr, *gvar[1])); appAddrSpace->insertSnippet(assignment1, *point25_1); // globalVariable25_3 = *globalVariable25_2 // Need to make sure this happens after the first one BPatch_arithExpr assignment2(BPatch_assign, *gvar[3], BPatch_arithExpr(BPatch_deref, *gvar[2])); appAddrSpace->insertSnippet(assignment2, *point25_1, BPatch_callBefore, BPatch_lastSnippet); // globalVariable25_5 = -globalVariable25_4 BPatch_arithExpr assignment3(BPatch_assign, *gvar[5], BPatch_arithExpr(BPatch_negate, *gvar[4])); appAddrSpace->insertSnippet(assignment3, *point25_1); // globalVariable25_7 = -globalVariable25_6 BPatch_arithExpr assignment4(BPatch_assign, *gvar[7], BPatch_arithExpr(BPatch_negate, *gvar[6])); appAddrSpace->insertSnippet(assignment4, *point25_1); // Check removed because MIPS is no longer supported // #endif // !MIPS BPatch::bpatch->setTypeChecking (true); return PASSED; }
test_results_t test1_28_Mutator::executeTest() { int i; if (isMutateeFortran(appImage)) { return SKIPPED; } // Create the types BPatch_type *intType = appImage->findType("int"); assert(intType); BPatch_Vector<char *> names; BPatch_Vector<BPatch_type *> types; names.push_back(const_cast<char*>("field1")); names.push_back(const_cast<char*>("field2")); types.push_back(intType); types.push_back(intType); // struct28_1 { int field1, int field 2; } BPatch_type *struct28_1 = BPatch::bpatch->createStruct("test1_28_struct1", names, types); BPatch_type *union28_1 = BPatch::bpatch->createUnion("testUnion27_1", names, types); assert(union28_1); names.push_back(const_cast<char*>("field3")); names.push_back(const_cast<char*>("field4")); BPatch_type *intArray = BPatch::bpatch->createArray("intArray", intType, 0, 9); types.push_back(intArray); types.push_back(struct28_1); // struct28_2 { int field1, int field 2, int field3[10],struct26_1 field4 } BPatch_type *struct28_2 = BPatch::bpatch->createStruct("test1_28_struct2", names, types); BPatch_type *type28_2 = BPatch::bpatch->createTypedef("type28_2", struct28_2); // now create variables of these types. BPatch_variableExpr *globalVariable28_1 = appImage->findVariable("test1_28_globalVariable1"); if (!globalVariable28_1) { logerror("[%s:%u] - Unable to find variable test1_28_globalVariable1\n", __FILE__, __LINE__); return FAILED; } globalVariable28_1->setType(type28_2); BPatch_variableExpr *globalVariable28_8 = appImage->findVariable("test1_28_globalVariable8"); if (!globalVariable28_8) { logerror("[%s:%u] - Unable to find variable test1_28_globalVariable8\n", __FILE__, __LINE__); return FAILED; } globalVariable28_8->setType(union28_1); // Next verify that we can find a local variable in call28 const char *fname = "test1_28_call1"; BPatch_Vector<BPatch_function *> found_funcs; if ((NULL == appImage->findFunction(fname, found_funcs)) || !found_funcs.size()) { logerror(" Unable to find function %s\n", fname); 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(), fname); } BPatch_Vector<BPatch_point *> *point28 = found_funcs[0]->findPoint(BPatch_entry); assert(point28 && (point28->size() == 1)); // FIXME We didn't look up a local variable!? BPatch_variableExpr *gvar[8]; for (i=1; i <= 7; i++) { char name[80]; sprintf(name, "test1_28_globalVariable%d", i); gvar[i] = appImage->findVariable(name); if (!gvar[i]) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" can't find variable %s\n", name); return FAILED; } } // start of code for globalVariable28 BPatch_Vector<BPatch_variableExpr *> *fields = gvar[1]->getComponents(); assert(fields && (fields->size() == 4)); for (i=0; i < 4; i++) { char fieldName[80]; sprintf(fieldName, "field%d", i+1); if (strcmp(fieldName, (*fields)[i]->getName())) { logerror("field %d of the struct is %s, not %s\n", i+1, fieldName, (*fields)[i]->getName()); return FAILED; } } // globalVariable28 = globalVariable28.field1 BPatch_arithExpr assignment1(BPatch_assign, *gvar[2], *((*fields)[0])); appAddrSpace->insertSnippet(assignment1, *point28); // globalVariable28 = globalVariable28.field2 BPatch_arithExpr assignment2(BPatch_assign, *gvar[3], *((*fields)[1])); appAddrSpace->insertSnippet(assignment2, *point28); // globalVariable28 = globalVariable28.field3[0] BPatch_arithExpr assignment3(BPatch_assign, *gvar[4], BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(0))); appAddrSpace->insertSnippet(assignment3, *point28); // globalVariable28 = globalVariable28.field3[5] BPatch_arithExpr assignment4(BPatch_assign, *gvar[5], BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(5))); appAddrSpace->insertSnippet(assignment4, *point28); BPatch_Vector<BPatch_variableExpr *> *subfields = (*fields)[3]->getComponents(); assert(subfields != NULL); // globalVariable28 = globalVariable28.field4.field1 BPatch_arithExpr assignment5(BPatch_assign, *gvar[6], *((*subfields)[0])); appAddrSpace->insertSnippet(assignment5, *point28); // globalVariable28 = globalVariable28.field4.field2 BPatch_arithExpr assignment6(BPatch_assign, *gvar[7], *((*subfields)[1])); appAddrSpace->insertSnippet(assignment6, *point28); // BPatch_Vector<BPatch_variableExpr *> *unionfields = globalVariable28_8->getComponents(); int n=1; int val1, val2, val3; ((*unionfields)[0])->writeValue(&n,true); ((*unionfields)[0])->readValue(&val1); if (val1 != 1) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" union field1 has wrong value after first set\n"); return FAILED; } n=2; ((*unionfields)[1])->writeValue(&n,true); ((*unionfields)[1])->readValue(&val2); if (val2 != 2) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" union field2 has wrong value after second set\n"); return FAILED; } ((*unionfields)[1])->readValue(&val3); if (val3 != 2) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" union field1 has wrong value after second set\n"); return FAILED; } // create a scalar BPatch_type *newScalar1 = BPatch::bpatch->createScalar("scalar1", 8); assert(newScalar1); int scalarSize = newScalar1->getSize(); if (scalarSize != 8) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" created scalar is %d bytes, expected %d\n", scalarSize, 8); return FAILED; } // create an enum BPatch_Vector<char *> enumItems; BPatch_Vector<int> enumVals; enumItems.push_back(const_cast<char*>("item1")); enumItems.push_back(const_cast<char*>("item2")); enumItems.push_back(const_cast<char*>("item3")); enumVals.push_back(42); enumVals.push_back(43); enumVals.push_back(44); BPatch_type *newEnum1 = BPatch::bpatch->createEnum("enum1", enumItems); BPatch_type *newEnum2 = BPatch::bpatch->createEnum("enum2", enumItems, enumVals); if (!newEnum1 || !newEnum2) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" failed to create enums as expected\n"); return FAILED; } if (!newEnum1->isCompatible(newEnum1)) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" identical enums reported incompatible\n"); return FAILED; } if (newEnum1->isCompatible(newEnum2)) { logerror("**Failed** test #28 (user defined fields)\n"); logerror(" different enums declared compatible\n"); return FAILED; } return PASSED; }
int main(int argc, char *argv[], char* envp[]) { if (argc < 2) { fprintf(stderr, "Usage: %s prog_filename prog_aruments\n", argv[0]); return 3; } #if 0 if (strcmp(argv[1], "prog") != 0 && strcmp(argv[1], "all")) { fprintf(stderr, "Options for patch selection are 'progonly' or 'all'\n"); return 3; } #endif int patchall = 0; //strcmp(argv[1], "all") != 0; // Create process BPatch_process *appProc = bpatch.processCreate(argv[1], (const char**) &(argv[1])); // Load pthread into the process... appProc->loadLibrary("libpthread.so.0"); // Get the process image BPatch_image *appImage = appProc->getImage(); // Find all the instrumentable procedures BPatch_Vector<BPatch_function*> *functions = appImage->getProcedures(); /************************************************************************* * General function search * *************************************************************************/ // Find the printf function BPatch_Vector<BPatch_function*> printfFuncs; appImage->findFunction("printf", printfFuncs); if (printfFuncs.size() == 0) appImage->findFunction("_printf", printfFuncs); if (printfFuncs.size() == 0) appImage->findFunction("__printf", printfFuncs); if(printfFuncs.size() == 0) { fprintf(stderr, "Could not find printf() function"); return 2; } // Find the exit function BPatch_Vector<BPatch_function*> exitFuncs; appImage->findFunction("exit", exitFuncs); if (exitFuncs.size() == 0) appImage->findFunction("_exit", exitFuncs); if (exitFuncs.size() == 0) appImage->findFunction("__exit", exitFuncs); if(exitFuncs.size() == 0) { fprintf(stderr, "Could not find exit() function"); return 2; } // Find the perror function BPatch_Vector<BPatch_function*> perrorFuncs; appImage->findFunction("perror", perrorFuncs); if (perrorFuncs.size() == 0) appImage->findFunction("_perror", perrorFuncs); if (perrorFuncs.size() == 0) appImage->findFunction("__perror", perrorFuncs); if(perrorFuncs.size() == 0) { fprintf(stderr, "Could not find perror() function"); return 2; } BPatch_Vector<BPatch_snippet*> mainEntryBlock; /************************************************************************ * Error exit call * ************************************************************************/ BPatch_Vector<BPatch_snippet*> exitArgs; BPatch_constExpr exitCode(-2); exitArgs.push_back(&exitCode); // Open call BPatch_funcCallExpr exitOnErrorCall(*exitFuncs[0], exitArgs); /************************************************************************ * Open imitate device patch * * **********************************************************************/ // Find main() BPatch_Vector<BPatch_function*> mainFunctions; appImage->findFunction("main", mainFunctions); if (mainFunctions.size() == 0) appImage->findFunction("_main", mainFunctions); if (mainFunctions.size() == 0) appImage->findFunction("__main", mainFunctions); if(mainFunctions.size() == 0) { fprintf(stderr, "Could not find main() function"); return 2; } // find open() BPatch_Vector<BPatch_function*> openFunctions; appImage->findFunction("open64", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("open", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("_open", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("__open", openFunctions); if(openFunctions.size() == 0) { fprintf(stderr, "Could not find open() function"); return 2; } // Get main() entry point BPatch_Vector<BPatch_point*> *mainPoints = mainFunctions[0]->findPoint(BPatch_entry); // Open call arguments BPatch_Vector<BPatch_snippet*> openArgs; BPatch_constExpr fileName("/dev/imitate0"); BPatch_constExpr fileFlags(O_RDWR); openArgs.push_back(&fileName); openArgs.push_back(&fileFlags); // Open call BPatch_funcCallExpr openDevCall(*openFunctions[0], openArgs); // Allocate file descriptor BPatch_variableExpr *devFd = appProc->malloc(*appImage->findType("int")); // Assign fd with result of open call BPatch_arithExpr openDevice(BPatch_assign, *devFd, openDevCall); // defFd check BPatch_boolExpr devFdCheck(BPatch_lt, *devFd, BPatch_constExpr(0)); // perror message BPatch_Vector<BPatch_snippet*> devFdErrorArgs; BPatch_constExpr devFdErrorMsg("Opening imitate kernel device"); devFdErrorArgs.push_back(&devFdErrorMsg); BPatch_funcCallExpr devFdError(*perrorFuncs[0], devFdErrorArgs); BPatch_Vector<BPatch_snippet*> openErrorBlock; openErrorBlock.push_back(&devFdError); openErrorBlock.push_back(&exitOnErrorCall); // if (devFd < 0) { perror(...) } BPatch_ifExpr devFdBlock(devFdCheck, BPatch_sequence(openErrorBlock)); mainEntryBlock.push_back(&openDevice); mainEntryBlock.push_back(&devFdBlock); /************************************************************************* * Send ioctl IMITATE_APP_RECORD to module * *************************************************************************/ // find ioctl() BPatch_Vector<BPatch_function*> ioctlFunctions; appImage->findFunction("ioctl", ioctlFunctions); if (ioctlFunctions.size() == 0) appImage->findFunction("_ioctl", ioctlFunctions); if (ioctlFunctions.size() == 0) appImage->findFunction("__ioctl", ioctlFunctions); if(ioctlFunctions.size() == 0) { fprintf(stderr, "Could not find ioctl() function"); return 2; } // ioctl() arguments BPatch_Vector<BPatch_snippet*> ioctlArgs; BPatch_constExpr operation(IMITATE_APP_RECORD); fprintf(stderr, "PPID: %d\n", getppid()); BPatch_constExpr monitorPid(getppid()); ioctlArgs.push_back(devFd); ioctlArgs.push_back(&operation); ioctlArgs.push_back(&monitorPid); // ioctl() call BPatch_funcCallExpr ioctlCall(*ioctlFunctions[0], ioctlArgs); // ioctl() result check BPatch_boolExpr ioctlCheck(BPatch_lt, ioctlCall, BPatch_constExpr(0)); // perror message BPatch_Vector<BPatch_snippet*> ioctlErrorArgs; BPatch_constExpr ioctlErrorMsg("Notifying imitate kernel driver of RECORD"); ioctlErrorArgs.push_back(&ioctlErrorMsg); BPatch_funcCallExpr ioctlError(*perrorFuncs[0], ioctlErrorArgs); BPatch_Vector<BPatch_snippet*> ioctlErrorBlock; ioctlErrorBlock.push_back(&ioctlError); ioctlErrorBlock.push_back(&exitOnErrorCall); // if (ioctl(...) < 0) { perror(...) } BPatch_ifExpr ioctlBlock(ioctlCheck, BPatch_sequence(ioctlErrorBlock)); // Add ioctl check to entry block mainEntryBlock.push_back(&ioctlBlock); /************************************************************************* * Counter mmap() * *************************************************************************/ // Find the mmap function BPatch_Vector<BPatch_function*> mmapFuncs; appImage->findFunction("mmap", mmapFuncs); if (mmapFuncs.size() == 0) appImage->findFunction("_mmap", mmapFuncs); if (mmapFuncs.size() == 0) appImage->findFunction("__mmap", mmapFuncs); if(mmapFuncs.size() == 0) { fprintf(stderr, "Could not find mmap() function"); return 2; } // Allocate counter BPatch_variableExpr *counterAddr = appProc->malloc(sizeof(sched_counter_t*)); sched_counter_t counterVal = 0; counterAddr->writeValue(&counterVal, sizeof(sched_counter_t*), false); // Notify kernel of address BPatch_Vector<BPatch_snippet*> mmapArgs; BPatch_constExpr mmapStart(0); BPatch_constExpr mmapLength(sizeof(sched_counter_t)); BPatch_constExpr mmapProt(PROT_READ | PROT_WRITE); BPatch_constExpr mmapFlags(MAP_SHARED); BPatch_constExpr mmapOffset(0); mmapArgs.push_back(&mmapStart); mmapArgs.push_back(&mmapLength); mmapArgs.push_back(&mmapProt); mmapArgs.push_back(&mmapFlags); mmapArgs.push_back(devFd); mmapArgs.push_back(&mmapOffset); // mmap() call BPatch_funcCallExpr mmapCall(*mmapFuncs[0], mmapArgs); // assign result to counterAddr BPatch_arithExpr mmapAssign(BPatch_assign, *counterAddr, mmapCall); // Add to entry block mainEntryBlock.push_back(&mmapAssign); // mmap() result check BPatch_boolExpr mmapCheck(BPatch_eq, *counterAddr, BPatch_constExpr(MAP_FAILED)); // perror message BPatch_Vector<BPatch_snippet*> mmapErrorArgs; BPatch_constExpr mmapErrorMsg("Memory mapping schedule (back edge) counter"); mmapErrorArgs.push_back(&mmapErrorMsg); BPatch_funcCallExpr mmapError(*perrorFuncs[0], mmapErrorArgs); BPatch_Vector<BPatch_snippet*> mmapErrorBlock; mmapErrorBlock.push_back(&mmapError); mmapErrorBlock.push_back(&exitOnErrorCall); // if (mmap(...) == MAP_FAILED) { perror(...) } BPatch_ifExpr mmapBlock(mmapCheck, BPatch_sequence(mmapErrorBlock)); mainEntryBlock.push_back(&mmapBlock); // Patch main entry BPatch_sequence mainEntrySeq(mainEntryBlock); appProc->insertSnippet(mainEntrySeq, *mainPoints); /************************************************************************* * Back-edge patching * *************************************************************************/ #if 0 printf("intCounter address: %x\n PID: %d\n", intCounter->getBaseAddr(), appProc->getPid()); fflush(stdout); #endif // Find the mutex lock/unlock functions BPatch_Vector<BPatch_function*> mutexLockFunctions; appImage->findFunction("pthread_mutex_lock", mutexLockFunctions); if (mutexLockFunctions.size() == 0) appImage->findFunction("_pthread_mutex_lock", mutexLockFunctions); if (mutexLockFunctions.size() == 0) appImage->findFunction("__pthread_mutex_lock", mutexLockFunctions); if(mutexLockFunctions.size() == 0) { fprintf(stderr, "Could not find pthread_mutex_lock() function"); return 2; } BPatch_Vector<BPatch_function*> mutexUnlockFunctions; appImage->findFunction("pthread_mutex_unlock", mutexUnlockFunctions); if (mutexUnlockFunctions.size() == 0) appImage->findFunction("_pthread_mutex_unlock", mutexUnlockFunctions); if (mutexUnlockFunctions.size() == 0) appImage->findFunction("__pthread_mutex_unlock", mutexUnlockFunctions); if(mutexUnlockFunctions.size() == 0) { fprintf(stderr, "Could not find pthread_mutex_unlock() function"); return 2; } // Allocate a mutex pthread_mutex_t mutexValue = PTHREAD_MUTEX_INITIALIZER; BPatch_variableExpr *mutex = appProc->malloc(sizeof(pthread_mutex_t)); mutex->writeValue(&mutexValue, sizeof(pthread_mutex_t), false); // Build mutex lock call BPatch_Vector<BPatch_snippet*> mutexArgs; BPatch_constExpr mutexAddress(mutex->getBaseAddr()); mutexArgs.push_back(&mutexAddress); BPatch_funcCallExpr mutexLockCall(*mutexLockFunctions[0], mutexArgs); BPatch_funcCallExpr mutexUnlockCall(*mutexUnlockFunctions[0], mutexArgs); BPatch_arithExpr derefCounter(BPatch_deref, *counterAddr); // Create 'increment counter' snippet BPatch_arithExpr addOneToCounter(BPatch_assign, derefCounter, BPatch_arithExpr(BPatch_plus, derefCounter, BPatch_constExpr(1))); BPatch_Vector<BPatch_snippet*> snippet; snippet.push_back(&mutexLockCall); snippet.push_back(&addOneToCounter); snippet.push_back(&mutexUnlockCall); BPatch_sequence addOneAtomic(snippet); char *name = (char*) malloc(sizeof(char)*200); char *modname = (char*) malloc(sizeof(char)*200); if (! (name && modname)) { fprintf(stderr, "%s %d: Out of memory!", __FILE__, __LINE__); return 1; } appProc->beginInsertionSet(); // Iterate through the procedures for (int i = 0; i < functions->size(); i++) { (*functions)[i]->getName(name, 199); (*functions)[i]->getModuleName(modname, 199); if ((patchall && strcmp(modname, "DEFAULT_MODULE") != 0) || strncmp(name, "pthread", 7) == 0 || strncmp(modname, "libpthread", 10) == 0 || strncmp(modname, "libdyninst", 10) == 0 || (name[0] == '_' && name[1] != '_' && strncmp(modname, "libc", 4) == 0)) continue; fprintf(stderr, "patcher: Patching function: '%s' (%s)", name, modname); // Patch back-edge for call if (strcmp(name, "main") != 0) appProc->insertSnippet(addOneAtomic, *((*functions)[i]->findPoint(BPatch_entry))); // Get the control flow graph for the procedure BPatch_flowGraph *graph = (*functions)[i]->getCFG(); // Find the loops BPatch_Vector<BPatch_basicBlockLoop*> *loops = new BPatch_Vector<BPatch_basicBlockLoop*>(); graph->getLoops(*loops); // Patch the loop back-edges for(int j = 0; j < loops->size(); j++) { appProc->insertSnippet(addOneAtomic, *((*loops)[j]->getBackEdge()->getPoint())); fprintf(stderr, ".", (int) (*loops)[j]->getBackEdge()->getPoint()->getAddress()); } fprintf(stderr, "\n"); // Free the loops found delete(loops); } fprintf(stderr, "Finalising patches..."); fflush(stderr); appProc->finalizeInsertionSet(false); fprintf(stderr, "Done.\n----------------------------------------\n"); // Clear up memory used to store the name free(name); free(modname); #if 0 /************************************************************************* * Exit point counter print patch * *************************************************************************/ // Patch exit() function to print out no of back branches at the end // Get exit() exit point BPatch_Vector<BPatch_point*> *exitPoints = exitFuncs[0]->findPoint(BPatch_entry); // Build printf() call: // printf("Total Total Back-branches: %d\n", counter); // Build arguments to printf() BPatch_Vector<BPatch_snippet*> printfArgs; BPatch_constExpr formatString("Total Back-branches: %d\n"); printfArgs.push_back(&formatString); printfArgs.push_back(&derefCounter); // Build call to printf() BPatch_funcCallExpr printfCall(*printfFuncs[0], printfArgs); // Patch into exit() appProc->insertSnippet(printfCall, *exitPoints); #endif // Continue mutatee... appProc->continueExecution(); // Wait for mutatee to finish while (!appProc->isTerminated()) { bpatch.waitForStatusChange(); } fprintf(stderr, "----------------------------------------\n"); fprintf(stderr, "Done.\n"); return 0; }