Loop instrumentation fixes, other minor fixes - - - - - - - - - - - - -
[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 #include "instPoint.h"
51 #include "process.h"
52 #include "InstrucIter.h"
53
54 pdstring 
55 edge_type_string(BPatch_edgeType t)
56
57     pdstring ts = "Invalid Edge Type";
58     switch (t) {
59     case CondJumpTaken: { ts = "CondJumpTaken"; break; }
60     case CondJumpNottaken: { ts = "CondJumpNottaken"; break; }
61     case UncondJump: { ts = "UncondJump"; break; } 
62     case NonJump: { ts = "NonJump"; break; }
63     }
64     return ts;
65 }
66
67 BPatch_edgeType 
68 BPatch_edge::getType()
69 {
70     InstrucIter sourceIter(source);
71     sourceIter.setCurrentAddress(source->getLastInsnAddress());
72     
73     if (sourceIter.isACondBranchInstruction()) {
74         if (source->getEndAddress() == target->getStartAddress()) 
75             return CondJumpNottaken;
76         else 
77             return CondJumpTaken;
78     }
79     else if (sourceIter.isAJumpInstruction())
80         return UncondJump;
81     else 
82         return NonJump;
83 }
84
85
86 void BPatch_edge::BPatch_edgeInt(BPatch_basicBlock *s, 
87                                  BPatch_basicBlock *t, 
88                                  BPatch_flowGraph *fg)
89     
90 {
91     assert(s != NULL);
92     assert(t != NULL);
93     
94     source = s;
95     target = t;
96     flowGraph = fg;
97     // point is set when this edge is instrumented. instAddr is set
98     // when either this edge or its conditional buddy is instrumented
99     point = NULL;    
100
101     type = getType();
102 }
103
104  
105 void BPatch_edge::BPatch_edge_dtor()
106 {
107     fprintf(stderr,"~BPatch_edge\n");
108 }
109
110
111 void BPatch_edge::dumpInt()
112 {
113     pdstring ts = edge_type_string(type);
114
115 //     fprintf(stderr," %3u --> %3u\n",
116 //             source->blockNo(),
117 //             target->blockNo());
118
119 //     fprintf(stderr,"  (b%u 0x%x 0x%x) --> (b%u 0x%x 0x%x)\n",
120 //             source->blockNo(),
121 //             source->getRelStart(),
122 //             source->getRelLast(),
123 //             target->blockNo(),
124 //             target->getRelStart(),
125 //             target->getRelLast());
126
127     fprintf(stderr," 0x%x, 0x%x --> 0x%x, 0x%x %s\n",
128             source->getStartAddress(),
129             source->getEndAddress(),
130             target->getStartAddress(),
131             target->getEndAddress(),
132             edge_type_string(type).c_str());
133
134 }
135
136
137 #if 0
138 // Only edges created by conditional jumps need edge trampolines
139 bool BPatch_edge::needsEdgeTrampInt()
140 {
141     return type == CondJumpNottaken || type == CondJumpTaken;
142 }
143 #endif
144
145
146 BPatch_point *BPatch_edge::getPoint()
147 {
148     if (!point) {
149         // BPatch_points typically represent an instruction. This doesn't;
150         // we can have two per instruction (fallthrough edge and target
151         // edge). Argh. 
152         assert(source);
153         assert(target);
154         Address lastInsnAddr = (Address) source->getLastInsnAddress();
155
156         process *ll_proc = flowGraph->getBProcess()->lowlevel_process();
157         assert(ll_proc);
158
159         //instPoint *ip = ll_proc->findInstPByAddr(lastInsnAddr);
160         instPoint *ip = instPoint::createArbitraryInstPoint(lastInsnAddr, ll_proc);
161                                                           
162         if (ip == NULL) {
163             fprintf(stderr, "Failed to find inst point at address 0x%lx\n",
164                     lastInsnAddr);
165             return NULL;
166         }
167
168         BPatch_point *newPoint = new BPatch_point(flowGraph->getBProcess(),
169                                                   flowGraph->getBFunction(),
170                                                   this,
171                                                   ip);
172         if (newPoint) {
173             point = newPoint;
174         }
175         else {
176             fprintf(stderr, "BPatch_edge: didn't create point!\n");
177         }
178     }
179     return point;
180 }
181