Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / baseTramp.h
1 /*
2  * Copyright (c) 1996-2009 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  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: baseTramp.h,v 1.24 2008/09/04 21:06:08 bill Exp $
33
34 // baseTramp class definition
35
36 #ifndef BASE_TRAMP_H
37 #define BASE_TRAMP_H
38
39 #include "common/h/Types.h"
40 #include "inst.h" // callWhen
41 #include "dyninstAPI/src/codeRange.h"
42 #include "instPoint.h"
43 #include "arch.h"
44 #include "multiTramp.h" // generatedCodeObject
45
46 class multiTramp;
47 class miniTramp;
48 class miniTrampInstance;
49 class baseTramp;
50 class instPointInstance;
51 class rpcMgr;
52
53 class generatedCodeObject;
54
55 // Todo: make things private/protected
56
57 // A baseTrampInstance represents a particular version of an
58 // overwritten instruction. Due to re+location and function cloning,
59 // there may be multiple baseTrampInstances for a particular logical
60 // baseTramp. This allows us to minimize the confusion of the
61 // necessary many:many mappings.
62
63 class baseTrampInstance : public generatedCodeObject { 
64     friend class baseTramp;
65  public:
66     baseTrampInstance(baseTramp *tramp,
67                       multiTramp *multi);
68     // FORK!
69     baseTrampInstance(const baseTrampInstance *pI,
70                       baseTramp *cBT,
71                       multiTramp *cMT,
72                       process *child);
73
74
75     Address trampAddr_;
76     unsigned trampSize_;
77     unsigned trampPostOffset;
78     unsigned saveStartOffset;
79     unsigned saveEndOffset;
80     unsigned restoreStartOffset;
81     unsigned restoreEndOffset;
82     Address trampPreAddr() const;
83     Address trampPostAddr() const;
84     //bool empty;
85     
86     baseTramp *baseT;
87     multiTramp *multiT;
88
89     bool isInInstance(Address pc);
90     bool isInInstru(Address pc);
91     
92     // codeRange...
93     Address get_address() const;
94     unsigned get_size() const; 
95     void *getPtrToInstruction(Address addr) const;
96     virtual std::string getTypeString() const;
97     
98
99     Address uninstrumentedAddr() const;
100
101     AddressSpace *proc() const;
102     
103     unsigned maxSizeRequired();
104     //const pdvector<instruction> &getCode();
105     bool shouldGenerate();
106
107     bool generateCode(codeGen &gen,
108                       Address baseInMutatee,
109                       UNW_INFO_TYPE * * unwindInformation);
110
111     bool generateCodeInlined(codeGen &gen,
112                              Address baseInMutatee,
113                              UNW_INFO_TYPE **unwindInformation);
114
115     bool installCode();
116
117     // Displacement is platform-independent; from start
118     // of branch insn to start of target insn.
119     bool finalizeGuardBranch(codeGen &gen,
120                              int displacement);
121
122     
123     void invalidateCode();
124     
125     // Patch in jumps
126     bool linkCode();
127
128     generatedCodeObject *replaceCode(generatedCodeObject *newParent);
129
130     // The subObject wants to be gone, do we delete us as well?
131     void removeCode(generatedCodeObject *subObject);
132
133     // Given the current range, can we safely clean up this
134     // area?
135     bool safeToFree(codeRange *range);
136
137     // Update the list of miniTrampInstances
138     void updateMTInstances();
139
140     bool checkForFuncJumps();
141
142     // Null out an MTI pointer
143     void deleteMTI(miniTrampInstance *mti);
144
145     ~baseTrampInstance();
146
147     int numDefinedRegs();
148     Address miniTrampReturnAddr();
149
150     bool isEmpty() const;
151
152     void updateTrampCost(unsigned cost);
153
154     instPoint *findInstPointByAddr(Address addr);
155
156     bool shouldRegenBaseTramp(registerSpace *rs);
157
158     unsigned genVersion;
159
160     pdvector<miniTrampInstance *> mtis;
161
162     // We need to keep these around to tell whether it's
163     // safe to delete yet.
164     pdvector<miniTrampInstance *> deletedMTIs;
165
166     // We may remove ourselves from the baseTramp's list of instances
167     // either directly (via removeCode) or during deletion -- but
168     // don't do it twice!!!
169     bool alreadyDeleted_;
170
171     Symbol *createBTSymbol();
172
173     //Information about code generated in this tramp
174  private:
175     bool hasOptInfo_;
176     bool spilledRegisters_;
177     bool hasLocalSpace_;
178     bool hasStackFrame_;
179     bool flags_saved_;
180     bool saved_fprs_;
181     bool saved_orig_addr_;
182     bool hasFuncJump_;
183     int trampStackHeight_;
184  public:
185     bitArray definedRegs;
186     bool hasOptInfo() { return hasOptInfo_; } 
187     bool spilledRegisters() { assert(hasOptInfo_); return spilledRegisters_; }
188     bool hasLocalSpace() { return hasLocalSpace_; }
189     bool hasStackFrame() { return hasStackFrame_; }
190     bool flagsSaved() { return flags_saved_; }
191     bool savedFPRs() { return saved_fprs_; }
192     bool savedOrigAddr() { return saved_orig_addr_; }
193     bool hasFuncJump() { return hasFuncJump_; }
194     int trampStackHeight() { return trampStackHeight_; }
195     void setHasOptInfo(bool v) { hasOptInfo_ = v; } 
196     void setSpilledRegisters(bool v) { spilledRegisters_ = v; }
197     void setHasLocalSpace(bool v) { hasLocalSpace_ = v; }
198     void setHasStackFrame(bool v) { hasStackFrame_ = v; }
199     void setFlagsSaved(bool v) { flags_saved_ = v; }
200     void setSavedFPRs(bool v) { saved_fprs_ = v; }
201     void setSavedOrigAddr(bool v) { saved_orig_addr_ = v; }
202     void setHasFuncJump(bool v) { hasFuncJump_ = v; }
203     void setTrampStackHeight(int v) { trampStackHeight_ = v; }
204 };
205
206 class baseTramp {
207     friend class baseTrampInstance;
208  public:
209 #if defined( cap_unwind )
210    unw_dyn_region_info_t * baseTrampRegion;
211 #endif
212     Address origInstAddr(); // For faking an in-function address
213
214     // Our instPoint
215     instPoint *instP_;
216
217     instPoint *instP() const { return instP_; }
218
219     // You know, a conservative tramp is equivalent to an iRPC...
220     rpcMgr *rpcMgr_;
221
222     AddressSpace *proc() const;
223
224     void invalidateBT() { valid = false; };
225
226     bool doOptimizations();
227     bool generateSaves(codeGen &,
228                        registerSpace *,
229                        baseTrampInstance *inst);
230     bool generateRestores(codeGen &,
231                           registerSpace *,
232                           baseTrampInstance *inst);
233
234     bool isConservative();
235     bool isCallsite();
236     bool isEntryExit();
237
238     void setCreateFrame(bool frame);
239     bool createFrame();
240
241     unsigned getBTCost();
242
243     bool inBasetramp( Address addr );
244     bool inSavedRegion( Address addr );
245
246     miniTramp *firstMini;
247     miniTramp *lastMini;
248
249     // Normal constructor
250     baseTramp(instPoint *iP, callWhen when);
251     // Fork constructor
252     baseTramp(const baseTramp *parentT, process *proc);
253
254     // destructor
255     ~baseTramp();
256
257     pdvector<baseTrampInstance *> instances;
258
259     // Hooks the minitramp into the appropriate place in the chains 'o minis,
260     // and sets the miniTramp next and prev members
261     bool addMiniTramp(miniTramp *newMT, callOrder order);
262
263     bool removeMiniTramp(miniTramp *oldMT);
264
265     // Remove the instrumentation skip jumps if necessary
266     bool clearBaseBranch();
267     
268     // Logic to correct all basetramp jumps.
269     // Unused?
270     //bool correctBTJumps();
271
272     // If all our minitramps are gone, clean up
273     void deleteIfEmpty();
274
275     // Get an instance (takes a multiTramp, looks up 
276     // or makes a new one);
277     baseTrampInstance *findOrCreateInstance(multiTramp *multi);
278
279     // Remove an instance
280     void unregisterInstance(baseTrampInstance *inst);
281
282     // Generated base tramp...
283     // Recursively create miniTramps... as a result, we need to 
284     // split the generated code for a baseT in half as there
285     // may be an arbitrary amount of space in between.
286
287     bool valid;
288     bool optimized_out_guards;
289
290     typedef enum {unset_BTR, recursive_BTR, guarded_BTR} guardState_t;
291     guardState_t guardState_;
292
293     bool suppress_threads_;
294     bool threaded() const;
295     void setThreaded(bool new_val);
296
297     void setRecursive(bool trampRecursive, bool force = false);
298     bool getRecursive() const;
299
300     // Easier to do logic this way...
301     bool guarded() const { return (guardState_ == guarded_BTR); }
302
303  private:
304     
305     bool createFrame_;
306     unsigned instVersion_;
307     callWhen when_;
308 };
309
310 extern baseTramp baseTemplate;
311
312 #define X86_REGS_SAVE_LIMIT 3
313
314 #endif
315
316
317