Update versions missed by previous commit.
[dyninst.git] / stackwalk / h / frame.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #ifndef FRAME_H_
32 #define FRAME_H_
33
34 #include "basetypes.h"
35 #include "Annotatable.h"
36 #include <string>
37 #include <set>
38
39 class StackCallback;
40
41 namespace Dyninst {
42 namespace Stackwalker {
43
44 class Walker;
45 class FrameStepper;
46
47 class SW_EXPORT Frame : public AnnotatableDense {
48   friend class Walker;
49   friend class CallTree;
50   friend class ::StackCallback;
51 protected:
52   Dyninst::MachRegisterVal ra;
53   Dyninst::MachRegisterVal fp;
54   Dyninst::MachRegisterVal sp;
55         
56   location_t ra_loc;
57   location_t fp_loc;
58   location_t sp_loc;
59   
60   mutable std::string sym_name;
61   mutable void *sym_value;
62   mutable enum { nv_unset, nv_set, nv_err } name_val_set;
63   
64   bool top_frame;
65   bool bottom_frame;
66   bool frame_complete;
67   bool non_call_frame;
68   
69   const Frame *prev_frame;
70   FrameStepper *stepper;
71   FrameStepper *next_stepper;
72   Walker *walker;
73   THR_ID originating_thread;
74   
75   void setStepper(FrameStepper *newstep);
76   void setWalker(Walker *newwalk);
77   void markTopFrame();
78   void markBottomFrame();
79   
80   void setNameValue() const;
81   
82  public:
83   Frame();
84   Frame(Walker *walker);
85   static Frame *newFrame(Dyninst::MachRegisterVal ra, Dyninst::MachRegisterVal sp, Dyninst::MachRegisterVal fp, Walker *walker);
86
87   bool operator==(const Frame &F) const;
88
89   Dyninst::MachRegisterVal getRA() const;
90   Dyninst::MachRegisterVal getSP() const;
91   Dyninst::MachRegisterVal getFP() const;
92   
93   void setRA(Dyninst::MachRegisterVal);
94   void setSP(Dyninst::MachRegisterVal);
95   void setFP(Dyninst::MachRegisterVal);
96   void setThread(THR_ID);
97
98   void setNonCall();
99   
100   location_t getRALocation() const;
101   location_t getSPLocation() const;
102   location_t getFPLocation() const;
103   
104   void setRALocation(location_t newval);
105   void setSPLocation(location_t newval);
106   void setFPLocation(location_t newval);
107   
108   bool getName(std::string &str) const;
109   bool getObject(void* &obj) const;
110   bool getLibOffset(std::string &lib, Dyninst::Offset &offset, void* &symtab) const;
111   
112   bool isTopFrame() const;
113   bool isBottomFrame() const;
114   bool isFrameComplete() const;
115   
116   const Frame *getPrevFrame() const;
117   FrameStepper *getStepper() const;
118   FrameStepper *getNextStepper() const;
119   Walker *getWalker() const;
120   THR_ID getThread() const;
121
122   // Dyninst instrumentation constructs "synthetic" frames that don't correspond
123   // to calls. We really need to know about these...
124   // Also, signal handlers. 
125   bool nonCall() const;
126
127   ~Frame();
128 };
129
130 //Default FrameComparators, if none provided
131 typedef bool (*frame_cmp_t)(const Frame &a, const Frame &b); //Return true if a < b, by some comparison
132 bool frame_addr_cmp(const Frame &a, const Frame &b); //Default
133 bool frame_lib_offset_cmp(const Frame &a, const Frame &b);
134 bool frame_symname_cmp(const Frame &a, const Frame &b);
135 bool frame_lineno_cmp(const Frame &a, const Frame &b);
136
137 class FrameNode;
138 struct frame_cmp_wrapper {
139    frame_cmp_t f;
140    bool operator()(const FrameNode *a, const FrameNode *b);
141 };
142 typedef std::set<FrameNode *, frame_cmp_wrapper> frame_set_t;
143
144 class FrameNode {
145    friend class CallTree;
146    friend class WalkerSet;
147    friend struct frame_cmp_wrapper;
148   private:
149
150    frame_set_t children;
151    FrameNode *parent;
152    enum {
153       FTFrame,
154       FTThread,
155       FTHead
156    } frame_type;
157    Frame frame;
158    THR_ID thrd;
159    Walker *walker;
160    bool had_error;
161
162    FrameNode(frame_cmp_wrapper f);
163   public:
164    ~FrameNode();
165
166    bool isFrame() const { return frame_type == FTFrame; }
167    bool isThread() const { return frame_type == FTThread; }
168    bool isHead() const { return frame_type == FTHead; }
169
170    const Frame *getFrame() const { return (frame_type == FTFrame) ? &frame : NULL; }
171    Frame *getFrame() { return (frame_type == FTFrame) ? &frame : NULL; }
172    THR_ID getThread() const { return (frame_type == FTThread) ? thrd : NULL_LWP; }
173    bool hadError() const { return (frame_type == FTThread) ? had_error : false; }
174
175    const frame_set_t &getChildren() const { return children; }
176    frame_set_t &getChildren() { return children; }
177
178    const FrameNode *getParent() const { return parent; }
179    FrameNode *getParent() { return parent; }
180
181    Walker *getWalker() { return walker; }
182    const Walker *getWalker() const { return walker; }
183 };
184
185 class CallTree {
186    friend class WalkerSet;
187   public:
188
189    CallTree(frame_cmp_t cmpf = frame_addr_cmp);
190    ~CallTree();
191
192    FrameNode *getHead() const { return head; }
193
194    FrameNode *addFrame(const Frame &f, FrameNode *parent);
195    FrameNode *addThread(THR_ID thrd, FrameNode *parent, Walker *walker, bool err_stack);
196
197    void addCallStack(const std::vector<Frame> &stk, THR_ID thrd, Walker *walker, bool err_stack);
198   private:
199    FrameNode *head;
200    frame_cmp_wrapper cmp_wrapper;
201 };
202
203 }
204 }
205
206 #endif