Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / tests / src / test6.mutatee.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.mutatee.c,v 1.31 2007/06/20 20:49:49 ssuen Exp $ */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <assert.h>
38
39 #define dprintf if (debugPrint) printf
40 int debugPrint = 0;
41
42 #define MAX_TEST 8
43
44 int runTest[MAX_TEST+1];
45 int passedTest[MAX_TEST+1];
46
47 #define TRUE    1
48 #define FALSE   0
49
50 #define USAGE "Usage: test6.mutatee [-verbose] -run <num> .."
51
52 /*
53  * Verify that a scalar value of a variable is what is expected
54  *
55  */
56 void verifyScalarValue(const char *name, int a, int value, int testNum, 
57                        const char *testName)
58 {
59     if (a != value) {
60         if (passedTest[testNum])
61             printf("**Failed** test %d (%s)\n", testNum, testName);
62         printf("  %s = %d, not %d\n", name, a, value);
63         passedTest[testNum] = FALSE;
64     }
65 }
66
67 extern long loadsnstores(long, long, long); /* ILP32 & LP64 */
68 int result_of_loadsnstores;
69
70 unsigned int loadCnt = 0;
71 unsigned int storeCnt = 0;
72 unsigned int prefeCnt = 0;
73 unsigned int accessCnt = 0;
74
75 unsigned int accessCntEA = 0;
76 unsigned int accessCntBC = 0;
77 int doomEA = 0;
78 int doomBC = 0;
79 void* eaList[1000];
80 unsigned int bcList[1000];
81 void* eaExp[1000];
82
83 unsigned int accessCntEAcc = 0;
84 unsigned int accessCntBCcc = 0;
85 int doomEAcc = 0;
86 int doomBCcc = 0;
87 void* eaListCC[1000];
88 unsigned int bcListCC[1000];
89 void* eaExpCC[1000];
90 unsigned int bcExpCC[1000];
91
92 #ifdef sparc_sun_solaris2_4
93 /* const */ unsigned int loadExp=15;
94 /* const */ unsigned int storeExp=13;
95 /* const */ unsigned int prefeExp=2;
96 /* const */ unsigned int accessExp=26;
97 /* const */ unsigned int accessExpCC=26;
98
99 unsigned int bcExp[] = { 4,1,2,8,4,1,1,  4,8,4,  4,4,8,8,16,
100                          0,0,  1,2,4,8,  4,8,16,4,8 };
101
102 int eaExpOffset[] =    { 0,3,2,0,0,3,3,  0,0,0,  0,0,0,0,0,
103                          0,0,  7,6,4,0,  0,0,0,4,0 };
104
105
106 extern void* eaExp[]; /* forward */
107 extern int divarw;
108 extern float dfvars;
109 extern double dfvard;
110 extern long double dfvarq;
111
112 /* _inline */ void init_test_data()
113 {
114   int i=0;
115
116   /*
117   printf("&divarw = %p\n", &divarw);
118   printf("&dfvars = %p\n", &dfvars);
119   printf("&dfvard = %p\n", &dfvard);
120   printf("&dfvarq = %p\n", &dfvarq);
121   */
122
123   for(; i<10; ++i)
124     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
125
126   for(; i<12; ++i)
127     eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
128
129   for(; i<14; ++i)
130     eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
131
132   for(; i<17; ++i)
133     eaExp[i] = (void*)((unsigned long)&dfvarq + eaExpOffset[i]);
134
135   for(; i<21; ++i)
136     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
137
138   eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
139   ++i;
140
141   eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
142   ++i;
143
144   eaExp[i] = (void*)((unsigned long)&dfvarq + eaExpOffset[i]);
145   ++i;
146
147   for(; i<26; ++i)
148     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
149
150   /* Duplicate the stream for cc */
151   for(i=0; i<accessExp; ++i) {
152     eaExpCC[i] = eaExp[i];
153     bcExpCC[i] = bcExp[i];
154   }
155 }
156 #endif
157
158 #ifdef rs6000_ibm_aix4_1
159 const unsigned int loadExp=41;
160 const unsigned int storeExp=32;
161 const unsigned int prefeExp=0;
162 const unsigned int accessExp=73;
163 const unsigned int accessExpCC=73;
164
165 unsigned int bcExp[] = { 4,  1,1,1,1,  2,2,2,2,  2,2,2,2,  4,4,4,4,
166                          4,4,4,  8,8,8,8,  1,1,1,1,  2,2,2,2,
167                          4,4,4,4,  8,8,8,8,  2,4,2,4,  76,76,24,20,
168                          20,20,  4,4,8,8,  4,  4,4,4,4,  4,  8,8,8,8,
169                          4,4,4,4,  8,8,8,8,  4 };
170
171 int eaExpOffset[] =    { 0, 17,3,1,2,  0,4,2,0,  2,2,2,2,  0,4,4,4,
172                          4,12,2,  0,0,0,0,  3,1,1,1,  2,6,2,2,
173                          0,4,4,4,  0,0,0,0,  0,0,0,0,  -76,-76,-24,-24,
174                          -20,-20,    0,0,0,0,  0,  0,4,0,4,  0,  0,8,8,8,
175                          4,4,0,0,  0,8,8,8,  0 };
176
177 extern void* eaExp[]; /* forward */
178 extern int divarw;
179 extern float dfvars;
180 extern double dfvard;
181
182 extern void* gettoc();
183 extern void* getsp();
184
185 #ifdef __GNUC__
186 #define _inline inline
187 #endif
188
189 /* _inline */ void init_test_data()
190 {
191   int i;
192
193   void *toc = gettoc();
194   void *sp  = getsp(1,2,3);
195
196   dprintf("&divarw = %p\n", &divarw);
197   dprintf("&dfvars = %p\n", &dfvars);
198   dprintf("&dfvard = %p\n", &dfvard);
199
200   dprintf("toc = %p\n", toc);
201   dprintf("sp = %p\n", sp);
202
203   eaExp[0] = toc; /* assuming that TOC entries are not reordered */
204
205   for(i=1; i<44; ++i)
206     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
207
208   for(i=44; i<50; ++i)
209     eaExp[i] = (void*)((unsigned long)sp + eaExpOffset[i]);; /* SP */
210   
211   for(i=50; i<54; ++i)
212     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
213
214   eaExp[54] = (void*)((unsigned long)toc + sizeof(void*)); /* TOC */
215
216   for(i=55; i<59; ++i)
217     eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
218
219   eaExp[59] = (void*)((unsigned long)toc + 2*sizeof(void*)); /* TOC */
220
221   for(i=60; i<64; ++i)
222     eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
223
224   for(i=64; i<68; ++i)
225     eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
226
227   for(i=68; i<72; ++i)
228     eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
229   
230   eaExp[72] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
231
232
233   /* Duplicate the stream for cc */
234   for(i=0; i<accessExp; ++i) {
235     eaExpCC[i] = eaExp[i];
236     bcExpCC[i] = bcExp[i];
237   }
238 }
239 #endif
240
241 #if defined(i386_unknown_linux2_0) \
242  || defined(i386_unknown_nt4_0)
243 unsigned int loadExp=65;
244 unsigned int storeExp=23;
245 unsigned int prefeExp=2;
246 unsigned int accessExp=88;
247 unsigned int accessExpCC=87;
248
249 struct reduction {
250   unsigned int loadRed;
251   unsigned int storeRed;
252   unsigned int prefeRed;
253   unsigned int axsRed;
254   unsigned int axsShift;
255 };
256
257 const struct reduction mmxRed = { 2, 1, 0, 3, 48 };
258 const struct reduction sseRed = { 2, 0, 1, 3, 51 };
259 const struct reduction sse2Red = { 2, 0, 0, 2, 54 };
260 const struct reduction amdRed = { 2, 0, 1, 3, 56 };
261
262 const struct reduction ccRed = { 0, 0, 0, 1, 83 };
263
264 int eaExpOffset[] =    { 0,0,0,0,  0,0,0,0,0,0,0,  4,8,4,8,4,8,4,  0,
265                          0,4,8,12,0,4,8,  12,0,8,8,8,0,4,8,4,  0,  4,4,4,0,4,0,4,8,0,0,4,0,
266                          0,8,0,  0,0,0,  0,0,  0,8,0,  0,12,0,0,0,44,25,   0,0,0,0,4,8,
267                          0,0,0,2,4,8,  0,0,  0,0,  0,4,8 };
268
269 extern void* eaExp[]; /* forward */
270
271 unsigned int bcExp[] = { 4,4,4,4,  4,4,4,4,4,4,4,  4,4,4,4,4,4,4,  4,
272                          4,4,4,4,4,4,4,   4,4,4,4,4,4,4,4,4,   4,  4,4,1,1,4,4,4,4,4,1,4,4,
273                          4,8,8,  16,4,0, 16,8, 8,8,0,  12,4,16,16,49,4,4,  4,8,10,2,4,8,
274                          4,8,10,2,4,8, 2,2,  28,28,  4,4,4,  4,4,4 };
275
276 extern int ia32features();
277 extern int amd_features();
278
279 extern int divarw;
280 extern float dfvars;
281 extern double dfvard;
282 extern long double dfvart; /* 10 byte hopefully, but it shouldn't matter... */
283 extern unsigned char dlarge[512];
284
285 #define CAP_MMX   (1<<23)
286 #define CAP_SSE   (1<<25)
287 #define CAP_SSE2  (1<<26)
288 #define CAP_3DNOW (1<<31)
289
290 void reduce(const struct reduction x)
291 {
292   unsigned int i;
293
294   loadExp  -= x.loadRed;
295   storeExp -= x.storeRed;
296   prefeExp -= x.prefeRed;
297
298   for(i=x.axsShift; i<accessExp; ++i)
299     eaExp[i] = eaExp[i+x.axsRed];
300
301   for(i=x.axsShift; i<accessExp; ++i)
302     bcExp[i] = bcExp[i+x.axsRed];
303
304   for(i=x.axsShift; i<accessExpCC; ++i)
305     eaExpCC[i] = eaExpCC[i+x.axsRed];
306
307   for(i=x.axsShift; i<accessExpCC; ++i)
308     bcExpCC[i] = bcExpCC[i+x.axsRed];
309
310   accessExp -= x.axsRed;
311   accessExpCC -= x.axsRed;
312 }
313
314 void reduceCC(const struct reduction x)
315 {
316   unsigned int i;
317
318   for(i=x.axsShift; i<accessExpCC; ++i)
319     eaExpCC[i] = eaExpCC[i+x.axsRed];
320
321   for(i=x.axsShift; i<accessExpCC; ++i)
322     bcExpCC[i] = bcExpCC[i+x.axsRed];
323
324   accessExpCC -= x.axsRed;
325 }
326
327
328 void init_test_data()
329 {
330   int caps;
331   unsigned int i;
332
333   dprintf("&divarw = %p\n", &divarw);
334   dprintf("&dfvars = %p\n", &dfvars);
335   dprintf("&dfvard = %p\n", &dfvard);
336   dprintf("&dfvart = %p\n", &dfvart);
337   dprintf("&dlarge = %p\n", &dlarge);
338
339   for(i=4; i<15; ++i)
340     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]); /* skip ebp for now */
341   for(i=16; i<18; ++i)
342     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
343   for(i=19; i<26; ++i)
344     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
345   i=26;
346   eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
347   for(i=28; i<35; ++i)
348     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
349   for(i=36; i<51; ++i)
350     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
351   for(i=51; i<53; ++i)
352     eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
353   i=53;
354   eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
355   for(i=54; i<56; ++i)
356     eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
357   for(i=56; i<58; ++i)
358     eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
359   i=58;
360   eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
361   for(i=59; i<62; ++i)
362     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
363   i=62; /* 2nd of mov */
364   eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
365   for(i=63; i<66; ++i) /* scas, cmps */
366     eaExp[i] = (void*)((unsigned long)&dlarge + eaExpOffset[i]);
367   i=66;
368   eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
369   i=67;
370   eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
371   i=68;
372   eaExp[i] = (void*)((unsigned long)&dfvart + eaExpOffset[i]);
373   for(i=69; i<72; ++i)
374     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
375   i=72;
376   eaExp[i] = (void*)((unsigned long)&dfvars + eaExpOffset[i]);
377   i=73;
378   eaExp[i] = (void*)((unsigned long)&dfvard + eaExpOffset[i]);
379   i=74;
380   eaExp[i] = (void*)((unsigned long)&dfvart + eaExpOffset[i]);
381   for(i=75; i<80; ++i)
382     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
383   for(i=80; i<82; ++i)
384     eaExp[i] = (void*)((unsigned long)&dlarge + eaExpOffset[i]);
385   for(i=82; i<85; ++i)
386     eaExp[i] = (void*)((unsigned long)&divarw + eaExpOffset[i]);
387
388   /* Duplicate & reduce the stream for cc */
389
390   for(i=0; i<accessExp; ++i) {
391     eaExpCC[i] = eaExp[i];
392     bcExpCC[i] = bcExp[i];
393   }
394
395   reduceCC(ccRed);
396
397   /* Order of reductions matters! It must be right to left. */
398
399   caps = amd_features();
400   if(!(caps & CAP_3DNOW))
401     reduce(amdRed);
402   caps = ia32features();
403   if(!(caps & CAP_SSE2))
404     reduce(sse2Red);
405   if(!(caps & CAP_SSE))
406     reduce(sseRed);
407   if(!(caps & CAP_MMX))
408     reduce(mmxRed);
409 }
410 #endif
411
412 #ifdef x86_64_unknown_linux2_4
413
414 unsigned int loadExp = 73;
415 unsigned int storeExp = 25;
416 unsigned int prefeExp = 2;
417 unsigned int accessExp = 98;
418 unsigned int accessExpCC = 97;
419
420 int eaExpOffset[] =    { 0,0,0,0,0,0,0,                             /* 7 initial stack pushes (EA not checked) */
421                          0,0,0,0,0,0,0,0,0,0,0,0,0,                 /* 13 mod=0 loads */
422                          4,8,-4,-8,4,8,-4,-8,4,8,-4,-8,127,-128,    /* 14 mod=1 loads */
423                          12,0,8,8,8,0,4,8,4,                        /* 9 SIB tests (same as x86) */
424                          4,4,4,0,4,0,4,8,0,4,0,0,                   /* 11 semantic tests (one has two accesses) */
425                          0,8,0,                                     /* 3 MMX tests */
426                          0,0,0,                                     /* 3 SSE tests */
427                          0,0,                                       /* 2 SSE2 tests */
428                          0,8,0,                                     /* 3 3DNow! tests */
429                          0,12,0,0,0,44,25,                          /* 5 REP tests (two have two accesses each) */
430                          0,0,0,0,4,8,                               /* x87 */
431                          0,0,0,2,4,8,
432                          0,0,
433                          0,0,
434                          0,4,8,                                     /* conditional moves */
435                          0,0,0,0,0,0                                /* 6 final stack pops */                     
436 };
437
438 unsigned int bcExp[] = { 8,8,8,8,8,8,8,                  /* 7 initial stack pushes */
439                          4,8,4,8,4,8,4,8,4,8,4,8,4,      /* 13 mod=0 loads */
440                          4,8,4,8,4,8,4,8,4,8,4,8,4,8,    /* 14 mod=1 loads */
441                          4,8,4,8,4,8,4,8,4,              /* 9 SIB tests */
442                          4,4,1,1,4,4,4,4,4,4,4,4,        /* 11 semantic tests (one has two accesses) */
443                          8,8,8,                          /* 3 MMX tests */                      
444                          16,4,0,                         /* 3 SSE tests */
445                          16,8,                           /* 2 SSE2 tests */
446                          8,8,0,                          /* 3 3DNow! tests */
447                          12,16,16,16,49,4,4,             /* 5 REP tests (two have two accesses each) */
448                          4,8,10,2,4,8,                   /* x87 */
449                          4,8,10,2,4,8,
450                          2,2,
451                          28,28,
452                          4,4,4,                          /* conditional moves */
453                          8,8,8,8,8,8                     /* 6 final stack pops */
454 };
455
456 int divarw;
457 float dfvars;
458 double dfvard;
459 long double dfvart;
460 char dlarge[512] = "keep the interface small and easy to understand.";
461
462 extern void* rip_relative_load_address;
463
464 void init_test_data()
465 {
466   int i;
467
468   dprintf("&divarw = %p\n", &divarw);
469   dprintf("&dfvars = %p\n", &dfvars);
470   dprintf("&dfvard = %p\n", &dfvard);
471   dprintf("&dfvart = %p\n", &dfvart);
472   dprintf("&dlarge = %p\n", &dlarge);
473
474   // we do not check the effective address for stack accesses,
475   // since it depends on the stack pointer,
476   // so we skip the initial 6 pushes
477   i = 7;
478
479   // ModRM and SIB loads and semantic tests (there are 54, but one has two accesses)
480   for (; i < 55; i++)
481       eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]);
482   
483   // the 12th is a load from [RIP + 1]
484   eaExp[11] = rip_relative_load_address;
485
486   // the 36th access uses RSP
487   eaExp[35] = 0;
488
489   // MMX
490   assert(i == 55);
491   for (; i < 58; i++)
492       eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]);
493
494   // SSE
495   assert(i == 58);
496   for (; i < 60; i++)
497       eaExp[i] = (void *)((unsigned long)&dfvart + eaExpOffset[i]);
498   assert(i == 60);
499   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++; // the prefetch
500
501   // SSE2
502   assert(i == 61);
503   for (; i < 63; i++)
504       eaExp[i] = (void *)((unsigned long)&dfvart + eaExpOffset[i]);
505
506   // 3DNow!
507   assert(i == 63);
508   for (; i < 65; i++)
509       eaExp[i] = (void *)((unsigned long)&dfvard + eaExpOffset[i]);
510   assert(i == 65);
511   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
512
513   // REP prefixes
514   assert(i == 66);
515   for (; i < 69; i++)
516       eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]);
517   assert(i == 69);
518   eaExp[i] = (void *)((unsigned long)&dfvars + eaExpOffset[i]); i++;
519   for (; i < 73; i++)
520       eaExp[i] = (void *)((unsigned long)&dlarge + eaExpOffset[i]);
521
522   // x87
523   assert(i == 73);
524   eaExp[i] = (void *)((unsigned long)&dfvars + eaExpOffset[i]); i++;
525   eaExp[i] = (void *)((unsigned long)&dfvard + eaExpOffset[i]); i++;
526   eaExp[i] = (void *)((unsigned long)&dfvart + eaExpOffset[i]); i++;
527   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
528   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
529   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
530
531   eaExp[i] = (void *)((unsigned long)&dfvars + eaExpOffset[i]); i++;
532   eaExp[i] = (void *)((unsigned long)&dfvard + eaExpOffset[i]); i++;
533   eaExp[i] = (void *)((unsigned long)&dfvart + eaExpOffset[i]); i++;
534   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
535   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
536   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
537
538   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
539   eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]); i++;
540
541   eaExp[i] = (void *)((unsigned long)&dlarge + eaExpOffset[i]); i++;
542    eaExp[i] = (void *)((unsigned long)&dlarge + eaExpOffset[i]); i++;
543
544   // conditional moves
545   assert(i == 89);
546   for (; i < 92; i++)
547       eaExp[i] = (void *)((unsigned long)&divarw + eaExpOffset[i]);
548
549   // duplicate stream for CC (except the second-to-last item)
550   for(i = 0; i < 90 ; i++) {
551     eaExpCC[i] = eaExp[i];
552     bcExpCC[i] = bcExp[i];
553   }
554   assert(i == 90);
555   eaExpCC[i] = eaExp[i+1];
556   bcExpCC[i] = bcExp[i+1];
557   for(i = 91; i < 97; i++)
558       bcExpCC[i] = bcExp[i+1];
559   
560
561   
562   
563 }
564 #endif
565
566 #ifdef ia64_unknown_linux2_4
567
568 #define loadExp 6
569 #define storeExp 3
570 #define prefeExp 3
571
572 /* Other platforms don't seem to count prefetches as accesses.  I'm not sure why. */
573 #define accessExp 12
574 #define accessExpCC 12
575
576 unsigned int bcExp[] = { 8, 8, 8,  8, 8, 8,  8, 16, 16, 0, 0, 0 };
577 unsigned int bcExpCC[] = { 8, 8, 8,  8, 8, 8,  8, 16, 16, 0, 0, 0 };
578
579 /* FIXME: this should be made more complicated and/or assembly
580    to actually test all the loads and stores that I know about
581    and claim that Dyninst will recognize and handle.  This
582    means redefining the stuff above to match up to the new
583    code.
584    
585    FIXME: I don't understand what the "CC" stuff is or does. 
586    
587    FIXME: I don't understand what the "EA" stuff is or does. 
588 */
589 extern long loadsnstores( long x, long y, long z );
590
591 void init_test_data()
592 {
593 }
594 #endif
595
596 #ifdef mips_sgi_irix6_4
597 #define loadExp 0
598 #define storeExp 0
599 #define prefeExp 0
600 #define accessExp 1
601 #define accessExpCC 1
602
603 long loadsnstores(long x, long y, long z)
604 {
605   return x + y + z;
606 }
607
608 unsigned int bcExp[] = { 0 };
609
610 void init_test_data()
611 {
612 }
613 #endif
614
615 #ifdef alpha_dec_osf4_0
616 #define loadExp 0
617 #define storeExp 0
618 #define prefeExp 0
619 #define accessExp 1
620 #define accessExpCC 1
621
622 long loadsnstores(long x, long y, long z)
623 {
624   return x + y + z;
625 }
626
627 unsigned int bcExp[] = { 0 };
628
629 void init_test_data()
630 {
631 }
632 #endif
633
634
635 #if defined(os_linux) && defined(arch_power)
636 #define loadExp 0
637 #define storeExp 0
638 #define prefeExp 0
639 #define accessExp 1
640 #define accessExpCC 1
641
642 long loadsnstores(long x, long y, long z)
643 {
644   return x + y + z;
645 }
646
647 unsigned int bcExp[] = { 0 };
648
649 void init_test_data()
650 {
651 }
652 #endif
653
654
655
656 /* Sun Forte/WorkShop cc releases older than 6.2 do not like these defines: */
657 #if !defined(__SUNPRO_C) || (__SUNPRO_C >= 0x530)
658 #define passorfail(i,p,d,r) if((p)) { \
659                               printf("Passed test #%d (%s)\n", (i), (d)); \
660                               passedTest[(i)] = TRUE; \
661                             } else { \
662                               printf("\n**Failed** test #%d (%s): %s\n", (i), (d), (r)); \
663                             }
664
665 #define skiptest(i,d) { printf("Skipping test #%d (%s)\n", (i), (d)); \
666                         printf("    not implemented on this platform\n"); \
667                         passedTest[(i)] = TRUE; }
668 #else
669 void passorfail(int i, int p, char* d, char* r)
670 {
671   if(p) {
672     printf("Passed test #%d (%s)\n", (i), (d));
673     passedTest[(i)] = TRUE;
674   } else {
675     printf("\n**Failed** test #%d (%s): %s\n", (i), (d), (r));
676   }
677 }
678
679 void skiptest(int i, char* d)
680 {
681   printf("Skipping test #%d (%s)\n", (i), (d));
682   printf("    not implemented on this platform\n");
683   passedTest[(i)] = TRUE;
684 }
685 #endif
686
687 int validateEA(void* ea1[], void* ea2[], unsigned int n)
688 {
689   int ok = 1;
690   unsigned int i=0;
691
692   for(; i<n; ++i) {
693     ok = (ok && ((ea1[i] == ea2[i]) || ea1[i] == NULL));
694     if(!ok) {
695       printf("EA Validation failed at access #%d. Expecting: %p. Got: %p.\n", i+1, ea1[i], ea2[i]);
696       return 0;
697     }
698   }
699   return 1;
700 }
701
702 int validateBC(unsigned int bc1[], unsigned int bc2[], unsigned int n)
703 {
704   int ok = 1;
705   unsigned int i=0;
706
707   for(; i<n; ++i) {
708     ok = (ok && (bc1[i] == bc2[i]));
709     if(!ok) {
710 printf("BC Validation failed at access #%d. Expecting: %d. Got: %d.\n", i+1, bc1[i], bc2[i]);
711       return 0;
712     }
713   }
714   return 1;
715 }
716
717 void check0()
718 {
719   passorfail(0, result_of_loadsnstores == 9, "function integrity", "function corrupted!");
720 }
721
722 void check1()
723 {
724   passorfail(1, loadCnt == loadExp, "load instrumentation", "load counter seems wrong.");
725 }
726
727 void check2()
728 {
729   passorfail(2, storeCnt == storeExp, "store instrumentation", "store counter seems wrong.");
730 }
731
732 void check3()
733 {
734   passorfail(3, prefeCnt == prefeExp, "prefetch instrumentation", "prefetch counter seems wrong.");
735 }
736
737 void check4()
738 {
739 #if !defined(sparc_sun_solaris2_4) \
740  &&(!defined(rs6000_ibm_aix4_1) || defined(AIX5)) \
741  && !defined(i386_unknown_linux2_0) \
742  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
743  && !defined(i386_unknown_nt4_0) \
744  && !defined(ia64_unknown_linux2_4)
745   skiptest(4, "access instrumentation");
746 #else
747   passorfail(4, accessCnt == accessExp, "access instrumentation", "access counter seems wrong.");
748   dprintf("accessCnt = %d    accessExp = %d\n", accessCnt, accessExp);
749 #endif
750 }
751
752 void check5()
753 {
754 #if !defined(sparc_sun_solaris2_4) \
755  &&(!defined(rs6000_ibm_aix4_1) || defined(AIX5)) \
756  && !defined(i386_unknown_linux2_0) \
757  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
758  && !defined(i386_unknown_nt4_0) \
759  && !defined(ia64_unknown_linux2_4)
760   skiptest(5, "instrumentation w/ [unconditional] effective address snippet");
761 #else
762   passorfail(5, !doomEA && validateEA(eaExp, eaList, accessExp),
763              "[unconditional] effective address snippet", "address sequences are different");
764 #endif
765 }
766
767 void check6()
768 {
769 #if !defined(sparc_sun_solaris2_4) \
770  && !defined(rs6000_ibm_aix4_1) \
771  && !defined(i386_unknown_linux2_0) \
772  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
773  && !defined(i386_unknown_nt4_0) \
774  && !defined(ia64_unknown_linux2_4)
775   skiptest(6, "instrumentation w/ [unconditional] byte count snippet");
776 #else
777   passorfail(6, !doomBC && validateBC(bcExp, bcList, accessExp),
778              "[unconditional] byte count snippet", "count sequences are different");
779 #endif
780 }
781
782 void check7()
783 {
784 #if !defined(sparc_sun_solaris2_4) \
785  &&(!defined(rs6000_ibm_aix4_1) || defined(AIX5)) \
786  && !defined(i386_unknown_linux2_0) \
787  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
788  && !defined(i386_unknown_nt4_0) \
789  && !defined(ia64_unknown_linux2_4)
790   skiptest(7, "instrumentation w/ conditional effective address snippet");
791 #else
792   passorfail(7, !doomEAcc && validateEA(eaExpCC, eaListCC, accessExpCC),
793              "conditional effective address snippet", "address sequences are different");
794 #endif
795 }
796
797 void check8()
798 {
799 #if !defined(sparc_sun_solaris2_4) \
800  && !defined(rs6000_ibm_aix4_1) \
801  && !defined(i386_unknown_linux2_0) \
802  && !defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
803  && !defined(i386_unknown_nt4_0) \
804  && !defined(ia64_unknown_linux2_4)
805   skiptest(8, "instrumentation w/ conditional byte count snippet");
806 #else
807   passorfail(8, !doomBCcc && validateBC(bcExpCC, bcListCC, accessExpCC),
808              "conditional byte count snippet", "count sequences are different");
809 #endif
810 }
811
812 /* functions called by the simple instrumentation points */
813 void countLoad()
814 {
815   ++loadCnt;
816 }
817
818 void countStore()
819 {
820   ++storeCnt;
821 }
822
823 void countPrefetch()
824 {
825   ++prefeCnt;
826 }
827
828 void countAccess()
829 {
830   ++accessCnt;
831 }
832
833
834 /* functions called by the effective address/byte count instrumentation points */
835 void listEffAddr(void* addr)
836 {
837   if(accessCntEA < accessExp)
838     eaList[accessCntEA] = addr;
839   else
840     doomEA = 1;
841   accessCntEA++;
842   dprintf("EA[%d]:%p ", accessCntEA, addr);
843 }
844
845 void listByteCnt(unsigned int count)
846 {
847   if(accessCntBC < accessExp)
848     bcList[accessCntBC] = count;
849   else
850     doomBC = 1;
851   accessCntBC++;
852   dprintf("BC[%d]:%d ", accessCntBC, count);
853 }
854
855
856 void listEffAddrCC(void* addr)
857 {
858   if(accessCntEAcc < accessExpCC)
859     eaListCC[accessCntEAcc] = addr;
860   else
861     doomEAcc = 1;
862   accessCntEAcc++;
863   dprintf("?A[%d]:%p ", accessCntEAcc, addr);
864 }
865
866 void listByteCntCC(unsigned int count)
867 {
868   if(accessCntBCcc < accessExpCC)
869     bcListCC[accessCntBCcc] = count;
870   else
871     doomBCcc = 1;
872   accessCntBCcc++;
873   dprintf("?C[%d]:%d ", accessCntBCcc, count);
874 }
875
876
877
878 int main(int iargc, char *argv[])
879 {                                       /* despite different conventions */
880   unsigned argc=(unsigned)iargc;      /* make argc consistently unsigned */
881   unsigned int i, j;
882   unsigned int testsFailed = 0;
883   
884   for (j=0; j <= MAX_TEST; j++) {
885     passedTest [j] = FALSE;
886     runTest [j] = FALSE;
887   }
888  
889   for (i=1; i < argc; i++) {
890     if (!strcmp(argv[i], "-verbose")) {
891       debugPrint = TRUE;
892     } else if (!strcmp(argv[i], "-runall")) {
893       dprintf("selecting all tests\n");
894       for (j=1; j <= MAX_TEST; j++) runTest[j] = TRUE;
895     } else if (!strcmp(argv[i], "-run")) {
896       for (j=i+1; j < argc; j++) {
897         unsigned int testId;
898         if ((testId = atoi(argv[j]))) {
899           if ((testId > 0) && (testId <= MAX_TEST)) {
900             dprintf("selecting test %d\n", testId);
901             runTest[testId] = TRUE;
902           } else {
903             printf("invalid test %d requested\n", testId);
904             exit(-1);
905           }
906         } else {
907           /* end of test list */
908           break;
909         }
910       }
911       i=j-1;
912     } else {
913       fprintf(stderr, "%s\n", USAGE);
914       exit(-1);
915     }
916   }
917
918   if (argc==1) exit(0);
919
920   loadCnt = 0;
921   storeCnt = 0;
922   prefeCnt = 0;
923   accessCnt = 0;
924
925   result_of_loadsnstores = loadsnstores(2,3,4);
926   dprintf("\nresult=0x%x loads=%d stores=%d prefetches=%d accesses=%d\n",
927           result_of_loadsnstores, loadCnt, storeCnt, prefeCnt, accessCnt);
928
929   init_test_data();
930
931   /* check0(); integrity check skipped needs more work to be really usefull */
932   if (runTest[1]) check1();
933   if (runTest[2]) check2();
934   if (runTest[3]) check3();
935   if (runTest[4]) check4();
936   if (runTest[5]) check5();
937   if (runTest[6]) check6();
938   if (runTest[7]) check7();
939   if (runTest[8]) check8();
940
941   /* See how we did running the tests. */
942   for (i=1; i <= MAX_TEST; i++) {
943     if (runTest[i] && !passedTest[i]) testsFailed++;
944   }
945
946   if (!testsFailed) {
947     printf("All tests passed\n");
948   } else {
949     printf("**Failed** %d test%c\n",testsFailed,(testsFailed>1)?'s':' ');
950   }
951
952   fflush(stdout);
953   dprintf("Mutatee %s terminating.\n", argv[0]);
954   return (testsFailed ? 127 : 0);
955 }