StackwalkerAPI BlueGene/P support. This commit was written by Todd Gamblin at LLNL
[dyninst.git] / stackwalk / src / framestepper.C
1 /*
2  * Copyright (c) 1996-2007 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 #include "stackwalk/h/framestepper.h"
33 #include "stackwalk/h/walker.h"
34 #include "stackwalk/h/procstate.h"
35 #include "stackwalk/h/swk_errors.h"
36 #include "stackwalk/h/steppergroup.h"
37
38 #include "stackwalk/src/sw.h"
39 #include <assert.h>
40
41 #if defined(os_linux)
42 #include "stackwalk/src/linux-swk.h"
43 #endif 
44 using namespace Dyninst;
45 using namespace Dyninst::Stackwalker;
46
47 FrameStepper::FrameStepper(Walker *w) :
48   walker(w)
49 {
50   sw_printf("[%s:%u] - Creating FrameStepper %p with walker %p\n", 
51             __FILE__, __LINE__, this, walker);
52   assert(walker);
53 }
54
55 FrameStepper::~FrameStepper() 
56 {
57   walker = NULL;
58   sw_printf("[%s:%u] - Deleting FrameStepper %p\n", __FILE__, __LINE__, this);
59 }
60
61 Walker *FrameStepper::getWalker()
62 {
63   assert(walker);
64   return walker;
65 }
66
67 ProcessState *FrameStepper::getProcessState() 
68 {
69   return getWalker()->getProcessState();
70 }
71
72 void FrameStepper::newLibraryNotification(LibAddrPair *, lib_change_t)
73 {
74 }
75
76 void FrameStepper::registerStepperGroup(StepperGroup *group)
77 {
78    unsigned addr_width = group->getWalker()->getProcessState()->getAddressWidth();
79    if (addr_width == 4)
80       group->addStepper(this, 0, 0xffffffff);
81 #if defined(arch_64bit)
82    else if (addr_width == 8)
83       group->addStepper(this, 0, 0xffffffffffffffff);
84 #endif
85    else
86       assert(0 && "Unknown architecture word size");
87 }
88
89 FrameFuncStepper::FrameFuncStepper(Walker *w, FrameFuncHelper *helper) :
90    FrameStepper(w)
91 {
92    impl = new FrameFuncStepperImpl(w, this, helper);
93 }
94
95 FrameFuncStepper::~FrameFuncStepper()
96 {
97    if (impl)
98       delete impl;
99 }
100
101 gcframe_ret_t FrameFuncStepper::getCallerFrame(const Frame &in, Frame &out)
102 {
103    if (impl)
104       return impl->getCallerFrame(in, out);
105    sw_printf("[%s:%u] - Platform does not have basic stepper\n", 
106              __FILE__, __LINE__);
107    setLastError(err_unsupported, "Function frames not supported on this platform.");
108    return gcf_error;
109 }
110
111 unsigned FrameFuncStepper::getPriority() const
112 {
113    if (impl)
114       return impl->getPriority();
115    sw_printf("[%s:%u] - Platform does not have basic stepper\n", 
116              __FILE__, __LINE__);
117    setLastError(err_unsupported, "Function frames not supported on this platform.");
118    return 0;
119 }
120
121 void FrameFuncStepper::registerStepperGroup(StepperGroup *group)
122 {
123    FrameStepper::registerStepperGroup(group);
124 }
125
126 FrameFuncHelper::FrameFuncHelper(ProcessState *proc_) :
127    proc(proc_)
128 {
129 }
130
131 FrameFuncHelper::~FrameFuncHelper()
132 {
133 }
134
135 #ifndef os_bg
136 BottomOfStackStepper::BottomOfStackStepper(Walker *w) :
137    FrameStepper(w)
138 {
139    sw_printf("[%s:%u] - Constructing BottomOfStackStepper at %p\n",
140              __FILE__, __LINE__, this);
141 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
142    impl = new BottomOfStackStepperImpl(w, this);
143 #else
144    impl = NULL;
145 #endif
146 }
147
148 gcframe_ret_t BottomOfStackStepper::getCallerFrame(const Frame &in, Frame &out)
149 {
150    if (impl) {
151       return impl->getCallerFrame(in, out);
152    }
153    sw_printf("[%s:%u] - Error, top of stack not implemented on this platform\n",
154              __FILE__, __LINE__);
155    setLastError(err_unsupported, "Top of stack recognition not supported on this platform");
156    return gcf_error;
157 }
158
159 unsigned BottomOfStackStepper::getPriority() const
160 {
161    if (impl) {
162       return impl->getPriority();
163    }
164    sw_printf("[%s:%u] - Error, top of stack not implemented on this platform\n",
165              __FILE__, __LINE__);
166    setLastError(err_unsupported, "Top of stack recognition not supported on this platform");
167    return 0;
168 }
169
170 void BottomOfStackStepper::registerStepperGroup(StepperGroup *group)
171 {
172    if (impl) {
173       return impl->registerStepperGroup(group);
174    }
175    sw_printf("[%s:%u] - Error, top of stack not implemented on this platform\n",
176              __FILE__, __LINE__);
177    setLastError(err_unsupported, "Top of stack recognition not supported on this platform");
178 }
179
180 BottomOfStackStepper::~BottomOfStackStepper()
181 {
182    sw_printf("[%s:%u] - Deleting BottomOfStackStepper %p (impl %p)\n", 
183              __FILE__, __LINE__, this, impl);
184    if (impl)
185       delete impl;
186 }
187 #endif // os_bg_compute