Fixes for StackwalkerAPI on BlueGene
[dyninst.git] / external / bluegene / bgl-debugger-interface.h
1 /**
2  * We've been told by IBM that this header is no longer IBM confidential.
3  * The contents are being released and we were given premission to 
4  * redistribute this--although they never gave us the new header without
5  * this copyright.
6  **/
7
8 /* begin_generated_IBM_copyright_prolog                             */
9 /*                                                                  */
10 /* This is an automatically generated copyright prolog.             */
11 /* After initializing, DO NOT MODIFY OR MOVE                        */
12 /* ---------------------------------------------------------------- */
13 /* IBM Confidential                                                 */
14 /*                                                                  */
15 /* OCO Source Materials                                             */
16 /*                                                                  */
17 /* Product(s):                                                      */
18 /* 5733-BG1                                                         */
19 /*                                                                  */
20 /* (C)Copyright IBM Corp. 2004, 2004                                */
21 /*                                                                  */
22 /* The Source code for this program is not published or otherwise   */
23 /* divested of its trade secrets, irrespective of what has been     */
24 /* deposited with the U.S. Copyright Office.                        */
25 /*                                                                  */
26 /*                                                                  */
27 /* ---------------------------------------------------------------  */
28 /* 3/22/09 Todd Gamblin    Modified to change BGL_ prefixes so that */
29 /*                         this matches the BG/P header.  Allows us */
30 /*                         to generify BG stackwalker code.         */
31 /* ---------------------------------------------------------------  */
32 /*                                                                  */
33 /* end_generated_IBM_copyright_prolog                               */
34 #ifndef DEBUGGER_INTERFACE_H
35 #define DEBUGGER_INTERFACE_H
36 #include <stdint.h>
37 #include <stdio.h>
38 namespace DebuggerInterface {
39 #define BG_DEBUGGER_WRITE_PIPE 3
40 #define BG_DEBUGGER_READ_PIPE 4
41    // Some typedefs to insure consistency later.
42    typedef uint32_t BG_NodeNum_t; // Which compute node under an I/O node
43    typedef uint32_t BG_ThreadID_t; // Which thread in the compute node
44    typedef uint32_t BG_GPR_t; // GPRs are 32 bit unsigned
45    typedef uint32_t BG_Addr_t; // 32 bit virtual address
46    /* Register numbers
47       The value of each enum is magically the same as the offset in
48       words into the GPRSet_t structure. The system is similar to,
49       but not necessarily the same as used by ptrace.h.
50    */
51    typedef enum {
52       BG_GPR0 = 0,
53       BG_GPR1,
54       BG_GPR2,
55       BG_GPR3,
56       BG_GPR4,
57       BG_GPR5,
58       BG_GPR6,
59       BG_GPR7,
60       BG_GPR8,
61       BG_GPR9,
62       BG_GPR10,
63       BG_GPR11,
64       BG_GPR12,
65       BG_GPR13,
66       BG_GPR14,
67       BG_GPR15,
68       BG_GPR16,
69       BG_GPR17,
70       BG_GPR18,
71       BG_GPR19,
72       BG_GPR20,
73       BG_GPR21,
74       BG_GPR22,
75       BG_GPR23,
76       BG_GPR24,
77       BG_GPR25,
78       BG_GPR26,
79       BG_GPR27,
80       BG_GPR28,
81       BG_GPR29,
82       BG_GPR30,
83       BG_GPR31 = 31,
84       BG_FPSCR = 32,
85       BG_LR = 33,
86       BG_CR = 34,
87       BG_XER = 35,
88       BG_CTR = 36,
89       BG_IAR = 37,
90       BG_MSR = 38,
91       BG_DEAR = 39,
92       BG_ESR = 40
93    } BG_GPR_Num_t;
94    /* Floating point register numbers
95       We have 'double hummer'. We will pretend that we have 32 registers,
96       each 128 bits (4 words) wide. Once again, the enum value is the
97       offset into the FPRSet_t struct.
98    */
99    typedef enum {
100       BG_FPR0 = 0,
101       BG_FPR1,
102       BG_FPR2,
103       BG_FPR3,
104       BG_FPR4,
105       BG_FPR5,
106       BG_FPR6,
107       BG_FPR7,
108       BG_FPR8,
109       BG_FPR9,
110       BG_FPR10,
111       BG_FPR11,
112       BG_FPR12,
113       BG_FPR13,
114       BG_FPR14,
115       BG_FPR15,
116       BG_FPR16,
117       BG_FPR17,
118       BG_FPR18,
119       BG_FPR19,
120       BG_FPR20,
121       BG_FPR21,
122       BG_FPR22,
123       BG_FPR23,
124       BG_FPR24,
125       BG_FPR25,
126       BG_FPR26,
127       BG_FPR27,
128       BG_FPR28,
129       BG_FPR29,
130       BG_FPR30,
131       BG_FPR31 = 31
132    } BG_FPR_Num_t;
133    /* MsgType
134       This doesn't match the ptrace interface very well.
135       Ptrace doesn't define most of these primitives.
136       Therefore, the enums are completely arbitrary.
137       Notice that except for SIGNAL_ENCOUNTERED, each
138       request from the debugger has a corresponding
139       acknowledgement message.
140    */
141    typedef enum { GET_REG,
142                   GET_ALL_REGS, // request gprs and other non-fp regs
143                   SET_REG, // set a specific register
144                   GET_MEM, // get memory values
145                   SET_MEM, // set memory
146                   GET_FLOAT_REG, //5
147                   GET_ALL_FLOAT_REGS,
148                   SET_FLOAT_REG,
149                   SINGLE_STEP, // step one instruction
150                   CONTINUE, // tell compute node to continue running
151                   KILL, // 10 send a signal w/ implicit continue
152                   ATTACH, // mark compute node
153                   DETACH, // unmark compute node
154                   GET_REG_ACK,
155                   GET_ALL_REGS_ACK, // sent when compute node responds
156                   SET_REG_ACK, // 15 send when compute node responds
157                   GET_MEM_ACK, // sent when compute node responds
158                   SET_MEM_ACK, // sent when compute node responds
159                   GET_FLOAT_REG_ACK,
160                   GET_ALL_FLOAT_REGS_ACK,
161                   SET_FLOAT_REG_ACK, //20
162                   SINGLE_STEP_ACK, // sent when compute node completes step
163                   CONTINUE_ACK, // sent when compute node is told
164                   KILL_ACK, // send when signal is sent
165                   ATTACH_ACK, // sent after compute node is marked
166                   DETACH_ACK, // 25 sent after compute node is unmarked
167                   SIGNAL_ENCOUNTERED, // sent when a signal is encountered
168                   PROGRAM_EXITED, // with implicit detach
169                   VERSION_MSG,
170                   VERSION_MSG_ACK,
171                   GET_DEBUG_REGS, //30
172                   GET_DEBUG_REGS_ACK,
173                   SET_DEBUG_REGS,
174                   SET_DEBUG_REGS_ACK,
175                   THIS_SPACE_FOR_RENT
176    } BG_MsgType_t;
177    extern const char *BG_Packet_Names[];
178    /* GPRSet_t
179       This is the set of general purpose registers.
180    */
181    typedef struct {
182       uint32_t gpr[32]; // gprs
183       uint32_t fpscr; // fpscr
184       uint32_t lr; // link
185       uint32_t cr; // condition reg
186       uint32_t xer; // xer
187       uint32_t ctr; // count register
188       uint32_t iar; // pc
189       uint32_t msr; // machine status register
190       uint32_t dear; // data exception address register
191       uint32_t esr; // exception syndrome register
192    } BG_GPRSet_t;
193    /* FPRSet_t
194       Our FPRs are a little bit different because of the double hummer.
195       We actually have 2 sets of FPRs.
196       The convention that we'll use is to treat the FPRs as one set of
197       32, with each FPR being four words instead of two.
198    */
199    typedef struct {
200       uint32_t w0; // First word of FPR in first FPR set
201       uint32_t w1; // Second word of FPR in first FPR set
202       uint32_t w2; // First word of FPR in second FPR set
203       uint32_t w3; // Second word of FPR in second FPR set
204    } BG_FPR_t;
205    typedef struct {
206       BG_FPR_t fprs[32];
207    } BG_FPRSet_t;
208    typedef struct {
209       uint32_t DBCR0; // Debug Control Register 0
210       uint32_t DBCR1; // Debug Control Register 1
211       uint32_t DBCR2; // Debug Control Register 2
212       uint32_t DBSR; // Debug Status Register
213       uint32_t IAC1; // Instruction Address Compare Register 1
214       uint32_t IAC2; // Instruction Address Compare Register 2
215       uint32_t IAC3; // Instruction Address Compare Register 3
216       uint32_t IAC4; // Instruction Address Compare Register 4
217       uint32_t DAC1; // Data Address Compare Register 1
218       uint32_t DAC2; // Data Address Compare Register 2
219       uint32_t DVC1; // Data Value Compare Register 1
220       uint32_t DVC2; // Data Value Compare Register 2
221    } BG_DebugSet_t;
222    typedef enum {
223       RC_NO_ERROR = 0,
224       RC_NOT_ATTACHED = 1,
225       RC_NOT_RUNNING = 2,
226       RC_BAD_NODE = 3,
227       RC_BAD_THREAD = 4,
228       RC_BAD_COMMAND = 5,
229       RC_BAD_REGISTER = 6,
230       RC_NOT_APP_SPACE = 7,
231       RC_LEN_TOO_LONG = 8,
232       RC_DENIED = 9,
233       RC_BAD_SIGNAL = 10,
234       RC_NOT_STOPPED = 11
235    } BG_ErrorCode_t;
236    /* Debugger_Msg_t
237       This is the packet header for the pipe. All messages use this.
238       messageType is self explanatory
239       nodeNumber is the target compute node
240       thread is the thread on the compute node
241       sequence can be used to keep track of packet flow
242       returnCode might be needed
243       dataLength is the size in chars of the payload
244       The 'payload' should follow the message header, and be received
245       into a buffer of size dataLength.
246       Not all messages have payloads. If your message doesn't have
247       a payload, set dataLength to 0.
248       'sequence' is probably best used as a 'packet count' or a sequence
249       number. This way you can match acknowledgement packets with the
250       original packet if things aren't being done in lockstep.
251       'returnCode' isn't architected yet, but we probably need it. If your
252       GET_MEM request fails how else will you know?
253       'dataStartsHere' is a placeholder. As a result, to get the true size
254       of this data structure you have to subtract 1 byte.
255    */
256 #define BG_Debugger_Msg_MAX_SIZE 4096
257 #define BG_Debugger_Msg_HEADER_SIZE 24
258 #define BG_Debugger_Msg_MAX_PAYLOAD_SIZE (BG_Debugger_Msg_MAX_SIZE-BG_Debugger_Msg_HEADER_SIZE)
259 #define BG_Debugger_Msg_MAX_MEM_SIZE 4064
260    class BG_Debugger_Msg {
261    public:
262       typedef struct {
263          BG_MsgType_t messageType;
264          BG_NodeNum_t nodeNumber;
265          BG_ThreadID_t thread;
266          uint32_t sequence;
267          uint32_t returnCode;
268          uint32_t dataLength; // excluding this header
269       } Header;
270       Header header;
271       typedef union {
272          struct {
273             BG_GPR_Num_t registerNumber;
274          } GET_REG;
275          struct {
276             BG_GPR_Num_t registerNumber;
277             BG_GPR_t value;
278          } GET_REG_ACK;
279          struct {
280          } GET_ALL_REGS;
281          struct {
282             BG_GPRSet_t gprs;
283          } GET_ALL_REGS_ACK;
284          struct {
285             BG_GPR_Num_t registerNumber;
286             BG_GPR_t value;
287          } SET_REG;
288          struct {
289             BG_GPR_Num_t registerNumber;
290          } SET_REG_ACK;
291          struct {
292             BG_Addr_t addr;
293             uint32_t len;
294          } GET_MEM;
295          struct {
296             BG_Addr_t addr;
297             uint32_t len;
298             unsigned char data[BG_Debugger_Msg_MAX_MEM_SIZE];
299          } GET_MEM_ACK;
300          struct {
301             BG_Addr_t addr;
302             uint32_t len;
303             unsigned char data[BG_Debugger_Msg_MAX_MEM_SIZE];
304          } SET_MEM;
305          struct {
306             BG_Addr_t addr;
307             uint32_t len;
308          } SET_MEM_ACK;
309          struct {
310             BG_FPR_Num_t registerNumber;
311          } GET_FLOAT_REG;
312          struct {
313             BG_FPR_Num_t registerNumber;
314             BG_FPR_t value;
315          } GET_FLOAT_REG_ACK;
316          struct {
317          } GET_ALL_FLOAT_REGS;
318          struct {
319             BG_FPRSet_t fprs;
320          } GET_ALL_FLOAT_REGS_ACK;
321          struct {
322             BG_FPR_Num_t registerNumber;
323             BG_FPR_t value;
324          } SET_FLOAT_REG;
325          struct {
326             BG_FPR_Num_t registerNumber;
327          } SET_FLOAT_REG_ACK;
328          struct {
329          } SINGLE_STEP;
330          struct {
331          } SINGLE_STEP_ACK;
332          struct {
333             uint32_t signal;
334          } CONTINUE;
335          struct {
336          } CONTINUE_ACK;
337          struct {
338             uint32_t signal;
339          } KILL;
340          struct {
341          } KILL_ACK;
342          struct {
343          } ATTACH;
344          struct {
345          } ATTACH_ACK;
346          struct {
347          } DETACH;
348          struct {
349          } DETACH_ACK;
350          struct {
351             uint32_t signal;
352          } SIGNAL_ENCOUNTERED;
353          struct {
354             int32_t type; // 0 = exit, 1 = signal
355             int32_t rc;
356          } PROGRAM_EXITED;
357          struct {
358          } VERSION_MSG;
359          struct {
360             uint32_t protocolVersion;
361             uint32_t numPhysicalProcessors;
362             uint32_t numLogicalProcessors;
363          } VERSION_MSG_ACK;
364          struct {
365          } GET_DEBUG_REGS;
366          struct {
367             BG_DebugSet_t debugRegisters;
368          } GET_DEBUG_REGS_ACK;
369          struct {
370             BG_DebugSet_t debugRegisters;
371          } SET_DEBUG_REGS;
372          struct {
373          } SET_DEBUG_REGS_ACK;
374          unsigned char dataStartsHere;
375       } DataArea;
376       DataArea dataArea;
377       // Ctor
378       BG_Debugger_Msg( void ) { header.messageType = THIS_SPACE_FOR_RENT; }
379       BG_Debugger_Msg( BG_MsgType_t type,
380                         BG_NodeNum_t node,
381                         BG_ThreadID_t thread,
382                         uint32_t sequence,
383                         uint32_t returnCode )
384          {
385             header.messageType = type;
386             header.nodeNumber = node;
387             header.thread = thread;
388             header.sequence = sequence;
389             header.returnCode = returnCode;
390          }
391       static BG_Debugger_Msg generateErrorPacket( BG_Debugger_Msg &original, BG_ErrorCode_t ec );
392       static void dump( BG_Debugger_Msg &msg );
393       static void dump( BG_Debugger_Msg &msg, FILE *outfile );
394
395       static bool writeOnFd(int fd, BG_Debugger_Msg &msg)
396       {
397         int result;
398         result = write(fd, &msg.header, sizeof(msg.header));
399         if (result != -1) {
400           result = write(fd, &msg.dataArea, msg.header.dataLength);
401         }
402         
403         return (result != -1);
404       }
405       
406       static bool readFromFd(int fd, BG_Debugger_Msg &msg)
407       {
408         int result;
409         result = read(fd, &msg.header, sizeof(msg.header));
410         if (result != -1 && msg.header.dataLength) {
411           result = read(fd, &msg.dataArea, msg.header.dataLength);
412         }
413         return (result != -1);
414       }
415      
416       static const char *getMessageName(BG_MsgType_t type)
417       {
418         static const char *BG_Packet_Names[] = 
419           {
420             "GET_REG",
421             "GET_ALL_REGS",
422             "SET_REG",
423             "GET_MEM", 
424             "SET_MEM", 
425             "GET_FLOAT_REG",
426             "GET_ALL_FLOAT_REGS",
427             "SET_FLOAT_REG",
428             "SINGLE_STEP",
429             "CONTINUE",
430             "KILL", 
431             "ATTACH",
432             "DETACH",
433             "GET_REG_ACK",
434             "GET_ALL_REGS_ACK",
435             "SET_REG_ACK", 
436             "GET_MEM_ACK", 
437             "SET_MEM_ACK", 
438             "GET_FLOAT_REG_ACK",
439             "GET_ALL_FLOAT_REGS_ACK",
440             "SET_FLOAT_REG_ACK", 
441             "SINGLE_STEP_ACK", 
442             "CONTINUE_ACK", 
443             "KILL_ACK", 
444             "ATTACH_ACK", 
445             "DETACH_ACK", 
446             "SIGNAL_ENCOUNTERED",
447             "PROGRAM_EXITED",
448             "VERSION_MSG",
449             "VERSION_MSG_ACK",
450             "GET_DEBUG_REGS",
451             "GET_DEBUG_REGS_ACK",
452             "SET_DEBUG_REGS",
453             "SET_DEBUG_REGS_ACK",
454             "THIS_SPACE_FOR_RENT"
455           };
456   
457         if ((type >= GET_REG) && (type < THIS_SPACE_FOR_RENT)) {
458           return BG_Packet_Names[type];
459         }
460         else {
461           return "UNKNOWN";
462         }
463       }
464    };
465 }
466
467 #endif // DEBUGGER_INTERFACE_H