* Bugfix: InstrucIter no longer used for int_function iteration.
[dyninst.git] / dyninstAPI / src / function.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: function.h,v 1.46 2007/12/11 20:22:06 bill Exp $
43
44 #ifndef FUNCTION_H
45 #define FUNCTION_H
46
47 #include "common/h/String.h"
48 #include "common/h/Vector.h"
49 #include "common/h/Types.h"
50 #include "common/h/Pair.h"
51 #include "codeRange.h"
52 #include "arch.h" // instruction
53 #include "util.h"
54 #include "image-func.h"
55
56 #include "bitArray.h"
57
58 class process;
59 class mapped_module;
60 class mapped_object;
61
62 class BPatch_flowGraph;
63 class BPatch_loopTreeNode;
64 class BPatch_basicBlock;
65 class BPatch_basicBlockLoop;
66
67 class instPointInstance;
68
69 #if defined(arch_ia64)
70 #include "dyninstAPI/h/BPatch_Set.h"
71 #endif
72
73 #include "dyninstAPI/src/ast.h"
74
75 class instPoint;
76
77 class Frame;
78
79 class functionReplacement;
80
81 class int_function;
82 class int_basicBlock;
83 class funcMod;
84
85 typedef enum callType {
86   unknown_call,
87   cdecl_call,
88   stdcall_call,
89   fastcall_call,
90   thiscall_call
91 } callType;
92
93 // A specific instance (relocated version) of a basic block
94 // It's really a semi-smart struct...
95 class bblInstance : public codeRange {
96     friend class int_basicBlock;
97     friend class int_function;
98     friend class multiTramp;
99
100     // "We'll set things up later" constructor. Private because only int_basicBlock
101     // should be playing in here
102     bblInstance(int_basicBlock *parent, int version);
103  public:
104     bblInstance(Address start, Address last, Address end, int_basicBlock *parent, int version);
105     bblInstance(const bblInstance *parent, int_basicBlock *block);
106     ~bblInstance();
107
108     Address firstInsnAddr() const { return firstInsnAddr_; }
109     Address lastInsnAddr() const { return lastInsnAddr_; }
110     // Just to be obvious -- this is the end addr of the block
111     Address endAddr() const { return blockEndAddr_; }
112     Address getSize() const { return blockEndAddr_ - firstInsnAddr_; }
113
114     // And equivalence in addresses...
115     Address equivAddr(bblInstance *otherBBL, Address otherAddr) const;
116
117     // As a note: do _NOT_ create an address-based comparison of this
118     // class unless you just need some sort of ordering. We may create these
119     // blocks in some random place; depending on address is just plain dumb.
120
121     Address get_address_cr() const { return firstInsnAddr(); }
122     unsigned get_size_cr() const { return getSize(); }
123     void *getPtrToInstruction(Address addr) const;
124     void *get_local_ptr() const;
125
126
127     const void *getPtrToOrigInstruction(Address addr) const;
128     unsigned getRelocInsnSize(Address addr) const;
129
130     void getOrigInstructionInfo(Address addr, void *&ptr, Address &origAddr, unsigned &origSize) const;
131
132     //process *proc() const;
133     AddressSpace *proc() const;
134     int_function *func() const;
135     int_basicBlock *block() const;
136     int version() const;
137
138 #if defined(cap_relocation)
139     // Get the most space necessary to relocate this basic block,
140     // using worst-case analysis.
141     bool relocationSetup(bblInstance *orig, pdvector<funcMod *> &mods);
142     unsigned sizeRequired();
143     // Pin a block to a particular address; in theory, we can only
144     // do these for blocks that can be entered via jumps, but for now
145     // we do it all the time.
146     void setStartAddr(Address addr);
147
148     // And generate a moved copy into ze basic block
149     bool generate();
150     // And write the block into the addr space
151     bool install();
152     // Check for safety...
153     bool check(pdvector<Address> &checkPCs);
154     // Link things up
155     bool link(pdvector<codeRange *> &overwrittenObjs);
156 #endif
157
158 #if defined(cap_relocation)
159     class reloc_info_t {
160     public:       
161        unsigned maxSize_;
162        bblInstance *origInstance_;
163        pdvector<funcMod *> appliedMods_;
164        codeGen generatedBlock_; // Kept so we can quickly iterate over the block
165        // in the future.
166        functionReplacement *jumpToBlock_; // Kept here between generate->link
167
168        struct relocInsn {
169          // Where we ended up; can derive size from next - this one
170          Address origAddr;
171          Address relocAddr;
172          instruction *origInsn;
173          const void *origPtr;
174          Address relocTarget;
175          unsigned relocSize;
176        };
177        
178        pdvector<relocInsn *> relocs_;
179
180        reloc_info_t();
181        reloc_info_t(reloc_info_t *parent, int_basicBlock *block);
182        ~reloc_info_t();
183     };
184
185  private:
186
187     //Setter functions for relocation information
188     pdvector<reloc_info_t::relocInsn *> &relocs();
189     unsigned &maxSize();
190     bblInstance *&origInstance();
191     pdvector<funcMod *> &appliedMods();
192     codeGen &generatedBlock();
193     functionReplacement *&jumpToBlock();
194
195
196     pdvector<reloc_info_t::relocInsn *> &get_relocs() const;
197
198     unsigned getMaxSize() const;
199     bblInstance *getOrigInstance() const;
200     pdvector<funcMod *> &getAppliedMods() const;
201     codeGen &getGeneratedBlock() const;
202     functionReplacement *getJumpToBlock() const;
203
204     reloc_info_t *reloc_info;
205 #endif
206
207     Address firstInsnAddr_;
208     Address lastInsnAddr_;
209     Address blockEndAddr_;
210     int_basicBlock *block_;
211     int version_;
212 };
213
214 class int_basicBlock {
215     friend class int_function;
216  public:
217     int_basicBlock(const image_basicBlock *ib, Address baseAddr, int_function *func, int id);
218     int_basicBlock(const int_basicBlock *parent, int_function *func, int id);
219     ~int_basicBlock();
220
221         // just because a block is an entry block doesn't mean it is
222         // an entry block that this block's function cares about
223     bool isEntryBlock() const;
224     bool isExitBlock() const { return ib_->isExitBlock(); }
225
226         // int_basicBlocks are not shared, but their underlying blocks
227         // may be
228     bool hasSharedBase() const { return ib_->isShared(); }
229
230     const image_basicBlock * llb() const { return ib_; }
231     
232     static int compare(int_basicBlock *&b1,
233                        int_basicBlock *&b2) {
234         // First instance: original bbl.
235         if (b1->instances_[0]->firstInsnAddr() < b2->instances_[0]->firstInsnAddr())
236             return -1;
237         if (b2->instances_[0]->firstInsnAddr() < b1->instances_[0]->firstInsnAddr())
238             return 1;
239         assert(b1 == b2);
240         return 0;
241     }
242
243     const pdvector<bblInstance *> &instances() const;
244     bblInstance *origInstance() const;
245     bblInstance *instVer(unsigned index) const;
246     void removeVersion(unsigned index);
247
248     void debugPrint();
249
250     void getSources(pdvector<int_basicBlock *> &ins) const;
251     void getTargets(pdvector<int_basicBlock *> &outs) const;
252     EdgeTypeEnum getSourceEdgeType(int_basicBlock *source) const;
253     EdgeTypeEnum getTargetEdgeType(int_basicBlock *target) const;
254
255     int_basicBlock *getFallthrough() const;
256
257     int id() const { return id_; }
258
259     // True if we need to put a jump in here. If we're an entry block
260     // or the target of an indirect jump (for now).
261     bool needsJumpToNewVersion();
262
263     // A block will need relocation (when instrumenting) if
264     // its underlying image_basicBlock is shared (this is independant
265     // of relocation requirements dependant on size available)
266     bool needsRelocation() const;
267
268     int_function *func() const { return func_; }
269     //process *proc() const;
270     AddressSpace *proc() const;
271
272 #if defined(arch_ia64)
273     // Data flow... for register analysis. Right now just used for 
274     // IA64 alloc calculations
275     // We need a set...
276     void setDataFlowIn(BPatch_Set<int_basicBlock *> *in);
277     void setDataFlowOut(BPatch_Set<int_basicBlock *> *out);
278     void setDataFlowGen(int_basicBlock *gen);
279     void setDataFlowKill(int_basicBlock *kill);
280
281     BPatch_Set<int_basicBlock *> *getDataFlowOut();
282     BPatch_Set<int_basicBlock *> *getDataFlowIn();
283     int_basicBlock *getDataFlowGen();
284     int_basicBlock *getDataFlowKill();    
285 #endif
286
287     void setHighLevelBlock(void *newb);
288     void *getHighLevelBlock() const;
289
290  private:
291     void *highlevel_block; //Should point to a BPatch_basicBlock, if they've
292                            //been created.
293 #if defined(arch_ia64)
294     BPatch_Set<int_basicBlock *> *dataFlowIn;
295     BPatch_Set<int_basicBlock *> *dataFlowOut;
296     int_basicBlock *dataFlowGen;
297     int_basicBlock *dataFlowKill;
298 #endif
299
300
301     int_function *func_;
302     const image_basicBlock *ib_;
303
304     int id_;
305
306     // A single "logical" basic block may correspond to multiple
307     // physical areas of code. In particular, we may relocate the
308     // block (either replaced or duplicated).
309     pdvector<bblInstance *> instances_;
310 };
311
312 class int_function {
313   friend class int_basicBlock;
314  public:
315    //static pdstring emptyString;
316
317    // Almost everything gets filled in later.
318    int_function(image_func *f,
319                 Address baseAddr,
320                 mapped_module *mod);
321
322    int_function(const int_function *parent,
323                 mapped_module *child_mod,
324                 process *childP);
325
326    ~int_function();
327
328    ////////////////////////////////////////////////
329    // Passthrough functions.
330    ////////////////////////////////////////////////
331    // To minimize wasted memory (since there will be many copies of
332    // this function) we make most methods passthroughs to the original
333    // parsed version.
334
335    const string &symTabName() const;
336    const string &prettyName() const { return ifunc_->prettyName(); };
337    const string &typedName() const { return ifunc_->typedName(); };
338    
339    const vector<string>& symTabNameVector() const { return ifunc_->symTabNameVector(); }
340    const vector<string>& prettyNameVector() const { return ifunc_->prettyNameVector(); }
341    const vector<string>& typedNameVector() const { return ifunc_->typedNameVector(); }
342
343    // Debuggering functions
344    void debugPrint() const;
345
346    // And add...
347    // Don't make the pdstring a reference; we want a copy.
348    void addSymTabName(const pdstring name, bool isPrimary = false);
349    void addPrettyName(const pdstring name, bool isPrimary = false);
350
351    // May change when we relocate...
352    Address getAddress() const {return addr_;}
353    // Don't use this...
354    unsigned getSize_NP();
355
356
357    // Not defined here so we don't have to play header file magic
358    // Not const; we can add names via the Dyninst layer
359    image_func *ifunc();
360    mapped_module *mod() const;
361    mapped_object *obj() const;
362    //process *proc() const;
363    AddressSpace *proc() const;
364
365    // Necessary for BPatch_set which needs a structure with a ()
366    // operator. Odd.
367    struct cmpAddr {
368      int operator() (const int_function *f1, const int_function *f2) const {
369        if (f1->getAddress() > f2->getAddress())
370          return 1;
371        else if (f1->getAddress() < f2->getAddress())
372          return -1;
373        else
374          return 0;
375      }
376    };
377
378    // extra debuggering info....
379    ostream & operator<<(ostream &s) const;
380    friend ostream &operator<<(ostream &os, int_function &f);
381
382    ////////////////////////////////////////////////
383    // Process-dependent (inter-module) parsing
384    ////////////////////////////////////////////////
385    void checkCallPoints();
386
387    ////////////////////////////////////////////////
388    // CFG and other function body methods
389    ////////////////////////////////////////////////
390
391    const std::vector< int_basicBlock* > &blocks();
392
393    // Perform a lookup (either linear or log(n)).
394    int_basicBlock *findBlockByAddr(Address addr);
395    int_basicBlock *findBlockByOffset(Address offset) { return findBlockByAddr(offset + getAddress()); }
396    bblInstance *findBlockInstanceByAddr(Address addr);
397
398
399    bool hasNoStackFrame() const {return ifunc_->hasNoStackFrame();}
400    bool makesNoCalls() const {return ifunc_->makesNoCalls();}
401    bool savesFramePointer() const {return ifunc_->savesFramePointer();}
402
403    //BPatch_flowGraph * getCFG();
404    //BPatch_loopTreeNode * getLoopTree();
405
406    ////////////////////////////////////////////////
407    // Instpoints!
408    ////////////////////////////////////////////////
409
410    void addArbitraryPoint(instPoint *insp);
411
412    const pdvector<instPoint*> &funcEntries();
413    // Note: the vector is constant, the instPoints aren't.
414    const pdvector<instPoint*> &funcExits();
415    const pdvector<instPoint*> &funcCalls();
416    const pdvector<instPoint*> &funcArbitraryPoints();
417    
418    instPoint *findInstPByAddr(Address addr);
419
420    // And for adding... we map by address to instPoint
421    // as a single instPoint may have multiple instances
422    void registerInstPointAddr(Address addr, instPoint *inst);
423    void unregisterInstPointAddr(Address addr, instPoint *inst);
424
425    bool isInstrumentable() const { return ifunc_->isInstrumentable(); }
426
427
428 #if defined(arch_x86) || defined(arch_x86_64)
429    //Replaces the function with a 'return val' statement.
430    // currently needed only on Linux/x86
431    // Defined in inst-x86.C
432    bool setReturnValue(int val);
433
434    //bool hasJumpToFirstFiveBytes() { return ifunc_->hasJumpToFirstFiveBytes(); }
435    // ----------------------------------------------------------------------
436 #endif
437
438    ////////////////////////////////////////////////
439    // Relocation
440    ////////////////////////////////////////////////
441
442    bool canBeRelocated() const { return ifunc_->canBeRelocated(); }
443    bool needsRelocation() const { return ifunc_->needsRelocation(); }
444    int version() const { return version_; }
445
446
447    ////////////////////////////////////////////////
448    // Code overlapping
449    ////////////////////////////////////////////////
450    // Get all functions that "share" the block. Actually, the
451    // int_basicBlock will not be shared (they are per function),
452    // but the underlying image_basicBlock records the sharing status. 
453    // So dodge through to the image layer and find out that info. 
454    // Returns true if such functions exist.
455
456    bool getSharingFuncs(int_basicBlock *b,
457                         pdvector<int_function *> &funcs);
458
459    // The same, but for any function that overlaps with any of
460    // our basic blocks.
461    // OPTIMIZATION: we're not checking all blocks, only an exit
462    // point; this _should_ work :) but needs to change if we
463    // ever do flow-sensitive parsing
464    bool getOverlappingFuncs(pdvector<int_function *> &funcs);
465
466
467    ////////////////////////////////////////////////
468    // Misc
469    ////////////////////////////////////////////////
470
471
472    const pdvector< int_parRegion* > &parRegions() { return parallelRegions_; }
473
474    bool containsSharedBlocks() const { return ifunc_->containsSharedBlocks(); }
475
476    unsigned getNumDynamicCalls();
477
478     // Fill the <callers> vector with pointers to the statically-determined
479     // list of functions that call this function.
480     void getStaticCallers(pdvector <int_function *> &callers);
481
482    codeRange *copy() const;
483     
484 #if defined(arch_alpha)
485    int frame_size() const { return ifunc_->frame_size; };
486
487 #endif
488
489 #if defined(sparc_sun_solaris2_4)
490    bool is_o7_live(){ return ifunc_->is_o7_live(); }
491 #endif
492
493    void updateForFork(process *childProcess, const process *parentProcess);
494
495 #if defined(arch_ia64)
496    // We need to know where all the alloc instructions in the
497    // function are to do a reasonable job of register allocation
498    // in the base tramp.
499    
500  private:
501    Address baseAddr_;
502    pdvector< Address > cachedAllocs;
503     
504  public:
505    // Accessor function that ensures that the cachedAllocs are
506    // up-to-date.  Necessary because of delayed parsing.
507    pdvector< Address > & getAllocs();
508    
509    // Since the IA-64 ABI does not define a frame pointer register,
510    // we use DWARF debug records (DW_AT_frame_base entries) to 
511    // construct an AST which calculates the frame pointer.
512    AstNodePtr getFramePointerCalculator();
513    
514    // Place to store the results of doFloatingPointStaticAnalysis().
515    // This way, if they are ever needed in a mini-tramp, emitFuncJump()
516    // for example, the expensive operation doesn't need to happen again.
517    bool * getUsedFPregs();
518 #endif
519
520 #if defined(cap_relocation)
521    // These are defined in reloc-func.C to keep large chunks of
522    // functionality separate!
523
524    // Deceptively simple... take a list of requested changes,
525    // and make a copy of the function somewhere out in space.
526    // Defaults to the first version of the function = 0
527    bool relocationGenerate(pdvector<funcMod *> &mods, 
528                            int version,
529                            pdvector<int_function *> &needReloc);
530    // The above gives us a set of basic blocks that have little
531    // code segments. Install them in the address space....
532    bool relocationInstall();
533    // Check whether we can overwrite...
534    bool relocationCheck(pdvector<Address> &checkPCs);
535    // And overwrite code with jumps to the relocated version
536    bool relocationLink(pdvector<codeRange *> &overwritten_objs);
537
538    // Cleanup code: remove (back to) the latest installed version...
539    bool relocationInvalidate();
540
541    // A top-level function; for each instPoint, see if we need to 
542    // relocate the function.
543    bool expandForInstrumentation();
544
545    pdvector<funcMod *> &enlargeMods() { return enlargeMods_; }
546
547 #endif
548
549 #if defined(os_windows) 
550    //Calling convention for this function
551    callType int_function::getCallingConvention();
552    int getParamSize() { return paramSize; }
553    void setParamSize(int s) { paramSize = s; }
554 #endif
555
556
557  private:
558
559    ///////////////////// Basic func info
560    Address addr_; // Absolute address of the start of the function
561
562    image_func *ifunc_;
563    mapped_module *mod_; // This is really a dodge; translate a list of
564                         // image_funcs to int_funcs
565
566    ///////////////////// CFG and function body
567    std::vector< int_basicBlock* > blockList;
568
569    // Added to support translation between function-specific int_basicBlocks
570    // and potentially shared image_basicBlocks
571    dictionary_hash<int, int> blockIDmap;
572
573    //BPatch_flowGraph *flowGraph;
574
575    ///////////////////// Instpoints 
576
577    pdvector<instPoint*> entryPoints_;   /* place to instrument entry (often not addr) */
578    pdvector<instPoint*> exitPoints_;    /* return point(s). */
579    pdvector<instPoint*> callPoints_;    /* pointer to the calls */
580    pdvector<instPoint*> arbitraryPoints_;              /* pointer to the calls */
581
582    dictionary_hash<Address, instPoint *> instPsByAddr_;
583
584    //////////////////////////  Parallel Regions 
585    pdvector<int_parRegion*> parallelRegions_; /* pointer to the parallel regions */
586
587
588 #if defined(cap_relocation)
589    // Status tracking variables
590    int generatedVersion_;
591    int installedVersion_;
592    int linkedVersion_;
593
594    // We want to keep around expansions for instrumentation
595    pdvector<funcMod *> enlargeMods_;
596
597    // The actual relocation workhorse (the public method is just a facade)
598    bool relocationGenerateInt(pdvector<funcMod *> &mods, 
599                               int version,
600                               pdvector<int_function *> &needReloc);
601 #endif
602
603    // Used to sync with instPoints
604    int version_;
605
606    codeRangeTree blocksByAddr_;
607    void addBBLInstance(bblInstance *instance);
608    void deleteBBLInstance(bblInstance *instance);
609
610 #if defined(os_windows) 
611    callType callingConv;
612    int paramSize;
613 #endif
614
615 };
616
617 // All-purpose; use for function relocation, actual function
618 // replacement, etc.
619 class functionReplacement : public codeRange {
620
621  public:
622     functionReplacement(int_basicBlock *sourceBlock,
623                         int_basicBlock *targetBlock,
624                         unsigned sourceVersion = 0,
625                         unsigned targetVersion = 0);
626     ~functionReplacement() {};
627
628     unsigned maxSizeRequired();
629
630     bool generateFuncRepJump(pdvector<int_function *> &needReloc);
631     bool generateFuncRepTrap(pdvector<int_function *> &needReloc);
632     bool installFuncRep();
633     bool checkFuncRep(pdvector<Address> &checkPCs);
634     bool linkFuncRep(pdvector<codeRange *> &overwrittenObjs);
635     void removeFuncRep();
636     
637     bool overwritesMultipleBlocks();
638
639     int_basicBlock *source();
640     int_basicBlock *target();
641     unsigned sourceVersion();
642     unsigned targetVersion();
643
644     Address get_address_cr() const;
645     unsigned get_size_cr() const;
646     void *get_local_ptr() const { return jumpToRelocated.start_ptr(); }
647
648     AddressSpace *proc() const;
649
650  private:
651     codeGen jumpToRelocated;
652     codeGen origInsns;
653
654     int_basicBlock *sourceBlock_;
655     int_basicBlock *targetBlock_;
656
657     // If no relocation, these will be zero.
658     unsigned sourceVersion_;
659     unsigned targetVersion_;
660
661     // We may need more room than there is in a block;
662     // this makes things "interesting".
663     bool overwritesMultipleBlocks_; 
664
665     bool usesTrap_;
666 };
667
668
669
670 #endif /* FUNCTION_H */