3 // libdyninst validation suite test #1
4 // Author: Jeff Hollingsworth (1/7/97)
5 // derived from a previous test by Bryan Buck
8 // This program tests the basic features of the dyninst API.
9 // The mutatee that goes with this file is test1.mutatee.c
11 // Naming conventions:
12 // All functions, variables, etc are name funcXX_YY, exprXX_YY, etc.
13 // XX is the test number
14 // YY is the instance withing the test
15 // func1_2 is the second function used in test case #1.
20 #if defined(sparc_sun_sunos4_1_3) || defined(sparc_sun_solaris2_4)
25 #include "BPatch_Vector.h"
26 #include "BPatch_thread.h"
27 #include "BPatch_snippet.h"
28 #include "test_util.h"
34 // control debug printf statements
35 #define dprintf if (debugPrint) printf
37 /**************************************************************************
39 **************************************************************************/
41 // check that the cost of a snippet is sane. Due to differences between
42 // platforms, it is impossible to check this exactly in a machine independent
44 void checkCost(BPatch_snippet snippet)
49 // test copy constructor too.
52 cost = snippet.getCost();
54 printf("*Error*: negative snippet cost\n");
55 } else if (cost == 0.0) {
56 printf("*Warning*: zero snippet cost\n");
57 } else if (cost > 0.01) {
58 printf("*Error*: snippet cost of %f, exceeds max expected of 0.1",
64 // Replace all calls in "inFunction" to "callTo" with calls to "replacement."
65 // If "replacement" is NULL, them use removeFunctionCall instead of
66 // replaceFunctionCall.
67 // Returns the number of replacements that were performed.
69 int replaceFunctionCalls(BPatch_thread *appThread, BPatch_image *appImage,
70 char *inFunction, char *callTo, char *replacement,
71 int testNo, char *testName,
72 int callsExpected = -1)
76 BPatch_Vector<BPatch_point *> *points =
77 appImage->findProcedurePoint(inFunction, BPatch_subroutine);
78 if (!points || (points->size() < 1)) {
79 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
80 fprintf(stderr, " Unable to find point %s - subroutine calls\n",
85 BPatch_function *call_replacement;
86 if (replacement != NULL) {
87 call_replacement = appImage->findFunction(replacement);
88 if (call_replacement == NULL) {
89 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
90 fprintf(stderr, " Unable to find function %s\n", replacement);
95 for (int n = 0; n < points->size(); n++) {
96 BPatch_function *func;
98 if ((func = (*points)[n]->getCalledFunction()) == NULL) continue;
101 if (func->getName(fn, 256) == NULL) {
102 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
103 fprintf(stderr, " Can't get name of called function in %s\n",
107 if (strcmp(fn, callTo) == 0) {
108 if (replacement == NULL)
109 appThread->removeFunctionCall(*((*points)[n]));
111 appThread->replaceFunctionCall(*((*points)[n]),
117 if (callsExpected > 0 && callsExpected != numReplaced) {
118 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
119 fprintf(stderr, " Expected to find %d %s to %s in %s, found %d\n",
120 callsExpected, callsExpected == 1 ? "call" : "calls",
121 callTo, inFunction, numReplaced);
131 // Return a pointer to a string identifying a BPatch_procedureLocation
133 char *locationName(BPatch_procedureLocation l)
140 case BPatch_subroutine:
141 return "call points";
142 case BPatch_longJump:
144 case BPatch_allLocations:
147 return "<invalid BPatch_procedureLocation>";
153 // Insert "snippet" at the location "loc" in the function "inFunction."
154 // Returns the value returned by BPatch_thread::insertSnippet.
156 BPatchSnippetHandle *insertSnippetAt(BPatch_thread *appThread,
157 BPatch_image *appImage, char *inFunction, BPatch_procedureLocation loc,
158 BPatch_snippet &snippet, int testNo, char *testName)
160 // Find the point(s) we'll be instrumenting
161 BPatch_Vector<BPatch_point *> *points =
162 appImage->findProcedurePoint(inFunction, loc);
165 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
166 fprintf(stderr, " Unable to find point %s - %s\n",
167 inFunction, locationName(loc));
172 return appThread->insertSnippet(snippet, *points);
176 // Create a snippet that calls the function "funcName" with no arguments
178 BPatch_snippet *makeCallSnippet(BPatch_image *appImage, char *funcName,
179 int testNo, char *testName)
181 BPatch_function *call_func = appImage->findFunction(funcName);
182 if (call_func == NULL) {
183 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
184 fprintf(stderr, " Unable to find function %s\n", funcName);
188 BPatch_Vector<BPatch_snippet *> nullArgs;
189 BPatch_snippet *ret = new BPatch_funcCallExpr(*call_func, nullArgs);
192 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
193 fprintf(stderr, " Unable to create snippet to call %s\n", funcName);
201 // Insert a snippet to call function "funcName" with no arguments into the
202 // procedure "inFunction" at the points given by "loc."
204 BPatchSnippetHandle *insertCallSnippetAt(BPatch_thread *appThread,
205 BPatch_image *appImage, char *inFunction, BPatch_procedureLocation loc,
206 char *funcName, int testNo, char *testName)
208 BPatch_snippet *call_expr =
209 makeCallSnippet(appImage, funcName, testNo, testName);
211 BPatchSnippetHandle *ret = insertSnippetAt(appThread, appImage,
212 inFunction, loc, *call_expr,
215 fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
216 fprintf(stderr, " Unable to insert snippet to call function %s\n",
227 /**************************************************************************
229 **************************************************************************/
232 // Start Test Case #6 - mutator side (arithmetic operators)
234 void mutatorTest6(BPatch_thread *appThread, BPatch_image *appImage)
236 // Find the entry point to the procedure "func6_1"
237 BPatch_Vector<BPatch_point *> *point6_1 =
238 appImage->findProcedurePoint("func6_1", BPatch_entry);
239 BPatch_variableExpr *expr6_1 = appImage->findVariable("globalVariable6_1");
240 BPatch_variableExpr *expr6_2 = appImage->findVariable("globalVariable6_2");
241 BPatch_variableExpr *expr6_3 = appImage->findVariable("globalVariable6_3");
242 BPatch_variableExpr *expr6_4 = appImage->findVariable("globalVariable6_4");
243 BPatch_variableExpr *expr6_5 = appImage->findVariable("globalVariable6_5");
244 BPatch_variableExpr *expr6_6 = appImage->findVariable("globalVariable6_6");
245 if (!expr6_1 || !expr6_2 || !expr6_3 || !expr6_4 ||
246 !expr6_5 || !expr6_6) {
247 fprintf(stderr, "**Failed** test #6 (arithmetic operators)\n");
248 fprintf(stderr, " Unable to locate one of globalVariable6_?\n");
252 BPatch_Vector<BPatch_snippet*> vect6_1;
254 // globalVariable6_1 = 60 + 2
255 BPatch_arithExpr arith6_1 (BPatch_assign, *expr6_1,
256 BPatch_arithExpr(BPatch_plus,BPatch_constExpr(60), BPatch_constExpr(2)));
257 vect6_1.push_back(&arith6_1);
259 // globalVariable6_2 = 64 - 1
260 BPatch_arithExpr arith6_2 (BPatch_assign, *expr6_2,
261 BPatch_arithExpr(BPatch_minus,BPatch_constExpr(64),BPatch_constExpr(1)));
262 vect6_1.push_back(&arith6_2);
264 // globalVariable6_3 = 66 / 3
265 BPatch_arithExpr arith6_3 (BPatch_assign, *expr6_3, BPatch_arithExpr(
266 BPatch_divide,BPatch_constExpr(66),BPatch_constExpr(3)));
267 vect6_1.push_back(&arith6_3);
269 // globalVariable6_4 = 67 / 3
270 BPatch_arithExpr arith6_4 (BPatch_assign, *expr6_4, BPatch_arithExpr(
271 BPatch_divide,BPatch_constExpr(67),BPatch_constExpr(3)));
272 vect6_1.push_back(&arith6_4);
274 // globalVariable6_5 = 6 * 5
275 BPatch_arithExpr arith6_5 (BPatch_assign, *expr6_5, BPatch_arithExpr(
276 BPatch_times,BPatch_constExpr(6),BPatch_constExpr(5)));
277 vect6_1.push_back(&arith6_5);
279 // globalVariable6_6 = 10,3
280 BPatch_arithExpr arith6_6 (BPatch_assign, *expr6_6,
281 BPatch_arithExpr(BPatch_seq,BPatch_constExpr(10),BPatch_constExpr(3)));
282 vect6_1.push_back(&arith6_6);
284 checkCost(BPatch_sequence(vect6_1));
285 appThread->insertSnippet( BPatch_sequence(vect6_1), *point6_1);
288 void genRelTest(BPatch_image *appImage,BPatch_Vector<BPatch_snippet*> &vect7_1,
289 BPatch_relOp op, int r1, int r2, char *var1)
291 BPatch_variableExpr *varExpr1 = appImage->findVariable(var1);
293 fprintf(stderr, "**Failed** test #7 (relational operators)\n");
294 fprintf(stderr, " Unable to locate variable %s\n", var1);
297 BPatch_ifExpr *tempExpr1 = new BPatch_ifExpr(
298 BPatch_boolExpr(op, BPatch_constExpr(r1), BPatch_constExpr(r2)),
299 BPatch_arithExpr(BPatch_assign, *varExpr1, BPatch_constExpr(72)));
300 vect7_1.push_back(tempExpr1);
305 // Start Test Case #7 - mutator side (relational operators)
307 void mutatorTest7(BPatch_thread *appThread, BPatch_image *appImage)
309 // Find the entry point to the procedure "func7_1"
310 BPatch_Vector<BPatch_point *> *point7_1 =
311 appImage->findProcedurePoint("func7_1", BPatch_entry);
312 BPatch_Vector<BPatch_snippet*> vect7_1;
314 genRelTest(appImage, vect7_1, BPatch_lt, 0, 1, "globalVariable7_1");
315 genRelTest(appImage, vect7_1, BPatch_lt, 1, 0, "globalVariable7_2");
316 genRelTest(appImage, vect7_1, BPatch_eq, 2, 2, "globalVariable7_3");
317 genRelTest(appImage, vect7_1, BPatch_eq, 2, 3, "globalVariable7_4");
318 genRelTest(appImage, vect7_1, BPatch_gt, 4, 3, "globalVariable7_5");
319 genRelTest(appImage, vect7_1, BPatch_gt, 3, 4, "globalVariable7_6");
320 genRelTest(appImage, vect7_1, BPatch_le, 3, 4, "globalVariable7_7");
321 genRelTest(appImage, vect7_1, BPatch_le, 4, 3, "globalVariable7_8");
322 genRelTest(appImage, vect7_1, BPatch_ne, 5, 6, "globalVariable7_9");
323 genRelTest(appImage, vect7_1, BPatch_ne, 5, 5, "globalVariable7_10");
324 genRelTest(appImage, vect7_1, BPatch_ge, 9, 7, "globalVariable7_11");
325 genRelTest(appImage, vect7_1, BPatch_ge, 7, 9, "globalVariable7_12");
326 genRelTest(appImage, vect7_1, BPatch_and, 1, 1, "globalVariable7_13");
327 genRelTest(appImage, vect7_1, BPatch_and, 1, 0, "globalVariable7_14");
328 genRelTest(appImage, vect7_1, BPatch_or, 1, 0, "globalVariable7_15");
329 genRelTest(appImage, vect7_1, BPatch_or, 0, 0, "globalVariable7_16");
331 dprintf("relops test vector length is %d\n", vect7_1.size());
333 checkCost(BPatch_sequence(vect7_1));
334 appThread->insertSnippet( BPatch_sequence(vect7_1), *point7_1);
338 // Start Test Case #8 - mutator side (preserve registers - expr)
340 void mutatorTest8(BPatch_thread *appThread, BPatch_image *appImage)
342 // Find the entry point to the procedure "func8_1"
343 BPatch_Vector<BPatch_point *> *point8_1 =
344 appImage->findProcedurePoint("func8_1", BPatch_entry);
345 BPatch_Vector<BPatch_snippet*> vect8_1;
347 BPatch_variableExpr *expr8_1 = appImage->findVariable("globalVariable8_1");
349 fprintf(stderr, "**Failed** test #3 (passing variables)\n");
350 fprintf(stderr, " Unable to locate variable globalVariable8_1\n");
354 BPatch_arithExpr arith8_1 (BPatch_assign, *expr8_1,
355 BPatch_arithExpr(BPatch_plus,
356 BPatch_arithExpr(BPatch_plus,
357 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(81),
358 BPatch_constExpr(82)),
359 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(83),
360 BPatch_constExpr(84))),
361 BPatch_arithExpr(BPatch_plus,
362 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(85),
363 BPatch_constExpr(86)),
364 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(87),
365 BPatch_constExpr(88)))));
366 vect8_1.push_back(&arith8_1);
368 checkCost(BPatch_sequence(vect8_1));
369 appThread->insertSnippet( BPatch_sequence(vect8_1), *point8_1);
373 // Start Test Case #9 - mutator side (preserve registers - funcCall)
375 void mutatorTest9(BPatch_thread *appThread, BPatch_image *appImage)
377 // Find the entry point to the procedure "func9_1"
378 BPatch_Vector<BPatch_point *> *point9_1 =
379 appImage->findProcedurePoint("func9_1", BPatch_entry);
381 BPatch_function *call9_func = appImage->findFunction("call9_1");
382 if (call9_func == NULL) {
383 fprintf(stderr, "Unable to find function \"call9_1.\"\n");
387 BPatch_Vector<BPatch_snippet *> call9_args;
389 BPatch_constExpr constExpr91(91);
390 call9_args.push_back(&constExpr91);
392 BPatch_constExpr constExpr92(92);
393 call9_args.push_back(&constExpr92);
395 BPatch_constExpr constExpr93(93);
396 call9_args.push_back(&constExpr93);
398 BPatch_constExpr constExpr94(94);
399 call9_args.push_back(&constExpr94);
401 BPatch_constExpr constExpr95(95);
402 call9_args.push_back(&constExpr95);
404 BPatch_funcCallExpr call9Expr(*call9_func, call9_args);
406 checkCost(call9Expr);
407 appThread->insertSnippet( call9Expr, *point9_1);
412 // Start Test Case #10 - mutator side (insert snippet order)
414 void mutatorTest10(BPatch_thread *appThread, BPatch_image *appImage)
416 // Find the entry point to the procedure "func10_1"
417 BPatch_Vector<BPatch_point *> *point10_1 =
418 appImage->findProcedurePoint("func10_1", BPatch_entry);
420 BPatch_function *call10_1_func = appImage->findFunction("call10_1");
421 if (call10_1_func == NULL) {
422 fprintf(stderr, "Unable to find function \"call10_1.\"\n");
426 BPatch_function *call10_2_func = appImage->findFunction("call10_2");
427 if (call10_2_func == NULL) {
428 fprintf(stderr, "Unable to find function \"call10_2.\"\n");
432 BPatch_function *call10_3_func = appImage->findFunction("call10_3");
433 if (call10_3_func == NULL) {
434 fprintf(stderr, "Unable to find function \"call10_3.\"\n");
438 BPatch_Vector<BPatch_snippet *> nullArgs;
439 BPatch_funcCallExpr call10_1Expr(*call10_1_func, nullArgs);
440 BPatch_funcCallExpr call10_2Expr(*call10_2_func, nullArgs);
441 BPatch_funcCallExpr call10_3Expr(*call10_3_func, nullArgs);
443 checkCost(call10_2Expr);
444 appThread->insertSnippet( call10_2Expr, *point10_1);
446 checkCost(call10_1Expr);
447 appThread->insertSnippet( call10_1Expr, *point10_1, BPatch_callBefore,
448 BPatch_firstSnippet);
450 checkCost(call10_3Expr);
451 appThread->insertSnippet( call10_3Expr, *point10_1, BPatch_callBefore,
457 // Start Test Case #11 - mutator side (snippets at entry,exit,call)
459 void mutatorTest11(BPatch_thread *appThread, BPatch_image *appImage)
461 // Find the entry point to the procedure "func11_1"
462 BPatch_Vector<BPatch_point *> *point11_1 =
463 appImage->findProcedurePoint("func11_1", BPatch_entry);
464 if (!point11_1 || (point11_1->size() < 1)) {
465 fprintf(stderr, "Unable to find point func11_1 - entry.\n");
469 // Find the subroutine points for the procedure "func11_1"
470 BPatch_Vector<BPatch_point *> *point11_2 =
471 appImage->findProcedurePoint("func11_1", BPatch_subroutine);
472 if (!point11_2 || (point11_2->size() < 1)) {
473 fprintf(stderr, "Unable to find point func11_1 - calls.\n");
477 // Find the exit point to the procedure "func11_1"
478 BPatch_Vector<BPatch_point *> *point11_3 =
479 appImage->findProcedurePoint("func11_1", BPatch_exit);
480 if (!point11_3 || (point11_3->size() < 1)) {
481 fprintf(stderr, "Unable to find point func11_1 - exit.\n");
485 BPatch_function *call11_1_func = appImage->findFunction("call11_1");
486 if (call11_1_func == NULL) {
487 fprintf(stderr, "Unable to find function \"call11_1.\"\n");
491 BPatch_function *call11_2_func = appImage->findFunction("call11_2");
492 if (call11_2_func == NULL) {
493 fprintf(stderr, "Unable to find function \"call11_2.\"\n");
497 BPatch_function *call11_3_func = appImage->findFunction("call11_3");
498 if (call11_3_func == NULL) {
499 fprintf(stderr, "Unable to find function \"call11_3.\"\n");
503 BPatch_function *call11_4_func = appImage->findFunction("call11_4");
504 if (call11_4_func == NULL) {
505 fprintf(stderr, "Unable to find function \"call11_4.\"\n");
509 BPatch_Vector<BPatch_snippet *> nullArgs;
510 BPatch_funcCallExpr call11_1Expr(*call11_1_func, nullArgs);
511 BPatch_funcCallExpr call11_2Expr(*call11_2_func, nullArgs);
512 BPatch_funcCallExpr call11_3Expr(*call11_3_func, nullArgs);
513 BPatch_funcCallExpr call11_4Expr(*call11_4_func, nullArgs);
515 checkCost(call11_1Expr);
516 appThread->insertSnippet(call11_1Expr, *point11_1);
518 checkCost(call11_2Expr);
519 appThread->insertSnippet(call11_2Expr, *point11_2, BPatch_callBefore);
521 checkCost(call11_3Expr);
522 appThread->insertSnippet(call11_3Expr, *point11_2, BPatch_callAfter);
524 checkCost(call11_4Expr);
525 appThread->insertSnippet(call11_4Expr, *point11_3);
528 BPatchSnippetHandle *snippetHandle12_1;
529 BPatch_variableExpr *varExpr12_1;
532 // Start Test Case #12 - mutator side (insert/remove and malloc/free)
534 void mutatorTest12a(BPatch_thread *appThread, BPatch_image *appImage)
536 // Find the entry point to the procedure "func12_2"
537 BPatch_Vector<BPatch_point *> *point12_2 =
538 appImage->findProcedurePoint("func12_2", BPatch_entry);
539 if (!point12_2 || (point12_2->size() < 1)) {
540 fprintf(stderr, "Unable to find point func12_2 - entry.\n");
544 varExpr12_1 = appThread->malloc(100);
546 fprintf(stderr, "Unable to allocate 100 bytes in mutatee\n");
550 BPatch_function *call12_1_func = appImage->findFunction("call12_1");
551 if (call12_1_func == NULL) {
552 fprintf(stderr, "Unable to find function \"call12_1.\"\n");
556 BPatch_Vector<BPatch_snippet *> nullArgs;
557 BPatch_funcCallExpr call12_1Expr(*call12_1_func, nullArgs);
559 checkCost(call12_1Expr);
560 snippetHandle12_1 = appThread->insertSnippet(call12_1Expr, *point12_2);
561 if (!snippetHandle12_1) {
563 "Unable to insert snippet to call function \"call12_1.\"\n");
568 void mutatorTest12b(BPatch_thread *appThread, BPatch_image * /*appImage*/)
570 waitUntilStopped(appThread, 12, "insert/remove and malloc/free");
572 // remove instrumentation and free memory
573 if (!appThread->deleteSnippet(snippetHandle12_1)) {
574 printf("**Failed test #12 (insert/remove and malloc/free)\n");
575 printf(" deleteSnippet returned an error\n");
578 appThread->free(*varExpr12_1);
581 appThread->continueExecution();
586 // Start Test Case #13 - mutator side (paramExpr,retExpr,nullExpr)
588 void mutatorTest13(BPatch_thread *appThread, BPatch_image *appImage)
590 // Find the entry point to the procedure "func13_1"
591 BPatch_Vector<BPatch_point *> *point13_1 =
592 appImage->findProcedurePoint("func13_1", BPatch_entry);
593 if (!point13_1 || (point13_1->size() < 1)) {
594 fprintf(stderr, "Unable to find point func13_1 - entry.\n");
598 BPatch_function *call13_1_func = appImage->findFunction("call13_1");
599 if (call13_1_func == NULL) {
600 fprintf(stderr, "Unable to find function \"call13_1.\"\n");
604 BPatch_Vector<BPatch_snippet *> funcArgs;
605 funcArgs.push_back(new BPatch_paramExpr(0));
606 funcArgs.push_back(new BPatch_paramExpr(1));
607 funcArgs.push_back(new BPatch_paramExpr(2));
608 funcArgs.push_back(new BPatch_paramExpr(3));
609 funcArgs.push_back(new BPatch_paramExpr(4));
610 BPatch_funcCallExpr call13_1Expr(*call13_1_func, funcArgs);
612 checkCost(call13_1Expr);
613 appThread->insertSnippet(call13_1Expr, *point13_1);
615 BPatch_nullExpr call13_2Expr;
616 checkCost(call13_1Expr);
617 appThread->insertSnippet(call13_2Expr, *point13_1);
619 // now test that a return value can be read.
620 BPatch_Vector<BPatch_point *> *point13_2 =
621 appImage->findProcedurePoint("func13_2", BPatch_exit);
622 if (!point13_2 || (point13_2->size() < 1)) {
623 fprintf(stderr, "Unable to find point func13_2 - exit.\n");
627 BPatch_function *call13_2_func = appImage->findFunction("call13_2");
628 if (call13_2_func == NULL) {
629 fprintf(stderr, "Unable to find function \"call13_1.\"\n");
633 BPatch_Vector<BPatch_snippet *> funcArgs2;
634 funcArgs2.push_back(new BPatch_retExpr());
635 BPatch_funcCallExpr call13_3Expr(*call13_2_func, funcArgs2);
637 checkCost(call13_1Expr);
638 appThread->insertSnippet(call13_3Expr, *point13_2);
643 // Start Test Case #14 - mutator side (replace function call)
645 void mutatorTest14(BPatch_thread *appThread, BPatch_image *appImage)
647 replaceFunctionCalls(appThread, appImage,
648 "func14_1", "func14_2", "call14_1",
649 14, "replace/remove function call", 1);
650 replaceFunctionCalls(appThread, appImage,
651 "func14_1", "func14_3", NULL,
652 14, "replace/remove function call", 1);
657 // Start Test Case #15 - mutator side (setMutationsActive)
659 void mutatorTest15a(BPatch_thread *appThread, BPatch_image *appImage)
661 insertCallSnippetAt(appThread, appImage, "func15_2", BPatch_entry,
662 "call15_1", 15, "setMutationsActive");
664 #if defined(sparc_sun_sunos4_1_3) || defined(sparc_sun_solaris2_4)
665 // On the Sparc, functions containing system calls are relocated into the
666 // heap when instrumented, making a special case we should check.
668 // "access" makes the "access" system call, so we'll instrument it
669 insertCallSnippetAt(appThread, appImage, "access", BPatch_entry,
670 "call15_2", 15, "setMutationsActive");
671 // We want to instrument more than one point, so do exit as well
672 insertCallSnippetAt(appThread, appImage, "access", BPatch_exit,
673 "call15_2", 15, "setMutationsActive");
676 replaceFunctionCalls(appThread, appImage, "func15_4", "func15_3",
677 "call15_3", 15, "setMutationsActive", 1);
681 void mutatorTest15b(BPatch_thread *appThread, BPatch_image * /*appImage*/)
683 waitUntilStopped(appThread, 15, "setMutationsActive");
685 // disable mutations and continue process
686 appThread->setMutationsActive(false);
687 appThread->continueExecution();
689 waitUntilStopped(appThread, 15, "setMutationsActive");
691 // re-enable mutations and continue process
692 appThread->setMutationsActive(true);
693 appThread->continueExecution();
698 // Start Test Case #16 - mutator side (if-else)
700 void mutatorTest16(BPatch_thread *appThread, BPatch_image *appImage)
702 BPatch_variableExpr *expr16_1=appImage->findVariable("globalVariable16_1");
703 BPatch_variableExpr *expr16_2=appImage->findVariable("globalVariable16_2");
704 BPatch_variableExpr *expr16_3=appImage->findVariable("globalVariable16_3");
705 BPatch_variableExpr *expr16_4=appImage->findVariable("globalVariable16_4");
706 if (!expr16_1 || !expr16_2 || !expr16_3 || !expr16_4) {
707 fprintf(stderr, "**Failed** test #16 (if-else)\n");
708 fprintf(stderr, " Unable to locate one of globalVariable16_?\n");
712 BPatch_arithExpr assign16_1(BPatch_assign, *expr16_1, BPatch_constExpr(1));
713 BPatch_arithExpr assign16_2(BPatch_assign, *expr16_2, BPatch_constExpr(1));
715 BPatch_ifExpr if16_2(BPatch_boolExpr(BPatch_eq,
717 BPatch_constExpr(1)),
718 assign16_1, assign16_2);
720 BPatch_arithExpr assign16_3(BPatch_assign, *expr16_3, BPatch_constExpr(1));
721 BPatch_arithExpr assign16_4(BPatch_assign, *expr16_4, BPatch_constExpr(1));
723 BPatch_ifExpr if16_3(BPatch_boolExpr(BPatch_eq,
725 BPatch_constExpr(1)),
726 assign16_3, assign16_4);
728 insertSnippetAt(appThread, appImage, "func16_2", BPatch_entry, if16_2,
730 insertSnippetAt(appThread, appImage, "func16_3", BPatch_entry, if16_3,
735 // Start Test Case #17 - mutator side (return values from func calls)
737 void mutatorTest17(BPatch_thread *appThread, BPatch_image *appImage)
739 // Find the entry point to the procedure "func17_1"
740 BPatch_Vector<BPatch_point *> *point17_1 =
741 appImage->findProcedurePoint("func17_1", BPatch_exit);
742 if (!point17_1 || (point17_1->size() < 1)) {
743 fprintf(stderr, "Unable to find point func17_1 - entry.\n");
747 BPatch_function *call17_1_func = appImage->findFunction("call17_1");
748 if (call17_1_func == NULL) {
749 fprintf(stderr, "Unable to find function \"call17_1.\"\n");
753 BPatch_Vector<BPatch_snippet *> funcArgs;
754 funcArgs.push_back(new BPatch_paramExpr(1));
755 BPatch_funcCallExpr call17_1Expr(*call17_1_func, funcArgs);
756 checkCost(call17_1Expr);
757 appThread->insertSnippet(call17_1Expr, *point17_1);
759 // Find the exit point to the procedure "func17_2"
760 BPatch_Vector<BPatch_point *> *point17_2 =
761 appImage->findProcedurePoint("func17_2", BPatch_exit);
762 if (!point17_2 || (point17_2->size() < 1)) {
763 fprintf(stderr, "Unable to find point func17_2 - entry.\n");
767 BPatch_function *call17_2_func = appImage->findFunction("call17_2");
768 if (call17_2_func == NULL) {
769 fprintf(stderr, "Unable to find function \"call17_2.\"\n");
773 BPatch_Vector<BPatch_snippet *> funcArgs2;
774 funcArgs2.push_back(new BPatch_constExpr(1));
775 BPatch_funcCallExpr call17_2Expr(*call17_2_func, funcArgs2);
776 checkCost(call17_2Expr);
778 // test interface to call into insertSnippet with only one parameter
779 const BPatch_point aPoint = *(*point17_2)[0];
780 appThread->insertSnippet(call17_2Expr, aPoint,
781 BPatch_callBefore, BPatch_lastSnippet);
785 // Start Test Case #18 - mutator side (read/write a variable in the mutatee)
787 void mutatorTest18(BPatch_thread *appThread, BPatch_image *appImage)
789 BPatch_variableExpr *expr18_1 =appImage->findVariable("globalVariable18_1");
790 if (expr18_1 == NULL) {
791 fprintf(stderr, "**Failed** test #18 (read/write a variable in the mutatee)\n");
792 fprintf(stderr, " Unable to locate globalVariable18_1\n");
797 expr18_1->readValue(&n);
800 fprintf(stderr, "**Failed** test #18 (read/write a variable in the mutatee)\n");
801 fprintf(stderr, " value read from globalVariable18_1 was %d, not 42 as expected\n", n);
806 expr18_1->writeValue(&n);
809 void mutatorMAIN(char *pathname, bool useAttach)
811 BPatch_thread *appThread;
813 // Create an instance of the bpatch library
817 printf("Starting \"%s\"\n", pathname);
822 child_argv[n++] = pathname;
823 if (useAttach) child_argv[n++] = "-attach";
824 if (debugPrint) child_argv[n++] = "-verbose";
825 child_argv[n] = NULL;
828 int pid = startNewProcess(pathname, child_argv);
830 printf("*ERROR*: unable to start tests due to error creating mutatee process\n");
834 appThread = bpatch->attachProcess(pathname, pid);
836 appThread = bpatch->createProcess(pathname, child_argv);
839 if (appThread == NULL) {
840 fprintf(stderr, "Unable to run test program.\n");
844 // Read the program's image and get an associated image object
845 BPatch_image *appImage = appThread->getImage();
847 // Signal the child that we've attached
849 signalAttached(appThread, appImage);
852 BPatch_Vector<BPatch_module *> *m = appImage->getModules();
853 for (i=0; i < m->size(); i++) {
854 // dprintf("func %s\n", (*m)[i]->name());
856 BPatch_Vector<BPatch_function *> *p1 = (*m)[0]->getProcedures();
858 BPatch_Vector<BPatch_function *> *p = appImage->getProcedures();
859 for (i=0; i < p->size(); i++) {
860 // dprintf("func %s\n", (*p)[i]->name());
863 // Start Test Case #1 - mutator side (call a zero argument function)
865 // Find the entry point to the procedure "func1_1"
866 BPatch_Vector<BPatch_point *> *point1_1 =
867 appImage->findProcedurePoint("func1_1", BPatch_entry);
869 if ((*point1_1).size() == 0) {
870 fprintf(stderr, "**Failed** test #1 (zero arg function call)\n");
871 fprintf(stderr, " Unable to find entry point to \"func1_1.\"\n");
875 BPatch_function *call1_func = appImage->findFunction("call1_1");
876 if (call1_func == NULL) {
877 fprintf(stderr, "**Failed** test #1 (zero arg function call)\n");
878 fprintf(stderr, "Unable to find function \"call1_1\"\n");
882 BPatch_Vector<BPatch_snippet *> call1_args;
883 BPatch_funcCallExpr call1Expr(*call1_func, call1_args);
885 dprintf("Inserted snippet2\n");
886 checkCost(call1Expr);
887 appThread->insertSnippet(call1Expr, *point1_1);
891 // Start Test Case #2 - mutator side (call a three argument function)
894 // Find the entry point to the procedure "func2_1"
895 BPatch_Vector<BPatch_point *> *point2_1 =
896 appImage->findProcedurePoint("func2_1", BPatch_entry);
898 if (!point2_1 || ((*point2_1).size() == 0)) {
899 fprintf(stderr, "**Failed** test #2 (three parameter function)\n");
900 fprintf(stderr, " Unable to find entry point to \"func2_1.\"\n");
904 BPatch_function *call2_func = appImage->findFunction("call2_1");
905 if (call2_func == NULL) {
906 fprintf(stderr, "**Failed** test #2 (three parameter function)\n");
907 fprintf(stderr, " Unable to find function \"call2_1.\"\n");
911 BPatch_Vector<BPatch_snippet *> call2_args;
912 BPatch_constExpr expr2_1(1);
913 BPatch_constExpr expr2_2(2);
914 BPatch_constExpr expr2_3("testString2_1");
915 call2_args.push_back(&expr2_1);
916 call2_args.push_back(&expr2_2);
917 call2_args.push_back(&expr2_3);
919 BPatch_funcCallExpr call2Expr(*call2_func, call2_args);
921 dprintf("Inserted snippet2\n");
922 checkCost(call2Expr);
923 appThread->insertSnippet(call2Expr, *point2_1);
926 // Start Test Case #3 - mutator side (passing variables to function)
929 // Find the entry point to the procedure "func3_1"
930 BPatch_Vector<BPatch_point *> *point3_1 =
931 appImage->findProcedurePoint("func3_1", BPatch_entry);
933 if (!point3_1 || ((*point3_1).size() == 0)) {
934 fprintf(stderr, "Unable to find entry point to \"func3_1.\"\n");
938 BPatch_function *call3_func = appImage->findFunction("call3_1");
939 if (call3_func == NULL) {
940 fprintf(stderr, "Unable to find function \"call3_1.\"\n");
944 BPatch_Vector<BPatch_snippet *> call3_args;
946 BPatch_variableExpr *expr3_1 = appImage->findVariable("globalVariable3_1");
948 fprintf(stderr, "**Failed** test #3 (passing variables)\n");
949 fprintf(stderr, " Unable to locate variable globalVariable3_1\n");
952 // see if we can find the address
953 if (expr3_1->getBaseAddr() <= 0) {
954 printf("*Error*: address %d for globalVariable3_1 is not valid\n",
955 (int) expr3_1->getBaseAddr());
958 BPatch_variableExpr *expr3_2 = appThread->malloc(*appImage->findType("int"));
960 fprintf(stderr, "**Failed** test #3 (passing variables)\n");
961 fprintf(stderr, " Unable to create new int variable\n");
965 call3_args.push_back(expr3_1);
966 call3_args.push_back(expr3_2);
968 BPatch_funcCallExpr call3Expr(*call3_func, call3_args);
969 checkCost(call3Expr);
970 appThread->insertSnippet(call3Expr, *point3_1);
972 BPatch_arithExpr expr3_3(BPatch_assign, *expr3_2, BPatch_constExpr(32));
974 appThread->insertSnippet(expr3_3, *point3_1);
976 dprintf("Inserted snippet3\n");
979 // Start Test Case #4 - mutator side (sequence)
982 // Find the entry point to the procedure "func4_1"
983 BPatch_Vector<BPatch_point *> *point4_1 =
984 appImage->findProcedurePoint("func4_1", BPatch_entry);
987 BPatch_variableExpr *expr4_1 = appImage->findVariable("globalVariable4_1");
989 fprintf(stderr, "**Failed** test #4 (sequence)\n");
990 fprintf(stderr, " Unable to locate variable globalVariable4_1\n");
994 BPatch_arithExpr expr4_2(BPatch_assign, *expr4_1, BPatch_constExpr(42));
995 BPatch_arithExpr expr4_3(BPatch_assign, *expr4_1, BPatch_constExpr(43));
997 BPatch_Vector<BPatch_snippet*> vect4_1;
998 vect4_1.push_back(&expr4_2);
999 vect4_1.push_back(&expr4_3);
1001 BPatch_sequence expr4_4(vect4_1);
1003 appThread->insertSnippet(expr4_4, *point4_1);
1006 // Start Test Case #5 - mutator side (if w.o. else)
1009 // Find the entry point to the procedure "func5_1"
1010 BPatch_Vector<BPatch_point *> *point5_1 =
1011 appImage->findProcedurePoint("func5_1", BPatch_entry);
1012 BPatch_variableExpr *expr5_1 = appImage->findVariable("globalVariable5_1");
1013 BPatch_variableExpr *expr5_2 = appImage->findVariable("globalVariable5_2");
1014 if (!expr5_1 || !expr5_2) {
1015 fprintf(stderr, "**Failed** test #5 (1f w.o. else)\n");
1016 fprintf(stderr, " Unable to locate variable globalVariable5_1 or ");
1017 fprintf(stderr, " variable globalVariable5_2\n");
1021 BPatch_Vector<BPatch_snippet*> vect5_1;
1023 // if (0 == 1) globalVariable5_1 = 52;
1024 BPatch_ifExpr expr5_3(
1025 BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0), BPatch_constExpr(1)),
1026 BPatch_arithExpr(BPatch_assign, *expr5_1, BPatch_constExpr(52)));
1028 // if (1 == 1) globalVariable5_2 = 53;
1029 BPatch_ifExpr expr5_4(
1030 BPatch_boolExpr(BPatch_eq, BPatch_constExpr(1), BPatch_constExpr(1)),
1031 BPatch_arithExpr(BPatch_assign, *expr5_2, BPatch_constExpr(53)));
1033 vect5_1.push_back(&expr5_3);
1034 vect5_1.push_back(&expr5_4);
1036 BPatch_sequence expr5_5(vect5_1);
1038 appThread->insertSnippet(expr5_5, *point5_1);
1040 mutatorTest6(appThread, appImage);
1042 mutatorTest7(appThread, appImage);
1044 mutatorTest8(appThread, appImage);
1046 mutatorTest9(appThread, appImage);
1048 mutatorTest10(appThread, appImage);
1050 mutatorTest11(appThread, appImage);
1052 mutatorTest12a(appThread, appImage);
1054 mutatorTest13(appThread, appImage);
1056 mutatorTest14(appThread, appImage);
1058 mutatorTest15a(appThread, appImage);
1060 mutatorTest16(appThread, appImage);
1062 mutatorTest17(appThread, appImage);
1064 mutatorTest18(appThread, appImage);
1066 // Start of code to continue the process.
1067 dprintf("starting program execution.\n");
1068 appThread->continueExecution();
1070 mutatorTest12b(appThread, appImage);
1072 mutatorTest15b(appThread, appImage);
1074 while (!appThread->isTerminated())
1075 waitForStatusChange();
1081 // main - decide our role and call the correct "main"
1083 main(int argc, char *argv[])
1085 bool useAttach = false;
1087 for (int i=1; i < argc; i++) {
1088 if (!strcmp(argv[i], "-verbose")) {
1090 } else if (!strcmp(argv[i], "-attach")) {
1093 fprintf(stderr, "Usage: test1 [-attach] [-verbose]\n");
1098 #if defined(sparc_sun_sunos4_1_3)
1100 printf("Attach is not supported on this platform.\n");
1106 #ifdef i386_unknown_nt4_0
1107 mutatorMAIN("test1.mutatee.exe", useAttach);
1109 mutatorMAIN("./test1.mutatee", useAttach);