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