Added features to the dyninst API library, including an optional "else"
[dyninst.git] / dyninstAPI / tests / src / test1.C
1
2 //
3 // libdyninst validation suite test #1
4 //    Author: Jeff Hollingsworth (1/7/97)
5 //        derived from a previous test by Bryan Buck
6 //
7
8 //  This program tests the basic features of the dyninst API.  
9 //      The mutatee that goes with this file is test1.mutatee.c
10 //      
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.
16 //
17
18 #include <stdio.h>
19 #include <signal.h>
20
21 #include "BPatch.h"
22 #include "BPatch_Vector.h"
23 #include "BPatch_thread.h"
24 #include "BPatch_snippet.h"
25
26 int debugPrint = 0;
27
28 BPatch *bpatch;
29
30 // control debug printf statements
31 #define dprintf if (debugPrint) printf
32
33 /**************************************************************************
34  * Utility functions
35  **************************************************************************/
36
37 //
38 // Replace all calls in "inFunction" to "callTo" with calls to "replacement."
39 // If "replacement" is NULL, them use removeFunctionCall instead of
40 // replaceFunctionCall.
41 // Returns the number of replacements that were performed.
42 //
43 int replaceFunctionCalls(BPatch_thread *appThread, BPatch_image *appImage,
44                          char *inFunction, char *callTo, char *replacement,
45                          int testNo, char *testName,
46                          int callsExpected = -1)
47 {
48     int numReplaced = 0;
49
50     BPatch_Vector<BPatch_point *> *points =
51         appImage->findProcedurePoint(inFunction, BPatch_subroutine);
52     if (!points) {
53         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
54         fprintf(stderr, "    Unable to find point %s - subroutine calls\n",
55                 inFunction);
56         exit(1);
57     }
58
59     BPatch_function *call_replacement;
60     if (replacement != NULL) {
61         call_replacement = appImage->findFunction(replacement);
62         if (call_replacement == NULL) {
63             fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
64             fprintf(stderr, "    Unable to find function %s\n", replacement);
65             exit(1);
66         }
67     }
68
69     for (int n = 0; n < points->size(); n++) {
70         BPatch_function *func;
71         if ((func = (*points)[n]->getCalledFunction()) == NULL) {
72             fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
73             fprintf(stderr, "    Can't get called function in %s\n",
74                     inFunction);
75             exit(1);
76         }
77         char fn[256];
78         if (func->getName(fn, 256) == NULL) {
79             fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
80             fprintf(stderr, "    Can't get name of called function in %s\n",
81                     inFunction);
82             exit(1);
83         }
84         if (strcmp(fn, callTo) == 0) {
85             if (replacement == NULL)
86                 appThread->removeFunctionCall(*((*points)[n]));
87             else
88                 appThread->replaceFunctionCall(*((*points)[n]),
89                                                *call_replacement);
90             numReplaced++;
91         }
92     }
93
94     if (callsExpected > 0 && callsExpected != numReplaced) {
95         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
96         fprintf(stderr, "    Expected to find %d %s to %s in %s, found %d\n",
97                 callsExpected, callsExpected == 1 ? "call" : "calls",
98                 callTo, inFunction, numReplaced);
99         exit(1);
100     }
101
102
103     return numReplaced;
104 }
105
106
107 //
108 // Return a pointer to a string identifying a BPatch_procedureLocation
109 //
110 char *locationName(BPatch_procedureLocation l)
111 {
112     switch(l) {
113       case BPatch_entry:
114         return "entry";
115       case BPatch_exit:
116         return "exit";
117       case BPatch_subroutine:
118         return "call points";
119       case BPatch_longJump:
120         return "long jump";
121       case BPatch_allLocations:
122         return "all";
123       default:
124         return "<invalid BPatch_procedureLocation>";
125     };
126 }
127
128
129 //
130 // Insert "snippet" at the location "loc" in the function "inFunction."
131 // Returns the value returned by BPatch_thread::insertSnippet.
132 //
133 BPatchSnippetHandle *insertSnippetAt(BPatch_thread *appThread,
134         BPatch_image *appImage, char *inFunction, BPatch_procedureLocation loc,
135         BPatch_snippet &snippet, int testNo, char *testName)
136 {
137     // Find the point(s) we'll be instrumenting
138     BPatch_Vector<BPatch_point *> *points =
139         appImage->findProcedurePoint(inFunction, loc);
140
141     if (!points) {
142         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
143         fprintf(stderr, "    Unable to find point %s - %s\n",
144                 inFunction, locationName(loc));
145         exit(-1);
146     }
147
148     return appThread->insertSnippet(snippet, *points);
149 }
150
151 //
152 // Create a snippet that calls the function "funcName" with no arguments
153 //
154 BPatch_snippet *makeCallSnippet(BPatch_image *appImage, char *funcName,
155                                 int testNo, char *testName)
156 {
157     BPatch_function *call_func = appImage->findFunction(funcName);
158     if (call_func == NULL) {
159         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
160         fprintf(stderr, "    Unable to find function %s\n", funcName);
161         exit(1);
162     }
163
164     BPatch_Vector<BPatch_snippet *> nullArgs;
165     BPatch_snippet *ret = new BPatch_funcCallExpr(*call_func, nullArgs);
166
167     if (ret == NULL) {
168         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
169         fprintf(stderr, "    Unable to create snippet to call %s\n", funcName);
170         exit(1);
171     }
172
173     return ret;
174 }
175
176 //
177 // Insert a snippet to call function "funcName" with no arguments into the
178 // procedure "inFunction" at the points given by "loc."
179 //
180 BPatchSnippetHandle *insertCallSnippetAt(BPatch_thread *appThread,
181         BPatch_image *appImage, char *inFunction, BPatch_procedureLocation loc,
182         char *funcName, int testNo, char *testName)
183 {
184     BPatch_snippet *call_expr =
185         makeCallSnippet(appImage, funcName, testNo, testName);
186
187     BPatchSnippetHandle *ret = insertSnippetAt(appThread, appImage,
188                                                inFunction, loc, *call_expr,
189                                                testNo, testName);
190     if (ret == NULL) {
191         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
192         fprintf(stderr, "    Unable to insert snippet to call function %s\n",
193                 funcName);
194         exit(-1);
195     }
196
197     delete call_expr;
198     
199     return ret;
200 }
201
202 //
203 // Wait for the mutatee to stop.
204 //
205 void waitUntilStopped(BPatch_thread *appThread, int testnum, char *testname)
206 {
207     // Wait for process to stop
208     while (!appThread->isStopped() && !appThread->isTerminated()) ;
209     if (!appThread->isStopped()) {
210         printf("**Failed test #%d (%s)\n", testnum, testname);
211         printf("    process did not signal mutator via SIGSTOP\n");
212         exit(-1);
213     } else if (appThread->stopSignal() != SIGSTOP) {
214         printf("**Failed test #%d (%s)\n", testnum, testname);
215         printf("    process stopped on signal %d, not SIGSTOP\n", 
216                 appThread->stopSignal());
217         exit(-1);
218     }
219 }
220
221 /**************************************************************************
222  * Tests
223  **************************************************************************/
224
225 //
226 // Start Test Case #6 - mutator side (arithmetic operators)
227 //
228 void mutatorTest6(BPatch_thread *appThread, BPatch_image *appImage)
229 {
230     // Find the entry point to the procedure "func6_1"
231     BPatch_Vector<BPatch_point *> *point6_1 =
232         appImage->findProcedurePoint("func6_1", BPatch_entry);
233     BPatch_variableExpr *expr6_1 = appImage->findVariable("globalVariable6_1");
234     BPatch_variableExpr *expr6_2 = appImage->findVariable("globalVariable6_2");
235     BPatch_variableExpr *expr6_3 = appImage->findVariable("globalVariable6_3");
236     BPatch_variableExpr *expr6_4 = appImage->findVariable("globalVariable6_4");
237     BPatch_variableExpr *expr6_5 = appImage->findVariable("globalVariable6_5");
238     BPatch_variableExpr *expr6_6 = appImage->findVariable("globalVariable6_6");
239     if (!expr6_1 || !expr6_2 || !expr6_3 || !expr6_4 || 
240         !expr6_5 || !expr6_6) {
241         fprintf(stderr, "**Failed** test #6 (arithmetic operators)\n");
242         fprintf(stderr, "    Unable to locate one of globalVariable6_?\n");
243         exit(1);
244     }
245
246     BPatch_Vector<BPatch_snippet*> vect6_1;
247
248     // globalVariable6_1 = 60 + 2
249     BPatch_arithExpr arith6_1 (BPatch_assign, *expr6_1, 
250       BPatch_arithExpr(BPatch_plus,BPatch_constExpr(60), BPatch_constExpr(2)));
251     vect6_1.push_back(&arith6_1);
252
253     // globalVariable6_2 = 64 - 1
254     BPatch_arithExpr arith6_2 (BPatch_assign, *expr6_2, 
255       BPatch_arithExpr(BPatch_minus,BPatch_constExpr(64),BPatch_constExpr(1)));
256     vect6_1.push_back(&arith6_2);
257
258     // globalVariable6_3 = 66 / 3
259     BPatch_arithExpr arith6_3 (BPatch_assign, *expr6_3, BPatch_arithExpr(
260       BPatch_divide,BPatch_constExpr(66),BPatch_constExpr(3)));
261     vect6_1.push_back(&arith6_3);
262
263     // globalVariable6_4 = 67 / 3
264     BPatch_arithExpr arith6_4 (BPatch_assign, *expr6_4, BPatch_arithExpr(
265       BPatch_divide,BPatch_constExpr(67),BPatch_constExpr(3)));
266     vect6_1.push_back(&arith6_4);
267
268     // globalVariable6_5 = 6 * 5
269     BPatch_arithExpr arith6_5 (BPatch_assign, *expr6_5, BPatch_arithExpr(
270       BPatch_times,BPatch_constExpr(6),BPatch_constExpr(5)));
271     vect6_1.push_back(&arith6_5);
272
273     // globalVariable6_6 = 10,3
274     BPatch_arithExpr arith6_6 (BPatch_assign, *expr6_6, 
275         BPatch_arithExpr(BPatch_seq,BPatch_constExpr(10),BPatch_constExpr(3)));
276     vect6_1.push_back(&arith6_6);
277
278     appThread->insertSnippet( BPatch_sequence(vect6_1), *point6_1);
279 }
280
281 void genRelTest(BPatch_image *appImage,BPatch_Vector<BPatch_snippet*> &vect7_1, 
282                 BPatch_relOp op, int r1, int r2, char *var1)
283 {
284     BPatch_variableExpr *varExpr1 = appImage->findVariable(var1);
285     if (!varExpr1) {
286         fprintf(stderr, "**Failed** test #7 (relational operators)\n");
287         fprintf(stderr, "    Unable to locate variable %s\n", var1);
288         exit(1);
289     }
290     BPatch_ifExpr *tempExpr1 = new BPatch_ifExpr(
291         BPatch_boolExpr(op, BPatch_constExpr(r1), BPatch_constExpr(r2)), 
292         BPatch_arithExpr(BPatch_assign, *varExpr1, BPatch_constExpr(72)));
293     vect7_1.push_back(tempExpr1);
294
295 }
296
297 //
298 // Start Test Case #7 - mutator side (relational operators)
299 //
300 void mutatorTest7(BPatch_thread *appThread, BPatch_image *appImage)
301 {
302     // Find the entry point to the procedure "func7_1"
303     BPatch_Vector<BPatch_point *> *point7_1 =
304         appImage->findProcedurePoint("func7_1", BPatch_entry);
305     BPatch_Vector<BPatch_snippet*> vect7_1;
306
307     genRelTest(appImage, vect7_1, BPatch_lt, 0, 1, "globalVariable7_1");
308     genRelTest(appImage, vect7_1, BPatch_lt, 1, 0, "globalVariable7_2");
309     genRelTest(appImage, vect7_1, BPatch_eq, 2, 2, "globalVariable7_3");
310     genRelTest(appImage, vect7_1, BPatch_eq, 2, 3, "globalVariable7_4");
311     genRelTest(appImage, vect7_1, BPatch_gt, 4, 3, "globalVariable7_5");
312     genRelTest(appImage, vect7_1, BPatch_gt, 3, 4, "globalVariable7_6");
313     genRelTest(appImage, vect7_1, BPatch_le, 3, 4, "globalVariable7_7");
314     genRelTest(appImage, vect7_1, BPatch_le, 4, 3, "globalVariable7_8");
315     genRelTest(appImage, vect7_1, BPatch_ne, 5, 6, "globalVariable7_9");
316     genRelTest(appImage, vect7_1, BPatch_ne, 5, 5, "globalVariable7_10");
317     genRelTest(appImage, vect7_1, BPatch_ge, 9, 7, "globalVariable7_11");
318     genRelTest(appImage, vect7_1, BPatch_ge, 7, 9, "globalVariable7_12");
319     genRelTest(appImage, vect7_1, BPatch_and, 1, 1, "globalVariable7_13");
320     genRelTest(appImage, vect7_1, BPatch_and, 1, 0, "globalVariable7_14");
321     genRelTest(appImage, vect7_1, BPatch_or, 1, 0, "globalVariable7_15");
322     genRelTest(appImage, vect7_1, BPatch_or, 0, 0, "globalVariable7_16");
323
324     dprintf("relops test vector length is %d\n", vect7_1.size());
325
326     appThread->insertSnippet( BPatch_sequence(vect7_1), *point7_1);
327 }
328
329 //
330 // Start Test Case #8 - mutator side (preserve registers - expr)
331 //
332 void mutatorTest8(BPatch_thread *appThread, BPatch_image *appImage)
333 {
334     // Find the entry point to the procedure "func8_1"
335     BPatch_Vector<BPatch_point *> *point8_1 =
336         appImage->findProcedurePoint("func8_1", BPatch_entry);
337     BPatch_Vector<BPatch_snippet*> vect8_1;
338
339     BPatch_variableExpr *expr8_1 = appImage->findVariable("globalVariable8_1");
340     if (!expr8_1) {
341         fprintf(stderr, "**Failed** test #3 (passing variables)\n");
342         fprintf(stderr, "    Unable to locate variable globalVariable8_1\n");
343         exit(1);
344     }
345
346     BPatch_arithExpr arith8_1 (BPatch_assign, *expr8_1, 
347       BPatch_arithExpr(BPatch_plus, 
348             BPatch_arithExpr(BPatch_plus, 
349                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(81), 
350                                               BPatch_constExpr(82)),
351                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(83), 
352                                               BPatch_constExpr(84))),
353             BPatch_arithExpr(BPatch_plus, 
354                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(85), 
355                                               BPatch_constExpr(86)),
356                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(87), 
357                                               BPatch_constExpr(88)))));
358     vect8_1.push_back(&arith8_1);
359
360     appThread->insertSnippet( BPatch_sequence(vect8_1), *point8_1);
361 }
362
363 //
364 // Start Test Case #9 - mutator side (preserve registers - funcCall)
365 //
366 void mutatorTest9(BPatch_thread *appThread, BPatch_image *appImage)
367 {
368     // Find the entry point to the procedure "func9_1"
369     BPatch_Vector<BPatch_point *> *point9_1 =
370         appImage->findProcedurePoint("func9_1", BPatch_entry);
371
372     BPatch_function *call9_func = appImage->findFunction("call9_1");
373     if (call9_func == NULL) {
374         fprintf(stderr, "Unable to find function \"call9_1.\"\n");
375         exit(1);
376     }
377
378     BPatch_Vector<BPatch_snippet *> call9_args;
379
380     BPatch_constExpr constExpr91(91);
381     call9_args.push_back(&constExpr91);
382
383     BPatch_constExpr constExpr92(92);
384     call9_args.push_back(&constExpr92);
385
386     BPatch_constExpr constExpr93(93);
387     call9_args.push_back(&constExpr93);
388
389     BPatch_constExpr constExpr94(94);
390     call9_args.push_back(&constExpr94);
391
392     BPatch_constExpr constExpr95(95);
393     call9_args.push_back(&constExpr95);
394
395     BPatch_funcCallExpr call9Expr(*call9_func, call9_args);
396
397     appThread->insertSnippet( call9Expr, *point9_1);
398 }
399
400
401 //
402 // Start Test Case #10 - mutator side (insert snippet order)
403 //
404 void mutatorTest10(BPatch_thread *appThread, BPatch_image *appImage)
405 {
406     // Find the entry point to the procedure "func10_1"
407     BPatch_Vector<BPatch_point *> *point10_1 =
408         appImage->findProcedurePoint("func10_1", BPatch_entry);
409
410     BPatch_function *call10_1_func = appImage->findFunction("call10_1");
411     if (call10_1_func == NULL) {
412         fprintf(stderr, "Unable to find function \"call10_1.\"\n");
413         exit(1);
414     }
415
416     BPatch_function *call10_2_func = appImage->findFunction("call10_2");
417     if (call10_2_func == NULL) {
418         fprintf(stderr, "Unable to find function \"call10_2.\"\n");
419         exit(1);
420     }
421
422     BPatch_function *call10_3_func = appImage->findFunction("call10_3");
423     if (call10_3_func == NULL) {
424         fprintf(stderr, "Unable to find function \"call10_3.\"\n");
425         exit(1);
426     }
427
428     BPatch_Vector<BPatch_snippet *> nullArgs;
429     BPatch_funcCallExpr call10_1Expr(*call10_1_func, nullArgs);
430     BPatch_funcCallExpr call10_2Expr(*call10_2_func, nullArgs);
431     BPatch_funcCallExpr call10_3Expr(*call10_3_func, nullArgs);
432
433     appThread->insertSnippet( call10_2Expr, *point10_1);
434     appThread->insertSnippet( call10_1Expr, *point10_1, BPatch_callBefore, 
435                                                         BPatch_firstSnippet);
436     appThread->insertSnippet( call10_3Expr, *point10_1, BPatch_callBefore, 
437                                                         BPatch_lastSnippet);
438 }
439
440
441 //
442 // Start Test Case #11 - mutator side (snippets at entry,exit,call)
443 //
444 void mutatorTest11(BPatch_thread *appThread, BPatch_image *appImage)
445 {
446     // Find the entry point to the procedure "func11_1"
447     BPatch_Vector<BPatch_point *> *point11_1 =
448         appImage->findProcedurePoint("func11_1", BPatch_entry);
449     if (!point11_1) {
450         fprintf(stderr, "Unable to find point func11_1 - entry.\n");
451         exit(-1);
452     }
453
454     // Find the subroutine points for the procedure "func11_1"
455     BPatch_Vector<BPatch_point *> *point11_2 =
456         appImage->findProcedurePoint("func11_1", BPatch_subroutine);
457     if (!point11_2) {
458         fprintf(stderr, "Unable to find point func11_1 - calls.\n");
459         exit(-1);
460     }
461
462     // Find the exit point to the procedure "func11_1"
463     BPatch_Vector<BPatch_point *> *point11_3 =
464         appImage->findProcedurePoint("func11_1", BPatch_exit);
465     if (!point11_3) {
466         fprintf(stderr, "Unable to find point func11_1 - exit.\n");
467         exit(-1);
468     }
469
470     BPatch_function *call11_1_func = appImage->findFunction("call11_1");
471     if (call11_1_func == NULL) {
472         fprintf(stderr, "Unable to find function \"call11_1.\"\n");
473         exit(1);
474     }
475
476     BPatch_function *call11_2_func = appImage->findFunction("call11_2");
477     if (call11_2_func == NULL) {
478         fprintf(stderr, "Unable to find function \"call11_2.\"\n");
479         exit(1);
480     }
481
482     BPatch_function *call11_3_func = appImage->findFunction("call11_3");
483     if (call11_3_func == NULL) {
484         fprintf(stderr, "Unable to find function \"call11_3.\"\n");
485         exit(1);
486     }
487
488     BPatch_function *call11_4_func = appImage->findFunction("call11_4");
489     if (call11_4_func == NULL) {
490         fprintf(stderr, "Unable to find function \"call11_4.\"\n");
491         exit(1);
492     }
493
494     BPatch_Vector<BPatch_snippet *> nullArgs;
495     BPatch_funcCallExpr call11_1Expr(*call11_1_func, nullArgs);
496     BPatch_funcCallExpr call11_2Expr(*call11_2_func, nullArgs);
497     BPatch_funcCallExpr call11_3Expr(*call11_3_func, nullArgs);
498     BPatch_funcCallExpr call11_4Expr(*call11_4_func, nullArgs);
499
500     appThread->insertSnippet(call11_1Expr, *point11_1);
501     appThread->insertSnippet(call11_2Expr, *point11_2, BPatch_callBefore);
502     appThread->insertSnippet(call11_3Expr, *point11_2, BPatch_callAfter);
503     appThread->insertSnippet(call11_4Expr, *point11_3);
504
505 }
506
507 BPatchSnippetHandle *snippetHandle12_1;
508 BPatch_variableExpr *varExpr12_1;
509
510 //
511 // Start Test Case #12 - mutator side (insert/remove and malloc/free)
512 //
513 void mutatorTest12a(BPatch_thread *appThread, BPatch_image *appImage)
514 {
515     // Find the entry point to the procedure "func12_2"
516     BPatch_Vector<BPatch_point *> *point12_2 =
517         appImage->findProcedurePoint("func12_2", BPatch_entry);
518     if (!point12_2) {
519         fprintf(stderr, "Unable to find point func12_2 - entry.\n");
520         exit(-1);
521     }
522
523     varExpr12_1 = appThread->malloc(100);
524     if (!varExpr12_1) {
525         fprintf(stderr, "Unable to allocate 100 bytes in mutatee\n");
526         exit(-1);
527     }
528
529     BPatch_function *call12_1_func = appImage->findFunction("call12_1");
530     if (call12_1_func == NULL) {
531         fprintf(stderr, "Unable to find function \"call12_1.\"\n");
532         exit(1);
533     }
534
535     BPatch_Vector<BPatch_snippet *> nullArgs;
536     BPatch_funcCallExpr call12_1Expr(*call12_1_func, nullArgs);
537     snippetHandle12_1 = appThread->insertSnippet(call12_1Expr, *point12_2);
538     if (!snippetHandle12_1) {
539         fprintf(stderr,
540                 "Unable to insert snippet to call function \"call12_1.\"\n");
541         exit(-1);
542     }
543 }
544
545 void mutatorTest12b(BPatch_thread *appThread, BPatch_image */*appImage*/)
546 {
547     while (!appThread->isStopped() && !appThread->isTerminated()) ;
548     if (appThread->stopSignal() == SIGSTOP) {
549         // remove instrumentation and free memory
550         if (!appThread->deleteSnippet(snippetHandle12_1)) {
551             printf("**Failed test #12 (insert/remove and malloc/free)\n");
552             printf("    deleteSnippet returned an error\n");
553             exit(-1);
554         }
555         appThread->free(*varExpr12_1);
556
557         // continue process
558         appThread->continueExecution();
559     } else if (appThread->isStopped()) {
560         printf("**Failed test #12 (insert/remove and malloc/free)\n");
561         printf("    process stopped on signal %d, not SIGSTOP\n", 
562                 appThread->stopSignal());
563         exit(-1);
564     } else {
565         printf("**Failed test #12 (insert/remove and malloc/free)\n");
566         printf("    process did not signal mutator via SIGSTOP\n");
567         exit(-1);
568     }
569 }
570
571
572 //
573 // Start Test Case #13 - mutator side (paramExpr,nullExpr)
574 //
575 void mutatorTest13(BPatch_thread *appThread, BPatch_image *appImage)
576 {
577     // Find the entry point to the procedure "func13_1"
578     BPatch_Vector<BPatch_point *> *point13_1 =
579         appImage->findProcedurePoint("func13_1", BPatch_entry);
580     if (!point13_1) {
581         fprintf(stderr, "Unable to find point func13_1 - entry.\n");
582         exit(-1);
583     }
584
585     BPatch_function *call13_1_func = appImage->findFunction("call13_1");
586     if (call13_1_func == NULL) {
587         fprintf(stderr, "Unable to find function \"call13_1.\"\n");
588         exit(1);
589     }
590
591     BPatch_Vector<BPatch_snippet *> funcArgs;
592     funcArgs.push_back(new BPatch_paramExpr(0));
593     funcArgs.push_back(new BPatch_paramExpr(1));
594     funcArgs.push_back(new BPatch_paramExpr(2));
595     funcArgs.push_back(new BPatch_paramExpr(3));
596     funcArgs.push_back(new BPatch_paramExpr(4));
597     BPatch_funcCallExpr call13_1Expr(*call13_1_func, funcArgs);
598     BPatch_nullExpr call13_2Expr;
599
600     appThread->insertSnippet(call13_1Expr, *point13_1);
601     // This causes a crash right now jkh 3/7/97
602     // appThread->insertSnippet(call13_2Expr, *point13_1);
603 }
604
605
606 //
607 // Start Test Case #14 - mutator side (replace function call)
608 //
609 void mutatorTest14(BPatch_thread *appThread, BPatch_image *appImage)
610 {
611     replaceFunctionCalls(appThread, appImage,
612                          "func14_1", "func14_2", "call14_1",
613                          14, "replace/remove function call", 1);
614     replaceFunctionCalls(appThread, appImage,
615                          "func14_1", "func14_3", NULL,
616                          14, "replace/remove function call", 1);
617 }
618
619
620 //
621 // Start Test Case #15 - mutator side (setMutationsActive)
622 //
623 void mutatorTest15a(BPatch_thread *appThread, BPatch_image *appImage)
624 {
625     insertCallSnippetAt(appThread, appImage, "func15_2", BPatch_entry,
626                         "call15_1", 15, "setMutationsActive");
627
628 #if defined(sparc_sun_sunos4_1_3) || defined(sparc_sun_solaris2_4)
629     // On the Sparc, functions containing system calls are relocated into the
630     // heap when instrumented, making a special case we should check.
631
632     // "access" makes the "access" system call, so we'll instrument it
633     insertCallSnippetAt(appThread, appImage, "access", BPatch_entry,
634                         "call15_2", 15, "setMutationsActive");
635     // We want to instrument more than one point, so do exit as well
636     insertCallSnippetAt(appThread, appImage, "access", BPatch_exit,
637                         "call15_2", 15, "setMutationsActive");
638 #endif
639
640     replaceFunctionCalls(appThread, appImage, "func15_4", "func15_3",
641                          "call15_3", 15, "setMutationsActive", 1);
642 }
643
644
645 void mutatorTest15b(BPatch_thread *appThread, BPatch_image */*appImage*/)
646 {
647     waitUntilStopped(appThread, 15, "setMutationsActive");
648
649     // disable mutations and continue process
650     appThread->setMutationsActive(false);
651     appThread->continueExecution();
652     
653     waitUntilStopped(appThread, 15, "setMutationsActive");
654
655     // re-enable mutations and continue process
656     appThread->setMutationsActive(true);
657     appThread->continueExecution();
658 }
659
660
661 //
662 // Start Test Case #16 - mutator side (if-else)
663 //
664 void mutatorTest16(BPatch_thread *appThread, BPatch_image *appImage)
665 {
666     BPatch_variableExpr *expr16_1=appImage->findVariable("globalVariable16_1");
667     BPatch_variableExpr *expr16_2=appImage->findVariable("globalVariable16_2");
668     BPatch_variableExpr *expr16_3=appImage->findVariable("globalVariable16_3");
669     BPatch_variableExpr *expr16_4=appImage->findVariable("globalVariable16_4");
670     if (!expr16_1 || !expr16_2 || !expr16_3 || !expr16_4) {
671         fprintf(stderr, "**Failed** test #16 (if-else)\n");
672         fprintf(stderr, "    Unable to locate one of globalVariable16_?\n");
673         exit(1);
674     }
675
676     BPatch_arithExpr assign16_1(BPatch_assign, *expr16_1, BPatch_constExpr(1));
677     BPatch_arithExpr assign16_2(BPatch_assign, *expr16_2, BPatch_constExpr(1));
678
679     BPatch_ifExpr if16_2(BPatch_boolExpr(BPatch_eq,
680                                          BPatch_constExpr(1),
681                                          BPatch_constExpr(1)),
682                          assign16_1, assign16_2);
683
684     BPatch_arithExpr assign16_3(BPatch_assign, *expr16_3, BPatch_constExpr(1));
685     BPatch_arithExpr assign16_4(BPatch_assign, *expr16_4, BPatch_constExpr(1));
686
687     BPatch_ifExpr if16_3(BPatch_boolExpr(BPatch_eq,
688                                          BPatch_constExpr(0),
689                                          BPatch_constExpr(1)),
690                          assign16_3, assign16_4);
691
692     insertSnippetAt(appThread, appImage, "func16_2", BPatch_entry, if16_2,
693                     16, "if-else");
694     insertSnippetAt(appThread, appImage, "func16_3", BPatch_entry, if16_3,
695                     16, "if-else");
696 }
697
698
699 void mutatorMAIN(char *pathname)
700 {
701     // Create an instance of the bpatch library
702     bpatch = new BPatch;
703
704     // Start the mutatee
705     printf("Starting \"%s\"\n", pathname);
706
707     char *child_argv[] = { pathname, "-verbose", NULL };
708     if (!debugPrint) {
709         // null out the verbose mode if not enabled.
710         child_argv[1] = NULL;
711     }
712     BPatch_thread *appThread =
713         new BPatch_thread(pathname, child_argv, NULL);
714
715     if (appThread->isTerminated()) {
716         fprintf(stderr, "Unable to run test program.\n");
717         exit(1);
718     }
719
720     // Read the program's image and get an associated image object
721     BPatch_image *appImage = appThread->getImage();
722
723     BPatch_Vector<BPatch_function *> *p = appImage->getProcedures();
724     for (int i=0; i < p->size(); i++) {
725         // dprintf("func %s\n", (*p)[i]->name());
726     }
727
728     // Start Test Case #1 - mutator side (call a zero argument function)
729
730     // Find the entry point to the procedure "func1_1"
731     BPatch_Vector<BPatch_point *> *point1_1 =
732         appImage->findProcedurePoint("func1_1", BPatch_entry);
733
734     if ((*point1_1).size() == 0) {
735         fprintf(stderr, "**Failed** test #1 (zero arg function call)\n");
736         fprintf(stderr, "    Unable to find entry point to \"func1_1.\"\n");
737         exit(1);
738     }
739
740     BPatch_function *call1_func = appImage->findFunction("call1_1");
741     if (call1_func == NULL) {
742         fprintf(stderr, "**Failed** test #1 (zero arg function call)\n");
743         fprintf(stderr, "Unable to find function \"call1_1\"\n");
744         exit(1);
745     }
746
747     BPatch_Vector<BPatch_snippet *> call1_args;
748     BPatch_funcCallExpr call1Expr(*call1_func, call1_args);
749
750     dprintf("Inserted snippet2\n");
751     appThread->insertSnippet(call1Expr, *point1_1);
752
753
754     //
755     // Start Test Case #2 - mutator side (call a three argument function)
756     //
757
758     // Find the entry point to the procedure "func2_1"
759     BPatch_Vector<BPatch_point *> *point2_1 =
760         appImage->findProcedurePoint("func2_1", BPatch_entry);
761
762     if (!point2_1 || ((*point2_1).size() == 0)) {
763         fprintf(stderr, "**Failed** test #2 (three parameter function)\n");
764         fprintf(stderr, "    Unable to find entry point to \"func2_1.\"\n");
765         exit(1);
766     }
767
768     BPatch_function *call2_func = appImage->findFunction("call2_1");
769     if (call2_func == NULL) {
770         fprintf(stderr, "**Failed** test #2 (three parameter function)\n");
771         fprintf(stderr, "    Unable to find function \"call2_1.\"\n");
772         exit(1);
773     }
774
775     BPatch_Vector<BPatch_snippet *> call2_args;
776     BPatch_constExpr expr2_1(1);
777     BPatch_constExpr expr2_2(2);
778     BPatch_constExpr expr2_3("testString2_1");
779     call2_args.push_back(&expr2_1);
780     call2_args.push_back(&expr2_2);
781     call2_args.push_back(&expr2_3);
782
783     BPatch_funcCallExpr call2Expr(*call2_func, call2_args);
784
785     dprintf("Inserted snippet2\n");
786     appThread->insertSnippet(call2Expr, *point2_1);
787
788     //
789     // Start Test Case #3 - mutator side (passing variables to function)
790     //
791
792     // Find the entry point to the procedure "func3_1"
793     BPatch_Vector<BPatch_point *> *point3_1 =
794         appImage->findProcedurePoint("func3_1", BPatch_entry);
795
796     if (!point3_1 || ((*point3_1).size() == 0)) {
797         fprintf(stderr, "Unable to find entry point to \"func3_1.\"\n");
798         exit(1);
799     }
800
801     BPatch_function *call3_func = appImage->findFunction("call3_1");
802     if (call3_func == NULL) {
803         fprintf(stderr, "Unable to find function \"call3_1.\"\n");
804         exit(1);
805     }
806
807     BPatch_Vector<BPatch_snippet *> call3_args;
808
809     BPatch_variableExpr *expr3_1 = appImage->findVariable("globalVariable3_1");
810     if (!expr3_1) {
811         fprintf(stderr, "**Failed** test #3 (passing variables)\n");
812         fprintf(stderr, "    Unable to locate variable globalVariable3_1\n");
813         exit(1);
814     }
815
816     BPatch_variableExpr *expr3_2 = appThread->malloc(*appImage->findType("int"));
817     if (!expr3_2) {
818         fprintf(stderr, "**Failed** test #3 (passing variables)\n");
819         fprintf(stderr, "    Unable to create new int variable\n");
820         exit(1);
821     }
822
823     call3_args.push_back(expr3_1);
824     call3_args.push_back(expr3_2);
825
826     BPatch_funcCallExpr call3Expr(*call3_func, call3_args);
827     appThread->insertSnippet(call3Expr, *point3_1);
828
829     BPatch_arithExpr expr3_3(BPatch_assign, *expr3_2, BPatch_constExpr(32));
830     appThread->insertSnippet(expr3_3, *point3_1);
831
832     dprintf("Inserted snippet3\n");
833
834     //
835     // Start Test Case #4 - mutator side (sequence)
836     //
837
838     // Find the entry point to the procedure "func4_1"
839     BPatch_Vector<BPatch_point *> *point4_1 =
840         appImage->findProcedurePoint("func4_1", BPatch_entry);
841
842
843     BPatch_variableExpr *expr4_1 = appImage->findVariable("globalVariable4_1");
844     if (!expr4_1) {
845         fprintf(stderr, "**Failed** test #4 (sequence)\n");
846         fprintf(stderr, "    Unable to locate variable globalVariable4_1\n");
847         exit(1);
848     }
849
850     BPatch_arithExpr expr4_2(BPatch_assign, *expr4_1, BPatch_constExpr(42));
851     BPatch_arithExpr expr4_3(BPatch_assign, *expr4_1, BPatch_constExpr(43));
852
853     BPatch_Vector<BPatch_snippet*> vect4_1;
854     vect4_1.push_back(&expr4_2);
855     vect4_1.push_back(&expr4_3);
856
857     BPatch_sequence expr4_4(vect4_1);
858     appThread->insertSnippet(expr4_4, *point4_1);
859
860     //
861     // Start Test Case #5 - mutator side (if w.o. else)
862     //
863
864     // Find the entry point to the procedure "func5_1"
865     BPatch_Vector<BPatch_point *> *point5_1 =
866         appImage->findProcedurePoint("func5_1", BPatch_entry);
867     BPatch_variableExpr *expr5_1 = appImage->findVariable("globalVariable5_1");
868     BPatch_variableExpr *expr5_2 = appImage->findVariable("globalVariable5_2");
869     if (!expr5_1 || !expr5_2) {
870         fprintf(stderr, "**Failed** test #5 (1f w.o. else)\n");
871         fprintf(stderr, "    Unable to locate variable globalVariable5_1 or ");
872         fprintf(stderr, "    variable globalVariable5_2\n");
873         exit(1);
874     }
875
876     BPatch_Vector<BPatch_snippet*> vect5_1;
877
878     // if (0 == 1) globalVariable5_1 = 52;
879     BPatch_ifExpr expr5_3(
880         BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0), BPatch_constExpr(1)), 
881         BPatch_arithExpr(BPatch_assign, *expr5_1, BPatch_constExpr(52)));
882
883     // if (1 == 1) globalVariable5_2 = 53;
884     BPatch_ifExpr expr5_4(
885         BPatch_boolExpr(BPatch_eq, BPatch_constExpr(1), BPatch_constExpr(1)), 
886         BPatch_arithExpr(BPatch_assign, *expr5_2, BPatch_constExpr(53)));
887
888     vect5_1.push_back(&expr5_3);
889     vect5_1.push_back(&expr5_4);
890
891     BPatch_sequence expr5_5(vect5_1);
892     appThread->insertSnippet(expr5_5, *point5_1);
893
894     mutatorTest6(appThread, appImage);
895
896     mutatorTest7(appThread, appImage);
897
898     mutatorTest8(appThread, appImage);
899
900     mutatorTest9(appThread, appImage);
901
902     mutatorTest10(appThread, appImage);
903
904     mutatorTest11(appThread, appImage);
905
906     mutatorTest12a(appThread, appImage);
907
908     mutatorTest13(appThread, appImage);
909
910     mutatorTest14(appThread, appImage);
911
912     mutatorTest15a(appThread, appImage);
913
914     mutatorTest16(appThread, appImage);
915
916     // Start of code to continue the process.
917     dprintf("starting program execution.\n");
918     appThread->continueExecution();
919
920     mutatorTest12b(appThread, appImage);
921
922     mutatorTest15b(appThread, appImage);
923
924     while (!appThread->isTerminated()) ;
925     dprintf("Done.\n");
926 }
927
928 //
929 // main - decide our role and call the correct "main"
930 //
931 main(int argc, char *argv[])
932 {
933     if (argc == 1) {
934         // become the mutator
935         mutatorMAIN("./test1.mutatee");
936     } else if (argc == 2 && !strcmp(argv[1], "-verbose")) {
937         debugPrint = 1;
938         mutatorMAIN("./test1.mutatee");
939     } else {
940         fprintf(stderr, "Usage: test1 [-verbose]\n");
941         exit(-1);
942     }
943
944     return 0;
945 }