fixes for gcc 4
[dyninst.git] / dyninstAPI / src / inst.h
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 // $Id: inst.h,v 1.104 2008/09/15 18:37:49 jaw Exp $
43
44 #ifndef INST_HDR
45 #define INST_HDR
46
47 #include <string>
48 #include "common/h/Vector.h"
49 #include "common/h/Dictionary.h"
50 #include "opcode.h" // enum opCode now defined here.
51 #include "common/h/Types.h"
52 #include "arch.h" // codeBufIndex_t 
53 #include "dyninstAPI/src/ast.h" // astNodePtr
54
55 /****************************************************************************/
56 /****************************************************************************/
57 /****************************************************************************/
58
59 class instPoint;
60 class miniTramp;
61 class baseTramp;
62 class process;
63 class int_function;
64 class metricFocusNode;
65 class codeGen;
66 class registerSpace;
67 class AddressSpace;
68
69 typedef enum { callNoArgs, callRecordType, callFullArgs } callOptions;
70 typedef enum { callPreInsn, callPostInsn, callBranchTargetInsn, callUnset } callWhen;
71 typedef enum { orderFirstAtPoint, orderLastAtPoint } callOrder;
72
73 extern pdvector<Address> getTrampAddressesAtPoint(process *proc, 
74                                                   const instPoint *loc,
75                                                   callWhen when);
76
77 class AstNode;
78
79 /*
80  * Insert instrumentation at the specified codeLocation.
81  * TODO: make these methods of class process
82  */
83
84 // writes to (*mtInfo)
85 #if 0
86 loadMiniTramp_result loadMergedTramp(miniTramp *&mtHandle,
87                                    process *proc, 
88                                    instPoint *&location,
89                                    AstNodePtr ast, // the ast could be changed 
90                                    callWhen when, callOrder order, bool noCost,
91                                    returnInstance *&retInstance,
92                                    bool trampRecursiveDesired = false,
93                                    bool allowTramp = true);
94 #endif
95 /* Utility functions */
96
97 float getPointFrequency(instPoint *point);
98 int getPointCost(process *proc, const instPoint *point);
99
100
101 /* return the function asociated with a point. */
102 int_function *getFunction(instPoint *point);
103
104 /*
105  * struct to define a list of inst requests 
106  *
107  */
108 #define FUNC_ENTRY      0x1             /* entry to the function */
109 #define FUNC_EXIT       0x2             /* exit from function */
110 #define FUNC_CALL       0x4             /* subroutines called from func */
111 #define FUNC_ARG        0x8             /* use arg as argument */
112
113 // Container class for "instrument this point with this function". 
114 // What I want to know is who is allergic to multi-letter arguments? Yeesh.
115 class instMapping {
116
117    public:
118
119       instMapping(const std::string f, const std::string i, const int w, 
120             callWhen wn, callOrder o, AstNodePtr a = AstNodePtr(), std::string l = "")
121          : func(f), inst(i), lib(l),
122          where(w), when(wn), order(o), useTrampGuard(true),
123          mt_only(false), allow_trap(false) {
124             if (a != AstNodePtr()) args.push_back(a);
125          }
126
127       instMapping(const std::string f, const std::string i, const int w, 
128             AstNodePtr a = AstNodePtr(), std::string l = "")
129          : func(f), inst(i), lib(l),
130          where(w), when(callPreInsn), order(orderLastAtPoint),
131          useTrampGuard(true), mt_only(false), allow_trap(false) {
132             if (a != AstNodePtr()) args.push_back(a);
133          }
134
135       instMapping(const std::string f, const std::string i, const int w, 
136             pdvector<AstNodePtr> &aList, std::string l = "") :
137          func(f), inst(i), lib(l),
138          where(w), when(callPreInsn), order(orderLastAtPoint),
139          useTrampGuard(true), mt_only(false), allow_trap(false) {
140             for(unsigned u=0; u < aList.size(); u++) {
141                if (aList[u] != AstNodePtr()) args.push_back(aList[u]);
142             }
143          };
144
145       // Fork
146       instMapping(const instMapping *parMapping, process *child);
147
148   ~instMapping() {
149   }
150
151 public:
152   void dontUseTrampGuard() { useTrampGuard = false; }
153   void markAs_MTonly() { mt_only = true; }
154   void canUseTrap(bool t) { allow_trap = t; }
155   bool is_MTonly() { return mt_only; }
156
157   std::string func;                 /* function to instrument */
158   std::string inst;                 /* inst. function to place at func */
159   std::string lib;                  /* library name */
160   int where;                   /* FUNC_ENTRY, FUNC_EXIT, FUNC_CALL */
161   callWhen when;               /* callPreInsn, callPostInsn */
162   callOrder order;             /* orderFirstAtPoint, orderLastAtPoint */
163   pdvector<AstNodePtr> args;      /* what to pass as arg0 ... n */
164   bool useTrampGuard;
165   bool mt_only;
166   bool allow_trap;
167   pdvector<miniTramp *> miniTramps;
168 };
169
170
171 /*
172  * get information about the cost of primitives.
173  *
174  */
175 void initPrimitiveCost();
176 void initDefaultPointFrequencyTable();
177
178 //
179 // Return the expected runtime of the passed function in instruction times.
180 //
181 unsigned getPrimitiveCost(const std::string &name);
182
183 /*
184  * Generate an instruction.
185  * Previously this was handled by the polymorphic "emit" function, which
186  * took a variety of argument types and variously returned either an
187  * Address or a Register or nothing of value.  The following family of
188  * functions replace "emit" with more strongly typed versions.
189  */
190
191 // The return value is a magic "hand this in when we update" black box;
192 // emitA handles emission of things like ifs that need to be updated later.
193 codeBufIndex_t emitA(opCode op, Register src1, Register src2, Register dst, 
194                      codeGen &gen, bool noCost);
195
196 // for operations requiring a Register to be returned
197 // (e.g., getRetValOp, getParamOp, getSysRetValOp, getSysParamOp)
198 Register emitR(opCode op, Register src1, Register src2, Register dst, 
199                codeGen &gen, bool noCost, 
200                const instPoint *location, bool for_multithreaded);
201
202 // for general arithmetic and logic operations which return nothing
203 void     emitV(opCode op, Register src1, Register src2, Register dst, 
204                codeGen &gen, bool noCost, 
205                registerSpace *rs = NULL, int size = 4,
206                const instPoint * location = NULL, AddressSpace * proc = NULL);
207
208 // for loadOp and loadConstOp (reading from an Address)
209 void     emitVload(opCode op, Address src1, Register src2, Register dst, 
210                    codeGen &gen, bool noCost, 
211                    registerSpace *rs = NULL, int size = 4, 
212                    const instPoint * location = NULL, AddressSpace * proc = NULL);
213
214 // for storeOp (writing to an Address)
215 void     emitVstore(opCode op, Register src1, Register src2, Address dst, 
216                     codeGen &gen, bool noCost, 
217                     registerSpace *rs = NULL, int size = 4, 
218                     const instPoint * location = NULL, AddressSpace * proc = NULL);
219
220 // and the retyped original emitImm companion
221 void     emitImm(opCode op, Register src, RegValue src2imm, Register dst, 
222                  codeGen &gen, bool noCost,
223                  registerSpace *rs = NULL);
224
225
226 //#include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
227 class BPatch_addrSpec_NP;
228 typedef BPatch_addrSpec_NP BPatch_countSpec_NP;
229
230 // Don't need the above: countSpec is typedefed to addrSpec
231
232 void emitJmpMC(int condition, int offset, codeGen &gen);
233
234 void emitASload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen, bool noCost);
235
236 void emitCSload(const BPatch_countSpec_NP *as, Register dest, codeGen &gen, bool noCost);
237
238 // VG(11/06/01): moved here and added location
239 Register emitFuncCall(opCode op, codeGen &gen,
240                       pdvector<AstNodePtr> &operands,
241                                           bool noCost, 
242                       int_function *func);
243
244 // Obsolete version that uses an address. DON'T USE THIS or expect it to survive.
245 Register emitFuncCall(opCode op, codeGen &gen,
246                       pdvector<AstNodePtr> &operands, 
247                                   bool noCost, 
248                       Address callee_addr_);
249
250 int getInsnCost(opCode t);
251
252 /*
253  * get the requested parameter into a register.
254  *
255  */
256 Register getParameter(Register dest, int param);
257
258 extern std::string getProcessStatus(const AddressSpace *p);
259
260 // TODO - what about mangled names ?
261 // expects the symbol name advanced past the underscore
262 extern unsigned findTags(const std::string funcName);
263
264 extern Address getMaxBranch();
265
266 // find these internal functions before finding any other functions
267 // extern dictionary_hash<std::string, unsigned> tagDict;
268 extern dictionary_hash <std::string, unsigned> primitiveCosts;
269
270 bool writeFunctionPtr(AddressSpace *p, Address addr, int_function *f);
271
272 /**
273  * A set of optimized emiters for common idioms.  Return 
274  * false if the platform can't perform any optimizations.
275  **/
276 //Store constant in memory at address
277 bool emitStoreConst(Address addr, int imm, codeGen &gen, bool noCost);
278 //Add constant to memory at address
279 bool emitAddSignedImm(Address addr, long int imm, codeGen &gen, bool noCost);
280 //Subtract constant from memory at address
281 bool emitSubSignedImm(Address addr, long int imm, codeGen &gen, bool noCost);
282
283 #endif