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