Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / dyninst / test1_17.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: test1_17.C,v 1.1 2008/10/30 19:17:58 legendre Exp $
33 /*
34  * #Name: test1_17
35  * #Desc: Mutator Side - Return Values from func calls
36  * #Dep: 
37  * #Notes: Verifies that instrumentation inserted at exit point doesn't clobber return value
38  */
39
40 #include "BPatch.h"
41 #include "BPatch_Vector.h"
42 #include "BPatch_thread.h"
43 #include "BPatch_snippet.h"
44
45 #include "test_lib.h"
46 #include "dyninst_comp.h"
47
48 class test1_17_Mutator : public DyninstMutator {
49         virtual test_results_t executeTest();
50 };
51
52 extern "C" DLLEXPORT  TestMutator *test1_17_factory() 
53 {
54         return new test1_17_Mutator();
55 }
56
57 // Start Test Case #17 - mutator side (return values from func calls)
58 // Verify that instrumentation inserted at a subroutine's exit point
59 // doesn't clobber its return value.
60 // Method: the mutatee's func17_1 (first and only) exit is instrumented to
61 // call call17_1 with parameter (constant) "1"; func17_2's (first and only)
62 // exit is similarly instrumented to call call17_2(1); a subsequent test in
63 // the mutatee compares the return values of func17_1 and func17_2.
64 // (No examination is made of the return values of call17_1 or call17_2.)
65 //
66
67 test_results_t test1_17_Mutator::executeTest() 
68 {
69         // Find the entry point to the procedure "func17_1"
70
71         const char *funcName = "test1_17_func1";
72         BPatch_Vector<BPatch_function *> found_funcs;
73
74         if ((NULL == appImage->findFunction(funcName, found_funcs))
75                         || !found_funcs.size()) 
76         {
77                 logerror("    Unable to find function %s\n", funcName);
78                 return FAILED;
79         }
80
81         if (1 < found_funcs.size()) 
82         {
83                 logerror("%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
84                                 __FILE__, __LINE__, found_funcs.size(), funcName);
85         }
86
87         BPatch_Vector<BPatch_point *> *point17_1 = found_funcs[0]->findPoint(BPatch_exit);
88
89         if (!point17_1 || (point17_1->size() < 1)) 
90         {
91                 logerror("Unable to find point %s - exit.\n", funcName);
92                 return FAILED;
93         }
94
95         BPatch_Vector<BPatch_function *> bpfv;
96         char *fn = "test1_17_call1";
97
98         if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
99                         || NULL == bpfv[0])
100         {
101                 logerror("    Unable to find function %s\n", fn);
102                 return FAILED;
103         }
104
105         BPatch_function *call17_1_func = bpfv[0];
106
107         BPatch_Vector<BPatch_snippet *> funcArgs;
108
109         BPatch_variableExpr *var17_1 = appAddrSpace->malloc (*appImage->findType ("int"));
110         BPatch_constExpr constExpr17_1 (0);
111         BPatch_arithExpr arithExpr17_1 (BPatch_assign, *var17_1, BPatch_constExpr (1));
112         appAddrSpace->insertSnippet (arithExpr17_1, *point17_1);
113
114         int mutateeFortran = isMutateeFortran(appImage);
115
116         if (mutateeFortran) 
117         {
118                 constExpr17_1 = var17_1->getBaseAddr ();
119         } 
120         else 
121         {
122                 constExpr17_1 = 1;
123         }
124
125         funcArgs.push_back (&constExpr17_1);
126
127         BPatch_funcCallExpr call17_1Expr(*call17_1_func, funcArgs);
128         checkCost(call17_1Expr);
129         appAddrSpace->insertSnippet(call17_1Expr, *point17_1, BPatch_callAfter, BPatch_lastSnippet);
130
131         // Find the exit point to the procedure "func17_2"
132         const char *funcName2 = "test1_17_func2";
133         BPatch_Vector<BPatch_function *> found_funcs2;
134
135         if ((NULL == appImage->findFunction(funcName2, found_funcs2))
136                         || !found_funcs2.size()) 
137         {
138                 logerror("    Unable to find function %s\n", funcName2);
139                 return FAILED;
140         }
141
142         if (1 < found_funcs2.size()) 
143         {
144                 logerror("%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
145                                 __FILE__, __LINE__, found_funcs2.size(), funcName2);
146         }
147
148         BPatch_Vector<BPatch_point *> *point17_2 = found_funcs2[0]->findPoint(BPatch_exit);
149
150         if (!point17_2 || (point17_2->size() < 1)) 
151         {
152                 logerror("Unable to find point %s - exit.\n", funcName2);
153                 return FAILED;
154         }
155
156         bpfv.clear();
157         char *fn2 = "test1_17_call2";
158
159         if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
160                         || NULL == bpfv[0])
161         {
162                 logerror("    Unable to find function %s\n", fn2);
163                 return FAILED;
164         }
165
166         BPatch_function *call17_2_func = bpfv[0];
167
168         BPatch_Vector<BPatch_snippet *> funcArgs2;
169
170         BPatch_variableExpr *var17_2 = appAddrSpace->malloc (*appImage->findType ("int"));
171         BPatch_constExpr constExpr17_2 (0);
172         BPatch_arithExpr arith17_2 (BPatch_assign, *var17_2, BPatch_constExpr (1));
173         appAddrSpace->insertSnippet (arith17_2, *point17_2);
174
175         if (mutateeFortran) 
176         {
177                 constExpr17_2 = var17_2->getBaseAddr ();
178         } 
179         else 
180         {
181                 constExpr17_2 = 1;
182         }
183
184         funcArgs2.push_back (&constExpr17_2);
185
186         BPatch_funcCallExpr call17_2Expr(*call17_2_func, funcArgs2);
187         checkCost(call17_2Expr);
188
189         // test interface to call into insertSnippet with only one parameter
190         BPatch_point &aPoint = *(*point17_2)[0];
191         appAddrSpace->insertSnippet(call17_2Expr, aPoint, BPatch_callAfter, BPatch_lastSnippet);
192
193         return PASSED;
194 }