Adapting Object-elf.C
[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 SW_EXPORT bool frame_addr_cmp(const Frame &a, const Frame &b); //Default
133 SW_EXPORT bool frame_lib_offset_cmp(const Frame &a, const Frame &b);
134 SW_EXPORT bool frame_symname_cmp(const Frame &a, const Frame &b);
135 SW_EXPORT bool frame_lineno_cmp(const Frame &a, const Frame &b);
136
137 class FrameNode;
138 struct SW_EXPORT frame_cmp_wrapper {
139    frame_cmp_t f;
140    bool operator()(const FrameNode *a, const FrameNode *b) const;
141 };
142 typedef std::set<FrameNode *, frame_cmp_wrapper> frame_set_t;
143
144 class SW_EXPORT 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       FTString,
156       FTHead
157    } frame_type;
158    Frame frame;
159    THR_ID thrd;
160    Walker *walker;
161    bool had_error;
162    std::string ftstring;
163
164    FrameNode(frame_cmp_wrapper f);
165   public:
166    ~FrameNode();
167
168    FrameNode(frame_cmp_wrapper f, std::string s);
169    FrameNode(const FrameNode &fn);
170    bool isFrame() const { return frame_type == FTFrame; }
171    bool isThread() const { return frame_type == FTThread; }
172    bool isHead() const { return frame_type == FTHead; }
173    bool isString() const { return frame_type == FTString; }
174
175    const Frame *getFrame() const { return (frame_type == FTFrame) ? &frame : NULL; }
176    Frame *getFrame() { return (frame_type == FTFrame) ? &frame : NULL; }
177    THR_ID getThread() const { return (frame_type == FTThread) ? thrd : NULL_LWP; }
178    std::string frameString() const { return ftstring; }
179    bool hadError() const { return (frame_type == FTThread) ? had_error : false; }
180
181    const frame_set_t &getChildren() const { return children; }
182    frame_set_t &getChildren() { return children; }
183
184    const FrameNode *getParent() const { return parent; }
185    FrameNode *getParent() { return parent; }
186
187    void addChild(FrameNode *fn) { children.insert(fn); fn->parent = this; }
188    
189    Walker *getWalker() { return walker; }
190    const Walker *getWalker() const { return walker; }
191 };
192
193 class SW_EXPORT CallTree {
194    friend class WalkerSet;
195   public:
196
197    CallTree(frame_cmp_t cmpf = frame_addr_cmp);
198    ~CallTree();
199
200    FrameNode *getHead() const { return head; }
201
202    FrameNode *addFrame(const Frame &f, FrameNode *parent);
203    FrameNode *addThread(THR_ID thrd, FrameNode *parent, Walker *walker, bool err_stack);
204    frame_cmp_t getComparator();
205    frame_cmp_wrapper getCompareWrapper();
206
207    void addCallStack(const std::vector<Frame> &stk, THR_ID thrd, Walker *walker, bool err_stack);
208   private:
209    FrameNode *head;
210    frame_cmp_wrapper cmp_wrapper;
211 };
212
213 }
214 }
215
216 #endif