StackwalkerAPI BlueGene/P support. This commit was written by Todd Gamblin at LLNL
[dyninst.git] / stackwalk / src / bluegene-swk.h
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 #ifndef BLUEGENE_SWK_H
33 #define BLUEGENE_SWK_H
34
35 #include "procstate.h"
36 #include "stl_utils.h"
37
38 #ifndef os_bg_ion
39 #error "ERROR: bluegene-swk.h is only for BlueGene ION builds."
40 #endif // os_bg_ion
41
42 // TODO: these bg debugger headers could be merged w/ifdefs in the headers.
43 // TODO: this would make things a little less nasty here.
44 #if   defined(os_bgl)
45 #include "external/bluegene/bgl-debugger-interface.h"
46 #elif defined (os_bgp)
47 #include "external/bluegene/bgp-debugger-interface.h"
48 #else
49 #error "ERROR: No suitable debug interface for this BG ION."
50 #endif
51
52 #define SINGLE_STEP_SIG 32064
53
54 #if !defined(BG_READCACHE_SIZE)
55 #define BG_READCACHE_SIZE 2048
56 #endif
57
58 namespace DebuggerInterface {
59   class DebugEvent;
60 }
61
62 namespace Dyninst {
63   namespace Stackwalker {
64     
65     ///
66     /// This is a base class for the BlueGene 3rd-party stackwalkers.  
67     /// 
68     /// Common functionality is implemented here, and subclasses should
69     /// provide other features such as threads and dynamic library handling.
70     ///
71     class ProcDebugBG : public ProcDebug {
72     protected:
73       virtual bool debug_continue(ThreadState *);
74       virtual bool version_msg();
75       virtual bool debug_waitfor_version_msg();
76       virtual bool debug_handle_event(DebugEvent ev);
77       virtual bool debug_handle_signal(DebugEvent *ev);
78       virtual bool debug_attach(ThreadState *);
79       virtual bool debug_pause(ThreadState *);
80       virtual bool debug_continue_with(ThreadState *, long sig);
81       virtual bool debug_version_msg();
82
83       // default implementation: this is a no-op.  Subclasses should override.
84       virtual bool pollForNewThreads();
85
86       // unsupported -- stub will fail!
87       virtual bool debug_create(const std::string &, const std::vector<std::string> &);
88
89       ///
90       /// This implements basic BG debugger event -> stackwalker event translation.  It's
91       /// called by the BG implementation of ProcDebug::debug_get_event().
92       /// 
93       /// Subclasses (future BG architecture implementations) should override to handle new 
94       /// event types, then delegate here to handle old ones.
95       ///
96       friend DebugEvent ProcDebug::debug_get_event(bool);
97       virtual void translate_event(const DebuggerInterface::BG_Debugger_Msg& msg, 
98                                    DebugEvent& ev);
99
100       /// BG currently has no asynchronous thread control, so the threads are stopped and
101       /// continued all together.  This applies operations to all threads.
102       template<class Functor> void for_all_threads(Functor f) {
103         for_each(threads.begin(), threads.end(), do_to_second(f));
104       }
105
106     public:
107       virtual bool detach(bool leave_stopped);
108       virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads);
109       virtual bool getDefaultThread(Dyninst::THR_ID &default_tid);
110       virtual unsigned getAddressWidth();
111       virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val);
112       virtual bool readMem(void *dest, Dyninst::Address source, size_t size);
113       virtual bool isLibraryTrap(Dyninst::THR_ID thrd);
114       
115     protected:
116       ProcDebugBG(Dyninst::PID pid, std::string exe);
117       virtual ~ProcDebugBG();
118
119       /// Creation function for making platform-specific ProcDebugBG
120       /// Need to include an implementation of this in any build that includes 
121       /// ProcDebugBG.
122       static ProcDebug *createProcDebugBG(PID pid, const std::string& executable);
123
124       /// Clears this process's memory read cache along with register caches 
125       /// from all of its threads.
126       virtual void clear_cache();
127
128       // Protected Data
129       DebuggerInterface::BG_Debugger_Msg::DataArea *mem_data;    // data from memory reads.
130
131       unsigned char *read_cache;
132       Dyninst::Address read_cache_start;
133       unsigned read_cache_size;
134     };
135
136     // helper for dealing with filehandles
137     bool bg_fdHasData(int fd);
138
139     //
140     // Like a regular ThreadState, but with a per-thread register cache.
141     // Also porvides ability to set thread id to account for the way the 
142     // BG debug interface handles threads.
143     //
144     class BGThreadState : public ThreadState {
145     private:
146       friend class ProcDebug;
147       void setTid(Dyninst::THR_ID id) { tid = id; }
148
149     public:
150       BGThreadState(ProcDebug *parent, Dyninst::THR_ID id) 
151         : ThreadState(parent, id), gprs_set(false) 
152       { }
153
154       virtual ~BGThreadState() { }
155
156       DebuggerInterface::BG_GPRSet_t gprs;   // Per-thread register cache.
157       bool gprs_set;                         // Valid flag for register cache.
158     };
159
160     /// Copy one thread's state to another.  
161     void copy_thread_state(ThreadState *source, ThreadState *dest);
162
163   } // Stackwalker
164 } // Dyninst
165
166 #endif // BLUEGENE_SWK_H