Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / tests / src / test6.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: test6.C,v 1.40 2008/04/11 23:30:36 legendre Exp $
33  
34 #include <stdio.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <stdarg.h>
38 #ifdef i386_unknown_nt4_0
39 #define WIN32_LEAN_AND_MEAN
40 #include <windows.h>
41 #include <winbase.h>
42 #else
43 #include <unistd.h>
44 #endif
45
46 #include "BPatch.h"
47 #include "BPatch_Vector.h"
48 #include "BPatch_thread.h"
49 #include "BPatch_snippet.h"
50 #include "BPatch_memoryAccess_NP.h"
51
52 #include "test_util.h"
53
54 const char *mutateeNameRoot = "test6.mutatee";
55
56 int inTest;             // current test #
57 #define DYNINST_NO_ERROR -1
58 int expectError = DYNINST_NO_ERROR;
59 int debugPrint = 0; // internal "mutator" tracing
60 int errorPrint = 0; // external "dyninst" tracing (via errorFunc)
61
62 bool forceRelocation = false;  // Force relocation upon instrumentation
63
64 // control debug printf statements
65 void dprintf(const char *fmt, ...) {
66    va_list args;
67    va_start(args, fmt);
68
69    if(debugPrint)
70       vfprintf(stderr, fmt, args);
71
72    va_end(args);
73
74    fflush(stderr);
75 }
76
77 bool runAllTests = true;
78 const unsigned int MAX_TEST = 8;
79 bool runTest[MAX_TEST+1];
80 bool passedTest[MAX_TEST+1];
81 bool failedTest[MAX_TEST+1];
82
83 BPatch *bpatch;
84
85 /*
86  * Given a string variable name and an expected value, lookup the varaible
87  *    in the child process, and verify that the value matches.
88  *
89  */
90 bool verifyChildMemory(BPatch_thread *appThread, 
91                               char *name, int expectedVal)
92 {
93      BPatch_image *appImage = appThread->getImage();
94
95      if (!appImage) {
96          dprintf("unable to locate image for %d\n", appThread->getPid());
97          return false;
98      }
99
100      BPatch_variableExpr *var = appImage->findVariable(name);
101      if (!var) {
102          dprintf("unable to located variable %s in child\n", name);
103          return false;
104      }
105
106      int actualVal;
107      var->readValue(&actualVal);
108
109      if (expectedVal != actualVal) {
110          printf("*** for %s, expected val = %d, but actual was %d\n",
111                 name, expectedVal, actualVal);
112          return false;
113      } else {
114          dprintf("verified %s was = %d\n", name, actualVal);
115          return true;
116      }
117 }
118
119 /**************************************************************************
120  * Error callback
121  **************************************************************************/
122
123 void errorFunc(BPatchErrorLevel level, int num, const char * const *params)
124 {
125   if (num == 0) {
126     // conditional reporting of warnings and informational messages
127     if (errorPrint) {
128       if (level == BPatchInfo)
129         { if (errorPrint > 1) printf("%s\n", params[0]); }
130       else
131         printf("%s", params[0]);
132     }
133   } else {
134     // reporting of actual errors
135     char line[256];
136     const char *msg = bpatch->getEnglishErrorString(num);
137     bpatch->formatErrorString(line, sizeof(line), msg, params);
138     
139     if (num != expectError) {
140       printf("Error #%d (level %d): %s\n", num, level, line);
141       
142       // We consider some errors fatal.
143      if (num == 101) {
144         exit(-1);
145       }
146     }
147   }
148 }
149
150 #ifdef i386_unknown_nt4_0
151 #define snprintf _snprintf
152 #endif
153
154 BPatch_callWhen instrumentWhere(  const BPatch_memoryAccess* memAccess){
155
156         BPatch_callWhen whenToCall;
157         if(memAccess != NULL){
158                 if(memAccess->hasALoad()){
159                         whenToCall = BPatch_callBefore;
160                 }else if(memAccess->hasAStore()){
161                         whenToCall = BPatch_callAfter;
162                 }else if(memAccess->hasAPrefetch_NP() ){
163                         whenToCall = BPatch_callBefore;
164                 }else{
165                         whenToCall = BPatch_callBefore;
166                 }
167         }else{
168                 whenToCall = BPatch_callBefore;
169         }
170         return whenToCall;
171 }
172
173 void instCall(BPatch_thread* bpthr, const char* fname,
174               const BPatch_Vector<BPatch_point*>* res)
175 {
176   char buf[30];
177         BPatch_callWhen whenToCall = BPatch_callBefore;
178
179   snprintf(buf, 30, "count%s", fname);
180
181   BPatch_Vector<BPatch_snippet*> callArgs;
182   BPatch_image *appImage = bpthr->getImage();
183
184   BPatch_Vector<BPatch_function *> bpfv;
185   if (NULL == appImage->findFunction(buf, bpfv) || !bpfv.size()
186       || NULL == bpfv[0]){
187     fprintf(stderr, "    Unable to find function %s\n", buf);
188     exit(1);
189   }
190   BPatch_function *countXXXFunc = bpfv[0];  
191
192   BPatch_funcCallExpr countXXXCall(*countXXXFunc, callArgs);
193
194   for(unsigned int i=0;i<(*res).size();i++){
195
196 #if defined(rs6000_ibm_aix4_1) && defined(AIX5)
197         const BPatch_memoryAccess* memAccess;
198         memAccess = (*res)[i]->getMemoryAccess() ;
199
200         whenToCall = instrumentWhere( memAccess);
201
202 #endif
203         bpthr->insertSnippet(countXXXCall, *((*res)[i]),whenToCall);
204   }
205 }
206
207 void instEffAddr(BPatch_thread* bpthr, const char* fname,
208                  const BPatch_Vector<BPatch_point*>* res,
209                  bool conditional)
210 {
211   char buf[30];
212   snprintf(buf, 30, "list%s%s", fname, (conditional ? "CC" : ""));
213   dprintf("CALLING: %s\n", buf);
214
215   BPatch_Vector<BPatch_snippet*> listArgs;
216   BPatch_effectiveAddressExpr eae;
217   listArgs.push_back(&eae);
218
219   BPatch_image *appImage = bpthr->getImage();
220
221   BPatch_Vector<BPatch_function *> bpfv;
222   if (NULL == appImage->findFunction(buf, bpfv) || !bpfv.size()
223       || NULL == bpfv[0]){
224     fprintf(stderr, "    Unable to find function %s\n", buf);
225     exit(1);
226   }
227   BPatch_function *listXXXFunc = bpfv[0];  
228   BPatch_funcCallExpr listXXXCall(*listXXXFunc, listArgs);
229
230
231   BPatch_callWhen whenToCall = BPatch_callBefore;
232   for(unsigned int i=0;i<(*res).size();i++){
233 #if defined(rs6000_ibm_aix4_1) && defined(AIX5) 
234         const BPatch_memoryAccess* memAccess;
235
236         memAccess = (*res)[i]->getMemoryAccess() ;
237
238         whenToCall = instrumentWhere( memAccess);
239 #endif
240         if(!conditional)
241             bpthr->insertSnippet(listXXXCall, *((*res)[i]), whenToCall, BPatch_lastSnippet);
242           else {
243             BPatch_ifMachineConditionExpr listXXXCallCC(listXXXCall);
244             bpthr->insertSnippet(listXXXCallCC, *((*res)[i]), whenToCall, BPatch_lastSnippet);
245           }
246   }
247
248 #if defined(i386_unknown_linux2_0) \
249  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
250  || defined(i386_unknown_nt4_0)
251   BPatch_effectiveAddressExpr eae2(1);
252   BPatch_Vector<BPatch_snippet*> listArgs2;
253   listArgs2.push_back(&eae2);
254
255   BPatch_funcCallExpr listXXXCall2(*listXXXFunc, listArgs2);
256   
257   const BPatch_Vector<BPatch_point*>* res2 = BPatch_memoryAccess::filterPoints(*res, 2);
258
259   if(!conditional)
260     bpthr->insertSnippet(listXXXCall2, *res2, BPatch_lastSnippet);
261   else {
262     BPatch_ifMachineConditionExpr listXXXCallCC2(listXXXCall2);
263     bpthr->insertSnippet(listXXXCallCC2, *res2, BPatch_lastSnippet);    
264   }
265 #endif
266 }
267
268 void instByteCnt(BPatch_thread* bpthr, const char* fname,
269                  const BPatch_Vector<BPatch_point*>* res,
270                  bool conditional)
271 {
272   char buf[30];
273   snprintf(buf, 30, "list%s%s", fname, (conditional ? "CC" : ""));
274   dprintf("CALLING: %s\n", buf);
275
276   BPatch_Vector<BPatch_snippet*> listArgs;
277   BPatch_bytesAccessedExpr bae;
278   listArgs.push_back(&bae);
279
280   BPatch_image *appImage = bpthr->getImage();
281
282   BPatch_Vector<BPatch_function *> bpfv;
283   if (NULL == appImage->findFunction(buf, bpfv) || !bpfv.size()
284       || NULL == bpfv[0]){
285     fprintf(stderr, "    Unable to find function %s\n", buf);
286     exit(1);
287   }
288   BPatch_function *listXXXFunc = bpfv[0];  
289
290   BPatch_callWhen whenToCall = BPatch_callBefore;
291
292   for(unsigned int i=0;i<(*res).size();i++){
293
294 #if defined(rs6000_ibm_aix4_1) && defined(AIX5)
295         const BPatch_memoryAccess* memAccess;
296         memAccess = (*res)[i]->getMemoryAccess() ;
297
298         whenToCall = instrumentWhere( memAccess);
299
300 #endif
301         BPatch_funcCallExpr listXXXCall(*listXXXFunc, listArgs);
302           if(!conditional)
303             bpthr->insertSnippet(listXXXCall, *((*res)[i]), whenToCall, BPatch_lastSnippet);
304           else {
305             BPatch_ifMachineConditionExpr listXXXCallCC(listXXXCall);
306             bpthr->insertSnippet(listXXXCallCC, *((*res)[i]), whenToCall, BPatch_lastSnippet);
307           }
308   }
309
310 #if defined(i386_unknown_linux2_0) \
311  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
312  || defined(i386_unknown_nt4_0)
313   BPatch_bytesAccessedExpr bae2(1);
314   BPatch_Vector<BPatch_snippet*> listArgs2;
315   listArgs2.push_back(&bae2);
316
317   BPatch_funcCallExpr listXXXCall2(*listXXXFunc, listArgs2);
318   
319   const BPatch_Vector<BPatch_point*>* res2 = BPatch_memoryAccess::filterPoints(*res, 2);
320   if(!conditional)
321     bpthr->insertSnippet(listXXXCall2, *res2, BPatch_lastSnippet);
322   else {
323     BPatch_ifMachineConditionExpr listXXXCallCC2(listXXXCall2);
324     bpthr->insertSnippet(listXXXCallCC2, *res2, BPatch_lastSnippet);
325   }
326 #endif
327 }
328
329 #define MK_LD(imm, rs1, rs2, bytes) (new BPatch_memoryAccess(NULL, 0,\
330                                                              true, false, \
331                                                              (bytes), (imm), (rs1), (rs2)))
332 #define MK_ST(imm, rs1, rs2, bytes) (new BPatch_memoryAccess(NULL, 0,\
333                                                              false, true, \
334                                                              (bytes), (imm), (rs1), (rs2)))
335 #define MK_LS(imm, rs1, rs2, bytes) (new BPatch_memoryAccess(NULL, 0,\
336                                                              true, true, \
337                                                              (bytes), (imm), (rs1), (rs2)))
338 #define MK_PF(imm, rs1, rs2, f) (new BPatch_memoryAccess(NULL, 0,\
339                                                          false, false, true, \
340                                                          (imm), (rs1), (rs2), \
341                                                          0, -1, -1, (f)))
342
343 #define MK_LDsc(imm, rs1, rs2, scale, bytes) (new BPatch_memoryAccess(NULL, 0,\
344                                                                       true, false, \
345                                                                       (bytes), \
346                                                                       (imm), (rs1), (rs2), \
347                                                                       (scale)))
348
349 #define MK_LDsccnd(imm, rs1, rs2, scale, bytes, cond) (new BPatch_memoryAccess(NULL, 0,true, false, (bytes), (imm), (rs1), (rs2), (scale), (cond), false))
350
351
352 #define MK_LD2(imm, rs1, rs2, bytes, imm_2, rs1_2, rs2_2, bytes_2) (new BPatch_memoryAccess(NULL, 0,true, false, (bytes), (imm), (rs1), (rs2), 0, true, false, (bytes_2), (imm_2), (rs1_2), (rs2_2), 0))
353 #define MK_SL2(imm, rs1, rs2, bytes, imm_2, rs1_2, rs2_2, bytes_2) (new BPatch_memoryAccess(NULL, 0,false, true, (bytes), (imm), (rs1), (rs2), 0, true, false, (bytes_2), (imm_2), (rs1_2), (rs2_2), 0))
354
355 #define MK_SL2vECX(imm, rs1, rs2, imm_2, rs1_2, rs2_2, bop) (new BPatch_memoryAccess(NULL, 0,false, true, (imm), (rs1), (rs2), 0, 0, -1, 1, (bop),  true, false, (imm_2), (rs1_2), (rs2_2), 0, 0, -1, 1, (bop)))
356
357 #define MK_STnt(imm, rs1, rs2, bytes) (new BPatch_memoryAccess(NULL, 0,\
358                                                                false, true, \
359                                                                (bytes), (imm), (rs1), (rs2), 0, \
360                                                                -1, true))
361 // what we expect to find in the "loadsnstores" function; platform specific
362 #ifdef sparc_sun_solaris2_4
363
364 const unsigned int nloads = 15;
365 const unsigned int nstores = 13;
366 const unsigned int nprefes = 2;
367 const unsigned int naxses = 26;
368
369 BPatch_memoryAccess* loadList[nloads];
370 BPatch_memoryAccess* storeList[nstores];
371 BPatch_memoryAccess* prefeList[nprefes];
372
373 void init_test_data()
374 {
375   int k=-1;
376
377   loadList[++k] = MK_LD(0,17,0,4);
378   loadList[++k] = MK_LD(3,1,-1,1);
379   loadList[++k] = MK_LD(2,2,-1,2);
380   loadList[++k] = MK_LD(0,17,0,8);
381   loadList[++k] = MK_LD(0,17,0,4);
382
383   loadList[++k] = MK_LS(3,17,-1,1); // ldstub
384   loadList[++k] = MK_LD(3,17,-1,1);
385
386   loadList[++k] = MK_LS(0,17,-1,4); // cas
387   loadList[++k] = MK_LS(0,17,-1,8); // casx
388   loadList[++k] = MK_LS(0,17,0,4);  // swap
389
390   loadList[++k] = MK_LD(0,17,0,4);
391   loadList[++k] = MK_LD(0,17,0,4);
392   loadList[++k] = MK_LD(0,17,0,8);
393   loadList[++k] = MK_LD(0,17,0,8);
394   loadList[++k] = MK_LD(0,17,0,16);
395
396   k=-1;
397
398   storeList[++k] = MK_LS(3,17,-1,1); // ldstub
399   storeList[++k] = MK_LS(0,17,-1,4); // cas
400   storeList[++k] = MK_LS(0,17,-1,8); // casx
401   storeList[++k] = MK_LS(0,17,0,4);  // swap
402
403   storeList[++k] = MK_ST(7,21,-1,1);
404   storeList[++k] = MK_ST(6,21,-1,2);
405   storeList[++k] = MK_ST(4,21,-1,4);
406   storeList[++k] = MK_ST(0,21,0,8);
407   storeList[++k] = MK_ST(0,17,0,4);
408   storeList[++k] = MK_ST(0,17,0,8);
409   storeList[++k] = MK_ST(0,18,0,16);
410   storeList[++k] = MK_ST(4,21,-1,4);
411   storeList[++k] = MK_ST(0,21,0,8);
412
413   k=-1;
414
415   prefeList[++k] = MK_PF(0,17,0,2);
416   prefeList[++k] = MK_PF(0,20,0,0);
417 }
418
419 #endif
420
421 #ifdef rs6000_ibm_aix4_1
422 const unsigned int nloads = 41;
423 const unsigned int nstores = 32;
424 const unsigned int nprefes = 0;
425 const unsigned int naxses = 73;
426
427 BPatch_memoryAccess* loadList[nloads];
428 BPatch_memoryAccess* storeList[nstores];
429 #if defined(__XLC__) || defined(__xlC__)
430 BPatch_memoryAccess* *prefeList;
431 #else
432 BPatch_memoryAccess* prefeList[nprefes];
433 #endif
434
435 void init_test_data()
436 {
437   int k=-1;
438
439   loadList[++k] = MK_LD(0, 7, -1, 4); // from la, l sequence
440
441   loadList[++k] = MK_LD(17, 7, -1, 1);
442   loadList[++k] = MK_LD(3, 7, -1, 1);
443
444   loadList[++k] = MK_LD(0, 3, 8, 1);
445   loadList[++k] = MK_LD(0, 3, 9, 1);
446
447   loadList[++k] = MK_LD(0, 3, -1, 2); // l6
448   loadList[++k] = MK_LD(4, 3, -1, 2);
449   loadList[++k] = MK_LD(2, 3, -1, 2);
450   loadList[++k] = MK_LD(0, 3, -1, 2);
451
452   loadList[++k] = MK_LD(0, 7, 9, 2); // l10
453   loadList[++k] = MK_LD(0, 7, 8, 2);
454   loadList[++k] = MK_LD(0, 7, 9, 2);
455   loadList[++k] = MK_LD(0, 7, 8, 2);
456
457   loadList[++k] = MK_LD(0, 7, -1, 4); // l14
458   loadList[++k] = MK_LD(4, 7, -1, 4);
459   loadList[++k] = MK_LD(0, 3, 9, 4);
460   loadList[++k] = MK_LD(0, 3, 9, 4);
461
462   loadList[++k] = MK_LD(4, 3, -1, 4); // l18
463   loadList[++k] = MK_LD(0, 7, 0, 4);  // 0 is 0 for rb...
464   loadList[++k] = MK_LD(0, 7, 8, 4);
465
466   loadList[++k] = MK_LD(0, 7, -1, 8); // l21
467   loadList[++k] = MK_LD(0, 3, -1, 8);
468   loadList[++k] = MK_LD(0, 7, 9, 8);
469   loadList[++k] = MK_LD(0, 3, 9, 8);
470
471   loadList[++k] = MK_LD(0, 8, 3, 2);  // l25
472   loadList[++k] = MK_LD(0, 9, 3, 4);
473
474   loadList[++k] = MK_LD(-76, 1, -1, 76);  // l27
475   loadList[++k] = MK_LD(0, 4, -1, 24);
476   loadList[++k] = new BPatch_memoryAccess(NULL, 0,
477                                    true, false,
478                                    (long)0, 1, 9,
479                                    (long)0, POWER_XER2531, -1);
480
481   loadList[++k] = MK_LD(0, -1, 3, 4);  // l30, 0 is -1 in ra...
482   loadList[++k] = MK_LD(0, -1, 7, 8);  // l31, idem
483
484   loadList[++k] = MK_LD(0, 4, -1, 4); // from la, l sequence
485
486   loadList[++k] = MK_LD(0, 4, -1, 4);
487   loadList[++k] = MK_LD(0, 4, 6, 4);
488   loadList[++k] = MK_LD(0, 4, -1, 4);
489   loadList[++k] = MK_LD(0, 6, 4, 4);
490
491   loadList[++k] = MK_LD(0, 6, -1, 4); // from la, l sequence
492
493   loadList[++k] = MK_LD(0, 6, -1, 8);
494   loadList[++k] = MK_LD(0, 6, 9, 8);
495   loadList[++k] = MK_LD(8, 6, -1, 8);
496   loadList[++k] = MK_LD(0, 9, 7, 8);
497
498   k=-1;
499
500   storeList[++k] = MK_ST(3, 7, -1, 1);
501   storeList[++k] = MK_ST(1, 7, -1, 1);
502   storeList[++k] = MK_ST(0, 3, 8, 1);
503   storeList[++k] = MK_ST(0, 8, 3, 1);
504
505   storeList[++k] = MK_ST(2, 7, -1, 2);
506   storeList[++k] = MK_ST(6, 7, -1, 2);
507   storeList[++k] = MK_ST(0, 3, 9, 2);
508   storeList[++k] = MK_ST(0, 9, 3, 2);
509
510   storeList[++k] = MK_ST(0, 7, -1, 4);
511   storeList[++k] = MK_ST(4, 7, -1, 4);
512   storeList[++k] = MK_ST(0, 3, 9, 4);
513   storeList[++k] = MK_ST(0, 9, 3, 4);
514
515   storeList[++k] = MK_ST(0, 7, -1, 8);
516   storeList[++k] = MK_ST(0, 7, -1, 8);
517   storeList[++k] = MK_ST(0, 7, 8, 8);
518   storeList[++k] = MK_ST(0, 8, 7, 8);
519
520   storeList[++k] = MK_ST(0, 8, 7, 2);
521   storeList[++k] = MK_ST(0, 9, 7, 4);
522
523   storeList[++k] = MK_ST(-76, 1, -1, 76);
524   storeList[++k] = MK_ST(0, 4, -1, 20);
525
526   storeList[++k] = new BPatch_memoryAccess(NULL, 0,
527                                     false, true,
528                                     (long)0, 1, 9,
529                                     (long)0, POWER_XER2531, -1);
530
531   storeList[++k] = MK_ST(0, -1, 3, 4); // 0 means -1 (no register) in ra
532   storeList[++k] = MK_ST(0, -1, 7, 8);
533
534   storeList[++k] = MK_ST(4, 4, -1, 4); // s24
535   storeList[++k] = MK_ST(0, 4, 0, 4);
536   storeList[++k] = MK_ST(0, 4, -1, 4);
537   storeList[++k] = MK_ST(0, -1, 4, 4);  // 0 means -1 (no register) in ra
538   storeList[++k] = MK_ST(0, 6, -1, 8);
539   storeList[++k] = MK_ST(0, 6, 9, 8);
540   storeList[++k] = MK_ST(8, 6, -1, 8);
541   storeList[++k] = MK_ST(0, 9, 7, 8);
542
543   storeList[++k] = MK_ST(0, -1, 4, 4);  // 0 means -1 (no register) in ra
544 }
545 #endif
546
547 #if defined(i386_unknown_linux2_0) \
548  || defined(i386_unknown_nt4_0)
549 const unsigned int nloads = 65;
550 const unsigned int nstores = 23;
551 const unsigned int nprefes = 2;
552 const unsigned int naxses = 85;
553
554 BPatch_memoryAccess* loadList[nloads];
555 BPatch_memoryAccess* storeList[nstores];
556 BPatch_memoryAccess* prefeList[nprefes + 1]; // for NT
557
558 void *divarwp, *dfvarsp, *dfvardp, *dfvartp, *dlargep;
559
560 void get_vars_addrs(BPatch_image* bip) // from mutatee
561 {
562 #ifdef i386_unknown_nt4_0
563   // FIXME: With or without leading _ dyninst cannot find these variables.
564   // VC++6 debugger has no such problems...
565   BPatch_variableExpr* bpvep_diwarw = bip->findVariable("_divarw");
566   BPatch_variableExpr* bpvep_diwars = bip->findVariable("_dfvars");
567   BPatch_variableExpr* bpvep_diward = bip->findVariable("_dfvard");
568   BPatch_variableExpr* bpvep_diwart = bip->findVariable("_dfvart");
569   BPatch_variableExpr* bpvep_dlarge = bip->findVariable("_dlarge");
570 #else
571   BPatch_variableExpr* bpvep_diwarw = bip->findVariable("divarw");
572   BPatch_variableExpr* bpvep_diwars = bip->findVariable("dfvars");
573   BPatch_variableExpr* bpvep_diward = bip->findVariable("dfvard");
574   BPatch_variableExpr* bpvep_diwart = bip->findVariable("dfvart");
575   BPatch_variableExpr* bpvep_dlarge = bip->findVariable("dlarge");
576 #endif
577   
578   divarwp = bpvep_diwarw->getBaseAddr();
579   dfvarsp = bpvep_diwars->getBaseAddr();
580   dfvardp = bpvep_diward->getBaseAddr();
581   dfvartp = bpvep_diwart->getBaseAddr();
582   dlargep = bpvep_dlarge->getBaseAddr();
583 }
584
585 void init_test_data()
586 {
587   int k=-1;
588
589   loadList[++k] = MK_LD(0,0,-1,4);
590   loadList[++k] = MK_LD(0,1,-1,4);
591   loadList[++k] = MK_LD(0,2,-1,4);
592   loadList[++k] = MK_LD(0,3,-1,4);
593   loadList[++k] = MK_LD((long)divarwp,-1,-1,4);
594   loadList[++k] = MK_LD(0,6,-1,4);
595   loadList[++k] = MK_LD(0,7,-1,4);
596
597   loadList[++k] = MK_LD(4,0,-1,4); // l8
598   loadList[++k] = MK_LD(8,1,-1,4);
599   loadList[++k] = MK_LD(4,2,-1,4);
600   loadList[++k] = MK_LD(8,3,-1,4);
601   loadList[++k] = MK_LD(4,5,-1,4);
602   loadList[++k] = MK_LD(8,6,-1,4);
603   loadList[++k] = MK_LD(4,7,-1,4);
604
605   loadList[++k] = MK_LD((long)divarwp-1,0,-1,4); // l15
606   loadList[++k] = MK_LD((long)divarwp+3,1,-1,4);
607   loadList[++k] = MK_LD((long)divarwp+7,2,-1,4);
608   loadList[++k] = MK_LD((long)divarwp+11,3,-1,4);
609   loadList[++k] = MK_LD((long)divarwp-1,5,-1,4);
610   loadList[++k] = MK_LD((long)divarwp+3,6,-1,4);
611   loadList[++k] = MK_LD((long)divarwp+7,7,-1,4);
612
613   loadList[++k] = MK_LD(0,3,6,4); // l22
614   loadList[++k] = MK_LD(0,4,-1,4);
615   loadList[++k] = MK_LDsc(0,3,1,1,4);
616   loadList[++k] = MK_LDsc((long)divarwp,-1,1,1,4);
617   loadList[++k] = MK_LD(4,3,1,4);
618   loadList[++k] = MK_LDsc((long)divarwp,2,2,3,4);
619   loadList[++k] = MK_LDsc(2,5,1,1,4); // l28
620   loadList[++k] = MK_LDsc(4,3,1,2,4);
621   loadList[++k] = MK_LDsc((long)divarwp,5,1,2,4);
622   
623   loadList[++k] = MK_LD(0,4,-1,4);// l31
624   loadList[++k] = MK_LS((long)divarwp+4,-1,-1,4);
625   loadList[++k] = MK_LD((long)divarwp+4,-1,-1,4);
626   loadList[++k] = MK_LD2(0,6,-1,1,0,7,-1,1);
627
628   loadList[++k] = MK_LS((long)divarwp,-1,-1,4); // l35
629   loadList[++k] = MK_LS((long)divarwp+4,-1,-1,4);
630   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,4);
631 //   loadList[++k] = MK_LD((long)divarwp+2,-1,-1,6); // l38
632   loadList[++k] = MK_LD((long)divarwp,-1,-1,1);
633   loadList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // l40
634   loadList[++k] = MK_LD((long)divarwp,-1,-1,4);
635
636   loadList[++k] = MK_LD((long)divarwp,-1,-1,4);
637   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,8);
638
639   loadList[++k] = MK_LD((long)dfvarsp,-1,-1,16); // l44
640   loadList[++k] = MK_LD((long)dfvarsp,-1,-1,4);
641
642   loadList[++k] = MK_LD((long)dfvardp,-1,-1,16);
643   loadList[++k] = MK_LD((long)dfvardp,-1,-1,8);
644
645   loadList[++k] = MK_LD((long)dfvarsp,-1,-1,8); // l48
646   loadList[++k] = MK_LD((long)dfvarsp+8,-1,-1,8);
647   
648
649   //loadList[++k] = MK_SL2(0,7,-1,4,0,6,-1,4); // l50
650   loadList[++k] = MK_SL2vECX(0,7,-1,0,6,-1,2);
651   loadList[++k] = new BPatch_memoryAccess(NULL, 0,
652                                           true, false,
653                                           0, 7, -1, 0,
654                                           0, -1, IA32_NESCAS, 0, 
655                                           -1, false);
656   loadList[++k] = new BPatch_memoryAccess(NULL, 0,
657                                           true, false,
658                                           0, 6, -1, 0,
659                                           0, -1, IA32_ECMPS, 0,
660                                           true, false,
661                                           0, 7, -1, 0,
662                                           0, -1, IA32_ECMPS, 0);
663
664   loadList[++k] = MK_LD((long)dfvarsp,-1,-1,4);
665   loadList[++k] = MK_LD((long)dfvardp,-1,-1,8);
666   loadList[++k] = MK_LD((long)dfvartp,-1,-1,10);
667   loadList[++k] = MK_LD((long)divarwp,-1,-1,2);
668   loadList[++k] = MK_LD((long)divarwp+4,-1,-1,4);
669   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,8);
670
671   loadList[++k] = MK_LD((long)divarwp,-1,-1,2);
672   loadList[++k] = MK_LD((long)dlargep,-1,-1,28);
673
674   loadList[++k] = MK_LDsccnd((long)divarwp,-1,-1,0,4,7); // cmova
675   loadList[++k] = MK_LDsccnd((long)divarwp+4,-1,-1,0,4,4); // cmove
676   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,4);
677
678   loadList[++k] = MK_LD(0,4,-1,4); // final pops
679   loadList[++k] = MK_LD(0,4,-1,4);
680   loadList[++k] = MK_LD(0,4,-1,4);
681
682   k=-1;
683
684   storeList[++k] = MK_ST(-4,4,-1,4);
685   storeList[++k] = MK_ST(-4,4,-1,4);
686   storeList[++k] = MK_ST(-4,4,-1,4);
687   storeList[++k] = MK_ST(-4,4,-1,4);
688   storeList[++k] = MK_ST(-4,4,-1,4);
689
690   storeList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // s6
691   storeList[++k] = MK_ST((long)divarwp+4,-1,-1,4);
692   storeList[++k] = MK_LS((long)divarwp,-1,-1,4);
693   storeList[++k] = MK_LS((long)divarwp+4,-1,-1,4);
694   storeList[++k] = MK_ST((long)divarwp,-1,-1,4);   // s10
695   storeList[++k] = MK_LS((long)divarwp+4,-1,-1,4);
696
697   storeList[++k] = MK_STnt((long)divarwp,-1,-1,8); // s12
698   //storeList[++k] = MK_ST(0,7,-1,4);
699   storeList[++k] = new BPatch_memoryAccess(NULL, 0,
700                                            false, true,
701                                            0, 7, -1, 0,
702                                            0, -1, 1, 2,
703                                            -1, false);
704   storeList[++k] = MK_ST(0,7,-1,4);
705   //storeList[++k] = MK_SL2(0,7,-1,4,0,6,-1,4); // s15
706   storeList[++k] = MK_SL2vECX(0,7,-1,0,6,-1,2);
707   
708   storeList[++k] = MK_ST((long)dfvarsp,-1,-1,4);
709   storeList[++k] = MK_ST((long)dfvardp,-1,-1,8);
710   storeList[++k] = MK_ST((long)dfvartp,-1,-1,10);
711   storeList[++k] = MK_ST((long)divarwp+2,-1,-1,2);
712   storeList[++k] = MK_ST((long)divarwp+4,-1,-1,4);
713   storeList[++k] = MK_ST((long)divarwp+8,-1,-1,8);
714
715   storeList[++k] = MK_ST((long)divarwp,-1,-1,2);
716   storeList[++k] = MK_ST((long)dlargep,-1,-1,28);
717
718   k=-1;
719
720   prefeList[++k] = MK_PF((long)divarwp,-1,-1,IA32prefetchT0);
721   prefeList[++k] = MK_PF((long)divarwp,-1,-1,IA32AMDprefetch);
722 }
723 #endif
724
725 #ifdef ia64_unknown_linux2_4
726
727 const unsigned int nloads = 6;
728 const unsigned int nstores = 3;
729 const unsigned int nprefes = 3;
730 /* I don't know why this doesn't include nprefes on other platforms. */
731 const unsigned int naxses = 12;
732
733 BPatch_memoryAccess* loadList[nloads];
734 BPatch_memoryAccess* storeList[nstores];
735 BPatch_memoryAccess* prefeList[nprefes];
736
737 void init_test_data() {
738         loadList[0] = MK_LD( 0, 16, -1, 8 );
739         loadList[1] = MK_LD( 0, 14, -1, 8 );
740         loadList[2] = MK_LD( 0, 15, -1, 8 );
741         
742         loadList[3] = MK_LD( 0, 14, -1, 8 );
743         loadList[4] = MK_LD( 0, 14, -1, 16 );
744         loadList[5] = MK_LD( 0, 14, -1, 16 );
745         
746         storeList[0] = MK_ST( 0, 14, -1, 8 );
747         storeList[1] = MK_ST( 0, 14, -1, 8 );
748         storeList[2] = MK_ST( 0, 14, -1, 8 );
749         
750         prefeList[0] = MK_PF( 0, 14, -1, 0 );
751         prefeList[1] = MK_PF( 0, 14, -1, 0 );
752         prefeList[2] = MK_PF( 0, 14, -1, 0 );
753         } /* end init_test_data() */
754 #endif
755
756 #ifdef x86_64_unknown_linux2_4
757
758 const unsigned int nloads = 73;
759 const unsigned int nstores = 25;
760 const unsigned int nprefes = 2;
761 const unsigned int naxses = 95;
762
763 BPatch_memoryAccess* loadList[nloads];
764 BPatch_memoryAccess* storeList[nstores];
765 BPatch_memoryAccess* prefeList[nprefes + 1]; // for NT
766
767 void *divarwp, *dfvarsp, *dfvardp, *dfvartp, *dlargep;
768
769 void get_vars_addrs(BPatch_image* bip) // from mutatee
770 {
771
772   BPatch_variableExpr* bpvep_diwarw = bip->findVariable("divarw");
773   BPatch_variableExpr* bpvep_diwars = bip->findVariable("dfvars");
774   BPatch_variableExpr* bpvep_diward = bip->findVariable("dfvard");
775   BPatch_variableExpr* bpvep_diwart = bip->findVariable("dfvart");
776   BPatch_variableExpr* bpvep_dlarge = bip->findVariable("dlarge");
777   divarwp = bpvep_diwarw->getBaseAddr();
778   dfvarsp = bpvep_diwars->getBaseAddr();
779   dfvardp = bpvep_diward->getBaseAddr();
780   dfvartp = bpvep_diwart->getBaseAddr();
781   dlargep = bpvep_dlarge->getBaseAddr();
782 }
783
784 void init_test_data()
785 {
786   int k=-1;
787
788   // ModRM loads
789
790   // mod = 00
791   loadList[++k] = MK_LD(0,0,-1,4);
792   loadList[++k] = MK_LD(0,1,-1,8);
793   loadList[++k] = MK_LD(0,2,-1,4);
794   loadList[++k] = MK_LD(0,3,-1,8);
795   loadList[++k] = NULL; // rip-relative data access (disable the check)
796   loadList[++k] = MK_LD(0,6,-1,8);
797   loadList[++k] = MK_LD(0,7,-1,4);
798   loadList[++k] = MK_LD(0,8,-1,8);
799   loadList[++k] = MK_LD(0,9,-1,4);
800   loadList[++k] = MK_LD(0,10,-1,8);
801   loadList[++k] = MK_LD(0,11,-1,4);
802   loadList[++k] = MK_LD(0,14,-1,8);
803   loadList[++k] = MK_LD(0,15,-1,4);
804
805   // mod = 01
806   loadList[++k] = MK_LD(4,0,-1,4);
807   loadList[++k] = MK_LD(8,1,-1,8);
808   loadList[++k] = MK_LD(-4,2,-1,4);
809   loadList[++k] = MK_LD(-8,3,-1,8);
810   loadList[++k] = MK_LD(4,5,-1,4);
811   loadList[++k] = MK_LD(8,6,-1,8);
812   loadList[++k] = MK_LD(-4,7,-1,4);
813   loadList[++k] = MK_LD(-8,8,-1,8);
814   loadList[++k] = MK_LD(4,9,-1,4);
815   loadList[++k] = MK_LD(8,10,-1,8);
816   loadList[++k] = MK_LD(-4,11,-1,4);
817   loadList[++k] = MK_LD(-8,13,-1,8);
818   loadList[++k] = MK_LD(127,14,-1,4);
819   loadList[++k] = MK_LD(-128,15,-1,8);
820
821   // SIB loads
822   loadList[++k] = MK_LD(0,3,6,4);
823   loadList[++k] = MK_LD(0,4,-1,8);
824   loadList[++k] = MK_LDsc(0,3,1,1,4);
825   loadList[++k] = MK_LDsc((long)divarwp,-1,1,1,8);
826   loadList[++k] = MK_LD(4,3,1,4);
827   loadList[++k] = MK_LDsc((long)divarwp,2,2,3,8);
828   loadList[++k] = MK_LDsc(2,5,1,1,4);
829   loadList[++k] = MK_LDsc(4,3,1,2,8);
830   loadList[++k] = MK_LDsc((long)divarwp,5,1,2,4);
831
832   // loads from semantic test cases
833   loadList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // inc
834   loadList[++k] = MK_LD((long)divarwp+4,-1,-1,4); // cmp
835   loadList[++k] = MK_LD2(0,6,-1,1,0,7,-1,1);      // cmpsb
836   loadList[++k] = MK_LS((long)divarwp,-1,-1,4);   // add
837   loadList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // xchg
838   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,4); // imul
839   loadList[++k] = MK_LD((long)divarwp,-1,-1,4);   // imul
840   loadList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // shld
841   loadList[++k] = MK_LD((long)divarwp,-1,-1,4);   // idiv
842
843   // MMX
844   loadList[++k] = MK_LD((long)divarwp,-1,-1,8);
845   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,8);
846
847   // SSE
848   loadList[++k] = MK_LD((long)dfvartp,-1,-1,16);
849   loadList[++k] = MK_LD((long)dfvartp,-1,-1,4);
850
851   // SSE2
852   loadList[++k] = MK_LD((long)dfvartp,-1,-1,16);
853   loadList[++k] = MK_LD((long)dfvartp,-1,-1,8);
854
855   // 3DNow!
856   loadList[++k] = MK_LD((long)dfvardp,-1,-1,8);
857   loadList[++k] = MK_LD((long)dfvardp+8,-1,-1,8);
858
859   // REP prefixes
860   loadList[++k] = MK_SL2vECX(0,7,-1,0,6,-1,2);
861   loadList[++k] = new BPatch_memoryAccess(NULL, 0,
862                                           true, false,
863                                           0, 7, -1, 0,
864                                           0, -1, IA32_NESCAS, 0, 
865                                           -1, false);
866   loadList[++k] = new BPatch_memoryAccess(NULL, 0,
867                                           true, false,
868                                           0, 6, -1, 0,
869                                           0, -1, IA32_ECMPS, 0,
870                                           true, false,
871                                           0, 7, -1, 0,
872                                           0, -1, IA32_ECMPS, 0);
873
874   // x87
875   loadList[++k] = MK_LD((long)dfvarsp,-1,-1,4);
876   loadList[++k] = MK_LD((long)dfvardp,-1,-1,8);
877   loadList[++k] = MK_LD((long)dfvartp,-1,-1,10);
878   loadList[++k] = MK_LD((long)divarwp,-1,-1,2);
879   loadList[++k] = MK_LD((long)divarwp+4,-1,-1,4);
880   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,8);
881
882   loadList[++k] = MK_LD((long)divarwp,-1,-1,2);
883   loadList[++k] = MK_LD((long)dlargep,-1,-1,28);
884
885   // conditional moves
886   loadList[++k] = MK_LDsccnd((long)divarwp,-1,-1,0,4,7); // cmova
887   loadList[++k] = MK_LDsccnd((long)divarwp+4,-1,-1,0,4,4); // cmove
888   loadList[++k] = MK_LD((long)divarwp+8,-1,-1,4);
889
890   // final 6 stack pops
891   loadList[++k] = MK_LD(0,4,-1,8);
892   loadList[++k] = MK_LD(0,4,-1,8);
893   loadList[++k] = MK_LD(0,4,-1,8);
894   loadList[++k] = MK_LD(0,4,-1,8);
895   loadList[++k] = MK_LD(0,4,-1,8);
896   loadList[++k] = MK_LD(0,4,-1,8);
897
898   k=-1;
899
900   // initial 7 pushes
901   storeList[++k] = MK_ST(-8,4,-1,8);
902   storeList[++k] = MK_ST(-8,4,-1,8);
903   storeList[++k] = MK_ST(-8,4,-1,8);
904   storeList[++k] = MK_ST(-8,4,-1,8);
905   storeList[++k] = MK_ST(-8,4,-1,8);
906   storeList[++k] = MK_ST(-8,4,-1,8);
907   storeList[++k] = MK_ST(-8,4,-1,8);
908
909   // stores from semantic test cases
910   storeList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // inc
911   storeList[++k] = MK_ST((long)divarwp+4,-1,-1,4); // mov
912   storeList[++k] = MK_LS((long)divarwp,-1,-1,4);   // add
913   storeList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // xchg
914   storeList[++k] = MK_LS((long)divarwp+4,-1,-1,4); // shld
915   storeList[++k] = MK_ST((long)divarwp,-1,-1,4); // mov
916
917   // MMX store
918   storeList[++k] = MK_STnt((long)divarwp,-1,-1,8); // mov
919
920   // REP stores
921   storeList[++k] = new BPatch_memoryAccess(NULL, 0,
922                                            false, true,
923                                            0, 7, -1, 0,
924                                            0, -1, 1, 2,
925                                            -1, false);  // rep stosl
926   storeList[++k] = new BPatch_memoryAccess(NULL, 0,
927                                            false, true,
928                                            0, 7, -1, 0,
929                                            0, -1, 1, 2,
930                                            -1, false);  // rep stosl
931   storeList[++k] = MK_SL2vECX(0,7,-1,0,6,-1,2);
932
933
934   // x87
935   storeList[++k] = MK_ST((long)dfvarsp,-1,-1,4);
936   storeList[++k] = MK_ST((long)dfvardp,-1,-1,8);
937   storeList[++k] = MK_ST((long)dfvartp,-1,-1,10);
938   storeList[++k] = MK_ST((long)divarwp+2,-1,-1,2);
939   storeList[++k] = MK_ST((long)divarwp+4,-1,-1,4);
940   storeList[++k] = MK_ST((long)divarwp+8,-1,-1,8);
941
942   storeList[++k] = MK_ST((long)divarwp,-1,-1,2);
943   storeList[++k] = MK_ST((long)dlargep,-1,-1,28);
944
945   k=-1;
946
947   // prefetches
948   prefeList[++k] = MK_PF((long)divarwp,-1,-1,IA32prefetchT0);
949   prefeList[++k] = MK_PF((long)divarwp,-1,-1,IA32AMDprefetch);
950 }
951 #endif
952
953
954 #ifdef mips_sgi_irix6_4
955 void init_test_data()
956 {
957 }
958 #endif
959
960 #ifdef alpha_dec_osf4_0
961 void init_test_data()
962 {
963 }
964 #endif
965
966 #if defined(os_linux) && defined(arch_power)
967 void init_test_data()
968 {
969 }
970 #endif
971
972 #define skiptest(i,d) passedTest[(i)] = true;
973
974 #define failtest(i,d,r) { fprintf(stderr, "**Failed** test #%d (%s)\n", (i), (d)); \
975                           fprintf(stderr, "    %s\n", (r)); \
976                           exit(1); }
977
978
979 static inline void dumpvect(BPatch_Vector<BPatch_point*>* res, const char* msg)
980 {
981   if(!debugPrint)
982     return;
983
984   printf("%s: %d\n", msg, res->size());
985   for(unsigned int i=0; i<res->size(); ++i) {
986     BPatch_point *bpp = (*res)[i];
987     const BPatch_memoryAccess* ma = bpp->getMemoryAccess();
988     const BPatch_addrSpec_NP& as = ma->getStartAddr_NP();
989     const BPatch_countSpec_NP& cs = ma->getByteCount_NP();
990     if(ma->getNumberOfAccesses() == 1) {
991       if(ma->isConditional_NP())
992         printf("%s[%d]: @[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld] ?[%X]\n", msg, i+1,
993                as.getReg(0), as.getReg(1), as.getScale(), as.getImm(),
994                cs.getReg(0), cs.getReg(1), cs.getImm(), ma->conditionCode_NP());
995         else
996           printf("%s[%d]: @[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld]\n", msg, i+1,
997                  as.getReg(0), as.getReg(1), as.getScale(), as.getImm(),
998                  cs.getReg(0), cs.getReg(1), cs.getImm());
999     }
1000     else {
1001       const BPatch_addrSpec_NP& as2 = ma->getStartAddr_NP(1);
1002       const BPatch_countSpec_NP& cs2 = ma->getByteCount_NP(1);
1003       printf("%s[%d]: @[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld] && "
1004              "@[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld]\n", msg, i+1,
1005              as.getReg(0), as.getReg(1), as.getScale(), as.getImm(),
1006              cs.getReg(0), cs.getReg(1), cs.getImm(),
1007              as2.getReg(0), as2.getReg(1), as2.getScale(), as2.getImm(),
1008              cs2.getReg(0), cs2.getReg(1), cs2.getImm());
1009     }
1010   }
1011 }
1012
1013
1014 static inline void dumpxpct(BPatch_memoryAccess* exp[], unsigned int size, const char* msg)
1015 {
1016   if(!debugPrint)
1017     return;
1018            
1019   printf("%s: %d\n", msg, size);
1020
1021   for(unsigned int i=0; i<size; ++i) {
1022     const BPatch_memoryAccess* ma = exp[i];
1023     if(!ma)
1024       continue;
1025     const BPatch_addrSpec_NP& as = ma->getStartAddr_NP();
1026     const BPatch_countSpec_NP& cs = ma->getByteCount_NP();
1027     if(ma->getNumberOfAccesses() == 1)
1028       printf("%s[%d]: @[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld]\n", msg, i+1,
1029              as.getReg(0), as.getReg(1), as.getScale(), as.getImm(),
1030              cs.getReg(0), cs.getReg(1), cs.getImm());
1031     else {
1032       const BPatch_addrSpec_NP& as2 = ma->getStartAddr_NP(1);
1033       const BPatch_countSpec_NP& cs2 = ma->getByteCount_NP(1);
1034       printf("%s[%d]: @[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld] && "
1035              "@[r%d+r%d<<%d+%ld] #[r%d+r%d+%ld]\n", msg, i+1,
1036              as.getReg(0), as.getReg(1), as.getScale(), as.getImm(),
1037              cs.getReg(0), cs.getReg(1), cs.getImm(),
1038              as2.getReg(0), as2.getReg(1), as2.getScale(), as2.getImm(),
1039              cs2.getReg(0), cs2.getReg(1), cs2.getImm());
1040     }
1041   }
1042 }
1043
1044
1045 static inline bool validate(BPatch_Vector<BPatch_point*>* res,
1046                             BPatch_memoryAccess* acc[], const char* msg)
1047 {
1048   bool ok = true;
1049
1050   for(unsigned int i=0; i<res->size(); ++i) {
1051     if (acc[i] != NULL) {
1052       BPatch_point* bpoint = (*res)[i];
1053       ok = (ok && bpoint->getMemoryAccess()->equals(acc[i]));
1054       if(!ok) {
1055         printf("Validation failed at %s #%d.\n", msg, i+1);
1056         dumpxpct(acc, res->size(), "Expected");
1057         return ok;
1058       }
1059     }
1060   }
1061   return ok;
1062 }
1063
1064
1065 // Find and instrument loads with a simple function call snippet
1066 void mutatorTest1(BPatch_thread *bpthr, BPatch_image *bpimg,
1067                   int testnum = 1, 
1068                   const char* testdesc = "load instrumentation")
1069 {
1070 #if !defined(sparc_sun_solaris2_4) \
1071  && !defined(rs6000_ibm_aix4_1) \
1072  && !defined(i386_unknown_linux2_0) \
1073  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1074  && !defined(i386_unknown_nt4_0) \
1075  && !defined(ia64_unknown_linux2_4)
1076   skiptest(testnum, testdesc);
1077 #else
1078   BPatch_Set<BPatch_opCode> loads;
1079   loads.insert(BPatch_opLoad);
1080
1081   BPatch_Vector<BPatch_function *> found_funcs;
1082   const char *inFunction = "loadsnstores";
1083   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1084     fprintf(stderr, "    Unable to find function %s\n",
1085             inFunction);
1086     exit(1);
1087   }
1088        
1089   if (1 < found_funcs.size()) {
1090     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1091             __FILE__, __LINE__, found_funcs.size(), inFunction);
1092   }
1093        
1094   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(loads);
1095
1096   if(!res1)
1097     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1098
1099   dumpvect(res1, "Loads");
1100
1101   if((*res1).size() != nloads)
1102     failtest(testnum, testdesc, "Number of loads seems wrong in function \"loadsnstores.\"\n");
1103
1104   if(!validate(res1, loadList, "load"))
1105     failtest(testnum, testdesc, "Load sequence failed validation.\n");
1106
1107   instCall(bpthr, "Load", res1);
1108 #endif
1109 }
1110
1111
1112 // Find and instrument stores with a simple function call snippet
1113 void mutatorTest2(BPatch_thread *bpthr, BPatch_image *bpimg,
1114                   int testnum = 2,
1115                   const char* testdesc = "store instrumentation")
1116 {
1117 #if !defined(sparc_sun_solaris2_4) \
1118  && !defined(rs6000_ibm_aix4_1) \
1119  && !defined(i386_unknown_linux2_0) \
1120  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1121  && !defined(i386_unknown_nt4_0) \
1122  && !defined(ia64_unknown_linux2_4)
1123   skiptest(testnum, testdesc);
1124 #else
1125   BPatch_Set<BPatch_opCode> stores;
1126   stores.insert(BPatch_opStore);
1127
1128   BPatch_Vector<BPatch_function *> found_funcs;
1129   const char *inFunction = "loadsnstores";
1130   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1131     fprintf(stderr, "    Unable to find function %s\n",
1132             inFunction);
1133     exit(1);
1134   }
1135        
1136   if (1 < found_funcs.size()) {
1137     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1138             __FILE__, __LINE__, found_funcs.size(), inFunction);
1139   }
1140        
1141   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(stores);
1142
1143   if(!res1)
1144     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1145
1146   dumpvect(res1, "Stores");
1147
1148   if((*res1).size() != nstores)
1149     failtest(testnum, testdesc, "Number of stores seems wrong in function \"loadsnstores.\"\n");
1150
1151   if(!validate(res1, storeList, "store"))
1152     failtest(testnum, testdesc, "Store sequence failed validation.\n");
1153
1154   instCall(bpthr, "Store", res1);
1155 #endif
1156 }
1157
1158 // Find and instrument prefetches with a simple function call snippet
1159 void mutatorTest3(BPatch_thread *bpthr, BPatch_image *bpimg,
1160                   int testnum = 3, 
1161                   const char* testdesc = "prefetch instrumentation")
1162 {
1163 #if !defined(sparc_sun_solaris2_4) \
1164  && !defined(rs6000_ibm_aix4_1) \
1165  && !defined(i386_unknown_linux2_0) \
1166  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1167  && !defined(i386_unknown_nt4_0) \
1168  && !defined(ia64_unknown_linux2_4)
1169   skiptest(testnum, testdesc);
1170 #else
1171   BPatch_Set<BPatch_opCode> prefes;
1172   prefes.insert(BPatch_opPrefetch);
1173
1174   BPatch_Vector<BPatch_function *> found_funcs;
1175   const char *inFunction = "loadsnstores";
1176   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1177     fprintf(stderr, "    Unable to find function %s\n",
1178             inFunction);
1179     exit(1);
1180   }
1181        
1182   if (1 < found_funcs.size()) {
1183     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1184             __FILE__, __LINE__, found_funcs.size(), inFunction);
1185   }
1186        
1187   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(prefes);
1188
1189   if(!res1)
1190     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1191
1192   dumpvect(res1, "Prefetches");
1193
1194   if((*res1).size() != nprefes)
1195     failtest(testnum, testdesc,
1196              "Number of prefetches seems wrong in function \"loadsnstores.\"\n");
1197
1198   if(!validate(res1, prefeList, "prefetch"))
1199     failtest(testnum, testdesc, "Prefetch sequence failed validation.\n");
1200
1201   instCall(bpthr, "Prefetch", res1);
1202 #endif
1203 }
1204
1205
1206 // Find and instrument all accesses with a simple function call snippet
1207 void mutatorTest4(BPatch_thread *bpthr, BPatch_image *bpimg,
1208                   int testnum = 4,
1209                   const char* testdesc = "access instrumentation")
1210 {
1211 #if !defined(sparc_sun_solaris2_4) \
1212  && !defined(rs6000_ibm_aix4_1) \
1213  && !defined(i386_unknown_linux2_0) \
1214  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1215  && !defined(i386_unknown_nt4_0) \
1216  && !defined(ia64_unknown_linux2_4)
1217   skiptest(testnum, testdesc);
1218 #else
1219   BPatch_Set<BPatch_opCode> axs;
1220   axs.insert(BPatch_opLoad);
1221   axs.insert(BPatch_opStore);
1222   axs.insert(BPatch_opPrefetch);
1223
1224   BPatch_Vector<BPatch_function *> found_funcs;
1225   const char *inFunction = "loadsnstores";
1226   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1227     fprintf(stderr, "    Unable to find function %s\n",
1228             inFunction);
1229     exit(1);
1230   }
1231        
1232   if (1 < found_funcs.size()) {
1233     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1234             __FILE__, __LINE__, found_funcs.size(), inFunction);
1235   }
1236        
1237   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(axs);
1238
1239   if(!res1)
1240     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1241
1242   // dumpvect(res1, "Accesses");
1243
1244   if((*res1).size() != naxses)
1245     failtest(testnum, testdesc,
1246              "Number of accesses seems wrong in function \"loadsnstores\".\n");
1247
1248   instCall(bpthr, "Access", res1);
1249 #if defined(i386_unknown_linux2_0) \
1250  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1251  || defined(i386_unknown_nt4_0)
1252   const BPatch_Vector<BPatch_point*>* res2 = BPatch_memoryAccess::filterPoints(*res1, 2);
1253   instCall(bpthr, "Access", res2);
1254 #endif
1255
1256 #endif
1257 }
1258
1259
1260 // Instrument all accesses with an effective address snippet
1261 void mutatorTest5(BPatch_thread *bpthr, BPatch_image *bpimg,
1262                   int testnum = 5,
1263                   const char* testdesc = "instrumentation w/effective address snippet")
1264 {
1265 #if !defined(sparc_sun_solaris2_4) \
1266  &&(!defined(rs6000_ibm_aix4_1) || defined(AIX5)) \
1267  && !defined(i386_unknown_linux2_0) \
1268  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1269  && !defined(i386_unknown_nt4_0) \
1270  && !defined(ia64_unknown_linux2_4)
1271   skiptest(testnum, testdesc);
1272 #else
1273   BPatch_Set<BPatch_opCode> axs;
1274   axs.insert(BPatch_opLoad);
1275   axs.insert(BPatch_opStore);
1276   axs.insert(BPatch_opPrefetch);
1277
1278
1279   BPatch_Vector<BPatch_function *> found_funcs;
1280   const char *inFunction = "loadsnstores";
1281   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1282     fprintf(stderr, "    Unable to find function %s\n",
1283             inFunction);
1284     exit(1);
1285   }
1286        
1287   if (1 < found_funcs.size()) {
1288     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1289             __FILE__, __LINE__, found_funcs.size(), inFunction);
1290   }
1291        
1292   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(axs);
1293
1294   if(!res1)
1295     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1296
1297   //fprintf(stderr, "Doing test %d!!!!!!\n", testnum);
1298   instEffAddr(bpthr, "EffAddr", res1, false);
1299 #endif
1300   //bpthr->detach(false);
1301 }
1302
1303 // Instrument all accesses with a byte count snippet
1304 void mutatorTest6(BPatch_thread *bpthr, BPatch_image *bpimg,
1305                   int testnum = 6,
1306                   const char* testdesc ="instrumentation w/byte count snippet")
1307 {
1308 #if !defined(sparc_sun_solaris2_4) \
1309  && !defined(rs6000_ibm_aix4_1) \
1310  && !defined(i386_unknown_linux2_0) \
1311  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1312  && !defined(i386_unknown_nt4_0) \
1313  && !defined(ia64_unknown_linux2_4)
1314   skiptest(testnum, testdesc);
1315 #else
1316   BPatch_Set<BPatch_opCode> axs;
1317   axs.insert(BPatch_opLoad);
1318   axs.insert(BPatch_opStore);
1319   axs.insert(BPatch_opPrefetch);
1320
1321   BPatch_Vector<BPatch_function *> found_funcs;
1322   const char *inFunction = "loadsnstores";
1323   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1324     fprintf(stderr, "    Unable to find function %s\n",
1325             inFunction);
1326     exit(1);
1327   }
1328        
1329   if (1 < found_funcs.size()) {
1330     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1331             __FILE__, __LINE__, found_funcs.size(), inFunction);
1332   }
1333        
1334   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(axs);
1335
1336   if(!res1)
1337     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1338
1339   if((*res1).size() != naxses)
1340     failtest(testnum, testdesc,
1341              "Number of accesses seems wrong in function \"loadsnstores\".\n");
1342
1343   //fprintf(stderr, "Doing test %d!!!!!!\n", testnum);
1344   instByteCnt(bpthr, "ByteCnt", res1, false);
1345 #endif
1346 }
1347
1348 void mutatorTest7(BPatch_thread *bpthr, BPatch_image *bpimg, int testnum = 7,
1349                   const char* testdesc = "conditional instrumentation w/effective address snippet")
1350 {
1351 #if !defined(sparc_sun_solaris2_4) \
1352  &&(!defined(rs6000_ibm_aix4_1) || defined(AIX5)) \
1353  && !defined(i386_unknown_linux2_0) \
1354  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1355  && !defined(i386_unknown_nt4_0) \
1356  && !defined(ia64_unknown_linux2_4)
1357   skiptest(testnum, testdesc);
1358 #else
1359   BPatch_Set<BPatch_opCode> axs;
1360   axs.insert(BPatch_opLoad);
1361   axs.insert(BPatch_opStore);
1362   axs.insert(BPatch_opPrefetch);
1363
1364   BPatch_Vector<BPatch_function *> found_funcs;
1365   const char *inFunction = "loadsnstores";
1366   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1367     fprintf(stderr, "    Unable to find function %s\n",
1368             inFunction);
1369     exit(1);
1370   }
1371        
1372   if (1 < found_funcs.size()) {
1373     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1374             __FILE__, __LINE__, found_funcs.size(), inFunction);
1375   }
1376        
1377   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(axs);
1378
1379   if(!res1)
1380     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1381
1382   //fprintf(stderr, "Doing test %d!!!!!!\n", testnum);
1383   instEffAddr(bpthr, "EffAddr", res1, true);
1384 #endif
1385   //bpthr->detach(false);
1386 }
1387
1388 // Instrument all accesses with a byte count snippet
1389 void mutatorTest8(BPatch_thread *bpthr, BPatch_image *bpimg, int testnum = 8,
1390                   const char* testdesc = "conditional instrumentation w/byte count snippet")
1391 {
1392 #if !defined(sparc_sun_solaris2_4) \
1393  && !defined(rs6000_ibm_aix4_1) \
1394  && !defined(i386_unknown_linux2_0) \
1395  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1396  && !defined(i386_unknown_nt4_0) \
1397  && !defined(ia64_unknown_linux2_4)
1398   skiptest(testnum, testdesc);
1399 #else
1400   BPatch_Set<BPatch_opCode> axs;
1401   axs.insert(BPatch_opLoad);
1402   axs.insert(BPatch_opStore);
1403   axs.insert(BPatch_opPrefetch);
1404
1405   BPatch_Vector<BPatch_function *> found_funcs;
1406   const char *inFunction = "loadsnstores";
1407   if ((NULL == bpimg->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
1408     fprintf(stderr, "    Unable to find function %s\n",
1409             inFunction);
1410     exit(1);
1411   }
1412        
1413   if (1 < found_funcs.size()) {
1414     fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
1415             __FILE__, __LINE__, found_funcs.size(), inFunction);
1416   }
1417        
1418   BPatch_Vector<BPatch_point *> *res1 = found_funcs[0]->findPoint(axs);
1419
1420   if(!res1)
1421     failtest(testnum, testdesc, "Unable to find function \"loadsnstores\".\n");
1422
1423   if((*res1).size() != naxses)
1424     failtest(testnum, testdesc,
1425              "Number of accesses seems wrong in function \"loadsnstores\".\n");
1426
1427   //fprintf(stderr, "Doing test %d!!!!!!\n", testnum);
1428   instByteCnt(bpthr, "ByteCnt", res1, true);
1429 #endif
1430 }
1431
1432 void mutatorMAIN(char *pathname)
1433 {
1434   // Create an instance of the BPatch library
1435   bpatch = new BPatch;
1436
1437   // Register a callback function that prints any error messages
1438   // Mental note: this needs to be done BEFORE thread creation...
1439   bpatch->registerErrorCallback(errorFunc);
1440
1441   BPatch_thread *bpthr;
1442
1443   // Force functions to be relocated
1444   // VG: not sure why we need this...
1445   //if (forceRelocation) {
1446   //    bpatch->setForcedRelocation_NP(true);
1447   //}
1448
1449   // Start the mutatee
1450   dprintf("Starting \"%s\"\n", pathname);
1451
1452   const char *child_argv[MAX_TEST+5];
1453
1454   int n = 0;
1455   child_argv[n++] = pathname;
1456   if (debugPrint) child_argv[n++] = const_cast<char*>("-verbose");
1457
1458   if (runAllTests) {
1459     child_argv[n++] = const_cast<char*>("-runall"); // signifies all tests
1460   } else {
1461     child_argv[n++] = const_cast<char*>("-run");
1462     for (unsigned int j=1; j <= MAX_TEST; j++) {
1463       if (runTest[j]) {
1464         char str[5];
1465         sprintf(str, "%d", j);
1466         child_argv[n++] = strdup(str);
1467       }
1468     }
1469   }
1470
1471   child_argv[n] = NULL;
1472
1473   bpthr = bpatch->createProcess(pathname, child_argv, NULL);
1474
1475   if (bpthr == NULL) {
1476     fprintf(stderr, "Unable to run test program.\n");
1477     exit(1);
1478   }
1479
1480   BPatch_image *bpimg = bpthr->getImage();
1481
1482 #if defined(i386_unknown_linux2_0) \
1483  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */
1484   get_vars_addrs(bpimg);
1485 #endif
1486   init_test_data();
1487
1488   if (runTest[1]) mutatorTest1(bpthr, bpimg);
1489   if (runTest[2]) mutatorTest2(bpthr, bpimg);
1490   if (runTest[3]) mutatorTest3(bpthr, bpimg);
1491   if (runTest[4]) mutatorTest4(bpthr, bpimg);
1492   if (runTest[5]) mutatorTest5(bpthr, bpimg);
1493   if (runTest[6]) mutatorTest6(bpthr, bpimg);
1494   if (runTest[7]) mutatorTest7(bpthr, bpimg);
1495   if (runTest[8]) mutatorTest8(bpthr, bpimg);
1496
1497   dprintf("starting program execution.\n");
1498   bpthr->continueExecution();
1499   // Wait for process to terminate
1500   while(!bpthr->isTerminated());
1501   
1502   //bpthr->detach(false);
1503
1504   unsigned int testsFailed = 0;
1505   for (unsigned int i=1; i <= MAX_TEST; i++) {
1506     if (runTest[i] && !passedTest[i]) testsFailed++;
1507   }
1508
1509   if (!testsFailed) {
1510     if (runAllTests) {
1511       printf("All tests passed\n");
1512     } else {
1513       printf("All requested tests passed\n");
1514     }
1515   }
1516 }
1517
1518 //
1519 // main - decide our role and call the correct "main"
1520 //
1521 int
1522 main(int argc, char *argv[])
1523 {
1524     unsigned int i;
1525     bool ABI_32=false;
1526     char mutateeName[128];
1527     char libRTname[256];
1528
1529     strcpy(mutateeName, mutateeNameRoot);
1530     libRTname[0]='\0';
1531
1532     if (!getenv("DYNINSTAPI_RT_LIB")) {
1533          fprintf(stderr,"Environment variable DYNINSTAPI_RT_LIB undefined:\n"
1534 #if defined(i386_unknown_nt4_0)
1535                  "    using standard search strategy for libdyninstAPI_RT.dll\n");
1536 #else
1537                  "    set it to the full pathname of libdyninstAPI_RT\n");   
1538          exit(-1);
1539 #endif
1540     } else
1541          strcpy((char *)libRTname, (char *)getenv("DYNINSTAPI_RT_LIB"));
1542
1543     updateSearchPaths(argv[0]);
1544
1545     // by default run all tests
1546     for (i=1; i <= MAX_TEST; i++) {
1547         runTest[i] = true;
1548         passedTest[i] = false;
1549     }
1550
1551     for (i=1; i < argc; i++) {
1552         if (strncmp(argv[i], "-v+", 3) == 0)    errorPrint++;
1553         if (strncmp(argv[i], "-v++", 4) == 0)   errorPrint++;
1554         if (strncmp(argv[i], "-verbose", 2) == 0) {
1555             debugPrint = 1;
1556         } else if (!strcmp(argv[i], "-V")) {
1557             if (libRTname[0]) 
1558                 fprintf (stdout, "DYNINSTAPI_RT_LIB=%s\n", libRTname);
1559             fflush(stdout);
1560         } else if (!strcmp(argv[i], "-skip")) {
1561             unsigned int j;
1562             runAllTests = false;
1563             for (j=i+1; j < argc; j++) {
1564                 unsigned int testId;
1565                 if ((testId = atoi(argv[j]))) {
1566                     if ((testId > 0) && (testId <= MAX_TEST)) {
1567                         runTest[testId] = false;
1568                     } else {
1569                         printf("invalid test %d requested\n", testId);
1570                         exit(-1);
1571                     }
1572                 } else {
1573                     // end of test list
1574                     break;
1575                 }
1576             }
1577             i=j-1;
1578         } else if (!strcmp(argv[i], "-run")) {
1579             unsigned int j;
1580             runAllTests = false;
1581             for (j=0; j <= MAX_TEST; j++) runTest[j] = false;
1582             for (j=i+1; j < argc; j++) {
1583                 unsigned int testId;
1584                 if ((testId = atoi(argv[j]))) {
1585                     if ((testId > 0) && (testId <= MAX_TEST)) {
1586                         runTest[testId] = true;
1587                     } else {
1588                         printf("invalid test %d requested\n", testId);
1589                         exit(-1);
1590                     }
1591                 } else {
1592                     // end of test list
1593                     break;
1594                 }
1595             }
1596             i=j-1;
1597         } else if (!strcmp(argv[i], "-mutatee")) {
1598             i++;
1599             if (*argv[i]=='_')
1600                 strcat(mutateeName,argv[i]);
1601             else
1602                 strcpy(mutateeName,argv[i]);
1603 #if defined(i386_unknown_nt4_0) \
1604  || defined(i386_unknown_linux2_0) \
1605  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
1606  || defined(sparc_sun_solaris2_4) \
1607  || defined(ia64_uknown_linux2_4)
1608         } else if (!strcmp(argv[i], "-relocate")) {
1609             forceRelocation = true;
1610 #endif
1611 #if defined(x86_64_unknown_linux2_4)
1612         } else if (!strcmp(argv[i], "-m32")) {
1613             ABI_32=true;
1614 #endif
1615         } else {
1616             fprintf(stderr, "Usage: test6 "
1617                     "[-V] [-verbose] "
1618 #if defined(mips_sgi_irix6_4)
1619                     "[-n32] "
1620 #endif
1621                     "[-mutatee <test4a.mutatee>] "
1622                     "[-run <test#> <test#> ...] "
1623                     "[-skip <test#> <test#> ...]\n");
1624             fprintf(stderr, "%d subtests\n", MAX_TEST);
1625             exit(-1);
1626         }
1627     }
1628
1629     if (!runAllTests) {
1630         printf("Running Tests: ");
1631         for (unsigned int j=1; j <= MAX_TEST; j++) {
1632             if (runTest[j]) printf("%d ", j);
1633         }
1634         printf("\n");
1635     }
1636
1637     // patch up the default compiler in mutatee name (if necessary)
1638     if (!strstr(mutateeName, "_"))
1639 #if defined(i386_unknown_nt4_0)
1640         strcat(mutateeName,"_VC");
1641 #else
1642         strcat(mutateeName,"_gcc");
1643 #endif
1644     if (ABI_32 || strstr(mutateeName,"_m32")) {
1645         // patch up file names based on alternate ABI (as necessary)
1646         if (!strstr(mutateeName, "_m32")) strcat(mutateeName,"_m32");
1647     }
1648     // patch up the platform-specific filename extensions
1649 #if defined(i386_unknown_nt4_0)
1650     if (!strstr(mutateeName, ".exe")) strcat(mutateeName,".exe");
1651 #endif
1652
1653     mutatorMAIN(mutateeName);
1654
1655     return 0;
1656 }