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