Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / dyninst / test1_22_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 #if defined(sparc_sun_solaris2_4_test) \
32  || defined(alpha_dec_osf4_0_test) \
33  || defined(i386_unknown_linux2_0_test) \
34  || defined(x86_64_unknown_linux2_4_test) /* Blind duplication - Ray */ \
35  || defined(i386_unknown_solaris2_5_test) \
36  || defined(ia64_unknown_linux2_4_test) \
37  || defined(os_aix_test) \
38  || defined(os_linux_test) /* better off using os #defines than whole platforms */
39 #include <dlfcn.h> /* For replaceFunction test */
40 #endif
41
42 #include "mutatee_util.h"
43
44 /* Externally accessed function prototypes.  These must have globally unique
45  * names.  I suggest following the pattern <testname>_<function>
46  */
47
48 int test1_22_call1(int x);
49 int test1_22_call2(int x);
50 int test1_22_call3(int x);
51 int test1_22_call7(int x);
52
53 /* Global variables accessed by the mutator.  These must have globally unique
54  * names.
55  */
56
57 /* Internally used function prototypes.  These should be declared with the
58  * keyword static so they don't interfere with other mutatees in the group.
59  */
60
61 /* Global variables used internally by the mutatee.  These should be declared
62  * with the keyword static so they don't interfere with other mutatees in the
63  * group.
64  */
65
66 static volatile int unused; /* move decl here to dump compiler warning - jkh */
67
68 /* These are copied in libtestA.c and libtestB.c */
69 #define MAGIC22_1   2200100
70 #define MAGIC22_2   2200200
71 #define MAGIC22_3   2200300
72 #define MAGIC22_4   2200400
73 #define MAGIC22_5A  2200510
74 #define MAGIC22_5B  2200520
75 #define MAGIC22_6   2200600
76 #define MAGIC22_7   2200700
77
78 #if defined(x86_64_unknown_linux2_4_test) && (__WORDSIZE == 32)
79 static const char *libNameA = "libtestA_m32.so";
80 #elif defined(os_windows_test)
81 static const char *libNameA = "libtestA.dll";
82 #else
83 static const char *libNameA = "libtestA.so";
84 #endif
85
86 /* Function definitions follow */
87
88 /*
89  * Test #22 - replace function
90  *
91  * These are defined in libtestA.so
92  */
93 extern void call22_5A(int);
94 extern void call22_6(int);
95
96 typedef int (*call_type)(int);
97
98 /* A couple of dlopen-related functions. Moved here from mutatee_util
99    so as not to introduce the libdl dependency on all mutatees */
100 #if defined(os_windows_test)
101 void printSysError(unsigned errNo) {
102     char buf[1000];
103     int result = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errNo, 
104                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
105                   buf, 1000, NULL);
106     if (!result) {
107         output->log(STDERR, "Couldn't print error message\n");
108     }
109     output->log(STDERR, "%s\n", buf);
110 }
111
112 void *loadDynamicLibrary(char *name) {
113   void *result = (void *) LoadLibrary(name);
114   if (!result) {
115       output->log(STDERR, "[%s:%u] - The mutatee could not load %s\n", __FILE__, __LINE__);
116       printSysError(GetLastError());
117   }
118   return result;
119 }
120
121 void *getFuncFromDLL(void *libhandle, char *func_name) {
122     void *result;
123     if (!libhandle || !func_name) {
124         output->log(STDERR, "[%s:%u] - Test error - getFuncFromDLL passed NULL "
125                 "parameter\n", __FILE__, __LINE__);
126         return NULL;            
127     }
128     result = GetProcAddress((HMODULE) libhandle, func_name);
129     if (!result) {
130         output->log(STDERR, "[%s:%u] - Couldn't load symbol %s\n", __FILE__, __LINE__, func_name);
131         printSysError(GetLastError());
132     }
133     return result;
134 }
135 #else
136 void *loadDynamicLibrary(char *name) {
137     void *result;
138 #if defined(os_solaris_test)
139     int dlopenMode = RTLD_NOW | RTLD_GLOBAL;
140 #else
141     int dlopenMode = RTLD_NOW;
142 #endif
143     result = dlopen(name, dlopenMode);
144     if (!result) {
145         perror("The mutatee couldn't load a dynamic library");
146     }
147     return result;
148 }
149
150 void *getFuncFromDLL(void *libhandle, char *func_name) {
151     void *result = dlsym(libhandle, func_name);
152     if (!result) {
153         perror("The mutatee couldn't find a function");
154     }
155     return result;
156 }
157 #endif
158
159 int test1_22_mutatee()
160 {
161     int retval = 0;
162 #if defined(os_solaris_test) \
163  || defined(alpha_dec_osf4_0_test) \
164  || defined(os_linux_test) \
165  || defined(os_windows_test)
166     /* libtestA.so should already be loaded (by the mutator), but we
167        need to use the dl interface to get pointers to the functions
168        it defines. */
169 /*     int (*call22_5)(int); */
170 /*     int (*call22_6)(int); */
171     call_type call22_5;
172     call_type call22_6; /* Why shadowing the top-level declaration? */
173
174     void *handleA;
175     char dlopenName[128];
176     int result;
177     unused = sprintf(dlopenName, "%s", libNameA);
178
179     handleA = loadDynamicLibrary(dlopenName);
180     if (! handleA) {
181          logerror("**Failed test #22 (replaceFunction)\n");
182          logerror("  Mutatee couldn't get handle for %s\n", libNameA);
183          retval = -1; /* Test failed */
184     }
185     /* call22_5 = (int(*)(int)) getFuncFromDLL(handleA, "call22_5"); */
186     call22_5 = (call_type) getFuncFromDLL(handleA, "call22_5a");
187     if (! call22_5) {
188          logerror("**Failed test #22 (replaceFunction)\n");
189          logerror("  Mutatee couldn't get handle for call22_5 in %s\n", libNameA);
190          retval = -1; /* Test failed */
191     }
192     /* call22_6 = (int(*)(int)) getFuncFromDLL(handleA, "call22_6"); */
193     call22_6 = (call_type) getFuncFromDLL(handleA, "call22_6");
194     if (! call22_6) {
195          logerror("**Failed test #22 (replaceFunction)\n");
196          logerror("  Mutatee couldn't get handle for call22_6 in %s\n", libNameA);
197          retval = -1; /* Test failed */
198     }
199
200     /* Call functions that have been replaced by the mutator.  The
201        side effects of these calls (replaced, not replaced, or
202        otherwise) are independent of each other. */
203     result = test1_22_call1(10);  /* replaced by test1_22_call2 */
204     if (result != 10 + MAGIC22_2) {
205          logerror("**Failed test #22 (replace function) (a.out -> a.out)\n");
206          retval = -1; /* Test failed */
207     }
208     result = test1_22_call3(20);  /* replaced by call22_4 */
209     if (result != 20 + MAGIC22_4) {
210          logerror("**Failed test #22 (replace function) (a.out -> shlib)\n");
211          retval = -1; /* Test failed */
212     }
213     if (call22_5 != NULL) {
214       result = call22_5(30);  /* replaced by call22_5 (in libtestB) */
215       if (result != 30 + MAGIC22_5B) {
216         logerror("**Failed test #22 (replace function) (shlib -> shlib)\n");
217         retval = -1; /* Test failed */
218       }
219     }
220     if (call22_6 != NULL) {
221       result = call22_6(40);  /* replaced by test1_22_call7 */
222       if (result != 40 + MAGIC22_7) {
223         logerror("**Failed test #22 (replace function) (shlib -> a.out)\n");
224         retval = -1; /* Test failed */
225       }
226     }
227     if (0 == retval) {
228       logerror("Passed test #22 (replace function)\n");
229       test_passes(testname);
230     }
231 #else
232     logerror("Skipped test #22 (replace function)\n");
233     logerror("\t- not implemented on this platform\n");
234     test_passes(testname);
235 #endif
236     return retval;
237 }
238
239 int test1_22_call1(int x) {
240     return x + MAGIC22_1;
241 }
242
243 int test1_22_call2(int x) {
244     return x + MAGIC22_2;
245 }
246
247 int test1_22_call3(int x) {
248     return x + MAGIC22_3;
249 }
250
251 int test1_22_call7(int x) {
252     return x + MAGIC22_7;
253 }