Infrastructure for SW CallTrees and group operations
[dyninst.git] / stackwalk / h / frame.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 FRAME_H_
33 #define FRAME_H_
34
35 #include "basetypes.h"
36 #include "Annotatable.h"
37 #include <string>
38 #include <set>
39
40 namespace Dyninst {
41 namespace Stackwalker {
42
43 class Walker;
44 class FrameStepper;
45
46 class Frame : public AnnotatableDense {
47   friend class Walker;
48   friend class CallTree;
49 protected:
50   Dyninst::MachRegisterVal ra;
51   Dyninst::MachRegisterVal fp;
52   Dyninst::MachRegisterVal sp;
53         
54   location_t ra_loc;
55   location_t fp_loc;
56   location_t sp_loc;
57   
58   mutable std::string sym_name;
59   mutable void *sym_value;
60   mutable enum { nv_unset, nv_set, nv_err } name_val_set;
61   
62   bool top_frame;
63   bool bottom_frame;
64   bool frame_complete;
65   
66   const Frame *prev_frame;
67   FrameStepper *stepper;
68   FrameStepper *next_stepper;
69   Walker *walker;
70   THR_ID originating_thread;
71   
72   void setStepper(FrameStepper *newstep);
73   void setWalker(Walker *newwalk);
74   void markTopFrame();
75   void markBottomFrame();
76   
77   void setNameValue() const;
78   
79  public:
80   Frame();
81   Frame(Walker *walker);
82   static Frame *newFrame(Dyninst::MachRegisterVal ra, Dyninst::MachRegisterVal sp, Dyninst::MachRegisterVal fp, Walker *walker);
83
84   bool operator==(const Frame &F) const;
85
86   Dyninst::MachRegisterVal getRA() const;
87   Dyninst::MachRegisterVal getSP() const;
88   Dyninst::MachRegisterVal getFP() const;
89   
90   void setRA(Dyninst::MachRegisterVal);
91   void setSP(Dyninst::MachRegisterVal);
92   void setFP(Dyninst::MachRegisterVal);
93   void setThread(THR_ID);
94   
95   location_t getRALocation() const;
96   location_t getSPLocation() const;
97   location_t getFPLocation() const;
98   
99   void setRALocation(location_t newval);
100   void setSPLocation(location_t newval);
101   void setFPLocation(location_t newval);
102   
103   bool getName(std::string &str) const;
104   bool getObject(void* &obj) const;
105   bool getLibOffset(std::string &lib, Dyninst::Offset &offset, void* &symtab) const;
106   
107   bool isTopFrame() const;
108   bool isBottomFrame() const;
109   bool isFrameComplete() const;
110   
111   const Frame *getPrevFrame() const;
112   FrameStepper *getStepper() const;
113   FrameStepper *getNextStepper() const;
114   Walker *getWalker() const;
115   THR_ID getThread() const;
116
117   ~Frame();
118 };
119
120 //Default FrameComparators, if none provided
121 typedef bool (*frame_cmp_t)(const Frame &a, const Frame &b); //Return true if a < b, by some comparison
122 bool frame_addr_cmp(const Frame &a, const Frame &b); //Default
123 bool frame_lib_offset_cmp(const Frame &a, const Frame &b);
124 bool frame_symname_cmp(const Frame &a, const Frame &b);
125 bool frame_lineno_cmp(const Frame &a, const Frame &b);
126
127 class FrameNode;
128 struct frame_cmp_wrapper {
129    frame_cmp_t f;
130    bool operator()(const FrameNode *a, const FrameNode *b);
131 };
132 typedef std::set<FrameNode *, frame_cmp_wrapper> frame_set_t;
133
134 class FrameNode {
135    friend class CallTree;
136    friend class WalkerSet;
137    friend struct frame_cmp_wrapper;
138   public:
139
140    frame_set_t children;
141    FrameNode *parent;
142    enum {
143       FTFrame,
144       FTThread,
145       FTHead
146    } frame_type;
147    Frame frame;
148    THR_ID thrd;
149
150    FrameNode(frame_cmp_wrapper f);
151   public:
152    ~FrameNode();
153
154    bool isFrame() const { return frame_type == FTFrame; }
155    bool isThread() const { return frame_type == FTThread; }
156    bool isHead() const { return frame_type == FTHead; }
157
158    const Frame *getFrame() const { return (frame_type == FTFrame) ? &frame : NULL; }
159    Frame *getFrame() { return (frame_type == FTFrame) ? &frame : NULL; }
160    THR_ID getThread() const { return (frame_type == FTThread) ? thrd : NULL_LWP; }
161
162    const frame_set_t &getChildren() const { return children; }
163    frame_set_t &getChildren() { return children; }
164
165    const FrameNode *getParent() const { return parent; }
166    FrameNode *getParent() { return parent; }
167 };
168
169 class CallTree {
170    friend class WalkerSet;
171   public:
172
173    CallTree(frame_cmp_t cmpf = frame_addr_cmp);
174    ~CallTree();
175
176    FrameNode *getHead() const { return head; }
177
178    FrameNode *addFrame(const Frame &f, FrameNode *parent);
179    FrameNode *addThread(THR_ID thrd, FrameNode *parent);
180
181    void addCallStack(const std::vector<Frame> &stk, THR_ID thrd);
182   private:
183    FrameNode *head;
184    frame_cmp_wrapper cmp_wrapper;
185 };
186
187 }
188 }
189
190 #endif