Infrastructure for SW CallTrees and group operations
[dyninst.git] / stackwalk / src / sw.h
1 /*
2  * Copyright (c) 1996-2011 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 #ifndef SW_INTERNAL_H_
33 #define SW_INTERNAL_H_
34
35 #include <set>
36 #include "common/h/addrRange.h"
37 #include "stackwalk/h/framestepper.h"
38 #include "stackwalk/h/walker.h"
39 #include "stackwalk/h/frame.h"
40 #include "stackwalk/src/libstate.h"
41
42 namespace Dyninst {
43 namespace Stackwalker {
44
45 struct ltstepper
46 {
47    bool operator()(const FrameStepper *a, const FrameStepper *b) const
48    {
49       return a->getPriority() < b->getPriority();
50    }
51 };
52
53 typedef std::set<FrameStepper *, ltstepper> StepperSet;
54
55 class AddrRangeStepper : public addrRange
56 {
57 public:
58    Address start;
59    Address end;
60    StepperSet steppers;
61
62    AddrRangeStepper() { }
63    AddrRangeStepper(Address s, Address e) { start = s; end = e; }
64
65    virtual Address get_address() const { return start; } 
66    virtual unsigned long get_size() const { return end - start; }
67    virtual ~AddrRangeStepper() { }
68 };
69
70 class FrameFuncStepperImpl : public FrameStepper
71 {
72  private:
73    FrameStepper *parent;
74    FrameFuncHelper *helper;
75  public:
76    FrameFuncStepperImpl(Walker *w, 
77                         FrameStepper *parent_,
78                         FrameFuncHelper *helper_);
79    virtual ~FrameFuncStepperImpl();
80    virtual gcframe_ret_t getCallerFrame(const Frame &in, 
81                                         Frame &out);
82    static gcframe_ret_t getBasicCallerFrame(const Frame &in, 
83                                             Frame &out);
84    virtual unsigned getPriority() const;
85    virtual const char *getName() const;
86 };
87
88 class BottomOfStackStepperImpl : public FrameStepper {
89 private:
90    BottomOfStackStepper *parent;
91    std::vector<std::pair<Address, Address> > ra_stack_tops;
92    std::vector<std::pair<Address, Address> > sp_stack_tops;
93    bool libc_init;
94    bool aout_init;
95    bool libthread_init;
96    void initialize();
97 public:
98    BottomOfStackStepperImpl(Walker *w, BottomOfStackStepper *parent);
99    virtual gcframe_ret_t getCallerFrame(const Frame &in, Frame &out);
100    virtual unsigned getPriority() const;
101    virtual void registerStepperGroup(StepperGroup *group);
102    virtual void newLibraryNotification(LibAddrPair *la, lib_change_t change);
103    virtual ~BottomOfStackStepperImpl();
104    virtual const char *getName() const;  
105 };
106
107 class DyninstInstrStepperImpl : public FrameStepper {
108  private:
109    static std::map<SymReader *, bool> isRewritten;
110    DyninstInstrStepper *parent;
111
112  public:
113    DyninstInstrStepperImpl(Walker *w, DyninstInstrStepper *p);
114    virtual gcframe_ret_t getCallerFrame(const Frame &in, Frame &out);
115    gcframe_ret_t getCallerFrameArch(const Frame &in, Frame &out, 
116                                     Address base, Address lib_base, 
117                                     unsigned size, unsigned stack_height);
118    virtual unsigned getPriority() const;
119    virtual void registerStepperGroup(StepperGroup *group);
120    virtual const char *getName() const;
121    virtual ~DyninstInstrStepperImpl();
122 };
123
124 class DyninstDynamicStepperImpl : public FrameStepper {
125  private:
126    DyninstDynamicStepper *parent;
127    DyninstDynamicHelper *helper;
128    bool prevEntryExit; // remember if the previous frame was entry/exit instrumentation
129   
130  public:
131    DyninstDynamicStepperImpl(Walker *w, DyninstDynamicStepper *p, DyninstDynamicHelper *h);
132    virtual gcframe_ret_t getCallerFrame(const Frame &in, Frame &out);
133    gcframe_ret_t getCallerFrameArch(const Frame &in, Frame &out, 
134                                     Address base, Address lib_base, 
135                                     unsigned size, unsigned stack_height,
136                                     Address orig_ra, bool pEntryExit);
137    virtual unsigned getPriority() const;
138    virtual void registerStepperGroup(StepperGroup *group);
139    virtual const char *getName() const;
140    virtual ~DyninstDynamicStepperImpl();
141 };
142
143 class int_walkerSet {
144    friend class Dyninst::Stackwalker::WalkerSet;
145 public:
146    int_walkerSet();
147    ~int_walkerSet();
148
149    pair<set<Walker *>::iterator, bool> insert(Walker *w);
150    void erase(set<Walker *>::iterator i);
151 private:
152    void addToProcSet(ProcDebug *);
153    void eraseFromProcSet(ProcDebug *);
154    void clearProcSet();
155    void initProcSet();
156    bool walkStacksProcSet(CallTree &tree, bool &bad_plat);
157
158    unsigned non_pd_walkers;
159    set<Walker *> walkers;
160    void *procset; //Opaque pointer, will refer to a ProcControl::ProcessSet in some situations
161 };
162
163 }
164 }
165
166 #endif