Edge/loop instrumentation (new BPatch_edge class)
[dyninst.git] / dyninstAPI / src / BPatch_edge.C
1 /*
2  * Copyright (c) 1996-2004 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #define BPATCH_FILE
43
44 #include "util.h"
45 #include "symtab.h"
46
47 #include "BPatch_edge.h"
48 #include "BPatch_flowGraph.h"
49 #include "BPatch_basicBlock.h"
50
51 // ELI
52 // for setting instPoint->addrInFuc
53 #include "instPoint.h" 
54
55 pdstring 
56 edge_type_string(BPatch_edgeType t)
57
58     pdstring ts = "Invalid Edge Type";
59     switch (t) {
60     case CondJumpTaken: { ts = "CondJumpTaken"; break; }
61     case CondJumpNottaken: { ts = "CondJumpNottaken"; break; }
62     case UncondJump: { ts = "UncondJump"; break; } 
63     case NonJump: { ts = "NonJump"; break; }
64     }
65     return ts;
66 }
67
68
69 #if defined(arch_x86)
70 BPatch_edgeType 
71 BPatch_edge::getType()
72 {
73     unsigned itype;
74
75     get_instruction(relocationPointer, itype);
76
77     // XXX indirect jumps not handled  (itype & INDIR)
78
79     if ((itype & IS_JUMP) || (itype & IS_JCC)) 
80         if (itype & IS_JCC) 
81             if (source->getRelEnd() == target->getRelStart()) 
82                 return CondJumpNottaken;
83             else 
84                 return CondJumpTaken;
85         else 
86             return UncondJump;
87     else 
88         return NonJump;
89 }
90 #else
91 //XXX loop port
92 BPatch_edgeType
93 BPatch_edge::getType()
94 {
95     return NonJump;
96 }
97 #endif
98
99
100 BPatch_edge::BPatch_edge(BPatch_basicBlock *s, 
101                          BPatch_basicBlock *t, 
102                          BPatch_flowGraph *fg,
103                          const unsigned char *rp)
104
105 {
106     assert(s != NULL);
107     assert(t != NULL);
108     
109     source = s;
110     target = t;
111     flowGraph = fg;
112     relocationPointer = rp;
113     // point is set when this edge is instrumented. instAddr is set
114     // when either this edge or its conditional buddy is instrumented
115     point = NULL;    
116     instAddr = NULL; 
117     conditionalBuddy = NULL;
118
119     type = getType();
120
121     Address addrInFunc = 0;
122 }
123
124  
125 BPatch_edge::~BPatch_edge()
126 {
127     fprintf(stderr,"~BPatch_edge\n");
128 }
129
130
131 void BPatch_edge::dump()
132 {
133     pdstring ts = edge_type_string(type);
134
135 //     fprintf(stderr," %3u --> %3u\n",
136 //             source->blockNo(),
137 //             target->blockNo());
138
139 //     fprintf(stderr,"  (b%u 0x%x 0x%x) --> (b%u 0x%x 0x%x)\n",
140 //             source->blockNo(),
141 //             source->getRelStart(),
142 //             source->getRelLast(),
143 //             target->blockNo(),
144 //             target->getRelStart(),
145 //             target->getRelLast());
146
147     fprintf(stderr," 0x%x, 0x%x --> 0x%x, 0x%x %s\n",
148             source->getRelStart(),
149             source->getRelLast(),
150             target->getRelStart(),
151             target->getRelLast(),
152             edge_type_string(type).c_str());
153
154 }
155
156
157 // Only edges created by conditional jumps need edge trampolines
158 bool BPatch_edge::needsEdgeTramp()
159 {
160     return type == CondJumpNottaken || type == CondJumpTaken;
161 }
162
163
164 BPatch_point *
165 BPatch_edge::instPoint()
166 {
167     if (!point)
168         point = flowGraph->createInstPointAtEdge(this);
169     // the above may fail
170     if (point)
171         // set instPoint's addrInFunc field for catchup to use
172         (point->getPoint())->addrInFunc = addrInFunc;
173     return point;
174 }
175