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