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