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