Add BPatch_thread::oneTimeCodeAsync and other changes to support it.
[dyninst.git] / dyninstAPI / tests / src / test1.C
1 // $Id: test1.C,v 1.52 2000/03/22 19:08:48 tikir Exp 
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 <string.h>
20 #include <ctype.h>
21 #include <assert.h>
22 #ifdef i386_unknown_nt4_0
23 #include <windows.h>
24 #include <winbase.h>
25 #else
26 #include <unistd.h>
27 #endif
28
29 #include "BPatch.h"
30 #include "BPatch_Vector.h"
31 #include "BPatch_thread.h"
32 #include "BPatch_snippet.h"
33 #include "test_util.h"
34 #include "test1.h"
35
36 // #include <vector.h>
37
38 int debugPrint = 0; // internal "mutator" tracing
39 int errorPrint = 0; // external "dyninst" tracing (via errorFunc)
40
41 bool forceRelocation = false; // force relocation of functions
42
43 int mutateeCplusplus = 0;
44 int mutateeFortran = 0;
45 int mutateeF77 = 0;
46 bool runAllTests = true;
47 const unsigned int MAX_TEST = 35;
48 bool runTest[MAX_TEST+1];
49 bool passedTest[MAX_TEST+1];
50 int saveWorld = 0;
51
52 template class BPatch_Vector<BPatch_variableExpr*>;
53 template class BPatch_Set<int>;
54
55 BPatch *bpatch;
56
57 static char *mutateeNameRoot = "test1.mutatee";
58 static char *libNameAroot = "libtestA";
59 static char *libNameBroot = "libtestB";
60 char libNameA[64], libNameB[64];
61
62 // control debug printf statements
63 #define dprintf if (debugPrint) printf
64
65 /**************************************************************************
66  * Error callback
67  **************************************************************************/
68
69 #define DYNINST_NO_ERROR -1
70
71 int expectError = DYNINST_NO_ERROR;
72
73 void errorFunc(BPatchErrorLevel level, int num, const char **params)
74 {
75     if (num == 0) {
76         // conditional reporting of warnings and informational messages
77         if (errorPrint) {
78             if (level == BPatchInfo)
79               { if (errorPrint > 1) printf("%s\n", params[0]); }
80             else
81                 printf("%s", params[0]);
82         }
83     } else {
84         // reporting of actual errors
85         char line[256];
86         const char *msg = bpatch->getEnglishErrorString(num);
87         bpatch->formatErrorString(line, sizeof(line), msg, params);
88         
89         if (num != expectError) {
90           if(num != 112)
91             printf("Error #%d (level %d): %s\n", num, level, line);
92         
93             // We consider some errors fatal.
94             if (num == 101) {
95                exit(-1);
96             }
97         }
98     }
99 }
100
101 void createInstPointError(BPatchErrorLevel level, int num, const char **params)
102 {
103     if (num != 117 && num != 118)
104         errorFunc(level, num, params);
105 }
106
107 /**************************************************************************
108  * Utility functions
109  **************************************************************************/
110
111 // check that the cost of a snippet is sane.  Due to differences between
112 //   platforms, it is impossible to check this exactly in a machine independent
113 //   manner.
114 void checkCost(BPatch_snippet snippet)
115 {
116     float cost;
117     BPatch_snippet copy;
118
119     // test copy constructor too.
120     copy = snippet;
121
122     cost = snippet.getCost();
123     dprintf("Snippet cost=%g\n", cost);
124     if (cost < 0.0) {
125         printf("*Error*: negative snippet cost\n");
126     } else if (cost == 0.0) {
127 #if !defined(alpha_dec_osf4_0)
128         printf("*Warning*: zero snippet cost\n");
129 #endif
130     } else if (cost > 0.01) {
131         printf("*Error*: snippet cost of %f, exceeds max expected of 0.1",
132             cost);
133     }
134 }
135
136 int functionNameMatch(char *gotName, char *targetName) 
137 {
138     if (!strcmp(gotName, targetName)) return 0;
139
140     if (!strncmp(gotName, targetName, strlen(targetName)) &&
141         (strlen(targetName) == strlen(gotName)-1) &&
142         (gotName[strlen(targetName)] == '_'))
143         return 0;
144
145     return 1;
146 }
147
148
149 //
150 // Replace all calls in "inFunction" to "callTo" with calls to "replacement."
151 // If "replacement" is NULL, them use removeFunctionCall instead of
152 // replaceFunctionCall.
153 // Returns the number of replacements that were performed.
154 //
155 int replaceFunctionCalls(BPatch_thread *appThread, BPatch_image *appImage,
156                          char *inFunction, char *callTo, char *replacement,
157                          int testNo, char *testName,
158                          int callsExpected = -1)
159 {
160     int numReplaced = 0;
161
162     BPatch_Vector<BPatch_point *> *points =
163         appImage->findProcedurePoint(inFunction, BPatch_subroutine);
164     if (!points || (points->size() < 1)) {
165         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
166         fprintf(stderr, "    Unable to find point %s - subroutine calls\n",
167                 inFunction);
168         exit(1);
169     }
170
171     BPatch_function *call_replacement;
172     if (replacement != NULL) {
173         call_replacement = appImage->findFunction(replacement);
174         if (call_replacement == NULL) {
175             fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
176             fprintf(stderr, "    Unable to find function %s\n", replacement);
177             exit(1);
178         }
179     }
180
181     for (unsigned int n = 0; n < points->size(); n++) {
182         BPatch_function *func;
183
184         if ((func = (*points)[n]->getCalledFunction()) == NULL) continue;
185
186         char fn[256];
187         if (func->getName(fn, 256) == NULL) {
188             fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
189             fprintf(stderr, "    Can't get name of called function in %s\n",
190                     inFunction);
191             exit(1);
192         }
193         if (functionNameMatch(fn, callTo) == 0) {
194             if (replacement == NULL)
195                 appThread->removeFunctionCall(*((*points)[n]));
196             else
197                 appThread->replaceFunctionCall(*((*points)[n]),
198                                                *call_replacement);
199             numReplaced++;
200         }
201     }
202
203     if (callsExpected > 0 && callsExpected != numReplaced) {
204         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
205         fprintf(stderr, "    Expected to find %d %s to %s in %s, found %d\n",
206                 callsExpected, callsExpected == 1 ? "call" : "calls",
207                 callTo, inFunction, numReplaced);
208         exit(1);
209     }
210
211
212     return numReplaced;
213 }
214
215
216 //
217 // Return a pointer to a string identifying a BPatch_procedureLocation
218 //
219 char *locationName(BPatch_procedureLocation l)
220 {
221     switch(l) {
222       case BPatch_entry:
223         return "entry";
224       case BPatch_exit:
225         return "exit";
226       case BPatch_subroutine:
227         return "call points";
228       case BPatch_longJump:
229         return "long jump";
230       case BPatch_allLocations:
231         return "all";
232       default:
233         return "<invalid BPatch_procedureLocation>";
234     };
235 }
236
237
238 //
239 // Insert "snippet" at the location "loc" in the function "inFunction."
240 // Returns the value returned by BPatch_thread::insertSnippet.
241 //
242 BPatchSnippetHandle *insertSnippetAt(BPatch_thread *appThread,
243         BPatch_image *appImage, char *inFunction, BPatch_procedureLocation loc,
244         BPatch_snippet &snippet, int testNo, char *testName)
245 {
246     // Find the point(s) we'll be instrumenting
247     BPatch_Vector<BPatch_point *> *points =
248         appImage->findProcedurePoint(inFunction, loc);
249
250     if (!points) {
251         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
252         fprintf(stderr, "    Unable to find point %s - %s\n",
253                 inFunction, locationName(loc));
254         exit(-1);
255     }
256
257     checkCost(snippet);
258     return appThread->insertSnippet(snippet, *points);
259 }
260
261 //
262 // Create a snippet that calls the function "funcName" with no arguments
263 //
264 BPatch_snippet *makeCallSnippet(BPatch_image *appImage, char *funcName,
265                                 int testNo, char *testName)
266 {
267     BPatch_function *call_func = appImage->findFunction(funcName);
268     if (call_func == NULL) {
269         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
270         fprintf(stderr, "    Unable to find function %s\n", funcName);
271         exit(1);
272     }
273
274     BPatch_Vector<BPatch_snippet *> nullArgs;
275     BPatch_snippet *ret = new BPatch_funcCallExpr(*call_func, nullArgs);
276
277     if (ret == NULL) {
278         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
279         fprintf(stderr, "    Unable to create snippet to call %s\n", funcName);
280         exit(1);
281     }
282
283     return ret;
284 }
285
286 //
287 // Insert a snippet to call function "funcName" with no arguments into the
288 // procedure "inFunction" at the points given by "loc."
289 //
290 BPatchSnippetHandle *insertCallSnippetAt(BPatch_thread *appThread,
291         BPatch_image *appImage, char *inFunction, BPatch_procedureLocation loc,
292         char *funcName, int testNo, char *testName)
293 {
294     BPatch_snippet *call_expr =
295         makeCallSnippet(appImage, funcName, testNo, testName);
296
297     BPatchSnippetHandle *ret = insertSnippetAt(appThread, appImage,
298                                                inFunction, loc, *call_expr,
299                                                testNo, testName);
300     if (ret == NULL) {
301         fprintf(stderr, "**Failed** test #%d (%s)\n", testNo, testName);
302         fprintf(stderr, "    Unable to insert snippet to call function %s\n",
303                 funcName);
304         exit(-1);
305     }
306
307     delete call_expr;
308
309     return ret;
310 }
311
312 // Wrapper function to find variables
313 // For Fortran, will look for lowercase variable, if mixed case not found
314 BPatch_variableExpr *findVariable (BPatch_image *appImage,
315      char* var, BPatch_Vector <BPatch_point *> *point = NULL)
316 {
317   //BPatch_variableExpr *FortVar = NULL;
318     BPatch_variableExpr *ret = NULL;
319     int i, numchars = strlen (var);
320     char *lowercase = new char [numchars];
321     int temp = expectError;
322
323     if (mutateeFortran && point) {
324             strcpy (lowercase, var);
325             expectError = 100;
326             for (i = 0; i < numchars; i++)
327                 lowercase [i] = tolower (lowercase [i]);
328             ret = appImage->findVariable (*(*point) [0], lowercase);
329         if (!ret) {
330             expectError = temp;
331             ret = appImage->findVariable (*(*point) [0], var);
332         }
333     } else {
334         ret = appImage->findVariable (var);
335     }
336
337     expectError = temp;
338     delete [] lowercase;
339     return ret;
340 }
341
342 /**************************************************************************
343  * Tests
344  **************************************************************************/
345
346 //
347 // Start Test Case #1 - (zero arg function call)
348 //
349 void mutatorTest1(BPatch_thread *appThread, BPatch_image *appImage)
350 {
351     // Find the entry point to the procedure "func1_1"
352
353     BPatch_Vector<BPatch_point *> *point1_1;
354
355     point1_1 = appImage->findProcedurePoint("func1_1", BPatch_entry);
356
357     if (!point1_1 || ((*point1_1).size() == 0)) {
358         fprintf(stderr, "**Failed** test #1 (zero arg function call)\n");
359         fprintf(stderr, "    Unable to find entry point to \"func1_1.\"\n");
360         exit(1);
361     }
362
363     BPatch_function *call1_func;
364
365     call1_func = appImage->findFunction("call1_1");
366
367     if (call1_func == NULL) {
368         fprintf(stderr, "**Failed** test #1 (zero arg function call)\n");
369         fprintf(stderr, "Unable to find function \"call1_1\"\n");
370         exit(1);
371     }
372
373     BPatch_Vector<BPatch_snippet *> call1_args;
374     BPatch_funcCallExpr call1Expr(*call1_func, call1_args);
375
376     dprintf("Inserted snippet2\n");
377     checkCost(call1Expr);
378     appThread->insertSnippet(call1Expr, *point1_1);
379 }
380
381 //
382 // Start Test Case #2 - mutator side (call a four argument function)
383 //
384 void mutatorTest2(BPatch_thread *appThread, BPatch_image *appImage)
385 {
386     // Find the entry point to the procedure "func2_1"
387
388     BPatch_Vector<BPatch_point *> *point2_1;
389
390     point2_1 = appImage->findProcedurePoint("func2_1", BPatch_entry);
391
392     if (!point2_1 || ((*point2_1).size() == 0)) {
393         fprintf(stderr, "**Failed** test #2 (four parameter function)\n");
394         fprintf(stderr, "    Unable to find entry point to \"func2_1.\"\n");
395         exit(1);
396     }
397
398     BPatch_function *call2_func;
399     call2_func = appImage->findFunction("call2_1");
400
401     if (call2_func == NULL) {
402         fprintf(stderr, "**Failed** test #2 (four parameter function)\n");
403         fprintf(stderr, "    Unable to find function \"call2_1.\"\n");
404         exit(1);
405     }
406
407     void *ptr;
408
409 #if defined(mips_sgi_irix6_4)
410     BPatch_variableExpr *pointerSizeVar = appImage->findVariable("pointerSize");
411     if (!pointerSizeVar) {
412         fprintf(stderr, "**Failed** test #2 (four parameter function)\n");
413         fprintf(stderr, "    Unable to locate variable pointerSize\n");
414         exit(1);
415     }
416
417     int pointerSize;
418     if (!pointerSizeVar->readValue(&pointerSize)) {
419         fprintf(stderr, "**Failed** test #2 (four parameter function)\n");
420         fprintf(stderr, "    Unable to read value of variable pointerSize\n");
421         exit(1);
422     }
423
424     assert(sizeof(void *) == sizeof(unsigned long) &&
425            sizeof(void *) == TEST_PTR_SIZE);
426
427     /* Determine the size of pointer we should use dynamically. */
428     if (pointerSize == 4) {
429         ptr = TEST_PTR_32BIT;
430     } else if (pointerSize == 8) {
431         ptr = TEST_PTR_64BIT;
432     } else {
433         fprintf(stderr, "**Failed** test #2 (four parameter function)\n");
434         fprintf(stderr, "    Unexpected value for pointerSize\n");
435         exit(1);
436     }
437 #else
438     /* For platforms where there is only one possible size for a pointer. */
439     ptr = TEST_PTR;
440 #endif
441
442     BPatch_Vector<BPatch_snippet *> call2_args;
443
444     BPatch_constExpr expr2_1 (0), expr2_2 (0), expr2_3 (0), expr2_4 (0);
445
446     if (mutateeFortran) {
447         BPatch_variableExpr *expr2_5 = appThread->malloc (*appImage->findType ("int"));
448         BPatch_variableExpr *expr2_6 = appThread->malloc (*appImage->findType ("int"));
449
450         expr2_1 = expr2_5->getBaseAddr ();
451         expr2_2 = expr2_6->getBaseAddr ();
452
453         BPatch_arithExpr expr2_7 (BPatch_assign, *expr2_5, BPatch_constExpr(1));
454         appThread->insertSnippet (expr2_7, *point2_1);
455
456         BPatch_arithExpr expr2_8 (BPatch_assign, *expr2_6, BPatch_constExpr(2));
457         appThread->insertSnippet (expr2_8, *point2_1);
458
459         expr2_3 = "testString2_1";
460         expr2_4 = 13;
461     } else {
462         expr2_1 = 1;
463         expr2_2 = 2;
464         expr2_3 = "testString2_1";
465         expr2_4 = ptr;
466     }
467
468     call2_args.push_back(&expr2_1);
469     call2_args.push_back(&expr2_2);
470     call2_args.push_back(&expr2_3);
471     call2_args.push_back(&expr2_4);
472
473     BPatch_funcCallExpr call2Expr(*call2_func, call2_args);
474
475     dprintf("Inserted snippet2\n");
476     checkCost(call2Expr);
477     appThread->insertSnippet(call2Expr, *point2_1, BPatch_callBefore, BPatch_lastSnippet);
478 }
479
480 //
481 // Start Test Case #3 - mutator side (passing variables to function)
482 //
483 void mutatorTest3(BPatch_thread *appThread, BPatch_image *appImage)
484 {
485     // Find the entry point to the procedure "func3_1"
486
487     BPatch_Vector<BPatch_point *> *point3_1;
488     point3_1 = appImage->findProcedurePoint("func3_1", BPatch_entry);
489
490     if (!point3_1 || ((*point3_1).size() == 0)) {
491         fprintf(stderr, "Unable to find entry point to \"func3_1.\"\n");
492         exit(1);
493     }
494
495     BPatch_function *call3_func;
496     call3_func = appImage->findFunction("call3_1");
497
498     if (call3_func == NULL) {
499         fprintf(stderr, "Unable to find function \"call3_1.\"\n");
500         exit(1);
501     }
502
503     BPatch_Vector<BPatch_snippet *> call3_args;
504
505     BPatch_Vector<BPatch_point *> *call3_1;
506     call3_1 = appImage->findProcedurePoint ("call3_1", BPatch_subroutine);
507
508     if (!call3_1 || ((*call3_1).size() == 0)) {
509         fprintf(stderr, "    Unable to find entry point to \"call3_1.\"\n");
510         exit(1);
511     }
512
513     BPatch_variableExpr *expr3_1 = findVariable (appImage, "globalVariable3_1", call3_1);
514
515     if (!expr3_1) {
516         fprintf(stderr, "**Failed** test #3 (passing variables)\n");
517         fprintf(stderr, "    Unable to locate variable globalVariable3_1\n");
518         exit(1);
519     }
520
521     // see if we can find the address
522     if (expr3_1->getBaseAddr() <= 0) {
523         printf("*Error*: address %p for globalVariable3_1 is not valid\n",
524             expr3_1->getBaseAddr());
525     }
526
527     BPatch_variableExpr *expr3_2 = appThread->malloc(*appImage->findType("int"));
528     if (!expr3_2) {
529         fprintf(stderr, "**Failed** test #3 (passing variables)\n");
530         fprintf(stderr, "    Unable to create new int variable\n");
531         exit(1);
532     }
533
534         BPatch_constExpr expr3_3 (expr3_1->getBaseAddr ());
535         BPatch_constExpr expr3_4 (expr3_2->getBaseAddr ());
536
537         if (mutateeFortran) {
538             call3_args.push_back (&expr3_3);
539             call3_args.push_back (&expr3_4);
540         } else {
541             call3_args.push_back(expr3_1);
542             call3_args.push_back(expr3_2);
543         }
544
545     BPatch_funcCallExpr call3Expr(*call3_func, call3_args);
546     checkCost(call3Expr);
547     appThread->insertSnippet(call3Expr, *point3_1);
548
549     BPatch_arithExpr expr3_5(BPatch_assign, *expr3_2, BPatch_constExpr(32));
550     checkCost(expr3_5);
551     appThread->insertSnippet(expr3_5, *point3_1);
552
553     dprintf("Inserted snippet3\n");
554 }
555
556 //
557 // Start Test Case #4 - mutator side (sequence)
558 //      Use the BPatch sequence operation to glue to expressions togehter.
559 //      The test is constructed to verify the correct execution order.
560 //
561 void mutatorTest4(BPatch_thread *appThread, BPatch_image *appImage)
562 {
563     // Find the entry point to the procedure "func4_1"
564     BPatch_Vector<BPatch_point *> *point4_1;
565     point4_1 = appImage->findProcedurePoint("func4_1", BPatch_entry);
566
567     if (!point4_1 || ((*point4_1).size() == 0)) {
568         fprintf(stderr, "Unable to find entry point to \"func4_1\".\n");
569         exit(1);
570     }
571
572     BPatch_variableExpr *expr4_1 = findVariable (appImage, "globalVariable4_1", point4_1);
573
574     if (!expr4_1) {
575         fprintf(stderr, "**Failed** test #4 (sequence)\n");
576         fprintf(stderr, "    Unable to locate variable globalVariable4_1\n");
577         exit(1);
578     }
579
580     BPatch_arithExpr expr4_2(BPatch_assign, *expr4_1, BPatch_constExpr(42));
581     BPatch_arithExpr expr4_3(BPatch_assign, *expr4_1, BPatch_constExpr(43));
582
583     BPatch_Vector<BPatch_snippet*> vect4_1;
584     vect4_1.push_back(&expr4_2);
585     vect4_1.push_back(&expr4_3);
586
587     BPatch_sequence expr4_4(vect4_1);
588     checkCost(expr4_4);
589     appThread->insertSnippet(expr4_4, *point4_1);
590 }
591
592 //
593 // Start Test Case #5 - mutator side (if w.o. else)
594 //
595 void mutatorTest5(BPatch_thread *appThread, BPatch_image *appImage)
596 {
597
598     // Find the entry point to the procedure "func5_2"
599     BPatch_Vector<BPatch_point *> *point5_1;
600     point5_1 = appImage->findProcedurePoint("func5_2", BPatch_entry);
601
602     if (!point5_1 || ((*point5_1).size() == 0)) {
603         fprintf(stderr, "Unable to find entry point to \"func5_2\".\n");
604         exit(1);
605     }
606
607     BPatch_Vector<BPatch_point *> *point5_2;
608     point5_2 = appImage->findProcedurePoint ("func5_1", BPatch_subroutine);
609
610     if (!point5_2 || ((*point5_2).size() == 0)) {
611         fprintf(stderr, "Unable to find entry point to \"func5_1\".\n");
612         exit(1);
613     }
614
615     BPatch_variableExpr *expr5_1 = findVariable (appImage, "globalVariable5_1", point5_2);
616     BPatch_variableExpr *expr5_2 = findVariable (appImage, "globalVariable5_2", point5_2);
617
618     if (!expr5_1 || !expr5_2) {
619         fprintf(stderr, "**Failed** test #5 (1f w.o. else)\n");
620         fprintf(stderr, "    Unable to locate variable globalVariable5_1 or ");
621         fprintf(stderr, "    variable globalVariable5_2\n");
622         exit(1);
623     }
624
625     BPatch_Vector<BPatch_snippet*> vect5_1;
626
627     // if (0 == 1) globalVariable5_1 = 52;
628     BPatch_ifExpr expr5_3(
629         BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0), BPatch_constExpr(1)), 
630         BPatch_arithExpr(BPatch_assign, *expr5_1, BPatch_constExpr(52)));
631
632     // if (1 == 1) globalVariable5_2 = 53;
633     BPatch_ifExpr expr5_4(
634         BPatch_boolExpr(BPatch_eq, BPatch_constExpr(1), BPatch_constExpr(1)), 
635         BPatch_arithExpr(BPatch_assign, *expr5_2, BPatch_constExpr(53)));
636
637     vect5_1.push_back(&expr5_3);
638     vect5_1.push_back(&expr5_4);
639
640     BPatch_sequence expr5_5(vect5_1);
641     checkCost(expr5_5);
642     appThread->insertSnippet(expr5_5, *point5_1);
643 }
644
645 //
646 // Start Test Case #6 - mutator side (arithmetic operators)
647 //
648 void mutatorTest6(BPatch_thread *appThread, BPatch_image *appImage)
649 {
650     // Find the entry point to the procedure "func6_2"
651     BPatch_Vector<BPatch_point *> *point6_1;
652     point6_1 = appImage->findProcedurePoint("func6_2", BPatch_entry);
653
654     if (!point6_1 || ((*point6_1).size() == 0)) {
655         fprintf(stderr, "Unable to find entry point to \"func6_2\".\n");
656         exit(1);
657     }
658
659     BPatch_Vector<BPatch_point *> *point6_2;
660     point6_2 = appImage->findProcedurePoint("func6_1", BPatch_subroutine);
661
662     if (!point6_2 || ((*point6_2).size() == 0)) {
663         fprintf(stderr, "Unable to find entry point to \"func6_1\".\n");
664         exit(1);
665     }
666
667     BPatch_variableExpr *expr6_1, *expr6_2, *expr6_3, *expr6_4, *expr6_5, *expr6_6,
668         *expr6_1a, *expr6_2a, *expr6_3a, *expr6_4a, *expr6_5a, *expr6_6a,
669         *constVar1, *constVar2, *constVar3, *constVar5, *constVar6,
670         *constVar10, *constVar60, *constVar64, *constVar66, *constVar67;
671
672     expr6_1 = findVariable(appImage, "globalVariable6_1", point6_2);
673     expr6_2 = findVariable(appImage, "globalVariable6_2", point6_2);
674     expr6_3 = findVariable(appImage, "globalVariable6_3", point6_2);
675     expr6_4 = findVariable(appImage, "globalVariable6_4", point6_2);
676     expr6_5 = findVariable(appImage, "globalVariable6_5", point6_2);
677     expr6_6 = findVariable(appImage, "globalVariable6_6", point6_2);
678     expr6_1a = findVariable(appImage, "globalVariable6_1a", point6_2);
679     expr6_2a = findVariable(appImage, "globalVariable6_2a", point6_2);
680     expr6_3a = findVariable(appImage, "globalVariable6_3a", point6_2);
681     expr6_4a = findVariable(appImage, "globalVariable6_4a", point6_2);
682     expr6_5a = findVariable(appImage, "globalVariable6_5a", point6_2);
683     expr6_6a = findVariable(appImage, "globalVariable6_6a", point6_2);
684
685     constVar1 = findVariable(appImage, "constVar1", point6_2);
686     constVar2 = findVariable(appImage, "constVar2", point6_2);
687     constVar3 = findVariable(appImage, "constVar3", point6_2);
688     constVar5 = findVariable(appImage, "constVar5", point6_2);
689     constVar6 = findVariable(appImage, "constVar6", point6_2);
690     constVar10 = findVariable(appImage, "constVar10", point6_2);
691     constVar60 = findVariable(appImage, "constVar60", point6_2);
692     constVar64 = findVariable(appImage, "constVar64", point6_2);
693     constVar66 = findVariable(appImage, "constVar66", point6_2);
694     constVar67 = findVariable(appImage, "constVar67", point6_2);
695
696     if (!expr6_1 || !expr6_2 || !expr6_3 || !expr6_4 ||
697         !expr6_5 || !expr6_6 || !expr6_1a || !expr6_2a || !expr6_3a ||
698         !expr6_4a || !expr6_5a || !expr6_6a) {
699         fprintf(stderr, "**Failed** test #6 (arithmetic operators)\n");
700         fprintf(stderr, "    Unable to locate one of globalVariable6_?\n");
701         exit(1);
702     }
703
704     if (!constVar1 || !constVar2 || !constVar3 || !constVar5 ||
705         !constVar6 || !constVar10 || !constVar60 || !constVar64 || 
706         !constVar66 || !constVar67) {
707         fprintf(stderr, "**Failed** test #6 (arithmetic operators)\n");
708         fprintf(stderr, "    Unable to locate one of constVar?\n");
709         exit(1);
710     }
711
712     BPatch_Vector<BPatch_snippet*> vect6_1;
713
714     // globalVariable6_1 = 60 + 2
715     BPatch_arithExpr arith6_1 (BPatch_assign, *expr6_1,
716       BPatch_arithExpr(BPatch_plus,BPatch_constExpr(60), BPatch_constExpr(2)));
717     vect6_1.push_back(&arith6_1);
718
719     // globalVariable6_2 = 64 - 1
720     BPatch_arithExpr arith6_2 (BPatch_assign, *expr6_2, 
721       BPatch_arithExpr(BPatch_minus,BPatch_constExpr(64),BPatch_constExpr(1)));
722     vect6_1.push_back(&arith6_2);
723
724     // globalVariable6_3 = 553648128 / 25165824 = 22
725     //    - make these big constants to test loading constants larger than
726     //      small immediate - jkh 6/22/98
727     BPatch_arithExpr arith6_3 (BPatch_assign, *expr6_3, BPatch_arithExpr(
728       BPatch_divide,BPatch_constExpr(553648128),BPatch_constExpr(25165824)));
729     vect6_1.push_back(&arith6_3);
730
731     // globalVariable6_4 = 67 / 3
732     BPatch_arithExpr arith6_4 (BPatch_assign, *expr6_4, BPatch_arithExpr(
733       BPatch_divide,BPatch_constExpr(67),BPatch_constExpr(3)));
734     vect6_1.push_back(&arith6_4);
735     // globalVariable6_5 = 6 * 5
736     BPatch_arithExpr arith6_5 (BPatch_assign, *expr6_5, BPatch_arithExpr(
737       BPatch_times,BPatch_constExpr(6),BPatch_constExpr(5)));
738     vect6_1.push_back(&arith6_5);
739
740     // globalVariable6_6 = 10,3
741     BPatch_arithExpr arith6_6 (BPatch_assign, *expr6_6, 
742         BPatch_arithExpr(BPatch_seq,BPatch_constExpr(10),BPatch_constExpr(3)));
743     vect6_1.push_back(&arith6_6);
744
745     // globalVariable6_1a = 60 + 2
746     BPatch_arithExpr arith6_1a (BPatch_assign, *expr6_1a, 
747       BPatch_arithExpr(BPatch_plus, *constVar60, *constVar2));
748     vect6_1.push_back(&arith6_1a);
749
750     // globalVariable6_2a = 64 - 1
751     BPatch_arithExpr arith6_2a (BPatch_assign, *expr6_2a, 
752       BPatch_arithExpr(BPatch_minus, *constVar64, *constVar1));
753     vect6_1.push_back(&arith6_2a);
754
755     // globalVariable6_3a = 66 / 3
756     BPatch_arithExpr arith6_3a (BPatch_assign, *expr6_3a, BPatch_arithExpr(
757       BPatch_divide, *constVar66, *constVar3));
758     vect6_1.push_back(&arith6_3a);
759
760     // globalVariable6_4a = 67 / 3
761     BPatch_arithExpr arith6_4a (BPatch_assign, *expr6_4a, BPatch_arithExpr(
762       BPatch_divide, *constVar67, *constVar3));
763     vect6_1.push_back(&arith6_4a);
764
765     // globalVariable6_5a = 6 * 5
766     BPatch_arithExpr arith6_5a (BPatch_assign, *expr6_5a, BPatch_arithExpr(
767       BPatch_times, *constVar6, *constVar5));
768     vect6_1.push_back(&arith6_5a);
769
770     // globalVariable6_6a = 10,3
771     // BPatch_arithExpr arith6_6a (BPatch_assign, *expr6_6a, *constVar3);
772     //  BPatch_arithExpr(BPatch_seq, *constVar10, BPatch_constExpr(3)));
773     BPatch_arithExpr arith6_6a (BPatch_assign, *expr6_6a,
774         BPatch_arithExpr(BPatch_seq, *constVar10, *constVar3));
775     vect6_1.push_back(&arith6_6a);
776
777     checkCost(BPatch_sequence(vect6_1));
778     appThread->insertSnippet( BPatch_sequence(vect6_1), *point6_1);
779 }
780
781 void genRelTest(BPatch_image *appImage,BPatch_Vector<BPatch_snippet*> &vect7_1, 
782                 BPatch_relOp op, int r1, int r2, char *var1)
783 {
784     BPatch_Vector <BPatch_point *> *point7_1;
785     point7_1 = appImage->findProcedurePoint ("func7_1", BPatch_entry);
786
787     if (!point7_1 || ((*point7_1).size() == 0)) {
788         fprintf(stderr, "Unable to find entry point to \"func7_1\".\n");
789         exit(1);
790     }
791
792     BPatch_variableExpr *expr1_1 = findVariable (appImage, var1, point7_1);
793
794     if (!expr1_1) {
795         fprintf(stderr, "**Failed** test #7 (relational operators)\n");
796         fprintf(stderr, "    Unable to locate variable %s\n", var1);
797         exit(1);
798     }
799     BPatch_ifExpr *tempExpr1 = new BPatch_ifExpr(
800         BPatch_boolExpr(op, BPatch_constExpr(r1), BPatch_constExpr(r2)), 
801         BPatch_arithExpr(BPatch_assign, *expr1_1, BPatch_constExpr(72)));
802     vect7_1.push_back(tempExpr1);
803 }
804
805 void genVRelTest(BPatch_image *appImage,
806                  BPatch_Vector<BPatch_snippet*> &vect7_1, 
807                  BPatch_relOp op, BPatch_variableExpr *r1, 
808                  BPatch_variableExpr *r2, char *var1)
809 {
810     BPatch_Vector <BPatch_point *> *point7_1;
811     point7_1 = appImage->findProcedurePoint ("func7_1", BPatch_entry);
812
813     if (!point7_1 || ((*point7_1).size() == 0)) {
814         fprintf(stderr, "Unable to find entry point to \"func7_1\".\n");
815         exit(1);
816     }
817
818     BPatch_variableExpr *expr1_1 = findVariable(appImage, var1, point7_1);
819
820     if (!expr1_1) {
821         fprintf(stderr, "**Failed** test #7 (relational operators)\n");
822         fprintf(stderr, "    Unable to locate variable %s\n", var1);
823         exit(1);
824     }
825     BPatch_ifExpr *tempExpr1 = new BPatch_ifExpr(
826         BPatch_boolExpr(op, *r1, *r2), 
827         BPatch_arithExpr(BPatch_assign, *expr1_1, BPatch_constExpr(74)));
828     vect7_1.push_back(tempExpr1);
829 }
830
831 //
832 // Start Test Case #7 - mutator side (relational operators)
833 //
834 void mutatorTest7(BPatch_thread *appThread, BPatch_image *appImage)
835 {
836     // Find the entry point to the procedure "func7_2"
837     BPatch_Vector<BPatch_point *> *point7_1;
838     point7_1 = appImage->findProcedurePoint("func7_2", BPatch_entry);
839
840     if (!point7_1 || ((*point7_1).size() == 0)) {
841         fprintf(stderr, "Unable to find entry point to \"func7_2\".\n");
842         exit(1);
843     }
844
845     BPatch_Vector<BPatch_snippet*> vect7_1;
846
847     genRelTest(appImage, vect7_1, BPatch_lt, 0, 1, "globalVariable7_1");
848     genRelTest(appImage, vect7_1, BPatch_lt, 1, 0, "globalVariable7_2");
849     genRelTest(appImage, vect7_1, BPatch_eq, 2, 2, "globalVariable7_3");
850     genRelTest(appImage, vect7_1, BPatch_eq, 2, 3, "globalVariable7_4");
851     genRelTest(appImage, vect7_1, BPatch_gt, 4, 3, "globalVariable7_5");
852     genRelTest(appImage, vect7_1, BPatch_gt, 3, 4, "globalVariable7_6");
853     genRelTest(appImage, vect7_1, BPatch_le, 3, 4, "globalVariable7_7");
854     genRelTest(appImage, vect7_1, BPatch_le, 4, 3, "globalVariable7_8");
855     genRelTest(appImage, vect7_1, BPatch_ne, 5, 6, "globalVariable7_9");
856     genRelTest(appImage, vect7_1, BPatch_ne, 5, 5, "globalVariable7_10");
857     genRelTest(appImage, vect7_1, BPatch_ge, 9, 7, "globalVariable7_11");
858     genRelTest(appImage, vect7_1, BPatch_ge, 7, 9, "globalVariable7_12");
859     genRelTest(appImage, vect7_1, BPatch_and, 1, 1, "globalVariable7_13");
860     genRelTest(appImage, vect7_1, BPatch_and, 1, 0, "globalVariable7_14");
861     genRelTest(appImage, vect7_1, BPatch_or, 1, 0, "globalVariable7_15");
862     genRelTest(appImage, vect7_1, BPatch_or, 0, 0, "globalVariable7_16");
863
864     BPatch_Vector <BPatch_point *> *func7_1;
865     func7_1 = appImage->findProcedurePoint ("func7_1", BPatch_subroutine);
866
867     if (!func7_1 || ((*func7_1).size() == 0)) {
868         fprintf(stderr, "Unable to find entry point to \"func7_1\".\n");
869         exit(1);
870     }
871
872     BPatch_variableExpr *constVar0, *constVar1, *constVar2, *constVar3, *constVar4, *constVar5, *constVar6, *constVar7, *constVar9;
873     constVar0 = findVariable(appImage, "constVar0", func7_1);
874     constVar1 = findVariable(appImage, "constVar1", func7_1);
875     constVar2 = findVariable(appImage, "constVar2", func7_1);
876     constVar3 = findVariable(appImage, "constVar3", func7_1);
877     constVar4 = findVariable(appImage, "constVar4", func7_1);
878     constVar5 = findVariable(appImage, "constVar5", func7_1);
879     constVar6 = findVariable(appImage, "constVar6", func7_1);
880     constVar7 = findVariable(appImage, "constVar7", func7_1);
881     constVar9 = findVariable(appImage, "constVar9", func7_1);
882
883     if (!constVar0 || !constVar1 || !constVar2 || !constVar3 || !constVar4 ||
884         !constVar5 || !constVar6 || !constVar7 || !constVar9 ) {
885         fprintf(stderr, "**Failed** test #7 (relational operators)\n");
886         fprintf(stderr, "    Unable to locate one of constVar?\n");
887         exit(1);
888     }
889
890     genVRelTest(appImage, vect7_1, BPatch_lt, constVar0, constVar1,
891         "globalVariable7_1a");
892     genVRelTest(appImage, vect7_1, BPatch_lt, constVar1, constVar0, 
893         "globalVariable7_2a");
894     genVRelTest(appImage, vect7_1, BPatch_eq, constVar2, constVar2, 
895         "globalVariable7_3a");
896     genVRelTest(appImage, vect7_1, BPatch_eq, constVar2, constVar3, 
897         "globalVariable7_4a");
898     genVRelTest(appImage, vect7_1, BPatch_gt, constVar4, constVar3, 
899         "globalVariable7_5a");
900     genVRelTest(appImage, vect7_1, BPatch_gt, constVar3, constVar4, 
901         "globalVariable7_6a");
902     genVRelTest(appImage, vect7_1, BPatch_le, constVar3, constVar4, 
903         "globalVariable7_7a");
904     genVRelTest(appImage, vect7_1, BPatch_le, constVar4, constVar3, 
905         "globalVariable7_8a");
906     genVRelTest(appImage, vect7_1, BPatch_ne, constVar5, constVar6, 
907         "globalVariable7_9a");
908     genVRelTest(appImage, vect7_1, BPatch_ne, constVar5, constVar5, 
909         "globalVariable7_10a");
910     genVRelTest(appImage, vect7_1, BPatch_ge, constVar9, constVar7, 
911         "globalVariable7_11a");
912     genVRelTest(appImage, vect7_1, BPatch_ge, constVar7, constVar9, 
913         "globalVariable7_12a");
914     genVRelTest(appImage, vect7_1, BPatch_and, constVar1, constVar1, 
915         "globalVariable7_13a");
916     genVRelTest(appImage, vect7_1, BPatch_and, constVar1, constVar0, 
917         "globalVariable7_14a");
918     genVRelTest(appImage, vect7_1, BPatch_or, constVar1, constVar0, 
919         "globalVariable7_15a");
920     genVRelTest(appImage, vect7_1, BPatch_or, constVar0, constVar0, 
921         "globalVariable7_16a");
922
923     dprintf("relops test vector length is %d\n", vect7_1.size());
924
925     checkCost(BPatch_sequence(vect7_1));
926     appThread->insertSnippet( BPatch_sequence(vect7_1), *point7_1);
927 }
928
929 //
930 // Start Test Case #8 - mutator side (preserve registers - expr)
931 //
932 void mutatorTest8(BPatch_thread *appThread, BPatch_image *appImage)
933 {
934     // Find the entry point to the procedure "func8_1"
935     BPatch_Vector<BPatch_point *> *point8_1;
936     point8_1 = appImage->findProcedurePoint("func8_1", BPatch_entry);
937
938     if (!point8_1 || ((*point8_1).size() == 0)) {
939         fprintf(stderr, "Unable to find entry point to \"func8_1\".\n");
940         exit(1);
941     }
942
943     BPatch_Vector<BPatch_snippet*> vect8_1;
944
945     BPatch_variableExpr *expr8_1 = findVariable(appImage, "globalVariable8_1", point8_1);
946
947     if (!expr8_1) {
948         fprintf(stderr, "**Failed** test #3 (passing variables)\n");
949         fprintf(stderr, "    Unable to locate variable globalVariable8_1\n");
950         exit(1);
951     }
952
953     BPatch_arithExpr arith8_1 (BPatch_assign, *expr8_1, 
954       BPatch_arithExpr(BPatch_plus, 
955             BPatch_arithExpr(BPatch_plus, 
956                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(81), 
957                                               BPatch_constExpr(82)),
958                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(83), 
959                                               BPatch_constExpr(84))),
960             BPatch_arithExpr(BPatch_plus, 
961                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(85), 
962                                               BPatch_constExpr(86)),
963                 BPatch_arithExpr(BPatch_plus, BPatch_constExpr(87), 
964                                               BPatch_constExpr(88)))));
965     vect8_1.push_back(&arith8_1);
966
967     checkCost(BPatch_sequence(vect8_1));
968     appThread->insertSnippet( BPatch_sequence(vect8_1), *point8_1);
969 }
970
971 //
972 // Start Test Case #9 - mutator side (preserve registers - funcCall)
973 //
974 void mutatorTest9(BPatch_thread *appThread, BPatch_image *appImage)
975 {
976     // Find the entry point to the procedure "func9_1"
977     BPatch_Vector<BPatch_point *> *point9_1;
978     point9_1 = appImage->findProcedurePoint("func9_1", BPatch_entry);
979
980     if (!point9_1 || ((*point9_1).size() == 0)) {
981         fprintf(stderr, "Unable to find entry point to \"func9_1\".\n");
982         exit(1);
983     }
984
985     BPatch_function *call9_func;
986     call9_func = appImage->findFunction("call9_1");
987
988     if (call9_func == NULL) {
989         fprintf(stderr, "Unable to find function \"call9_1.\"\n");
990         exit(1);
991     }
992
993     BPatch_Vector<BPatch_snippet *> call9_args;
994
995     BPatch_variableExpr *expr9_1 = appThread->malloc (*appImage->findType ("int"));
996     BPatch_constExpr constExpr9_1 (0);
997     BPatch_arithExpr arithexpr9_1 (BPatch_assign, *expr9_1, BPatch_constExpr (91));
998     appThread->insertSnippet (arithexpr9_1, *point9_1);
999
1000     if (mutateeFortran) {
1001         constExpr9_1 = expr9_1->getBaseAddr ();
1002     } else {
1003         constExpr9_1 = 91;
1004     }
1005
1006     call9_args.push_back(&constExpr9_1);
1007
1008     BPatch_variableExpr *expr9_2 = appThread->malloc (*appImage->findType ("int"));
1009     BPatch_constExpr constExpr9_2 (0);
1010     BPatch_arithExpr arithexpr9_2 (BPatch_assign, *expr9_2, BPatch_constExpr (92));
1011     appThread->insertSnippet (arithexpr9_2, *point9_1);
1012
1013     if (mutateeFortran) {
1014         constExpr9_2 = expr9_2->getBaseAddr ();
1015     } else {
1016         constExpr9_2 = 92;
1017     }
1018
1019     call9_args.push_back(&constExpr9_2);
1020
1021     BPatch_variableExpr *expr9_3 = appThread->malloc (*appImage->findType ("int"));
1022     BPatch_constExpr constExpr9_3 (0);
1023     BPatch_arithExpr arithexpr9_3 (BPatch_assign, *expr9_3, BPatch_constExpr (93));
1024     appThread->insertSnippet (arithexpr9_3, *point9_1);
1025
1026     if (mutateeFortran) {
1027         constExpr9_3 = expr9_3->getBaseAddr ();
1028     } else {
1029         constExpr9_3 = 93;
1030     }
1031
1032     call9_args.push_back(&constExpr9_3);
1033
1034     BPatch_variableExpr *expr9_4 = appThread->malloc (*appImage->findType ("int"));
1035     BPatch_constExpr constExpr9_4 (0);
1036     BPatch_arithExpr arithexpr9_4 (BPatch_assign, *expr9_4, BPatch_constExpr (94));
1037     appThread->insertSnippet (arithexpr9_4, *point9_1);
1038
1039     if (mutateeFortran) {
1040         constExpr9_4 = expr9_4->getBaseAddr ();
1041     } else {
1042         constExpr9_4 = 94;
1043     }
1044
1045     call9_args.push_back(&constExpr9_4);
1046
1047     BPatch_variableExpr *expr9_5 = appThread->malloc (*appImage->findType ("int"));
1048     BPatch_constExpr constExpr9_5 (0);
1049     BPatch_arithExpr arithexpr9_5 (BPatch_assign, *expr9_5, BPatch_constExpr (95));
1050     appThread->insertSnippet (arithexpr9_5, *point9_1);
1051
1052     if (mutateeFortran) {
1053         constExpr9_5 = expr9_5->getBaseAddr ();
1054     } else {
1055         constExpr9_5 = 95;
1056     }
1057
1058     call9_args.push_back(&constExpr9_5);
1059
1060     BPatch_funcCallExpr call9Expr(*call9_func, call9_args);
1061
1062     checkCost(call9Expr);
1063     appThread->insertSnippet(call9Expr, *point9_1, BPatch_callBefore, BPatch_lastSnippet);
1064 }
1065
1066 //
1067 // Start Test Case #10 - mutator side (insert snippet order)
1068 //
1069 void mutatorTest10(BPatch_thread *appThread, BPatch_image *appImage)
1070 {
1071     // Find the entry point to the procedure "func10_1"
1072     BPatch_Vector<BPatch_point *> *point10_1;
1073     point10_1 = appImage->findProcedurePoint("func10_1", BPatch_entry);
1074
1075     if (!point10_1 || ((*point10_1).size() == 0)) {
1076         fprintf(stderr, "Unable to find entry point to \"func10_1\".\n");
1077         exit(1);
1078     }
1079
1080     BPatch_function *call10_1_func;
1081     call10_1_func = appImage->findFunction("call10_1");
1082
1083     if (call10_1_func == NULL) {
1084         fprintf(stderr, "Unable to find function \"call10_1.\"\n");
1085         exit(1);
1086     }
1087
1088     BPatch_function *call10_2_func;
1089     call10_2_func = appImage->findFunction("call10_2");
1090
1091     if (call10_2_func == NULL) {
1092         fprintf(stderr, "Unable to find function \"call10_2.\"\n");
1093         exit(1);
1094     }
1095
1096     BPatch_function *call10_3_func;
1097     call10_3_func = appImage->findFunction("call10_3");
1098
1099     if (call10_3_func == NULL) {
1100         fprintf(stderr, "Unable to find function \"call10_3.\"\n");
1101         exit(1);
1102     }
1103
1104     BPatch_Vector<BPatch_snippet *> nullArgs;
1105     BPatch_funcCallExpr call10_1Expr(*call10_1_func, nullArgs);
1106     BPatch_funcCallExpr call10_2Expr(*call10_2_func, nullArgs);
1107     BPatch_funcCallExpr call10_3Expr(*call10_3_func, nullArgs);
1108
1109     checkCost(call10_2Expr);
1110     appThread->insertSnippet( call10_2Expr, *point10_1);
1111
1112     checkCost(call10_1Expr);
1113     appThread->insertSnippet( call10_1Expr, *point10_1, BPatch_callBefore, 
1114                                                         BPatch_firstSnippet);
1115
1116     checkCost(call10_3Expr);
1117     appThread->insertSnippet( call10_3Expr, *point10_1, BPatch_callBefore, 
1118                                                         BPatch_lastSnippet);
1119 }
1120
1121 //
1122 // Start Test Case #11 - mutator side (snippets at entry,exit,call)
1123 //
1124 void mutatorTest11(BPatch_thread *appThread, BPatch_image *appImage)
1125 {
1126     // Find the entry point to the procedure "func11_1"
1127     BPatch_Vector<BPatch_point *> *point11_1;
1128     point11_1 = appImage->findProcedurePoint("func11_1", BPatch_entry);
1129
1130     if (!point11_1 || (point11_1->size() < 1)) {
1131         fprintf(stderr, "Unable to find point func11_1 - entry.\n");
1132         exit(-1);
1133     }
1134
1135     // Find the subroutine points for the procedure "func11_1"
1136     BPatch_Vector<BPatch_point *> *point11_2;
1137     point11_2 = appImage->findProcedurePoint("func11_1", BPatch_subroutine);
1138
1139     if (!point11_2 || (point11_2->size() < 1)) {
1140         fprintf(stderr, "Unable to find point func11_1 - calls.\n");
1141         exit(-1);
1142     }
1143
1144     // Find the exit point to the procedure "func11_1"
1145     BPatch_Vector<BPatch_point *> *point11_3;
1146     point11_3 = appImage->findProcedurePoint("func11_1", BPatch_exit);
1147
1148     if (!point11_3 || (point11_3->size() < 1)) {
1149         fprintf(stderr, "Unable to find point func11_1 - exit.\n");
1150         exit(-1);
1151     }
1152
1153     BPatch_function *call11_1_func;
1154     call11_1_func = appImage->findFunction("call11_1");
1155
1156     if (call11_1_func == NULL) {
1157         fprintf(stderr, "Unable to find function \"call11_1.\"\n");
1158         exit(1);
1159     }
1160
1161     BPatch_function *call11_2_func;
1162     call11_2_func = appImage->findFunction("call11_2");
1163
1164     if (call11_2_func == NULL) {
1165         fprintf(stderr, "Unable to find function \"call11_2.\"\n");
1166         exit(1);
1167     }
1168
1169     BPatch_function *call11_3_func;
1170     call11_3_func = appImage->findFunction("call11_3");
1171
1172     if (call11_3_func == NULL) {
1173         fprintf(stderr, "Unable to find function \"call11_3.\"\n");
1174         exit(1);
1175     }
1176
1177     BPatch_function *call11_4_func;
1178     call11_4_func = appImage->findFunction("call11_4");
1179
1180     if (call11_4_func == NULL) {
1181         fprintf(stderr, "Unable to find function \"call11_4.\"\n");
1182         exit(1);
1183     }
1184
1185     BPatch_Vector<BPatch_snippet *> nullArgs;
1186     BPatch_funcCallExpr call11_1Expr(*call11_1_func, nullArgs);
1187     BPatch_funcCallExpr call11_2Expr(*call11_2_func, nullArgs);
1188     BPatch_funcCallExpr call11_3Expr(*call11_3_func, nullArgs);
1189     BPatch_funcCallExpr call11_4Expr(*call11_4_func, nullArgs);
1190
1191     checkCost(call11_1Expr);
1192     appThread->insertSnippet(call11_1Expr, *point11_1);
1193
1194     checkCost(call11_2Expr);
1195     appThread->insertSnippet(call11_2Expr, *point11_2, BPatch_callBefore);
1196
1197     checkCost(call11_3Expr);
1198     appThread->insertSnippet(call11_3Expr, *point11_2, BPatch_callAfter);
1199
1200     checkCost(call11_4Expr);
1201     appThread->insertSnippet(call11_4Expr, *point11_3);
1202 }
1203
1204 BPatchSnippetHandle *snippetHandle12_1;
1205 BPatch_variableExpr *varExpr12_1;
1206
1207 const int HEAP_TEST_UNIT_SIZE = 5000;
1208
1209 //
1210 // Start Test Case #12 - mutator side (insert/remove and malloc/free)
1211 //
1212 void mutatorTest12a(BPatch_thread *appThread, BPatch_image *appImage)
1213 {
1214     // Find the entry point to the procedure "func12_2"
1215     BPatch_Vector<BPatch_point *> *point12_2;
1216     point12_2 = appImage->findProcedurePoint("func12_2", BPatch_entry);
1217
1218     if (!point12_2 || (point12_2->size() < 1)) {
1219         fprintf(stderr, "Unable to find point func12_2 - entry.\n");
1220         exit(-1);
1221     }
1222
1223     varExpr12_1 = appThread->malloc(100);
1224     if (!varExpr12_1) {
1225         fprintf(stderr, "Unable to allocate 100 bytes in mutatee\n");
1226         exit(-1);
1227     }
1228
1229     // Heap stress test - allocate memory until we run out, free it all
1230     //   and then allocate a small amount of memory.
1231     expectError = 66; // We're expecting a heap overflow error
1232     BPatch_variableExpr* memStuff[30000];
1233     BPatch_variableExpr *temp;
1234     temp = appThread->malloc(HEAP_TEST_UNIT_SIZE); 
1235     int count = 0;
1236     while (temp) {
1237 #if defined(USES_DYNAMIC_INF_HEAP)
1238         if (! temp) {
1239              printf("*** Inferior malloc stress test failed\n"); 
1240              exit(-1);
1241         }
1242 #endif /* USES_DYNAMIC_INF_HEAP */
1243         memStuff[count++] = temp;
1244         temp = appThread->malloc(HEAP_TEST_UNIT_SIZE);
1245 #if defined(USES_DYNAMIC_INF_HEAP)
1246         // heap will grow indefinitely on dynamic heap platforms
1247         //if (count == 10000) break;
1248         // I get tired of waiting
1249         if (count == 500) break;
1250 #endif /* USES_DYNAMIC_INF_HEAP */
1251         assert(count < 30000);
1252     }
1253     expectError = DYNINST_NO_ERROR;
1254
1255     int freeCount = 0;
1256     for (int i =0; i < count; i++) {
1257         appThread->free(*memStuff[i]);
1258         freeCount++;
1259     }
1260
1261     temp = appThread->malloc(500); 
1262     if (!temp) {
1263         printf("*** Unable to allocate memory after using then freeing heap\n");
1264     }
1265
1266     BPatch_function *call12_1_func;
1267     call12_1_func = appImage->findFunction("call12_1");
1268
1269     if (call12_1_func == NULL) {
1270         fprintf(stderr, "Unable to find function \"call12_1.\"\n");
1271         exit(1);
1272     }
1273
1274     BPatch_Vector<BPatch_snippet *> nullArgs;
1275     BPatch_funcCallExpr call12_1Expr(*call12_1_func, nullArgs);
1276
1277     checkCost(call12_1Expr);
1278     snippetHandle12_1 = appThread->insertSnippet(call12_1Expr, *point12_2);
1279     if (!snippetHandle12_1) {
1280         fprintf(stderr,
1281                 "Unable to insert snippet to call function \"call12_1.\"\n");
1282         exit(-1);
1283     }
1284 }
1285
1286 void mutatorTest12b(BPatch_thread *appThread, BPatch_image * /*appImage*/)
1287 {
1288     waitUntilStopped(bpatch, appThread, 12, "insert/remove and malloc/free");
1289
1290     // remove instrumentation and free memory
1291     if (!appThread->deleteSnippet(snippetHandle12_1)) {
1292         printf("**Failed test #12 (insert/remove and malloc/free)\n");
1293         printf("    deleteSnippet returned an error\n");
1294         exit(-1);
1295     }
1296     appThread->free(*varExpr12_1);
1297
1298     // continue process
1299     appThread->continueExecution();
1300 }
1301
1302 //
1303 // Start Test Case #13 - mutator side (paramExpr,retExpr,nullExpr)
1304 //
1305 void mutatorTest13(BPatch_thread *appThread, BPatch_image *appImage)
1306 {
1307     // Find the entry point to the procedure "func13_1"
1308     BPatch_Vector<BPatch_point *> *point13_1;
1309     point13_1 = appImage->findProcedurePoint("func13_1", BPatch_entry);
1310
1311     if (!point13_1 || (point13_1->size() < 1)) {
1312         fprintf(stderr, "Unable to find point func13_1 - entry.\n");
1313         exit(-1);
1314     }
1315
1316     BPatch_function *call13_1_func;
1317     call13_1_func = appImage->findFunction("call13_1");
1318
1319     if (call13_1_func == NULL) {
1320         fprintf(stderr, "Unable to find function \"call13_1.\"\n");
1321         exit(1);
1322     }
1323
1324     BPatch_Vector<BPatch_snippet *> funcArgs;
1325
1326     funcArgs.push_back(new BPatch_paramExpr(0));
1327     funcArgs.push_back(new BPatch_paramExpr(1));
1328     funcArgs.push_back(new BPatch_paramExpr(2));
1329     funcArgs.push_back(new BPatch_paramExpr(3));
1330     funcArgs.push_back(new BPatch_paramExpr(4));
1331     BPatch_funcCallExpr call13_1Expr(*call13_1_func, funcArgs);
1332
1333     checkCost(call13_1Expr);
1334     appThread->insertSnippet(call13_1Expr, *point13_1);
1335
1336     BPatch_nullExpr call13_2Expr;
1337     checkCost(call13_2Expr);
1338     appThread->insertSnippet(call13_2Expr, *point13_1);
1339
1340     // now test that a return value can be read.
1341     BPatch_Vector<BPatch_point *> *point13_2;
1342     point13_2 = appImage->findProcedurePoint("func13_2", BPatch_exit);
1343
1344     if (!point13_2 || (point13_2->size() < 1)) {
1345         fprintf(stderr, "Unable to find point func13_2 - exit.\n");
1346         exit(-1);
1347     }
1348
1349     BPatch_function *call13_2_func;
1350     call13_2_func = appImage->findFunction("call13_2");
1351
1352     if (call13_2_func == NULL) {
1353         fprintf(stderr, "Unable to find function \"call13_2.\"\n");
1354         exit(1);
1355     }
1356
1357     BPatch_Vector<BPatch_snippet *> funcArgs2;
1358
1359     BPatch_variableExpr *expr13_1;
1360     BPatch_retExpr *ret_var;
1361     BPatch_constExpr expr13_2 (0);
1362
1363     if (mutateeFortran) {
1364         expr13_1 = appThread->malloc (*appImage->findType ("int"));
1365         ret_var = new BPatch_retExpr();
1366         BPatch_arithExpr test_arith (BPatch_assign, *expr13_1, *ret_var);
1367         appThread->insertSnippet (test_arith, *point13_2);
1368         expr13_2 = expr13_1->getBaseAddr ();
1369         funcArgs2.push_back (&expr13_2);
1370     } else {
1371         funcArgs2.push_back(new BPatch_retExpr());
1372     }
1373
1374     BPatch_funcCallExpr call13_3Expr(*call13_2_func, funcArgs2);
1375
1376     checkCost(call13_1Expr);
1377     appThread->insertSnippet(call13_3Expr, *point13_2, BPatch_callAfter, BPatch_lastSnippet);
1378 }
1379
1380 //
1381 // Start Test Case #14 - mutator side (replace function call)
1382 //
1383 void mutatorTest14(BPatch_thread *appThread, BPatch_image *appImage)
1384 {
1385     replaceFunctionCalls(appThread, appImage, "func14_1", "func14_2", "call14_1", 
1386         14, "replace/remove function call", 1);
1387     replaceFunctionCalls(appThread, appImage, "func14_1", "func14_3", NULL,
1388         14, "replace/remove function call", 1);
1389 }
1390
1391 //
1392 // Start Test Case #15 - mutator side (setMutationsActive)
1393 //
1394 void mutatorTest15a(BPatch_thread *appThread, BPatch_image *appImage)
1395 {
1396     insertCallSnippetAt(appThread, appImage, "func15_2", BPatch_entry,
1397             "call15_1", 15, "setMutationsActive");
1398
1399 #if defined(sparc_sun_sunos4_1_3) || defined(sparc_sun_solaris2_4)
1400     // On the Sparc, functions containing system calls are relocated into the
1401     // heap when instrumented, making a special case we should check.
1402
1403     // "access" makes the "access" system call, so we'll instrument it
1404     insertCallSnippetAt(appThread, appImage, "access", BPatch_entry,
1405         "call15_2", 15, "setMutationsActive");
1406
1407     // We want to instrument more than one point, so do exit as well
1408     insertCallSnippetAt(appThread, appImage, "access", BPatch_exit,
1409         "call15_2", 15, "setMutationsActive");
1410 #endif
1411
1412     replaceFunctionCalls(appThread, appImage, "func15_4", "func15_3",
1413         "call15_3", 15, "setMutationsActive", 1);
1414 }
1415
1416 void mutatorTest15b(BPatch_thread *appThread, BPatch_image * /*appImage*/)
1417 {
1418     waitUntilStopped(bpatch, appThread, 15, "setMutationsActive");
1419
1420     // disable mutations and continue process
1421     appThread->setMutationsActive(false);
1422     appThread->continueExecution();
1423     
1424     waitUntilStopped(bpatch, appThread, 15, "setMutationsActive");
1425
1426     // re-enable mutations and continue process
1427     appThread->setMutationsActive(true);
1428     appThread->continueExecution();
1429 }
1430
1431 BPatch_Vector<BPatch_snippet *> genLongExpr(BPatch_arithExpr *tail)
1432 {
1433     BPatch_Vector<BPatch_snippet *> *ret;
1434     
1435     ret = new(BPatch_Vector<BPatch_snippet *>);
1436     for (int i=0; i < 1000; i++) {
1437         ret->push_back(tail);
1438     }
1439     return *ret;
1440 }
1441
1442 //
1443 // Start Test Case #16 - mutator side (if-else)
1444 //
1445 void mutatorTest16(BPatch_thread *appThread, BPatch_image *appImage)
1446 {
1447     BPatch_Vector <BPatch_point *> *func16_1;
1448     func16_1 = appImage->findProcedurePoint ("func16_1", BPatch_subroutine);
1449
1450     if (!func16_1 || ((*func16_1).size() == 0)) {
1451         fprintf(stderr, "Unable to find entry point to \"func16_1\".\n");
1452         exit(1);
1453     }
1454
1455     BPatch_variableExpr *expr16_1, *expr16_2, *expr16_3, *expr16_4, *expr16_5,
1456         *expr16_6, *expr16_7, *expr16_8, *expr16_9, *expr16_10;
1457
1458     expr16_1 = findVariable(appImage, "globalVariable16_1", func16_1);
1459     expr16_2 = findVariable(appImage, "globalVariable16_2", func16_1);
1460     expr16_3 = findVariable(appImage, "globalVariable16_3", func16_1);
1461     expr16_4 = findVariable(appImage, "globalVariable16_4", func16_1);
1462     expr16_5 = findVariable(appImage, "globalVariable16_5", func16_1);
1463     expr16_6 = findVariable(appImage, "globalVariable16_6", func16_1);
1464     expr16_7 = findVariable(appImage, "globalVariable16_7", func16_1);
1465     expr16_8 = findVariable(appImage, "globalVariable16_8", func16_1);
1466     expr16_9 = findVariable(appImage, "globalVariable16_9", func16_1);
1467     expr16_10 = findVariable(appImage, "globalVariable16_10", func16_1);
1468
1469     if (!expr16_1 || !expr16_2 || !expr16_3 || !expr16_4 || !expr16_5 ||
1470         !expr16_6 || !expr16_7 || !expr16_8 || !expr16_9 || !expr16_10) {
1471         fprintf(stderr, "**Failed** test #16 (if-else)\n");
1472         fprintf(stderr, "    Unable to locate one of globalVariable16_?\n");
1473         exit(1);
1474     }
1475
1476     BPatch_arithExpr assign16_1(BPatch_assign, *expr16_1, BPatch_constExpr(1));
1477     BPatch_arithExpr assign16_2(BPatch_assign, *expr16_2, BPatch_constExpr(1));
1478
1479     BPatch_ifExpr if16_2(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(1),
1480         BPatch_constExpr(1)), assign16_1, assign16_2);
1481
1482     BPatch_arithExpr assign16_3(BPatch_assign, *expr16_3, BPatch_constExpr(1));
1483     BPatch_arithExpr assign16_4(BPatch_assign, *expr16_4, BPatch_constExpr(1));
1484
1485     BPatch_ifExpr if16_3(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0),
1486         BPatch_constExpr(1)), assign16_3, assign16_4);
1487
1488     BPatch_arithExpr assign16_5(BPatch_assign, *expr16_5, BPatch_constExpr(1));
1489     BPatch_arithExpr assign16_6(BPatch_assign, *expr16_6, BPatch_constExpr(1));
1490     BPatch_sequence longExpr16_1(genLongExpr(&assign16_5));
1491
1492
1493     BPatch_ifExpr if16_4(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0),
1494         BPatch_constExpr(1)), longExpr16_1, assign16_6);
1495
1496     BPatch_arithExpr assign16_7(BPatch_assign, *expr16_7, BPatch_constExpr(1));
1497     BPatch_arithExpr assign16_8(BPatch_assign, *expr16_8, BPatch_constExpr(1));
1498     BPatch_sequence longExpr16_2(genLongExpr(&assign16_8));
1499
1500     BPatch_ifExpr if16_5(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0),
1501         BPatch_constExpr(1)), assign16_7, longExpr16_2);
1502
1503     BPatch_arithExpr assign16_9(BPatch_assign, *expr16_9, BPatch_constExpr(1));
1504     BPatch_arithExpr assign16_10(BPatch_assign, *expr16_10,BPatch_constExpr(1));
1505     BPatch_sequence longExpr16_3(genLongExpr(&assign16_9));
1506     BPatch_sequence longExpr16_4(genLongExpr(&assign16_10));
1507
1508     BPatch_ifExpr if16_6(BPatch_boolExpr(BPatch_eq, BPatch_constExpr(0),
1509         BPatch_constExpr(1)), longExpr16_3, longExpr16_4);
1510
1511     insertSnippetAt(appThread, appImage, "func16_2", BPatch_entry, if16_2,
1512         16, "if-else");
1513     insertSnippetAt(appThread, appImage, "func16_3", BPatch_entry, if16_3,
1514         16, "if-else");
1515     insertSnippetAt(appThread, appImage, "func16_4", BPatch_entry, if16_4,
1516         16, "if-else");
1517     insertSnippetAt(appThread, appImage, "func16_4", BPatch_entry, if16_5,
1518         16, "if-else");
1519     insertSnippetAt(appThread, appImage, "func16_4", BPatch_entry, if16_6,
1520         16, "if-else");
1521 }
1522
1523 //
1524 // Start Test Case #17 - mutator side (return values from func calls)
1525 // Verify that instrumentation inserted at a subroutine's exit point
1526 // doesn't clobber its return value.
1527 // Method: the mutatee's func17_1 (first and only) exit is instrumented to
1528 // call call17_1 with parameter (constant) "1"; func17_2's (first and only)
1529 // exit is similarly instrumented to call call17_2(1); a subsequent test in
1530 // the mutatee compares the return values of func17_1 and func17_2.
1531 // (No examination is made of the return values of call17_1 or call17_2.)
1532 //
1533 void mutatorTest17(BPatch_thread *appThread, BPatch_image *appImage)
1534 {
1535     // Find the entry point to the procedure "func17_1"
1536     BPatch_Vector<BPatch_point *> *point17_1;
1537     point17_1 = appImage->findProcedurePoint("func17_1", BPatch_exit);
1538
1539     if (!point17_1 || (point17_1->size() < 1)) {
1540         fprintf(stderr, "Unable to find point func17_1 - exit.\n");
1541         exit(-1);
1542     }
1543
1544     BPatch_function *call17_1_func;
1545     call17_1_func = appImage->findFunction("call17_1");
1546
1547     if (call17_1_func == NULL) {
1548         fprintf(stderr, "Unable to find function \"call17_1.\"\n");
1549         exit(1);
1550     }
1551
1552     BPatch_Vector<BPatch_snippet *> funcArgs;
1553
1554     BPatch_variableExpr *var17_1 = appThread->malloc (*appImage->findType ("int"));
1555     BPatch_constExpr constExpr17_1 (0);
1556     BPatch_arithExpr arithExpr17_1 (BPatch_assign, *var17_1, BPatch_constExpr (1));
1557     appThread->insertSnippet (arithExpr17_1, *point17_1);
1558
1559     if (mutateeFortran) {
1560         constExpr17_1 = var17_1->getBaseAddr ();
1561     } else {
1562         constExpr17_1 = 1;
1563     }
1564
1565     funcArgs.push_back (&constExpr17_1);
1566
1567     BPatch_funcCallExpr call17_1Expr(*call17_1_func, funcArgs);
1568     checkCost(call17_1Expr);
1569     appThread->insertSnippet(call17_1Expr, *point17_1, BPatch_callAfter, BPatch_lastSnippet);
1570
1571     // Find the exit point to the procedure "func17_2"
1572     BPatch_Vector<BPatch_point *> *point17_2;
1573     point17_2 = appImage->findProcedurePoint("func17_2", BPatch_exit);
1574
1575     if (!point17_2 || (point17_2->size() < 1)) {
1576         fprintf(stderr, "Unable to find point func17_2 - exit.\n");
1577         exit(-1);
1578     }
1579
1580     BPatch_function *call17_2_func;
1581     call17_2_func = appImage->findFunction("call17_2");
1582
1583     if (call17_2_func == NULL) {
1584         fprintf(stderr, "Unable to find function \"call17_2.\"\n");
1585         exit(1);
1586     }
1587
1588     BPatch_Vector<BPatch_snippet *> funcArgs2;
1589
1590     BPatch_variableExpr *var17_2 = appThread->malloc (*appImage->findType ("int"));
1591     BPatch_constExpr constExpr17_2 (0);
1592     BPatch_arithExpr arith17_2 (BPatch_assign, *var17_2, BPatch_constExpr (1));
1593     appThread->insertSnippet (arith17_2, *point17_2);
1594
1595     if (mutateeFortran) {
1596         constExpr17_2 = var17_2->getBaseAddr ();
1597     } else {
1598         constExpr17_2 = 1;
1599     }
1600
1601     funcArgs2.push_back (&constExpr17_2);
1602
1603     BPatch_funcCallExpr call17_2Expr(*call17_2_func, funcArgs2);
1604     checkCost(call17_2Expr);
1605
1606     // test interface to call into insertSnippet with only one parameter
1607     BPatch_point aPoint = *(*point17_2)[0];
1608     appThread->insertSnippet(call17_2Expr, aPoint, BPatch_callAfter, BPatch_lastSnippet);
1609 }
1610
1611 //
1612 // Start Test Case #18 - mutator side (read/write a variable in the mutatee)
1613 //
1614 void mutatorTest18(BPatch_thread *appThread, BPatch_image *appImage)
1615 {
1616     BPatch_Vector <BPatch_point *> *func18_1;
1617     func18_1 = appImage->findProcedurePoint ("func18_1", BPatch_subroutine);
1618
1619     if (!func18_1 || ((*func18_1).size() == 0)) {
1620         fprintf(stderr, "Unable to find entry point to \"func18_1\".\n");
1621         exit(1);
1622     }
1623
1624     BPatch_variableExpr *expr18_1 = findVariable(appImage, "globalVariable18_1", func18_1);
1625
1626 /* Initialization must be done, because C would have done initialization at declaration */
1627     if (mutateeFortran) {
1628         BPatch_arithExpr arith18_1 (BPatch_assign, *expr18_1, BPatch_constExpr (42));
1629         appThread->oneTimeCode (arith18_1);
1630     }
1631
1632     if (expr18_1 == NULL) {
1633         fprintf(stderr, "**Failed** test #18 (read/write a variable in the mutatee)\n");
1634         fprintf(stderr, "    Unable to locate globalVariable18_1\n");
1635         exit(1);
1636     }
1637
1638     int n;
1639     expr18_1->readValue(&n);
1640
1641     if (n != 42) {
1642         fprintf(stderr, "**Failed** test #18 (read/write a variable in the mutatee)\n");
1643         fprintf(stderr, "    value read from globalVariable18_1 was %d, not 42 as expected\n", n);
1644         exit(1);
1645     }
1646
1647     n = 17;
1648     expr18_1->writeValue(&n);
1649 }
1650
1651 void test19_oneTimeCodeCallback(BPatch_thread *thread,
1652                                 void *userData,
1653                                 void *returnValue)
1654 {
1655     *(int *)userData = 1;
1656 }
1657
1658 //
1659 // Start Test Case #19 - mutator side (oneTimeCode)
1660 //
1661 void mutatorTest19(BPatch_thread *appThread, BPatch_image *appImage)
1662 {
1663     waitUntilStopped(bpatch, appThread, 19, "oneTimeCode");
1664
1665     BPatch_function *call19_1_func;
1666     call19_1_func = appImage->findFunction("call19_1");
1667
1668     if (call19_1_func == NULL) {
1669         fprintf(stderr, "Unable to find function \"call19_1.\"\n");
1670         exit(1);
1671     }
1672
1673     BPatch_Vector<BPatch_snippet *> nullArgs;
1674     BPatch_funcCallExpr call19_1Expr(*call19_1_func, nullArgs);
1675     checkCost(call19_1Expr);
1676
1677     appThread->oneTimeCode(call19_1Expr);
1678
1679     // Let the mutatee run to check the result
1680     appThread->continueExecution();
1681
1682     // Wait for the next test
1683     waitUntilStopped(bpatch, appThread, 19, "oneTimeCode");
1684
1685     BPatch_function *call19_2_func;
1686     call19_2_func = appImage->findFunction("call19_2");
1687
1688     if (call19_2_func == NULL) {
1689         fprintf(stderr, "Unable to find function \"call19_2.\"\n");
1690         exit(1);
1691     }
1692
1693     BPatch_funcCallExpr call19_2Expr(*call19_2_func, nullArgs);
1694     checkCost(call19_2Expr);
1695
1696     int callbackFlag = 0;
1697
1698     // Register a callback that will set the flag callbackFlag
1699     BPatchOneTimeCodeCallback oldCallback = 
1700         bpatch->registerOneTimeCodeCallback(test19_oneTimeCodeCallback);
1701
1702     appThread->oneTimeCodeAsync(call19_2Expr, (void *)&callbackFlag);
1703
1704     // Wait for the callback to be called
1705     while (!appThread->isTerminated() && !callbackFlag) ;
1706
1707     // Restore old callback (if there was one)
1708     bpatch->registerOneTimeCodeCallback(oldCallback);
1709
1710     // Let the mutatee run to check the result and then go on to the next test
1711     appThread->continueExecution();
1712 }
1713
1714 //
1715 // Start Test Case #20 - mutator side (instrumentation at arbitrary points)
1716 //
1717 void mutatorTest20(BPatch_thread *appThread, BPatch_image *appImage)
1718 {
1719     BPatch_function *call20_1_func;
1720     call20_1_func = appImage->findFunction("call20_1");
1721
1722     if (call20_1_func == NULL) {
1723         fprintf(stderr, "Unable to find function \"call20_1.\"\n");
1724         exit(1);
1725     }
1726
1727     BPatch_Vector<BPatch_snippet *> nullArgs;
1728     BPatch_funcCallExpr call20_1Expr(*call20_1_func, nullArgs);
1729     checkCost(call20_1Expr);
1730
1731     BPatch_function *f;
1732     f = appImage->findFunction("func20_2");
1733
1734     if (f == NULL) {
1735         fprintf(stderr, "Unable to find function \"func20_2.\"\n");
1736         exit(1);
1737     }
1738
1739     BPatch_point *p = NULL;
1740     bool found_one = false;
1741
1742     if (f->getSize() == 0) {
1743         fprintf(stderr, "**Failed** test #20 (instrumentation at arbitrary points)\n");
1744         fprintf(stderr, "    getSize returned a size of 0 for the function \"func20_2\"\n");
1745         exit(1);
1746     }
1747
1748     /* We expect certain errors from createInstPointAtAddr. */
1749     BPatchErrorCallback oldError =
1750         bpatch->registerErrorCallback(createInstPointError);
1751
1752     for (unsigned int i = 0; i < f->getSize(); i+= 1) {
1753         p = appImage->createInstPointAtAddr((char *)f->getBaseAddr() + i);
1754
1755         if (p) {
1756             if (p->getPointType() == BPatch_instruction) {
1757                 found_one = true;
1758                 if (appThread->insertSnippet(call20_1Expr, *p) == NULL) {
1759                     fprintf(stderr,
1760                       "Unable to insert snippet into function \"func20_2.\"\n");
1761                     exit(1);
1762                 }
1763             }
1764         }
1765     }
1766
1767     bpatch->registerErrorCallback(oldError);
1768
1769     if (!found_one) {
1770         fprintf(stderr, "Unable to find a point to instrument in function \"func20_2.\"\n");
1771         exit(1);
1772     }
1773 }
1774
1775
1776 //
1777 // Start Test Case #21 - mutator side (findFunction in module)
1778 //
1779 // There is no corresponding failure (test2) testing because the only
1780 // bad input to replaceFunction is a non-existent BPatch_function.
1781 // But this is already checked by the "non-existent function" test in
1782 // test2.
1783
1784 void readyTest21or22(BPatch_thread *appThread)
1785 {
1786     char libA[128], libB[128];
1787     sprintf(libA, "./%s", libNameA);
1788     sprintf(libB, "./%s", libNameB);
1789 #if !defined(i386_unknown_nt4_0) && !defined(alpha_dec_osf4_0)
1790     if (!mutateeFortran) {
1791         if (! appThread->loadLibrary(libA)) {
1792              fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1793              fprintf(stderr, "  Mutator couldn't load %s into mutatee\n", libNameA);
1794              exit(1);
1795         }
1796         if (! appThread->loadLibrary(libB)) {
1797              fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1798              fprintf(stderr, "  Mutator couldn't load %s into mutatee\n", libNameB);
1799              exit(1);
1800         }
1801     }
1802 #endif
1803 }
1804
1805 void mutatorTest21(BPatch_thread *, BPatch_image *appImage)
1806 {
1807 #if defined(sparc_sun_solaris2_4) \
1808  || defined(i386_unknown_solaris2_5) \
1809  || defined(i386_unknown_linux2_0) \
1810  || defined(ia64_unknown_linux2_4) \
1811  || defined(mips_sgi_irix6_4) \
1812  || defined(rs6000_ibm_aix4_1)
1813
1814     // Lookup the libtestA.so and libtestB.so modules that we've just loaded
1815
1816     if (mutateeFortran) {
1817         return;
1818     }
1819
1820     BPatch_module *modA = NULL;
1821     BPatch_module *modB = NULL;
1822     BPatch_Vector<BPatch_module *> *mods = appImage->getModules();
1823     if (!mods || mods->size() == 0) {
1824          fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1825          fprintf(stderr, "  Mutator couldn't search modules of mutatee\n");
1826          exit(1);
1827     }
1828
1829     for (unsigned int i = 0; i < mods->size() && !(modA && modB); i++) {
1830          char buf[1024];
1831          BPatch_module *m = (*mods)[i];
1832          m->getName(buf, 1024);
1833          // module names sometimes have "_module" appended
1834          if (!strncmp(libNameA, buf, strlen(libNameA)))
1835               modA = m;
1836          else if (!strncmp(libNameB, buf, strlen(libNameB)))
1837               modB = m;
1838     }
1839     if (! modA || ! modB) {
1840          fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1841          fprintf(stderr, "  Mutator couldn't find shlib in mutatee\n");
1842          fflush(stdout);
1843          exit(1);
1844     }
1845
1846     // Find the function CALL21_1 in each of the modules
1847     BPatch_function *funcA = modA->findFunction("call21_1");
1848     BPatch_function *funcB = modB->findFunction("call21_1");
1849     if (! funcA) {
1850          fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1851          fprintf(stderr, "  Mutator couldn't find a function in %s\n", libNameA);
1852          exit(1);
1853     }
1854     if (! funcB) {
1855          fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1856          fprintf(stderr, "  Mutator couldn't find a function in %s\n", libNameB);
1857          exit(1);
1858     }
1859     // Kludgily test whether the functions are distinct
1860     if (funcA->getBaseAddr() == funcB->getBaseAddr()) {
1861          fprintf(stderr, "**Failed test #21 (findFunction in module)\n");
1862          fprintf(stderr,
1863                 "  Mutator cannot distinguish two functions from different shlibs\n");
1864          exit(1);
1865     }
1866 #endif
1867 }
1868
1869
1870 //
1871 // Start Test Case #22 - mutator side (replace function)
1872 //
1873 // There is no corresponding failure (test2) testing because the only
1874 // invalid input to replaceFunction is a non-existent BPatch_function.
1875 // But this is already checked by the "non-existent function" test in
1876 // test2.
1877 void mutatorTest22(BPatch_thread *appThread, BPatch_image *appImage)
1878 {
1879 #if defined(sparc_sun_solaris2_4)
1880
1881     if (mutateeFortran) {
1882         return;
1883     }
1884
1885     char errbuf[1024]; errbuf[0] = '\0';
1886     BPatch_module *modA = NULL;
1887     BPatch_module *modB = NULL;
1888
1889     // Assume that a prior test (mutatorTest21) has loaded the
1890     // libraries libtestA.so and libtestB.so into the mutator.
1891     BPatch_Vector<BPatch_module *> *mods = appImage->getModules();
1892     if (!mods || mods->size() == 0) {
1893          fprintf(stderr, "**Failed test #22 (replace function)\n");
1894          fprintf(stderr, "  Mutator couldn't find shlib in mutatee\n");
1895          exit(1);
1896     }
1897     // Lookup the libtestA.so and libtestB.so modules
1898     for (int i = 0; i < mods->size() && !(modA && modB); i++) {
1899          char buf[1024];
1900          BPatch_module *m = (*mods)[i];
1901          m->getName(buf, 1024);
1902          // module names sometimes have "_module" appended
1903          if (!strncmp(libNameA, buf, strlen(libNameA)))
1904               modA = m;
1905          else if (!strncmp(libNameB, buf, strlen(libNameB)))
1906               modB = m;
1907     }
1908     if (! modA || ! modB) {
1909          fprintf(stderr, "**Failed test #22 (replace function)\n");
1910          fprintf(stderr, "  Mutator couldn't find dynamically loaded modules\n");
1911          exit(1);
1912     }
1913     
1914     //  Mutatee function replacement scheme:
1915
1916     //  function      module     replaced    global
1917     //                         or called?   
1918
1919     //  call22_1       a.out     replaced         1       global is the index
1920     //  call22_2       a.out       called         1       of the global variable
1921     //  call22_3       a.out     replaced         2       in test1.mutatee updated
1922     //  call22_4    libtestA       called         2       by the function
1923     //  call22_5A   libtestA     replaced         3
1924     //  call22_5B   libtestB       called         3
1925     //  call22_6    libtestA     replaced         4
1926     //  call22_7       a.out       called         4
1927
1928     // Both of each pair of functions (e.g., call22_1, call22_2)
1929     // increments a global variable.  The mutatee will test that the
1930     // variable has been updated only be the "called" function.
1931
1932     // Replace an a.out with another a.out function
1933     BPatch_function *call22_1func = appImage->findFunction("call22_1");
1934     BPatch_function *call22_2func = appImage->findFunction("call22_2");
1935     if (! call22_1func || ! call22_2func) {
1936          fprintf(stderr, "**Failed test #22 (replace function)\n");
1937          fprintf(stderr, "  Mutator couldn't find functions in mutatee\n");
1938          exit(1);
1939     }
1940     if (! appThread->replaceFunction(*call22_1func, *call22_2func)) {
1941          fprintf(stderr, "**Failed test #22 (replace function)\n");
1942          fprintf(stderr, "  Mutator couldn't replaceFunction (a.out -> a.out)\n");
1943          exit(1);
1944     }
1945
1946     // Replace an a.out function with a shlib function
1947     BPatch_function *call22_3func = appImage->findFunction("call22_3");
1948     BPatch_function *call22_4func = modA->findFunction("call22_4");
1949     if (! call22_3func || ! call22_4func) {
1950          fprintf(stderr, "**Failed test #22 (replace function)\n");
1951          fprintf(stderr, "  Mutator couldn't find functions in mutatee\n");
1952          exit(1);
1953     }
1954     if (! appThread->replaceFunction(*call22_3func, *call22_4func)) {
1955          fprintf(stderr, "**Failed test #22 (replace function)\n");
1956          fprintf(stderr, "  Mutator couldn't replaceFunction (a.out -> shlib)\n");
1957          exit(1);
1958     }
1959
1960     // Replace a shlib function with a shlib function
1961     BPatch_function *call22_5Afunc = modA->findFunction("call22_5");
1962     BPatch_function *call22_5Bfunc = modB->findFunction("call22_5");
1963     if (! call22_5Afunc || ! call22_5Bfunc) {
1964          fprintf(stderr, "**Failed test #22 (replace function)\n");
1965          fprintf(stderr, "  Mutator couldn't find functions in mutatee\n");
1966          exit(1);
1967     }
1968     if (! appThread->replaceFunction(*call22_5Afunc, *call22_5Bfunc)) {
1969          fprintf(stderr, "**Failed test #22 (replace function)\n");
1970          fprintf(stderr, "  Mutator couldn't replaceFunction (shlib -> shlib)\n");
1971     }
1972
1973     // Replace a shlib function with an a.out function
1974     BPatch_function *call22_6func = modA->findFunction("call22_6");
1975     BPatch_function *call22_7func = appImage->findFunction("call22_7");
1976     if (! call22_6func || ! call22_7func) {
1977          fprintf(stderr, "**Failed test #22 (replace function)\n");
1978          fprintf(stderr, "  Mutator couldn't find functions in mutatee\n");
1979          exit(1);
1980     }
1981     if (! appThread->replaceFunction(*call22_6func, *call22_7func)) {
1982          fprintf(stderr, "**Failed test #22 (replace function)\n");
1983          fprintf(stderr, "  Mutator couldn't replaceFunction (shlib -> a.out)\n");
1984          exit(1);
1985     }
1986
1987 #endif
1988 }
1989
1990 //
1991 // Start Test Case #23 - local variables
1992 //
1993 void mutatorTest23(BPatch_thread *appThread, BPatch_image *appImage)
1994 {
1995 #if !defined(mips_sgi_irix6_4) && !defined(alpha_dec_osf4_0)
1996     if (!mutateeFortran) {
1997         //     First verify that we can find a local variable in call23_1
1998         BPatch_Vector<BPatch_point *> *point23_1 =
1999             appImage->findProcedurePoint("call23_1", BPatch_subroutine);
2000
2001         assert(point23_1);
2002
2003         BPatch_variableExpr *var1 = appImage->findVariable(*(*point23_1)[0],
2004             "localVariable23_1");
2005         BPatch_variableExpr *var2 = appImage->findVariable(*(*point23_1)[0],
2006             "shadowVariable23_1");
2007         BPatch_variableExpr *var3 = appImage->findVariable("shadowVariable23_2");
2008         BPatch_variableExpr *var4 = appImage->findVariable("globalVariable23_1");
2009
2010         if (!var1 || !var2 || !var3 || !var4) {
2011             fprintf(stderr, "**Failed** test #23 (local variables)\n");
2012             if (!var1)
2013                 fprintf(stderr, "  can't find local variable localVariable23_1\n");
2014             if (!var2)
2015                 fprintf(stderr, "  can't find local variable shadowVariable23_1\n");
2016             if (!var3)
2017                 fprintf(stderr,"  can't find global variable shadowVariable23_2\n");
2018             return;
2019         }
2020
2021         BPatch_arithExpr expr23_1(BPatch_assign, *var1, BPatch_constExpr(2300001));
2022         BPatch_arithExpr expr23_2(BPatch_assign, *var2, BPatch_constExpr(2300012));
2023         BPatch_arithExpr expr23_3(BPatch_assign, *var3, BPatch_constExpr(2300023));
2024         BPatch_arithExpr expr23_4(BPatch_assign, *var4, *var1);
2025
2026         BPatch_Vector<BPatch_snippet *> exprs;
2027
2028         exprs.push_back(&expr23_4); // put this one first so it isn't clobbered
2029         exprs.push_back(&expr23_1);
2030         exprs.push_back(&expr23_2);
2031         exprs.push_back(&expr23_3);
2032
2033         BPatch_sequence allParts(exprs);
2034
2035         BPatch_Vector<BPatch_point *> *points =
2036         appImage->findProcedurePoint("call23_1", BPatch_subroutine);
2037         if (!points || (points->size() < 1)) {
2038             fprintf(stderr, "**Failed** test #23 (local variables)\n");
2039             fprintf(stderr, "  Unable to find point call23_1 - subroutine calls\n");
2040             exit(1);
2041         }
2042         appThread->insertSnippet(allParts, *points);
2043     }
2044 #endif
2045 }
2046
2047 //
2048 // Start Test Case #24 - array variables
2049 //
2050 void mutatorTest24(BPatch_thread *appThread, BPatch_image *appImage)
2051 {
2052 #if !defined(mips_sgi_irix6_4)
2053     if (!mutateeFortran) {
2054         //     First verify that we can find function call24_1
2055         BPatch_function *call24_1func = appImage->findFunction("call24_1");
2056         if (call24_1func == NULL) {
2057             fprintf(stderr, "Unable to find function \"call24_1\".\n");
2058            return;
2059         }
2060
2061         //     Then verify that we can find a local variable in call24_1
2062         BPatch_Vector<BPatch_point *> *temp =
2063         appImage->findProcedurePoint("call24_1", BPatch_subroutine);
2064         if (!temp) {
2065             fprintf(stderr, "**Failed** test #24 (array variables)\n");
2066             fprintf(stderr, "  can't find function call24_1\n");
2067             return;
2068         } else {
2069             dprintf("Found %d callsites in function call24_1\n", temp->size());
2070         }
2071
2072         BPatch_Vector<BPatch_point *> *point24_1  =
2073             new(BPatch_Vector<BPatch_point *>);
2074         point24_1->push_back((*temp)[0]);
2075
2076         BPatch_Vector<BPatch_point *> *point24_2 =
2077             appImage->findProcedurePoint("call24_1", BPatch_exit);
2078
2079         BPatch_Vector<BPatch_point *> *point24_3 =
2080         appImage->findProcedurePoint("func24_1", BPatch_entry);
2081
2082         assert(point24_1 && point24_2 && point24_3);
2083
2084         BPatch_variableExpr *lvar;
2085         BPatch_variableExpr *gvar[10];
2086
2087         for (int i=1; i <= 9; i++) {
2088             char name[80];
2089
2090             sprintf(name, "globalVariable24_%d", i);
2091             gvar[i] = appImage->findVariable(name);
2092             if (!gvar[i]) {
2093                 fprintf(stderr, "**Failed** test #24 (array variables)\n");
2094                 fprintf(stderr, "  can't find variable globalVariable24_%d\n", i);
2095                 return;
2096             }
2097         }
2098
2099         lvar = appImage->findVariable(*(*point24_1)[0], "localVariable24_1");
2100         if (!lvar) {
2101             fprintf(stderr, "**Failed** test #24 (array variables)\n");
2102             fprintf(stderr, "  can't find variable localVariable24_1\n");
2103             return;
2104         }
2105
2106         //     globalVariable24_1[1] = 2400001
2107         BPatch_arithExpr assignment1(BPatch_assign,
2108             BPatch_arithExpr(BPatch_ref, *gvar[1], BPatch_constExpr(1)),
2109         BPatch_constExpr(2400001));
2110         appThread->insertSnippet(assignment1, *point24_1);
2111
2112         //     globalVariable24_1[globalVariable24_2] = 2400002
2113         BPatch_arithExpr assignment2(BPatch_assign,
2114             BPatch_arithExpr(BPatch_ref, *gvar[1], *gvar[2]),
2115         BPatch_constExpr(2400002));
2116         appThread->insertSnippet(assignment2, *point24_1);
2117
2118         //     globalVariable24_3 = globalVariable24_1[79]
2119         BPatch_arithExpr assignment3(BPatch_assign, *gvar[3],
2120             BPatch_arithExpr(BPatch_ref, *gvar[1], BPatch_constExpr(79)));
2121         appThread->insertSnippet(assignment3, *point24_1);
2122
2123         //     globalVariable24_5 = globalVariable24_1[globalVariable24_4]
2124         BPatch_arithExpr assignment4(BPatch_assign, *gvar[5],
2125             BPatch_arithExpr(BPatch_ref, *gvar[1], *gvar[4]));
2126         appThread->insertSnippet(assignment4, *point24_1);
2127
2128         // now the local variables
2129         //     localVariable24_1[1] = 2400005
2130         BPatch_arithExpr assignment5(BPatch_assign,
2131             BPatch_arithExpr(BPatch_ref, *lvar, BPatch_constExpr(1)),
2132             BPatch_constExpr(2400005));
2133         appThread->insertSnippet(assignment5, *point24_1);
2134
2135         //     localVariable24_1[globalVariable24_2] = 2400006
2136         BPatch_arithExpr assignment6(BPatch_assign,
2137             BPatch_arithExpr(BPatch_ref, *lvar, *gvar[2]),
2138             BPatch_constExpr(2400006));
2139         appThread->insertSnippet(assignment6, *point24_1);
2140
2141         //     globalVariable24_6 = localVariable24_1[79]
2142         BPatch_arithExpr assignment7(BPatch_assign, *gvar[6],
2143             BPatch_arithExpr(BPatch_ref, *lvar, BPatch_constExpr(79)));
2144         appThread->insertSnippet(assignment7, *point24_1);
2145
2146         //     globalVariable24_7 = localVariable24_1[globalVariable24_4]
2147         BPatch_arithExpr assignment8(BPatch_assign, *gvar[7],
2148             BPatch_arithExpr(BPatch_ref, *lvar, *gvar[4]));
2149         appThread->insertSnippet(assignment8, *point24_1);
2150
2151         // now test multi-dimensional arrays
2152         //         globalVariable24_8[2][3] = 2400011
2153         BPatch_arithExpr assignment9(BPatch_assign,
2154             BPatch_arithExpr(BPatch_ref, BPatch_arithExpr(BPatch_ref, *gvar[8],
2155             BPatch_constExpr(2)), BPatch_constExpr(3)), BPatch_constExpr(2400011));
2156         appThread->insertSnippet(assignment9, *point24_1);
2157
2158         // globalVariable24_9 = globalVariable24_8[7][9]
2159         BPatch_arithExpr assignment10(BPatch_assign, *gvar[9],
2160             BPatch_arithExpr(BPatch_ref, BPatch_arithExpr(BPatch_ref, *gvar[8],
2161             BPatch_constExpr(7)), BPatch_constExpr(9)));
2162       appThread->insertSnippet(assignment10, *point24_1);
2163     }
2164 #endif
2165 }
2166
2167 //
2168 // Start Test Case #25 - unary operators
2169 //
2170 void mutatorTest25(BPatch_thread *appThread, BPatch_image *appImage)
2171 {
2172         // Used as hack for Fortran to allow assignment of a pointer to an int
2173         bpatch->setTypeChecking (false);
2174 #if !defined(mips_sgi_irix6_4) && !defined(alpha_dec_osf4_0)
2175     //     First verify that we can find a local variable in call25_1
2176     BPatch_Vector<BPatch_point *> *point25_1;
2177     point25_1 = appImage->findProcedurePoint("call25_1", BPatch_entry);
2178
2179     assert(point25_1);
2180 //    assert(point25_1 && (point25_1->size() == 1));
2181
2182     BPatch_variableExpr *gvar[8];
2183
2184     for (int i=1; i <= 7; i++) {
2185         char name[80];
2186
2187         sprintf (name, "globalVariable25_%d", i);
2188         gvar [i] = findVariable (appImage, name, point25_1);
2189
2190         if (!gvar[i]) {
2191             fprintf(stderr, "**Failed** test #25 (unary operaors)\n");
2192             fprintf(stderr, "  can't find variable globalVariable25_%d\n", i);
2193             exit(-1);
2194         }
2195     }
2196
2197     //     globalVariable25_2 = &globalVariable25_1
2198 #if !defined(sparc_sun_solaris2_4) && \
2199     !defined(rs6000_ibm_aix4_1) && \
2200     !defined(alpha_dec_osf4_0) && \
2201     !defined(i386_unknown_linux2_0) && \
2202     !defined(ia64_unknown_linux2_4) && \
2203     !defined(i386_unknown_solaris2_5) && \
2204     !defined(i386_unknown_nt4_0)
2205
2206     // without type info need to inform
2207     BPatch_type *type = appImage->findType("void *");
2208     assert(type);
2209     gvar[2]->setType(type);
2210 #endif
2211
2212     BPatch_arithExpr assignment1(BPatch_assign, *gvar[2],
2213         BPatch_arithExpr(BPatch_addr, *gvar[1]));
2214
2215     appThread->insertSnippet(assignment1, *point25_1);
2216
2217     //     globalVariable25_3 = *globalVariable25_2
2218     //          Need to make sure this happens after the first one
2219     BPatch_arithExpr assignment2(BPatch_assign, *gvar[3],
2220         BPatch_arithExpr(BPatch_deref, *gvar[2]));
2221     appThread->insertSnippet(assignment2, *point25_1,  BPatch_callBefore,
2222             BPatch_lastSnippet);
2223
2224     //     globalVariable25_5 = -globalVariable25_4
2225     BPatch_arithExpr assignment3(BPatch_assign, *gvar[5],
2226         BPatch_arithExpr(BPatch_negate, *gvar[4]));
2227     appThread->insertSnippet(assignment3, *point25_1);
2228
2229     //     globalVariable25_7 = -globalVariable25_6
2230     BPatch_arithExpr assignment4(BPatch_assign, *gvar[7],
2231         BPatch_arithExpr(BPatch_negate, *gvar[6]));
2232     appThread->insertSnippet(assignment4, *point25_1);
2233 #endif
2234         bpatch->setTypeChecking (true);
2235 }
2236
2237
2238 //
2239 // Start Test Case #26 - struct elements
2240 //
2241 void mutatorTest26(BPatch_thread *appThread, BPatch_image *appImage)
2242 {
2243 #if !defined(mips_sgi_irix6_4) && !defined(alpha_dec_osf4_0)
2244
2245     if (!mutateeFortran) {
2246         //     First verify that we can find a local variable in call26_1
2247         BPatch_Vector<BPatch_point *> *point26_1;
2248         point26_1 = appImage->findProcedurePoint("call26_1", BPatch_subroutine);
2249
2250         BPatch_Vector<BPatch_point *> *point26_2;
2251         point26_2 = appImage->findProcedurePoint("func26_1", BPatch_subroutine);
2252
2253         assert(point26_1 && (point26_1->size() == 1));
2254         assert(point26_2);
2255
2256         BPatch_variableExpr *lvar;
2257         BPatch_variableExpr *gvar[14];
2258
2259         int i;
2260         for (i=1; i <= 13; i++) {
2261             char name[80];
2262
2263             sprintf (name, "globalVariable26_%d", i);
2264             gvar [i] = findVariable(appImage, name, point26_2);
2265
2266             if (!gvar[i]) {
2267                 fprintf(stderr, "**Failed** test #26 (struct elements)\n");
2268                 fprintf(stderr, "  can't find variable globalVariable26_%d\n", i);
2269                 exit(-1);
2270             }
2271         }
2272
2273         // start of code for globalVariable26_1
2274         BPatch_Vector<BPatch_variableExpr *> *fields = gvar[1]->getComponents();
2275         if (!fields) {
2276             fprintf(stderr, "**Failed** test #26 (struct elements)\n");
2277             fprintf(stderr, "  struct lacked correct number of elements\n");
2278             exit(-1);
2279         }
2280
2281         for (i=0; i < 4; i++) {
2282             char fieldName[80];
2283             sprintf(fieldName, "field%d", i+1);
2284             if (!(*fields)[i]->getName())
2285                 printf("NULL NAME!\n");
2286             if (strcmp(fieldName, (*fields)[i]->getName())) {
2287                 printf("field %d of the struct is %s, not %s\n",
2288                     i+1, fieldName, (*fields)[i]->getName());
2289                 return;
2290             }
2291         }
2292
2293             //     globalVariable26_2 = globalVariable26_1.field1
2294         BPatch_arithExpr assignment1(BPatch_assign, *gvar[2], *((*fields)[0]));
2295             appThread->insertSnippet(assignment1, *point26_2);
2296
2297         //         globalVariable26_3 = globalVariable26_1.field2
2298             BPatch_arithExpr assignment2(BPatch_assign, *gvar[3], *((*fields)[1]));
2299         appThread->insertSnippet(assignment2, *point26_2);
2300
2301             //     globalVariable26_4 = globalVariable26_1.field3[0]
2302         BPatch_arithExpr assignment3(BPatch_assign, *gvar[4],
2303                 BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(0)));
2304         appThread->insertSnippet(assignment3, *point26_2);
2305
2306             //     globalVariable26_5 = globalVariable26_1.field3[5]
2307         BPatch_arithExpr assignment4(BPatch_assign, *gvar[5],
2308                 BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(5)));
2309         appThread->insertSnippet(assignment4, *point26_2);
2310
2311             BPatch_Vector<BPatch_variableExpr *> *subfields =
2312                 (*fields)[3]->getComponents();
2313             assert(subfields != NULL);
2314
2315         //         globalVariable26_6 = globalVariable26_1.field4.field1
2316             BPatch_arithExpr assignment5(BPatch_assign, *gvar[6], *((*subfields)[0]));
2317         appThread->insertSnippet(assignment5, *point26_2);
2318
2319             //     globalVariable26_7 = globalVariable26_1.field4.field2
2320         BPatch_arithExpr assignment6(BPatch_assign, *gvar[7], *((*subfields)[1]));
2321             appThread->insertSnippet(assignment6, *point26_2);
2322
2323         // start of code for localVariable26_1
2324         expectError = 100;
2325         lvar = appImage->findVariable(*(*point26_1) [0], "localVariable26_1");
2326         if (!lvar)
2327             lvar = appImage->findVariable(*(*point26_1) [0], "localvariable26_1");
2328         assert(lvar);
2329         expectError = DYNINST_NO_ERROR;
2330
2331         fields = lvar->getComponents();
2332         if (!fields || (fields->size() < 4)) {
2333             fprintf(stderr, "**Failed** test #26 (struct elements)\n");
2334             fprintf(stderr, "  struct lacked correct number of elements\n");
2335             exit(-1);
2336         }
2337
2338             for (i=0; i < 4; i++) {
2339                  char fieldName[80];
2340                  sprintf(fieldName, "field%d", i+1);
2341                  if (strcmp(fieldName, (*fields)[i]->getName())) {
2342                   printf("field %d of the local struct is %s, not %s\n",
2343                           i+1, fieldName, (*fields)[i]->getName());
2344                       return;
2345                  }
2346         }
2347
2348             //     globalVariable26_8 = localVariable26_1.field1
2349         BPatch_arithExpr assignment7(BPatch_assign, *gvar[8], *((*fields)[0]));
2350             appThread->insertSnippet(assignment7, *point26_1);
2351
2352         //         globalVariable26_9 = localVariable26_1.field2
2353             BPatch_arithExpr assignment8(BPatch_assign, *gvar[9], *((*fields)[1]));
2354         appThread->insertSnippet(assignment8, *point26_1);
2355
2356             //     globalVariable26_10 = localVariable26_1.field3[0]
2357         BPatch_arithExpr assignment9(BPatch_assign, *gvar[10],
2358                 BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(0)));
2359         appThread->insertSnippet(assignment9, *point26_1);
2360
2361             //     globalVariable26_11 = localVariable26_1.field3[5]
2362         BPatch_arithExpr assignment10(BPatch_assign, *gvar[11],
2363                 BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(5)));
2364         appThread->insertSnippet(assignment10, *point26_1);
2365
2366             subfields = (*fields)[3]->getComponents();
2367         assert(subfields != NULL);
2368
2369             //     globalVariable26_12 = localVariable26_1.field4.field1
2370         BPatch_arithExpr assignment11(BPatch_assign, *gvar[12], *((*subfields)[0]));
2371             appThread->insertSnippet(assignment11, *point26_1);
2372
2373             //     globalVariable26_13 = localVariable26_1.field4.field2
2374         BPatch_arithExpr assignment12(BPatch_assign, *gvar[13], *((*subfields)[1]));
2375             appThread->insertSnippet(assignment12, *point26_1);
2376     }
2377 #endif
2378 }
2379
2380 //
2381 // Start Test Case #27 - type compatibility
2382 //
2383 void mutatorTest27(BPatch_thread *, BPatch_image *appImage)
2384 {
2385 #if !defined(mips_sgi_irix6_4)
2386
2387     BPatch_type *type27_1 = appImage->findType("type27_1");
2388     BPatch_type *type27_2 = appImage->findType("type27_2");
2389     BPatch_type *type27_3 = appImage->findType("type27_3");
2390     BPatch_type *type27_4 = appImage->findType("type27_4");
2391
2392     if (!type27_1 || !type27_2 || !type27_3 || !type27_4) {
2393         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2394         fprintf(stderr, "    Unable to locate one of type27_{1,2,3,4}\n");
2395         return;
2396     }
2397
2398     if (!type27_1->isCompatible(type27_2)) {
2399         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2400         fprintf(stderr,"    type27_1 reported as incompatibile with type27_2\n");
2401         return;
2402     }
2403
2404     if (!type27_2->isCompatible(type27_1)) {
2405         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2406         fprintf(stderr,"    type27_2 reported as incompatibile with type27_1\n");
2407         return;
2408     }
2409
2410     if (!type27_3->isCompatible(type27_3)) {
2411         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2412         fprintf(stderr,"    type27_3 reported as incompatibile with type27_4\n");
2413         return;
2414     }
2415
2416     if (!type27_4->isCompatible(type27_3)) {
2417         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2418         fprintf(stderr,"    type27_4 reported as incompatibile with type27_3\n");
2419         return;
2420     }
2421
2422     expectError = 112; // We're expecting type conflicts here
2423     if (type27_1->isCompatible(type27_3)) {
2424         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2425         fprintf(stderr,"    type27_1 reported as compatibile with type27_3\n");
2426         return;
2427     }
2428
2429     if (type27_4->isCompatible(type27_2)) {
2430         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2431         fprintf(stderr,"    type27_4 reported as compatibile with type27_2\n");
2432         return;
2433     }
2434     expectError = DYNINST_NO_ERROR;
2435
2436     BPatch_Vector<BPatch_point *> *point27_1;
2437     point27_1 = appImage->findProcedurePoint("func27_1", BPatch_entry);
2438
2439     assert (point27_1);
2440
2441     BPatch_variableExpr *expr27_5, *expr27_6, *expr27_7, *expr27_8;
2442
2443     expr27_5 = findVariable(appImage, "globalVariable27_5", point27_1);
2444     expr27_6 = findVariable(appImage, "globalVariable27_6", point27_1);
2445     expr27_7 = findVariable(appImage, "globalVariable27_7", point27_1);
2446     expr27_8 = findVariable(appImage, "globalVariable27_8", point27_1);
2447
2448     assert(expr27_5 && expr27_6 && expr27_7 && expr27_8);
2449
2450     BPatch_type *type27_5 = const_cast<BPatch_type *> (expr27_5->getType());
2451     BPatch_type *type27_6 = const_cast<BPatch_type *> (expr27_6->getType());
2452     BPatch_type *type27_7 = const_cast<BPatch_type *> (expr27_7->getType());
2453     BPatch_type *type27_8 = const_cast<BPatch_type *> (expr27_8->getType());
2454
2455     assert(type27_5 && type27_6 && type27_7 && type27_8);
2456
2457     if (!type27_5->isCompatible(type27_6)) {
2458         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2459         fprintf(stderr,"    type27_5 reported as incompatibile with type27_6\n");
2460         return;
2461     }
2462
2463     // difderent number of elements
2464     expectError = 112; // We're expecting type conflicts here
2465     if (type27_5->isCompatible(type27_7)) {
2466         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2467         fprintf(stderr,"    type27_5 reported as compatibile with type27_7\n");
2468         return;
2469     }
2470
2471     // same # of elements, different type
2472     if (type27_5->isCompatible(type27_8)) {
2473         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2474         fprintf(stderr,"    type27_5 reported as compatibile with type27_8\n");
2475         return;
2476     }
2477
2478     // all ok, set the global variable, depends on test 18 working
2479     BPatch_variableExpr *expr27_1 = findVariable(appImage, "globalVariable27_1", point27_1);
2480
2481     if (expr27_1 == NULL) {
2482         fprintf(stderr, "**Failed** test #27 (type compatibility)\n");
2483         fprintf(stderr, "    Unable to locate globalVariable27_1\n");
2484         return;
2485     }
2486     expectError = DYNINST_NO_ERROR;
2487
2488     int n = 1;
2489     expr27_1->writeValue(&n);
2490 #endif
2491 }
2492
2493 //
2494 // Start Test Case #28 - user defined fields
2495 //
2496 void mutatorTest28(BPatch_thread *appThread, BPatch_image *appImage)
2497 {
2498     int i;
2499
2500     //     Create the types
2501     BPatch_type *intType = appImage->findType("int");
2502     assert(intType);
2503
2504     BPatch_Vector<char *> names;
2505     BPatch_Vector<BPatch_type *> types;
2506
2507     if (mutateeFortran) {
2508         return;
2509     }
2510
2511     names.push_back("field1");
2512     names.push_back("field2");
2513     types.push_back(intType);
2514     types.push_back(intType);
2515
2516     //  struct28_1 { int field1, int field 2; }
2517     BPatch_type *struct28_1 = bpatch->createStruct("struct28_1", names, types);
2518
2519     names.push_back("field3");
2520     names.push_back("field4");
2521     BPatch_type *intArray = bpatch->createArray("intArray", intType, 0, 9);
2522     types.push_back(intArray);
2523     types.push_back(struct28_1);
2524
2525     // struct28_2 { int field1, int field 2, int field3[10],struct26_1 field4 } 
2526     BPatch_type *struct28_2 = bpatch->createStruct("struct28_2", names, types);
2527
2528     // now create variables of these types.
2529     BPatch_variableExpr *globalVariable28_1 = 
2530         appImage->findVariable("globalVariable28_1");
2531     globalVariable28_1->setType(struct28_2);
2532
2533     //     Next verify that we can find a local variable in call28
2534     BPatch_Vector<BPatch_point *> *point28 =
2535         appImage->findProcedurePoint("call28_1", BPatch_entry);
2536
2537     assert(point28 && (point28->size() == 1));
2538
2539     BPatch_variableExpr *gvar[8];
2540
2541     for (i=1; i <= 7; i++) {
2542         char name[80];
2543
2544         sprintf(name, "globalVariable28_%d", i);
2545         gvar[i] = appImage->findVariable(name);
2546         if (!gvar[i]) {
2547             fprintf(stderr, "**Failed** test #28 (user defined fields)\n");
2548             fprintf(stderr, "  can't find variable globalVariable28_%d\n", i);
2549             exit(-1);
2550         }
2551     }
2552
2553     // start of code for globalVariable28
2554     BPatch_Vector<BPatch_variableExpr *> *fields = gvar[1]->getComponents();
2555     assert(fields && (fields->size() == 4));
2556
2557     for (i=0; i < 4; i++) {
2558          char fieldName[80];
2559          sprintf(fieldName, "field%d", i+1);
2560          if (strcmp(fieldName, (*fields)[i]->getName())) {
2561               printf("field %d of the struct is %s, not %s\n",
2562                   i+1, fieldName, (*fields)[i]->getName());
2563               return;
2564          }
2565     }
2566
2567     //     globalVariable28 = globalVariable28.field1
2568     BPatch_arithExpr assignment1(BPatch_assign, *gvar[2], *((*fields)[0]));
2569     appThread->insertSnippet(assignment1, *point28);
2570
2571     //     globalVariable28 = globalVariable28.field2
2572     BPatch_arithExpr assignment2(BPatch_assign, *gvar[3], *((*fields)[1]));
2573     appThread->insertSnippet(assignment2, *point28);
2574
2575     //     globalVariable28 = globalVariable28.field3[0]
2576     BPatch_arithExpr assignment3(BPatch_assign, *gvar[4], 
2577         BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(0)));
2578     appThread->insertSnippet(assignment3, *point28);
2579
2580     //     globalVariable28 = globalVariable28.field3[5]
2581     BPatch_arithExpr assignment4(BPatch_assign, *gvar[5], 
2582         BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(5)));
2583     appThread->insertSnippet(assignment4, *point28);
2584
2585     BPatch_Vector<BPatch_variableExpr *> *subfields = 
2586         (*fields)[3]->getComponents();
2587     assert(subfields != NULL);
2588
2589     //     globalVariable28 = globalVariable28.field4.field1
2590     BPatch_arithExpr assignment5(BPatch_assign, *gvar[6], *((*subfields)[0]));
2591     appThread->insertSnippet(assignment5, *point28);
2592
2593     //     globalVariable28 = globalVariable28.field4.field2
2594     BPatch_arithExpr assignment6(BPatch_assign, *gvar[7], *((*subfields)[1]));
2595     appThread->insertSnippet(assignment6, *point28);
2596 }
2597
2598 bool printSrcObj(BPatch_sourceObj *p, int level)
2599 {
2600     unsigned int i;
2601     bool ret = true;
2602
2603     BPatch_Vector<BPatch_sourceObj *> curr;
2604
2605     if (!p) return(true);
2606
2607     switch (p->getSrcType()) {
2608         case BPatch_sourceProgram:
2609             if (level != 0) ret = false;
2610             break;
2611
2612         case BPatch_sourceModule: 
2613             if (level != 1) ret = false;
2614             break;
2615
2616         case BPatch_sourceFunction: 
2617             if (level != 2) ret = false;
2618             break;
2619
2620         default:
2621             printf("<unknown type>");
2622     }
2623
2624     if (!p->getSourceObj(curr)) {
2625         // eveything down to functions should have something
2626         return((level == 2) ? true : false);
2627     }
2628
2629     for (i=0; i < curr.size(); i++) {
2630         p = curr[i];
2631         ret = printSrcObj(p, level+1) && ret;
2632     }
2633
2634     return ret;
2635 }
2636
2637 //
2638 // Start Test Case #29 - getParent/Child
2639 //
2640 void mutatorTest29(BPatch_thread *, BPatch_image *appImage)
2641 {
2642     BPatch_sourceObj *p;
2643
2644     p = (BPatch_sourceObj *) appImage;
2645     passedTest[29] = printSrcObj(p, 0);
2646
2647     if (!passedTest[29]) {
2648         fprintf(stderr, "**Failed** test #29 (class BPatch_srcObj)\n");
2649         return;
2650     }
2651
2652     BPatch_Vector<BPatch_point *> *point29_1;
2653     point29_1 = appImage->findProcedurePoint("func29_1", BPatch_entry);
2654
2655     assert (point29_1);
2656
2657     BPatch_variableExpr *expr29_1 = findVariable(appImage, "globalVariable29_1", point29_1);
2658
2659     if (expr29_1 == NULL) {
2660         fprintf(stderr, "**Failed** test #29 (class BPatch_srcObj)\n");
2661         fprintf(stderr, "    Unable to locate globalVariable27_1\n");
2662         return;
2663     }
2664     expectError = DYNINST_NO_ERROR;
2665
2666     int n = 1;
2667     expr29_1->writeValue(&n);
2668 }
2669
2670 //
2671 // Start Test Case #30 - (line information)
2672 //
2673 void mutatorTest30(BPatch_thread *appThread, BPatch_image *appImage)
2674 {
2675
2676 #if defined(sparc_sun_solaris2_4) || \
2677     defined(i386_unknown_solaris2_5) || \
2678     defined(i386_unknown_linux2_0) || \
2679     defined(ia64_unknown_linux2_4) || \
2680     defined(i386_unknown_nt4_0) ||\
2681     defined(rs6000_ibm_aix4_1) || \
2682     defined(alpha_dec_osf4_0)
2683
2684   unsigned n;
2685   unsigned long baseAddr,lastAddr;
2686   unsigned int call30_1_line_no;
2687   unsigned short lineNo;
2688   char fileName[256];
2689
2690         if (mutateeFortran) {
2691             return;
2692         } 
2693
2694         //instrument with the function that will set the line number
2695         BPatch_Vector<BPatch_point *> *point30_1 =
2696                 appImage->findProcedurePoint("func30_1", BPatch_entry);
2697         if (!point30_1 || (point30_1->size() < 1)) {
2698                 fprintf(stderr, "Unable to find point func30_1 - entry.\n");
2699                 exit(-1);
2700         }
2701         BPatch_function *call30_1func = appImage->findFunction("call30_1");
2702         if (call30_1func == NULL) {
2703                 fprintf(stderr, "Unable to find function \"call30_1.\"\n");
2704                 exit(1);
2705         }
2706         BPatch_Vector<BPatch_snippet *> nullArgs;
2707         BPatch_funcCallExpr call30_1Expr(*call30_1func, nullArgs);
2708
2709         checkCost(call30_1Expr);
2710         appThread->insertSnippet(call30_1Expr, *point30_1);
2711
2712         //get the line number of the function call30_1
2713         BPatch_variableExpr *expr30_7 = 
2714                 appImage->findVariable("globalVariable30_7");
2715         if (expr30_7 == NULL) {
2716                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2717                 fprintf(stderr, "    Unable to locate globalVariable30_7\n");
2718                 exit(1);
2719         }
2720         expr30_7->readValue(&n);
2721         call30_1_line_no = (unsigned)(n+1);
2722
2723         //get the base addr and last addr of the function call30_1
2724         baseAddr = (unsigned long)(call30_1func->getBaseAddr());
2725         lastAddr = baseAddr + call30_1func->getSize();
2726
2727         //now write the base address and last address of the function
2728         BPatch_variableExpr *expr30_8 = 
2729                         appImage->findVariable("globalVariable30_8");
2730         if (expr30_8 == NULL) {
2731                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2732                 fprintf(stderr, "    Unable to locate globalVariable30_8\n");
2733         }
2734
2735         BPatch_variableExpr *expr30_9 = 
2736                         appImage->findVariable("globalVariable30_9");
2737         if (expr30_9 == NULL) {
2738                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2739                 fprintf(stderr, "    Unable to locate globalVariable30_9\n");
2740         }
2741
2742         expr30_8->writeValue(&baseAddr);
2743         expr30_9->writeValue(&lastAddr);
2744         
2745         
2746         //check getLineAddr for appImage
2747         BPatch_variableExpr *expr30_3 =
2748                         appImage->findVariable("globalVariable30_3");
2749         if (expr30_3 == NULL) {
2750                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2751                 fprintf(stderr, "    Unable to locate globalVariable30_3\n");
2752                 exit(1);
2753         }
2754         BPatch_Vector<unsigned long> buffer1; 
2755         if(appImage->getLineToAddr("test1.mutatee.c",call30_1_line_no,buffer1))
2756         {
2757                 n = buffer1[0];
2758                 expr30_3->writeValue(&n);
2759         }
2760
2761         //check getLineAddr for module
2762         BPatch_variableExpr *expr30_4 =
2763                         appImage->findVariable("globalVariable30_4");
2764         if (expr30_4 == NULL) {
2765                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2766                 fprintf(stderr, "    Unable to locate globalVariable30_4\n");
2767                 exit(1);
2768         }
2769         BPatch_Vector<BPatch_module*>* appModules = appImage->getModules();
2770         for(unsigned int i=0;i<appModules->size();i++){
2771                 char mname[256];
2772                 (*appModules)[i]->getName(mname,255);mname[255] = '\0';
2773                 if(!strncmp(mname,"test1.mutatee.c",15)){
2774                         BPatch_Vector<unsigned long> buffer2;
2775                         if((*appModules)[i]->getLineToAddr(
2776                                         call30_1_line_no,buffer2))
2777                         {
2778                                 n = buffer2[0];
2779                                 expr30_4->writeValue(&n);
2780                         }
2781                         break;
2782                 }
2783         }
2784
2785         //check getLineAddr works for the function
2786         BPatch_variableExpr *expr30_5 =
2787                 appImage->findVariable("globalVariable30_5");
2788         if (expr30_5 == NULL) {
2789                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2790                 fprintf(stderr, "    Unable to locate globalVariable30_5\n");
2791                 exit(1);
2792         }
2793         BPatch_Vector<unsigned long> buffer3; 
2794         if(call30_1func->getLineToAddr(call30_1_line_no,buffer3))
2795         {
2796                 n = buffer3[0];
2797                 expr30_5->writeValue(&n);
2798         }
2799
2800         //check whether getLineFile works for appThread
2801         BPatch_variableExpr *expr30_6 =
2802                 appImage->findVariable("globalVariable30_6");
2803         if (expr30_6 == NULL) {
2804                 fprintf(stderr, "**Failed** test #30 (line information)\n");
2805                 fprintf(stderr, "    Unable to locate globalVariable30_6\n");
2806                 exit(1);
2807         }
2808         /* since the first line address of a function changes with the
2809            compiler type (gcc,native) we need to check with next address
2810            etc. Instead I use the last address of the function*/
2811         if(appThread->getLineAndFile(lastAddr-1,lineNo,fileName,256)){
2812                 n = lineNo;
2813                 expr30_6->writeValue(&n);
2814         }
2815 #endif
2816 }
2817
2818 /*******************************************************************************/
2819 /*******************************************************************************/
2820 /*******************************************************************************/
2821
2822 typedef BPatch_Vector<BPatch_point * > point_vector;
2823 // typedef vector<BPatchSnippetHandle * > handle_vector;
2824
2825 void instrument_entry_points( BPatch_thread * app_thread,
2826                               BPatch_image * ,
2827                               BPatch_function * func,
2828                               BPatch_snippet * code )
2829 {
2830   assert( func != 0 );
2831   assert( code != 0 );
2832
2833 //   handle_vector * list_of_handles = new handle_vector;
2834
2835   int null_entry_point_count = 0;
2836   int failed_snippet_insertion_count = 0;
2837
2838   point_vector * entries = func->findPoint( BPatch_entry );
2839   assert( entries != 0 );
2840
2841   for( unsigned int i = 0; i < entries->size(); i++ )
2842     {
2843       BPatch_point * point = ( * entries )[ i ];
2844       if( point == 0 )
2845         {
2846           null_entry_point_count++;
2847         }
2848       else
2849         {
2850           BPatchSnippetHandle * result =
2851             app_thread->insertSnippet( * code,
2852                                        * point, BPatch_callBefore, BPatch_firstSnippet );
2853           if( result == 0 )
2854             {
2855               failed_snippet_insertion_count++;
2856             }
2857 //        else
2858 //          {
2859 //            list_of_handles->push_back( result );
2860 //          }
2861         }
2862     }
2863
2864   delete code;
2865
2866 //   return * list_of_handles;
2867 }
2868
2869 /*******************************************************************************/
2870 /*******************************************************************************/
2871 /*******************************************************************************/
2872
2873 void instrument_exit_points( BPatch_thread * app_thread,
2874                              BPatch_image * ,
2875                              BPatch_function * func,
2876                              BPatch_snippet * code )
2877 {
2878   assert( func != 0 );
2879   assert( code != 0 );
2880
2881 //   handle_vector * list_of_handles = new handle_vector;
2882
2883   int null_exit_point_count = 0;
2884   int failed_snippet_insertion_count = 0;
2885
2886   point_vector * exits = func->findPoint( BPatch_exit );
2887   assert( exits != 0 );
2888
2889   for( unsigned int i = 0; i < exits->size(); i++ )
2890     {
2891       BPatch_point * point = ( * exits )[ i ];
2892       if( point == 0 )
2893         {
2894           null_exit_point_count++;
2895         }
2896       else
2897         {
2898           BPatchSnippetHandle * result =
2899             app_thread->insertSnippet( * code,
2900                                        * point, BPatch_callAfter, BPatch_firstSnippet );
2901           if( result == 0 )
2902             {
2903               failed_snippet_insertion_count++;
2904             }
2905 //        else
2906 //          {
2907 //            list_of_handles->push_back( result );
2908 //          }
2909         }
2910     }
2911
2912   delete code;
2913
2914 //   return * list_of_handles;
2915 }
2916
2917 /*******************************************************************************/
2918 /*******************************************************************************/
2919 /*******************************************************************************/
2920
2921 //
2922 // Start Test Case #31 - (non-recursive base tramp)
2923 //
2924 void mutatorTest31( BPatch_thread * appThread, BPatch_image * appImage )
2925 {
2926     char * foo_name = "func31_2";
2927     char * bar_name = "func31_3";
2928     char * baz_name = "func31_4";
2929
2930   BPatch_image * app_image = appImage;
2931   BPatch_thread * app_thread = appThread;
2932
2933   BPatch_function *foo_function;
2934   foo_function = app_image->findFunction(foo_name);
2935
2936   if( foo_function == 0 )
2937     {
2938       fprintf( stderr, "Cannot find \"%s\" function.",
2939                foo_name );
2940       exit( -1 );
2941     }
2942
2943   BPatch_function *bar_function;
2944   bar_function = app_image->findFunction(bar_name);
2945
2946   if( bar_function == 0 )
2947     {
2948       fprintf( stderr, "Cannot find \"%s\" function.",
2949                bar_name );
2950       exit( -1 );
2951     }
2952
2953   BPatch_function *baz_function;
2954   baz_function = app_image->findFunction(baz_name);
2955
2956   if( baz_function == 0 )
2957     {
2958       fprintf( stderr, "Cannot find \"%s\" function.",
2959                baz_name );
2960       exit( -1 );
2961     }
2962
2963   bool old_value = BPatch::bpatch->isTrampRecursive();
2964   BPatch::bpatch->setTrampRecursive( false );
2965
2966   BPatch_Vector<BPatch_snippet *> foo_args;
2967   BPatch_snippet * foo_snippet =
2968     new BPatch_funcCallExpr( * bar_function,
2969                              foo_args );
2970   instrument_entry_points( app_thread, app_image, foo_function, foo_snippet );
2971
2972   BPatch_Vector<BPatch_snippet *> bar_args_1;
2973   bar_args_1.push_back( new BPatch_constExpr( 1 ) );
2974   BPatch_snippet * bar_snippet_1 =
2975     new BPatch_funcCallExpr( * baz_function,
2976                              bar_args_1 );
2977   instrument_entry_points( app_thread, app_image, bar_function, bar_snippet_1 );
2978
2979   BPatch_Vector<BPatch_snippet *> bar_args_2;
2980   bar_args_2.push_back( new BPatch_constExpr( 2 ) );
2981   BPatch_snippet * bar_snippet_2 =
2982     new BPatch_funcCallExpr( * baz_function,
2983                              bar_args_2 );
2984   instrument_exit_points( app_thread, app_image, bar_function, bar_snippet_2 );
2985
2986   BPatch::bpatch->setTrampRecursive( old_value );
2987 }
2988
2989 /*******************************************************************************/
2990 /*******************************************************************************/
2991 /*******************************************************************************/
2992
2993 //
2994 // Start Test Case #32 - (recursive base tramp)
2995 //
2996 void mutatorTest32( BPatch_thread * appThread, BPatch_image * appImage )
2997 {
2998   char * foo_name = "func32_2";
2999   char * bar_name = "func32_3";
3000   char * baz_name = "func32_4";
3001
3002   BPatch_image * app_image = appImage;
3003   BPatch_thread * app_thread = appThread;
3004
3005   BPatch_function * foo_function;
3006   foo_function = app_image->findFunction(foo_name);
3007
3008   if( foo_function == 0 )
3009   {
3010     fprintf( stderr, "Cannot find \"%s\" function.",
3011        foo_name );
3012     exit( -1 );
3013   }
3014
3015   BPatch_function * bar_function;
3016   bar_function = app_image->findFunction(bar_name);
3017
3018   if( bar_function == 0 )
3019     {
3020       fprintf( stderr, "Cannot find \"%s\" function.",
3021                bar_name );
3022       exit( -1 );
3023     }
3024   BPatch_function * baz_function;
3025   baz_function = app_image->findFunction(baz_name);
3026
3027   if( baz_function == 0 )
3028     {
3029       fprintf( stderr, "Cannot find \"%s\" function.",
3030                baz_name );
3031       exit( -1 );
3032     }
3033
3034   bool old_value = BPatch::bpatch->isTrampRecursive();
3035   BPatch::bpatch->setTrampRecursive( true );
3036
3037   BPatch_Vector<BPatch_snippet *> foo_args;
3038   BPatch_snippet * foo_snippet =
3039     new BPatch_funcCallExpr( * bar_function,
3040                              foo_args );
3041   instrument_entry_points( app_thread, app_image, foo_function, foo_snippet );
3042
3043   BPatch_Vector<BPatch_snippet *> bar_args_1;
3044
3045   if (mutateeFortran) {
3046     BPatch_variableExpr *expr32_1 = appThread->malloc (*appImage->findType ("int"));
3047     BPatch_constExpr expr32_2 = expr32_1->getBaseAddr ();
3048
3049     BPatch_arithExpr expr32_3 (BPatch_assign, *expr32_1, BPatch_constExpr(1));
3050
3051     appThread->oneTimeCode (expr32_3);
3052     bar_args_1.push_back (&expr32_2);
3053   } else {
3054     bar_args_1.push_back (new BPatch_constExpr (1));
3055   }
3056
3057   bar_args_1.push_back (new BPatch_constExpr (1));
3058   BPatch_snippet * bar_snippet_1 =
3059     new BPatch_funcCallExpr( * baz_function,
3060                              bar_args_1 );
3061   instrument_entry_points( app_thread, app_image, bar_function, bar_snippet_1 );
3062
3063   BPatch_Vector<BPatch_snippet *> bar_args_2;
3064
3065   if (mutateeFortran) {
3066     BPatch_variableExpr *expr32_4 = appThread->malloc (*appImage->findType ("int"));
3067     BPatch_constExpr expr32_5 = expr32_4->getBaseAddr ();
3068
3069     BPatch_arithExpr expr32_6 (BPatch_assign, *expr32_4, BPatch_constExpr (2));
3070     appThread->oneTimeCode (expr32_6);
3071     bar_args_2.push_back (&expr32_5);
3072   } else {
3073     bar_args_2.push_back (new BPatch_constExpr (2));
3074   }
3075
3076   BPatch_snippet * bar_snippet_2 =
3077     new BPatch_funcCallExpr( * baz_function,
3078                              bar_args_2 );
3079   instrument_exit_points( app_thread, app_image, bar_function, bar_snippet_2 );
3080
3081   BPatch::bpatch->setTrampRecursive( old_value );
3082 }
3083
3084 /*******************************************************************************/
3085 /*******************************************************************************/
3086 /*******************************************************************************/
3087
3088 //
3089 // Start Test Case #33 - (control flow graphs)
3090 //
3091
3092 bool hasBackEdge(BPatch_basicBlock *bb, BPatch_Set<int> visited)
3093 {
3094     if (visited.contains(bb->getBlockNumber()))
3095         return true;
3096
3097     visited.insert(bb->getBlockNumber());
3098
3099     BPatch_Vector<BPatch_basicBlock*> targets;
3100     bb->getTargets(targets);
3101
3102     unsigned int i;
3103     for (i = 0; i < targets.size(); i++) {
3104         if (hasBackEdge(targets[i], visited))
3105             return true;
3106     }
3107
3108     return false;
3109 }
3110
3111 void mutatorTest33( BPatch_thread * /*appThread*/, BPatch_image * appImage )
3112 {
3113     unsigned int i;
3114
3115     BPatch_function *func2;
3116     BPatch_function *func3;
3117
3118     if (mutateeFortran) {
3119         return;
3120     }
3121
3122     func2 = appImage->findFunction("func33_2");
3123
3124     if (func2 == NULL) {
3125         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3126         fprintf(stderr, "  Unable to find function func33_2\n");
3127         exit(1);
3128     }
3129
3130     BPatch_flowGraph *cfg = func2->getCFG();
3131     if (cfg == NULL) {
3132         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3133         fprintf(stderr, "  Unable to get control flow graph of func33_2\n");
3134         exit(1);
3135     }
3136
3137     /*
3138      * Test for consistency of entry basic blocks.
3139      */
3140     BPatch_Vector<BPatch_basicBlock*> entry_blocks;
3141     cfg->getEntryBasicBlock(entry_blocks);
3142
3143     if (entry_blocks.size() != 1) {
3144             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3145             fprintf(stderr, "  Detected %d entry basic blocks in func33_2, should have been one.\n", entry_blocks.size());
3146     }
3147
3148     for (i = 0; i < entry_blocks.size(); i++) {
3149         BPatch_Vector<BPatch_basicBlock*> sources;
3150         entry_blocks[i]->getSources(sources);
3151         if (sources.size() > 0) {
3152             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3153             fprintf(stderr, "  An entry basic block has incoming edges in the control flow graph\n");
3154             exit(1);
3155         }
3156
3157         BPatch_Vector<BPatch_basicBlock*> targets;
3158         entry_blocks[i]->getTargets(targets);
3159         if (targets.size() < 1) {
3160             fprintf(stderr, "**Failed** test #33 (control flow graphs\n");
3161             fprintf(stderr, "  An entry basic block has no outgoing edges in the control flow graph\n");
3162             exit(1);
3163         }
3164     }
3165
3166     /*
3167      * Test for consistency of exit basic blocks.
3168      */
3169     BPatch_Vector<BPatch_basicBlock*> exit_blocks;
3170     cfg->getExitBasicBlock(exit_blocks);
3171
3172     if (exit_blocks.size() != 1) {
3173             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3174             fprintf(stderr, "  Detected %d exit basic blocks in func33_2, should have been one.\n", exit_blocks.size());
3175     }
3176
3177     for (i = 0; i < exit_blocks.size(); i++) {
3178         BPatch_Vector<BPatch_basicBlock*> sources;
3179         exit_blocks[i]->getSources(sources);
3180         if (sources.size() < 1) {
3181             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3182             fprintf(stderr, "  An exit basic block has no incoming edges in the control flow graph\n");
3183             exit(1);
3184         }
3185
3186         BPatch_Vector<BPatch_basicBlock*> targets;
3187         exit_blocks[i]->getTargets(targets);
3188         if (targets.size() > 0) {
3189             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3190             fprintf(stderr, "  An exit basic block has outgoing edges in the control flow graph\n");
3191             exit(1);
3192         }
3193     }
3194
3195     /*
3196      * Check structure of control flow graph.
3197      */
3198     BPatch_Set<BPatch_basicBlock*> blocks;
3199     cfg->getAllBasicBlocks(blocks);
3200     if (blocks.size() < 4) {
3201         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3202         fprintf(stderr, "  Detected %d basic blocks in func33_2, should be at least four.\n", blocks.size());
3203         exit(1);
3204     }
3205
3206     BPatch_basicBlock **block_elements = new BPatch_basicBlock*[blocks.size()];
3207     blocks.elements(block_elements);
3208
3209     bool foundOutDegreeTwo = false;
3210     bool foundInDegreeTwo = false;
3211     int blocksNoIn = 0, blocksNoOut = 0;
3212
3213     for (i = 0; i < (unsigned int) blocks.size(); i++) {
3214         BPatch_Vector<BPatch_basicBlock*> in;
3215         BPatch_Vector<BPatch_basicBlock*> out;
3216
3217         block_elements[i]->getSources(in);
3218         block_elements[i]->getTargets(out);
3219
3220         if (in.size() == 0)
3221             blocksNoIn++;
3222
3223         if (out.size() == 0)
3224             blocksNoOut++;
3225
3226         if (in.size() > 2 || out.size() > 2) {
3227             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3228             fprintf(stderr, "  Detected a basic block in func33_2 with %d incoming edges and %d\n", in.size(), out.size());
3229             fprintf(stderr, "  outgoing edges - neither should be greater than two.\n");
3230             exit(1);
3231         } else if (in.size() > 1 && out.size() > 1) {
3232             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3233             fprintf(stderr, "  Detected a basic block in func33_2 with %d incoming edges and %d\n", in.size(), out.size());
3234             fprintf(stderr, "  outgoing edges - only one should be greater than one.\n");
3235             exit(1);
3236         } else if (in.size() == 0 && out.size() == 0) {
3237             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3238             fprintf(stderr, "  Detected a basic block in func33_2 with no incoming or outgoing edges.\n");
3239             exit(1);
3240         } else if (in.size() == 2) {
3241             assert(out.size() <= 1);
3242
3243             if (foundInDegreeTwo) {
3244                 fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3245                 fprintf(stderr, "  Detected two basic blocks in func33_2 with in degree two, there should only\n");
3246                 fprintf(stderr, "  be one.\n");
3247                 exit(1);
3248             }
3249             foundInDegreeTwo = true;
3250
3251             if (in[0]->getBlockNumber() == in[1]->getBlockNumber()) {
3252                 fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3253                 fprintf(stderr, "  Two edges go to the same block (number %d).\n", in[0]->getBlockNumber());
3254                 exit(1);
3255             }
3256         } else if (out.size() == 2) {
3257             assert(in.size() <= 1);
3258
3259             if (foundOutDegreeTwo) {
3260                 fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3261                 fprintf(stderr, "  Detected two basic blocks in func33_2 with out degree two, there should only\n");
3262                 fprintf(stderr, "  be one.\n");
3263                 exit(1);
3264             }
3265             foundOutDegreeTwo = true;
3266
3267             if (out[0]->getBlockNumber() == out[1]->getBlockNumber()) {
3268                 fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3269                 fprintf(stderr, "  Two edges go to the same block (number %d).\n", out[0]->getBlockNumber());
3270                 exit(1);
3271             }
3272         } else if (in.size() > 1 || out.size() > 1) {
3273             /* Shouldn't be able to get here. */
3274             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3275             fprintf(stderr, "  Detected a basic block in func33_2 with %d incoming edges and %d\n", in.size(), out.size());
3276             fprintf(stderr, "  outgoing edges.\n");
3277             exit(1);
3278         }
3279     }
3280
3281     delete [] block_elements;
3282     
3283     if (blocksNoIn > 1) {
3284             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3285             fprintf(stderr, "  Detected more than one block in func33_2 with no incoming edges.\n");
3286             exit(1);
3287     }
3288
3289     if (blocksNoOut > 1) {
3290             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3291             fprintf(stderr, "  Detected more than block in func33_2 with no outgoing edges.\n");
3292             exit(1);
3293     }
3294
3295     if (!foundOutDegreeTwo) {
3296             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3297             fprintf(stderr, "  Did not detect the \"if\" statement in func33_2.\n");
3298             exit(1);
3299     }
3300
3301     /*
3302      * Check for loops (there aren't any in the function we're looking at).
3303      */
3304     BPatch_Set<int> empty;
3305     if (hasBackEdge(entry_blocks[0], empty)) {
3306         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3307         fprintf(stderr, "  Detected a loop in func33_2, there should not be one.\n");
3308         exit(1);
3309     }
3310
3311     /*
3312      * Now check a function with a switch statement.
3313      */
3314     func3 = appImage->findFunction("func33_3");
3315
3316     if (func3 == NULL) {
3317         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3318         fprintf(stderr, "  Unable to find function func33_3\n");
3319         exit(1);
3320     }
3321
3322     BPatch_flowGraph *cfg3 = func3->getCFG();
3323     if (cfg3 == NULL) {
3324         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3325         fprintf(stderr, "  Unable to get control flow graph of func33_3\n");
3326         exit(1);
3327     }
3328
3329     BPatch_Set<BPatch_basicBlock*> blocks3;
3330     cfg3->getAllBasicBlocks(blocks3);
3331     if (blocks3.size() < 10) {
3332         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3333         fprintf(stderr, "  Detected %d basic blocks in func33_3, should be at least ten.\n", blocks3.size());
3334         exit(1);
3335     }
3336
3337     block_elements = new BPatch_basicBlock*[blocks3.size()];
3338     blocks3.elements(block_elements);
3339
3340     bool foundSwitchIn = false;
3341     bool foundSwitchOut = false;
3342     bool foundRangeCheck = false;
3343     for (i = 0; i < (unsigned int)blocks3.size(); i++) {
3344         BPatch_Vector<BPatch_basicBlock*> in;
3345         BPatch_Vector<BPatch_basicBlock*> out;
3346
3347         block_elements[i]->getSources(in);
3348         block_elements[i]->getTargets(out);
3349
3350         if (!foundSwitchOut && out.size() >= 10 && in.size() <= 1) {
3351             foundSwitchOut = true;
3352         } else if (!foundSwitchIn && in.size() >= 10 && out.size() <= 1) {
3353             foundSwitchIn = true;
3354         } else if (!foundRangeCheck && out.size() == 2 && in.size() <= 1) {
3355             foundRangeCheck = true;
3356         } else if (in.size() > 1 && out.size() > 1) {
3357             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3358             fprintf(stderr, "  Found basic block in func33_3 with unexpected number of edges.\n");
3359             fprintf(stderr, "  %d incoming edges, %d outgoing edges.\n",
3360                     in.size(), out.size());
3361             exit(1);
3362         }
3363     }
3364
3365     if (!foundSwitchIn || !foundSwitchOut) {
3366         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3367         if (!foundSwitchIn)
3368             fprintf(stderr,"  Did not find \"switch\" statement in func33_3.\n");
3369         if (!foundSwitchOut)
3370             fprintf(stderr,"  Did not find block afer \"switch\" statement.\n");
3371         exit(1);
3372     }
3373
3374     /* Check dominator info. */
3375     BPatch_Vector<BPatch_basicBlock*> entry3;
3376     cfg3->getEntryBasicBlock(entry3);
3377     if (entry3.size() != 1) {
3378         fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3379         fprintf(stderr, "  Detected %d entry basic blocks in func33_3, should have been one.\n", entry_blocks.size());
3380         exit(1);
3381     }
3382
3383     for (i = 0; i < (unsigned int) blocks3.size(); i++) {
3384         if (!entry3[0]->dominates(block_elements[i])) {
3385             fprintf(stderr, "**Failed** test #33 (control flow graphs)\n");
3386             fprintf(stderr, "  Entry block does not dominate all blocks in func33_3\n");
3387             exit(1);
3388         }
3389     }
3390
3391     delete [] block_elements;
3392 }
3393
3394 /*******************************************************************************/
3395 /*******************************************************************************/
3396 /*******************************************************************************/
3397
3398 int numContainedLoops(BPatch_basicBlockLoop *loop)
3399 {
3400     BPatch_Vector<BPatch_basicBlockLoop*> containedLoops;
3401     loop->getContainedLoops(containedLoops);
3402
3403     return containedLoops.size();
3404 }
3405
3406 int numBackEdges(BPatch_basicBlockLoop *loop)
3407 {
3408     BPatch_Vector<BPatch_basicBlock*> backEdges;
3409     loop->getBackEdges(backEdges);
3410
3411     return backEdges.size();
3412 }
3413
3414 //
3415 // Start Test Case #34 - (loop information)
3416 //
3417 void mutatorTest34( BPatch_thread * /*appThread*/, BPatch_image * appImage )
3418 {
3419     unsigned int i;
3420
3421     BPatch_function *func2;
3422     func2 = appImage->findFunction("func34_2");
3423
3424     if (func2 == NULL) {
3425         fprintf(stderr, "**Failed** test #34 (loop information)\n");
3426         fprintf(stderr, "  Unable to find function func34_2\n");
3427         exit(1);
3428     }
3429
3430     BPatch_flowGraph *cfg = func2->getCFG();
3431     if (cfg == NULL) {
3432         fprintf(stderr, "**Failed** test #34 (loop information)\n");
3433         fprintf(stderr, "  Unable to get control flow graph of func34_2\n");
3434         exit(1);
3435     }
3436
3437     BPatch_Vector<BPatch_basicBlockLoop*> loops;
3438     cfg->getLoops(loops);
3439     if (loops.size() != 4) {
3440         fprintf(stderr, "**Failed** test #34 (loop information)\n");
3441         fprintf(stderr, "  Detected %d loops, should have been four.\n",
3442                 loops.size());
3443         exit(1);
3444     }
3445
3446     /*
3447      * Find the loop that contains two loops (that should be the outermost
3448      * one).
3449      */
3450     BPatch_basicBlockLoop *outerLoop = NULL;
3451     for (i = 0; i < loops.size(); i++) {
3452         if (numContainedLoops(loops[i]) == 3) {
3453             outerLoop = loops[i];
3454             break;
3455         }
3456     }
3457
3458     if (outerLoop == NULL) {
3459         fprintf(stderr, "**Failed** test #34 (loop information)\n");
3460         fprintf(stderr, "  Unable to find a loop containing two other loops.\n");
3461         exit(1);
3462     }
3463
3464     if (numBackEdges(outerLoop) != 1) {
3465         fprintf(stderr, "**Failed** test #34 (loop information)\n");
3466         fprintf(stderr, "  There should be exactly one backedge in the outer loops, but there are %d\n", numBackEdges(outerLoop));
3467         exit(1);
3468     }
3469
3470     BPatch_Vector<BPatch_basicBlockLoop*> insideOuterLoop;
3471     outerLoop->getContainedLoops(insideOuterLoop);
3472     assert(insideOuterLoop.size() == 3);
3473
3474     bool foundFirstLoop = false;
3475     int deepestLoops = 0;
3476     for (i = 0; i < insideOuterLoop.size(); i++) {
3477         BPatch_Vector<BPatch_basicBlockLoop*> tmpLoops;
3478         insideOuterLoop[i]->getContainedLoops(tmpLoops);
3479
3480         if (tmpLoops.size() == 1) { /* The first loop has one nested inside. */
3481             if (foundFirstLoop) {
3482                 fprintf(stderr, "**Failed** test #34 (loop information)\n");
3483                 fprintf(stderr, "  Found more than one second-level loop with one nested inside.\n");
3484                 exit(1);
3485             }
3486             foundFirstLoop = true;
3487
3488             if (numBackEdges(insideOuterLoop[i]) != 1) {
3489                 fprintf(stderr, "**Failed** test #34 (loop information)\n");
3490                 fprintf(stderr, "  There should be exactly one backedge in the first inner loop, but there are %d\n", numBackEdges(tmpLoops[0]));
3491                 exit(1);
3492             }
3493
3494             if (numBackEdges(tmpLoops[0]) != 1) {
3495                 fprintf(stderr, "**Failed** test #34 (loop information)\n");
3496                 fprintf(stderr, "  There should be exactly one backedge in the third level loop, but there are %d\n", numBackEdges(tmpLoops[0]));
3497                 exit(1);
3498             }
3499
3500             if (numContainedLoops(tmpLoops[0]) != 0) {
3501                 fprintf(stderr, "**Failed** test #34 (loop information)\n");
3502                 fprintf(stderr, "  The first loop at the third level should not have any loops nested inside,\n");
3503                 fprintf(stderr, "  but %d were detected.\n",
3504                         numContainedLoops(tmpLoops[0]));
3505                 exit(1);
3506             }
3507
3508         } else if(tmpLoops.size() == 0) { /* The second loop has none nested. */
3509             if (deepestLoops >= 2) {
3510                 fprintf(stderr, "**Failed** test #34 (loop information)\n");
3511                 fprintf(stderr, "  Found more than two loops without any nested inside.\n");
3512                 exit(1);
3513             }
3514             deepestLoops++;
3515
3516             if (numBackEdges(insideOuterLoop[i]) != 1) {
3517                 fprintf(stderr, "**Failed** test #34 (loop information)\n");
3518                 fprintf(stderr, "  Unexpected number of backedges in loop (%d)\n", numBackEdges(insideOuterLoop[i]));
3519                 exit(1);
3520             }
3521         } else { /* All loops should be recognized above. */
3522             fprintf(stderr, "**Failed** test #34 (loop information)\n");
3523             fprintf(stderr, "  Found a loop containing %d loops, should be one or  none.\n", tmpLoops.size());
3524             exit(1);
3525         }
3526     }
3527
3528     if (!foundFirstLoop || deepestLoops < 2) {
3529         /* We shouldn't be able to get here. */
3530         fprintf(stderr, "**Failed** test #34 (loop information)\n");
3531         if (!foundFirstLoop)
3532             fprintf(stderr, "  Could not find the first nested loop.\n");
3533         if (deepestLoops < 2)
3534             fprintf(stderr, "  Could not find all the deepest level loops.\n");
3535         exit(1);
3536     }
3537 }
3538
3539 // Start Test Case #35 - (function relocation)
3540 void mutatorTest35( BPatch_thread * appThread, BPatch_image * appImage )
3541 {
3542 #if defined(i386_unknown_solaris2_5) || defined(i386_unknown_linux2_0) || defined(sparc_sun_solaris2_4) || defined(ia64_unknown_linux2_4)
3543
3544     char * foo_name = "call35_1";
3545
3546     if (mutateeFortran)
3547         return;
3548
3549
3550     BPatch_function * foo_function = appImage->findFunction(foo_name);
3551     if( foo_function == 0 )
3552     {
3553       fprintf( stderr, "Cannot find \"%s\" function.",
3554                foo_name );
3555       exit( -1 );
3556     }
3557
3558     BPatch_Vector<BPatch_point *> *point35_1 =  
3559         foo_function->findPoint(BPatch_subroutine);
3560
3561     assert(point35_1);
3562
3563     BPatch_variableExpr *var1 = appImage->findVariable(*(*point35_1)[0], 
3564         "localVariable35_1");
3565     BPatch_variableExpr *var2 = appImage->findVariable(*(*point35_1)[0], 
3566         "localVariable35_2");
3567     BPatch_variableExpr *var3 = appImage->findVariable(*(*point35_1)[0], 
3568         "total35_1");
3569     BPatch_variableExpr *var4 = appImage->findVariable(*(*point35_1)[0], 
3570         "total35_2");
3571
3572     if (!var1 || !var2 || !var3 || !var4 ) {
3573         fprintf(stderr, "**Failed** test #35 (function relocation)\n");
3574         if (!var1) 
3575             fprintf(stderr, "  can't find local variable localVariable35_1\n");
3576         if (!var2) 
3577             fprintf(stderr, "  can't find local variable localVariable35_2\n");
3578         if (!var3) 
3579             fprintf(stderr, "  can't find local variable total35_1\n");
3580         if (!var4) 
3581             fprintf(stderr, "  can't find local variable total35_2\n");
3582         return;
3583     }
3584
3585     BPatch_snippet * snippet35_1 = 
3586       new BPatch_arithExpr(BPatch_assign, *var1, BPatch_constExpr(7));
3587
3588     BPatch_snippet * snippet35_2 = 
3589       new BPatch_arithExpr(BPatch_assign, *var2, BPatch_constExpr(5));
3590
3591     BPatch_snippet * snippet35_3 = 
3592       new BPatch_arithExpr(BPatch_assign, *var4, *var3);
3593