ProcControlAPI BG fixes
[dyninst.git] / external / bluegene / bgp-debugger-interface.h
1 /* begin_generated_IBM_copyright_prolog                             */
2 /*                                                                  */
3 /* This is an automatically generated copyright prolog.             */
4 /* After initializing,  DO NOT MODIFY OR MOVE                       */
5 /*  --------------------------------------------------------------- */
6 /*                                                                  */
7 /* (C) Copyright IBM Corp.  2004, 2009                              */
8 /* IBM CPL License                                                  */
9 /*                                                                  */
10 /*  --------------------------------------------------------------- */
11 /*                                                                  */
12 /* end_generated_IBM_copyright_prolog                               */
13
14 #ifndef CIODEBUGGERPROTOCOL_H
15 #define CIODEBUGGERPROTOCOL_H
16
17 #include <stdint.h>
18 #include <stdio.h>
19 #include <time.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <signal.h>
24 #include <bpcore/bgp_types.h>
25
26 //Printf wrapping added for ProcControlAPI
27 #define fprintf wrap_fprintf
28
29 namespace DebuggerInterface {
30
31 /*
32    Protocol Version Change Log:
33    1 - Initial implementation
34    2 - Thread id passed in message header to reduce message traffic
35    3 - Added GET_STACK_TRACE and END_DEBUG messages, Signal for detach from nodes
36    4-  Added GET_PROCESS_DATA and GET_THREAD_DATA messages
37    5 - Added HOLD_THREAD, RELEASE_THREAD, SIGACTION, MAP_MEM and FAST_TRAP messages
38    6 - Added debugger ignore sinal function - DEBUG_IGNORE_SIG message
39 */
40 #define BG_Debugger_PROTOCOL_VERSION 6
41
42 #define BG_DEBUGGER_WRITE_PIPE 3
43 #define BG_DEBUGGER_READ_PIPE  4
44 #define BG_PIPE_TIMEOUT 10
45
46 // Max threads passed on get active threads at one time
47 #define BG_Debugger_MAX_THREAD_IDS   32
48
49 //! Buffer size for GET_AUX_VECTORS request
50 #define BG_Debugger_AUX_VECS_BUFFER 1024
51
52 //! Number of stack frames returned from compute node
53 #define BG_Debugger_MAX_STACK_FRAMES 400 
54
55
56 // Some typedefs to insure consistency later.
57
58 typedef uint32_t BG_NodeNum_t;    // Which compute node under an I/O node
59 typedef uint32_t BG_ThreadID_t;   // Which thread in the compute node
60 typedef uint32_t BG_GPR_t;        // GPRs are 32 bit unsigned
61 typedef uint32_t BG_Addr_t;       // 32 bit virtual address
62
63
64
65 /* Register numbers
66
67    The value of each enum is magically the same as the offset in
68    words into the GPRSet_t structure.  The system is similar to,
69    but not necessarily the same as used by ptrace.h.
70  
71 */
72
73 typedef enum {
74
75   BG_GPR0 = 0,
76   BG_GPR1,
77   BG_GPR2,
78   BG_GPR3,
79   BG_GPR4,
80   BG_GPR5,
81   BG_GPR6,
82   BG_GPR7,
83   BG_GPR8,
84   BG_GPR9,
85   BG_GPR10,
86   BG_GPR11,
87   BG_GPR12,
88   BG_GPR13,
89   BG_GPR14,
90   BG_GPR15,
91   BG_GPR16,
92   BG_GPR17,
93   BG_GPR18,
94   BG_GPR19,
95   BG_GPR20,
96   BG_GPR21,
97   BG_GPR22,
98   BG_GPR23,
99   BG_GPR24,
100   BG_GPR25,
101   BG_GPR26,
102   BG_GPR27,
103   BG_GPR28,
104   BG_GPR29,
105   BG_GPR30,
106   BG_GPR31 = 31,
107
108   BG_FPSCR      = 32,
109   BG_LR         = 33,
110   BG_CR         = 34,
111   BG_XER        = 35,
112   BG_CTR        = 36,
113   BG_IAR        = 37,
114   BG_MSR        = 38,
115   BG_DEAR       = 39,
116   BG_ESR        = 40
117
118 } BG_GPR_Num_t;
119
120
121
122
123
124 /* Floating point register numbers
125
126    We have 'double hummer'.  We will pretend that we have 32 registers,
127    each 128 bits (4 words) wide.  Once again, the enum value is the
128    offset into the FPRSet_t struct.
129
130 */
131
132 typedef enum {
133
134   BG_FPR0 = 0,
135   BG_FPR1,
136   BG_FPR2,
137   BG_FPR3,
138   BG_FPR4,
139   BG_FPR5,
140   BG_FPR6,
141   BG_FPR7,
142   BG_FPR8,
143   BG_FPR9,
144   BG_FPR10,
145   BG_FPR11,
146   BG_FPR12,
147   BG_FPR13,
148   BG_FPR14,
149   BG_FPR15,
150   BG_FPR16,
151   BG_FPR17,
152   BG_FPR18,
153   BG_FPR19,
154   BG_FPR20,
155   BG_FPR21,
156   BG_FPR22,
157   BG_FPR23,
158   BG_FPR24,
159   BG_FPR25,
160   BG_FPR26,
161   BG_FPR27,
162   BG_FPR28,
163   BG_FPR29,
164   BG_FPR30,
165   BG_FPR31 = 31
166
167 } BG_FPR_Num_t;
168
169
170 /* MsgType
171
172    This doesn't match the ptrace interface very well.
173    Ptrace doesn't define most of these primitives.
174    Therefore, the enums are completely arbitrary.
175
176    Notice that except for SIGNAL_ENCOUNTERED, each
177    request from the debugger has a corresponding
178    acknowledgement message.
179
180 */
181
182 typedef enum { GET_REG = 0,
183                GET_ALL_REGS,            // request gprs and other non-fp regs 
184                SET_REG,                 // set a specific register
185                GET_MEM,                 // get memory values
186                SET_MEM,                 // set memory
187                GET_FLOAT_REG,
188                GET_ALL_FLOAT_REGS,
189                SET_FLOAT_REG,
190                SINGLE_STEP,             // step one instruction
191                CONTINUE,                // tell compute node to continue running
192                KILL,                    // send a signal w/ implicit continue
193                ATTACH,                  // mark compute node
194                DETACH,                  // unmark compute node
195
196                GET_REG_ACK,
197                GET_ALL_REGS_ACK,        // sent when compute node responds
198                SET_REG_ACK,             // send when compute node responds
199                GET_MEM_ACK,             // sent when compute node responds
200                SET_MEM_ACK,             // sent when compute node responds
201                GET_FLOAT_REG_ACK,
202                GET_ALL_FLOAT_REGS_ACK,
203                SET_FLOAT_REG_ACK,
204                SINGLE_STEP_ACK,         // sent when compute node completes step
205                CONTINUE_ACK,            // sent when compute node is told
206                KILL_ACK,                // send when signal is sent
207                ATTACH_ACK,              // sent after compute node is marked
208                DETACH_ACK,              // sent after compute node is unmarked
209
210                SIGNAL_ENCOUNTERED,      // sent when a signal is encountered
211
212                PROGRAM_EXITED,          // with implicit detach
213
214                VERSION_MSG,
215                VERSION_MSG_ACK,
216
217                GET_DEBUG_REGS,
218                GET_DEBUG_REGS_ACK,
219
220                SET_DEBUG_REGS,
221                SET_DEBUG_REGS_ACK,
222
223                GET_THREAD_INFO,
224                GET_THREAD_INFO_ACK,
225                THREAD_ALIVE,
226                THREAD_ALIVE_ACK,
227                GET_THREAD_ID,
228                GET_THREAD_ID_ACK,
229                SET_THREAD_OPS,
230                SET_THREAD_OPS_ACK,
231
232                GET_REGS_AND_FLOATS,  // Get regs and floating point registers
233                GET_REGS_AND_FLOATS_ACK,  // sent when compute node responds
234
235                GET_AUX_VECTORS,  // Request to get the aux vectors
236                GET_AUX_VECTORS_ACK, // Send when compute node responds 
237               
238                GET_STACK_TRACE,  // Request to get the stack traceback
239                GET_STACK_TRACE_ACK,  // Sent when compute node responds
240
241                END_DEBUG,  // Indicate done debugging
242                END_DEBUG_ACK,  // Sent when CIOD acknowledges ending of debug
243
244                GET_PROCESS_DATA,
245                GET_PROCESS_DATA_ACK,
246
247                GET_THREAD_DATA,
248                GET_THREAD_DATA_ACK,
249
250                HOLD_THREAD,
251                HOLD_THREAD_ACK,
252
253                RELEASE_THREAD,
254                RELEASE_THREAD_ACK,
255
256                SIGACTION,
257                SIGACTION_ACK,
258
259                MAP_MEM,
260                MAP_MEM_ACK,
261
262                FAST_TRAP,
263                FAST_TRAP_ACK,
264
265                DEBUG_IGNORE_SIG,
266                DEBUG_IGNORE_SIG_ACK,
267
268                THIS_SPACE_FOR_RENT
269
270 } BG_MsgType_t;
271
272
273 /* GPRSet_t
274
275    This is the set of general purpose registers.
276
277 */
278
279 typedef struct {
280
281   uint32_t gpr[32];     // gprs
282   uint32_t fpscr;       // fpscr
283   uint32_t lr;          // link
284   uint32_t cr;          // condition reg
285   uint32_t xer;         // xer
286   uint32_t ctr;         // count register
287   uint32_t iar;         // pc
288   uint32_t msr;         // machine status register
289   uint32_t dear;        // data exception address register
290   uint32_t esr;         // exception syndrome register
291   
292 } BG_GPRSet_t;
293
294
295
296 /* FPRSet_t
297
298    Our FPRs are a little bit different because of the double hummer.
299    We actually have 2 sets of FPRs.
300
301    The convention that we'll use is to treat the FPRs as one set of
302    32, with each FPR being four words instead of two.
303
304 */
305
306
307 typedef struct {
308   uint32_t w0;    // First word of FPR in first FPR set
309   uint32_t w1;    // Second word of FPR in first FPR set
310   uint32_t w2;    // First word of FPR in second FPR set
311   uint32_t w3;    // Second word of FPR in second FPR set
312 } BG_FPR_t;
313
314 typedef struct {
315   BG_FPR_t fprs[32];
316 } BG_FPRSet_t;
317
318
319
320 typedef struct {
321   uint32_t DBCR0;    // Debug Control Register 0
322   uint32_t DBCR1;    // Debug Control Register 1
323   uint32_t DBCR2;    // Debug Control Register 2
324   uint32_t DBSR;     // Debug Status Register
325   uint32_t IAC1;     // Instruction Address Compare Register 1
326   uint32_t IAC2;     // Instruction Address Compare Register 2
327   uint32_t IAC3;     // Instruction Address Compare Register 3
328   uint32_t IAC4;     // Instruction Address Compare Register 4
329   uint32_t DAC1;     // Data Address Compare Register 1
330   uint32_t DAC2;     // Data Address Compare Register 2
331   uint32_t DVC1;     // Data Value Compare Register 1
332   uint32_t DVC2;     // Data Value Compare Register 2
333 } BG_DebugSet_t;
334
335
336
337 // Structure for stack data
338 typedef struct
339 {
340   BG_Addr_t frameAddr;
341   BG_Addr_t savedLR;
342 } BG_Stack_Info_t;
343
344
345 // Structure for process data.
346 typedef struct {
347   uint32_t rank;                       // MPI rank
348   uint32_t tgid;                       // Thread group id
349   uint32_t xCoord;                     // X coordinate
350   uint32_t yCoord;                     // Y coordinate
351   uint32_t zCoord;                     // Z coordinate
352   uint32_t tCoord;                     // T coordinate
353   BG_Addr_t sharedMemoryStartAddr;     // Shared memory region start address
354   BG_Addr_t sharedMemoryEndAddr;       // Shared memory region end address
355   BG_Addr_t persistMemoryStartAddr;    // Persistent memory region start address
356   BG_Addr_t persistMemoryEndAddr;      // Persistent memory region end address
357   BG_Addr_t heapStartAddr;             // Heap start address
358   BG_Addr_t heapEndAddr;               // Heap end address 
359   BG_Addr_t heapBreakAddr;             // Heap break address
360   BG_Addr_t mmapStartAddr;             // Memory map start address
361   BG_Addr_t mmapEndAddr;               // Memory map end address
362   struct timeval jobTime;              // Time job has been running
363 } BG_Process_Data_t;
364
365 // State of a thread.
366 typedef enum {
367   Running = 1,                         // Thread is running executable code
368   Sleeping,                            // Thread is sleeping
369   Waiting,                             // Thread is waiting for event
370   Zombie,                              // Thread is ended
371   Idle                                 // Thread is available 
372 } BG_Thread_State_t;
373
374 // Structure for thread data.
375 typedef struct {
376   BG_ThreadID_t threadID;              // Thread id
377   int core;                            // Core number
378   BG_Thread_State_t state;             // Thread state
379   BG_Addr_t stackStartAddr;            // Stack start address
380   BG_Addr_t stackEndAddr;              // Stack end address
381   BG_Addr_t guardStartAddr;            // Guard page start address
382   BG_Addr_t guardEndAddr;              // Guard page end address
383   BG_GPRSet_t gprs;                    // Set of general purpose registers
384   BG_FPRSet_t fprs;                    // Set of floating point registers
385   BG_DebugSet_t debugRegisters;        // Set of debug registers
386   uint32_t numStackFrames;             // Number of stack frame addr/saved lr entries returned
387   BG_Stack_Info_t stackInfo[BG_Debugger_MAX_STACK_FRAMES]; // Stack trace back
388 } BG_Thread_Data_t;
389
390
391 typedef enum {
392
393   RC_NO_ERROR          = 0,
394   RC_NOT_ATTACHED      = 1,
395   RC_NOT_RUNNING       = 2,
396   RC_BAD_NODE          = 3,
397   RC_BAD_THREAD        = 4,
398   RC_BAD_COMMAND       = 5,
399   RC_BAD_REGISTER      = 6,
400   RC_NOT_APP_SPACE     = 7,
401   RC_LEN_TOO_LONG      = 8,
402   RC_DENIED            = 9,
403   RC_BAD_SIGNAL        = 10,
404   RC_NOT_STOPPED       = 11,
405   RC_NOT_INITIALIZED   = 12,
406   RC_TIMEOUT           = 13
407   
408 } BG_ErrorCode_t;
409
410
411
412
413 // Externs for managing the pipe.  Use by a client is optional.
414 //
415 // DebuggerReadStarted and DebuggerWriteStarted: get set whenever you call
416 // our public method to read or write on the debugger pipe.  An alarm
417 // handler can look to see how long you've been waiting on the pipe.
418 //
419 // AbortPipeIO: If the alarm handler wants to abort a read or write on
420 // the pipe it can set this.  When the loop is resumed it will check
421 // this flag and end the loop if necessary.
422
423 extern volatile time_t DebuggerReadStarted;
424 extern volatile time_t DebuggerWriteStarted;
425 extern volatile int AbortPipeIO;
426
427
428 /* Debugger_Msg_t
429
430    This is the packet header for the pipe.  All messages use this.
431
432      messageType is self explanatory
433      nodeNumber is the target compute node
434      thread is the thread on the compute node
435      sequence can be used to keep track of packet flow
436      returnCode might be needed
437      dataLength is the size in chars of the payload
438
439    The 'payload' should follow the message header, and be received
440    into a buffer of size dataLength.
441
442    Not all messages have payloads.  If your message doesn't have
443    a payload, set dataLength to 0.
444
445    'sequence' is probably best used as a 'packet count' or a sequence
446    number.  This way you can match acknowledgement packets with the
447    original packet if things aren't being done in lockstep.
448
449    'returnCode' isn't architected yet, but we probably need it.  If your
450    GET_MEM request fails how else will you know?
451
452    'dataStartsHere' is a placeholder.  As a result, to get the true size
453    of this data structure you have to subtract 1 byte.
454
455 */
456
457 #define BG_Debugger_Msg_MAX_SIZE     4096
458 #define BG_Debugger_Msg_HEADER_SIZE    24
459 #define BG_Debugger_Msg_MAX_PAYLOAD_SIZE (BG_Debugger_Msg_MAX_SIZE-BG_Debugger_Msg_HEADER_SIZE)
460 #define BG_Debugger_Msg_MAX_MEM_SIZE 4064
461
462
463
464 class BG_Debugger_Msg {
465
466   public:
467
468     typedef struct {
469
470       BG_MsgType_t      messageType;
471       BG_NodeNum_t      nodeNumber;
472       BG_ThreadID_t     thread;
473       uint32_t           sequence;
474       uint32_t           returnCode;
475       uint32_t           dataLength;   // excluding this header
476
477     } Header;
478
479     Header header;
480
481     typedef union {
482
483       struct {
484         BG_GPR_Num_t      registerNumber;
485       } GET_REG;
486
487       struct {
488         BG_GPR_Num_t      registerNumber;
489         BG_GPR_t          value;
490       } GET_REG_ACK;
491
492       struct {
493       } GET_ALL_REGS;
494
495       struct {
496         BG_GPRSet_t       gprs;
497       } GET_ALL_REGS_ACK;
498
499       struct {
500         BG_GPR_Num_t     registerNumber;
501         BG_GPR_t         value;
502       } SET_REG;
503
504       struct {
505         BG_GPR_Num_t     registerNumber;
506       } SET_REG_ACK;  
507
508       struct {
509         BG_Addr_t        addr;
510         uint32_t          len;
511       } GET_MEM;
512
513       struct {
514         BG_Addr_t        addr;
515         uint32_t          len;
516         unsigned char     data[BG_Debugger_Msg_MAX_MEM_SIZE];
517       } GET_MEM_ACK;
518
519       struct {
520         BG_Addr_t        addr;
521         uint32_t          len;
522         unsigned char     data[BG_Debugger_Msg_MAX_MEM_SIZE];
523       } SET_MEM;
524
525       struct {
526         BG_Addr_t        addr;
527         uint32_t          len;
528       } SET_MEM_ACK;
529
530       struct {
531         BG_FPR_Num_t     registerNumber;
532       } GET_FLOAT_REG;
533
534       struct {
535         BG_FPR_Num_t     registerNumber;
536         BG_FPR_t         value;
537       } GET_FLOAT_REG_ACK;  
538
539       struct {
540       } GET_ALL_FLOAT_REGS;
541
542       struct {
543         BG_FPRSet_t      fprs;
544       } GET_ALL_FLOAT_REGS_ACK;
545
546       struct {
547         BG_FPR_Num_t     registerNumber;
548         BG_FPR_t         value;
549       } SET_FLOAT_REG;
550
551       struct {
552         BG_FPR_Num_t     registerNumber;
553       } SET_FLOAT_REG_ACK;  
554
555       struct {
556       } SINGLE_STEP;
557
558       struct {
559       } SINGLE_STEP_ACK;
560
561       struct {
562          uint32_t          signal;
563       } CONTINUE;
564
565       struct {
566       } CONTINUE_ACK;
567
568       struct {
569          uint32_t          signal;
570       } KILL;
571
572       struct {
573       } KILL_ACK;
574
575       struct {
576       } ATTACH;
577
578       struct {
579       } ATTACH_ACK;
580
581       struct {
582       } DETACH;
583
584       struct {
585       } DETACH_ACK;
586
587       struct {
588         uint32_t          signal;
589       } SIGNAL_ENCOUNTERED;
590
591       struct {
592         int32_t           type;  // 0 = exit, 1 = signal
593         int32_t           rc;
594       } PROGRAM_EXITED;
595
596       struct {
597       } VERSION_MSG;
598
599       struct {
600         uint32_t          protocolVersion;
601         uint32_t          numPhysicalProcessors;
602         uint32_t          numLogicalProcessors;
603       } VERSION_MSG_ACK;
604
605       struct {
606       } GET_DEBUG_REGS;
607
608       struct {
609         BG_DebugSet_t   debugRegisters;
610       } GET_DEBUG_REGS_ACK;
611
612       struct {
613         BG_DebugSet_t   debugRegisters;
614       } SET_DEBUG_REGS;
615
616       struct {
617       } SET_DEBUG_REGS_ACK;
618
619       struct {
620       } GET_THREAD_INFO;
621
622       struct {
623         uint32_t numThreads;
624         uint32_t threadIDS[BG_Debugger_MAX_THREAD_IDS];
625       } GET_THREAD_INFO_ACK;
626
627       struct {
628         uint32_t tid;
629       } THREAD_ALIVE;
630
631       struct {
632       } THREAD_ALIVE_ACK;
633
634       struct {
635       } GET_THREAD_ID;
636
637       struct {
638         uint32_t tid;
639       } GET_THREAD_ID_ACK;
640
641       struct {
642         uint32_t tid;
643         int32_t operation;  // 0='g' operations 1='c' operations
644       } SET_THREAD_OPS;
645
646       struct {
647       } SET_THREAD_OPS_ACK;
648
649       struct {
650       } GET_REGS_AND_FLOATS;
651
652       struct {
653         BG_GPRSet_t      gprs;
654         BG_FPRSet_t      fprs;
655       } GET_REGS_AND_FLOATS_ACK;
656
657       struct {
658         uint32_t auxVecBufferOffset; // Requested offset within the available AuxVec data to begin retrieval
659         uint32_t auxVecBufferLength; // Requested length of data to be returned
660       } GET_AUX_VECTORS;
661
662       struct {
663         uint32_t auxVecData[BG_Debugger_AUX_VECS_BUFFER/sizeof(uint32_t)]; 
664         uint32_t auxVecBufferOffset; // Offset within the available AuxVec data of retrieved data
665         uint32_t auxVecBufferLength; // Number of bytes of aux vec data stored within the auxVecData buffer
666         bool endOfVecData;           // Indicator set to true if the end of the AuxVec data was reached
667       } GET_AUX_VECTORS_ACK;
668
669       struct {
670       } GET_STACK_INFO;
671
672       struct {
673         uint32_t lr;  // Current link register
674         uint32_t iar;  // Current instruction address
675         uint32_t stackFrame;  // Current stack frame pointer(R1)
676         uint32_t numStackFrames;  // Number of stack frame addr/saved lr entries returned
677         BG_Stack_Info_t stackInfo[ BG_Debugger_MAX_STACK_FRAMES ];
678       } GET_STACK_INFO_ACK;
679
680       struct {
681       } END_DEBUG;
682
683       struct {
684       } END_DEBUG_ACK;
685
686       struct {
687       } GET_PROCESS_DATA;
688
689       struct {
690         BG_Process_Data_t processData;
691         uint32_t numThreads;
692         BG_ThreadID_t threadIDS[BG_Debugger_MAX_THREAD_IDS];
693       } GET_PROCESS_DATA_ACK;
694
695       struct {
696       } GET_THREAD_DATA;
697
698       struct {
699          BG_Thread_Data_t threadData;
700       } GET_THREAD_DATA_ACK;
701
702       struct {
703         uint32_t timeout;
704       } HOLD_THREAD;
705
706       struct {
707       } HOLD_THREAD_ACK;
708
709       struct {
710       } RELEASE_THREAD;
711
712       struct {
713       } RELEASE_THREAD_ACK;
714
715       struct {
716         uint32_t signum;        // signal number. Only supported value is SIGTRAP
717         __sighandler_t handler; // SIGTRAP signal handler function
718         uint32_t       mask;    // signal mask  (see syscall sigaction)
719         uint32_t       flags;   // signal flags (see syscall sigaction)
720       } SIGACTION;
721
722       struct {
723       } SIGACTION_ACK;
724
725       struct {
726         uint32_t          len;
727       } MAP_MEM;
728
729       struct {
730         BG_Addr_t        addr;
731       } MAP_MEM_ACK;
732
733       struct {
734         bool         enable;
735       } FAST_TRAP;
736
737       struct {
738       } FAST_TRAP_ACK;
739
740       struct {
741         sigset_t     ignoreSet;
742       } DEBUG_IGNORE_SIG;
743
744       struct {
745       } DEBUG_IGNORE_SIG_ACK;
746
747       unsigned char      dataStartsHere;
748
749     } DataArea;
750
751     DataArea dataArea;
752
753     // Ctor
754
755     BG_Debugger_Msg( void ) { header.messageType = THIS_SPACE_FOR_RENT; }
756
757
758     BG_Debugger_Msg( BG_MsgType_t type,
759                         BG_NodeNum_t node,
760                         BG_ThreadID_t thread,
761                         uint32_t sequence,
762                         uint32_t returnCode )
763     {
764       header.messageType = type;
765       header.nodeNumber = node;
766       header.thread = thread;
767       header.sequence = sequence;
768       header.returnCode = returnCode;
769     } 
770
771     static BG_Debugger_Msg generateErrorPacket( BG_Debugger_Msg &original, BG_ErrorCode_t ec )
772     {
773
774        BG_Debugger_Msg errMsg;
775
776        errMsg.header.nodeNumber = original.header.nodeNumber;
777        errMsg.header.thread     = original.header.thread;
778        errMsg.header.sequence   = original.header.sequence;
779        errMsg.header.returnCode = ec;
780
781
782        switch ( original.header.messageType ) {
783
784          case GET_REG: {
785            errMsg.header.messageType = GET_REG_ACK;
786            errMsg.header.dataLength  = sizeof( errMsg.dataArea.GET_REG_ACK );
787            errMsg.dataArea.GET_REG_ACK.registerNumber = original.dataArea.GET_REG.registerNumber;
788            errMsg.dataArea.GET_REG_ACK.value = 0xDEADBEEF;
789            break;
790          }
791
792          case GET_ALL_REGS: {
793            errMsg.header.messageType = GET_ALL_REGS_ACK;
794            errMsg.header.dataLength = 0;
795            break;
796          }
797
798          case SET_REG: {
799            errMsg.header.messageType = SET_REG_ACK;
800            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SET_REG_ACK );
801            errMsg.dataArea.SET_REG_ACK.registerNumber = original.dataArea.SET_REG.registerNumber;
802            break;
803          }
804
805          case GET_MEM: {
806            errMsg.header.messageType = GET_MEM_ACK;
807            errMsg.header.dataLength  = sizeof( errMsg.dataArea.GET_MEM_ACK ) - BG_Debugger_Msg_MAX_MEM_SIZE;
808            errMsg.dataArea.GET_MEM_ACK.addr = original.dataArea.GET_MEM.addr;
809            errMsg.dataArea.GET_MEM_ACK.len  = original.dataArea.GET_MEM.len;
810            break;
811          }
812
813          case SET_MEM: {
814            errMsg.header.messageType = SET_MEM_ACK;
815            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SET_MEM_ACK );
816            errMsg.dataArea.SET_MEM_ACK.addr = original.dataArea.SET_MEM.addr;
817            errMsg.dataArea.SET_MEM_ACK.len  = original.dataArea.SET_MEM.len;
818            break;
819          }
820
821          case GET_FLOAT_REG: {
822            errMsg.header.messageType = GET_FLOAT_REG_ACK;
823            errMsg.header.dataLength  = sizeof( errMsg.dataArea.GET_FLOAT_REG_ACK );
824            errMsg.dataArea.GET_FLOAT_REG_ACK.registerNumber = original.dataArea.GET_FLOAT_REG.registerNumber;
825            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w0 = 0xDEADBEEF;
826            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w1 = 0xDEADBEEF;
827            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w2 = 0xDEADBEEF;
828            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w3 = 0xDEADBEEF;
829            break;
830          }
831
832          case GET_ALL_FLOAT_REGS: {
833            errMsg.header.messageType = GET_ALL_FLOAT_REGS_ACK;
834            errMsg.header.dataLength  = 0;
835            break;
836          }
837
838          case SET_FLOAT_REG: {
839            errMsg.header.messageType = SET_FLOAT_REG_ACK;
840            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SET_FLOAT_REG_ACK );
841            errMsg.dataArea.SET_FLOAT_REG_ACK.registerNumber = original.dataArea.SET_FLOAT_REG.registerNumber;
842            break;
843          }
844
845          case SINGLE_STEP: {
846            errMsg.header.messageType = SINGLE_STEP_ACK;
847            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SINGLE_STEP_ACK );
848            break;
849          }
850
851          case CONTINUE: {
852            errMsg.header.messageType = CONTINUE_ACK;
853            errMsg.header.dataLength  = sizeof( errMsg.dataArea.CONTINUE_ACK );
854            break;
855          }
856
857          case KILL: {
858            errMsg.header.messageType = KILL_ACK;
859            errMsg.header.dataLength  = sizeof( errMsg.dataArea.KILL_ACK );
860            break;
861          }
862
863          case ATTACH: {
864            errMsg.header.messageType = ATTACH_ACK;
865            errMsg.header.dataLength  = sizeof( errMsg.dataArea.ATTACH_ACK );
866            break;
867          }
868
869          case DETACH: {
870            errMsg.header.messageType = DETACH_ACK;
871            errMsg.header.dataLength  = sizeof( errMsg.dataArea.DETACH_ACK );
872            break;
873          }
874
875          case GET_DEBUG_REGS: {
876            errMsg.header.messageType = GET_DEBUG_REGS_ACK;
877            errMsg.header.dataLength  = 0;
878            break;
879          }
880
881          case SET_DEBUG_REGS: {
882            errMsg.header.messageType = SET_DEBUG_REGS_ACK;
883            errMsg.header.dataLength  = 0;
884            break;
885          }
886
887          case GET_THREAD_INFO: {
888            errMsg.header.messageType = GET_THREAD_INFO_ACK;
889            errMsg.header.dataLength  = 0;
890            break;
891          }
892
893          case THREAD_ALIVE: {
894            errMsg.header.messageType = THREAD_ALIVE_ACK;
895            errMsg.header.dataLength  = sizeof( errMsg.dataArea.THREAD_ALIVE_ACK );
896            break;
897          }
898
899          case GET_THREAD_ID: {
900            errMsg.header.messageType = GET_THREAD_ID_ACK;
901            errMsg.header.dataLength  = 0;
902            break;
903          }
904
905          case SET_THREAD_OPS: {
906            errMsg.header.messageType = SET_THREAD_OPS_ACK;
907            errMsg.header.dataLength  = 0;
908            break;
909          }
910
911          case GET_REGS_AND_FLOATS: {
912            errMsg.header.messageType = GET_ALL_REGS_ACK;
913            errMsg.header.dataLength = 0;
914            break;
915          }
916
917          case GET_AUX_VECTORS: {
918            errMsg.header.messageType = GET_AUX_VECTORS_ACK;
919            errMsg.header.dataLength = 0;
920            break;
921          }
922
923          case GET_STACK_TRACE: {
924            errMsg.header.messageType = GET_STACK_TRACE_ACK;
925            errMsg.header.dataLength = 0;
926            break;
927          }
928
929          case END_DEBUG: {
930            errMsg.header.messageType = END_DEBUG_ACK;
931            errMsg.header.dataLength  = 0;
932            break;
933          }
934
935          case GET_PROCESS_DATA: {
936            errMsg.header.messageType = GET_PROCESS_DATA_ACK;
937            errMsg.header.dataLength = 0;
938            break;
939          }
940
941          case GET_THREAD_DATA: {
942            errMsg.header.messageType = GET_THREAD_DATA_ACK;
943            errMsg.header.dataLength = 0;
944            break;
945          }
946
947          default: {
948            errMsg.header.messageType = original.header.messageType;
949            errMsg.header.dataLength = 0;
950            break;
951          }
952
953        }
954
955        return errMsg;
956
957     }
958
959     //! \brief  Read a debugger message from a descriptor.
960     //! \param  fd Descriptor to read from.
961     //! \param  msg Reference to debugger message.
962     //! \return True when message was read successfully, false if there was an error.
963
964     static bool readFromFd( int fd, BG_Debugger_Msg &msg )
965     {
966        return readFromFd_p( fd, msg, NULL );
967     }
968
969     //! \brief  Read a debugger message from a descriptor.
970     //! \param  fd Descriptor to read from.
971     //! \param  msg Reference to debugger message.
972     //! \param  abortPipeIO Pointer to integer that indicates whether to abort read on error.
973     //! \return True when message was read successfully, false if there was an error.
974
975     static bool readFromFd( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
976     {
977        return readFromFd_p( fd, msg, abortPipeIO );
978     }
979
980     //! \brief  Write a debugger message to a descriptor.
981     //! \param  fd Descriptor to write to.
982     //! \param  msg Reference to debugger message.
983     //! \return True when message was written successfully, false if there was an error.
984
985     static bool writeOnFd( int fd, BG_Debugger_Msg &msg )
986     {
987        return writeOnFd_p( fd, msg, NULL );
988     }
989
990     //! \brief  Write a debugger message to a descriptor.
991     //! \param  fd Descriptor to write to.
992     //! \param  msg Reference to debugger message.
993     //! \param  abortPipeIO Pointer to integer that indicates whether to abort read on error.
994     //! \return True when message was written successfully, false if there was an error.
995
996     static bool writeOnFd( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
997     {
998        return writeOnFd_p( fd, msg, abortPipeIO );
999     }
1000
1001     //! \brief  Get a string describing a debugger message type.
1002     //! \param  type Debugger message type.
1003     //! \return Pointer to string.
1004
1005     static const char *getMessageName(BG_MsgType_t type)
1006     {
1007        static const char *BG_Packet_Names[] = 
1008        {
1009           "GET_REG",
1010           "GET_ALL_REGS",
1011           "SET_REG",
1012           "GET_MEM",
1013           "SET_MEM",
1014           "GET_FLOAT_REG",
1015           "GET_ALL_FLOAT_REGS",
1016           "SET_FLOAT_REG",
1017           "SINGLE_STEP",
1018           "CONTINUE",
1019           "KILL",
1020           "ATTACH",
1021           "DETACH",
1022           "GET_REG_ACK",
1023           "GET_ALL_REGS_ACK",
1024           "SET_REG_ACK",
1025           "GET_MEM_ACK",
1026           "SET_MEM_ACK",
1027           "GET_FLOAT_REG_ACK",
1028           "GET_ALL_FLOAT_REGS_ACK",
1029           "SET_FLOAT_REG_ACK",
1030           "SINGLE_STEP_ACK",
1031           "CONTINUE_ACK",
1032           "KILL_ACK",
1033           "ATTACH_ACK",
1034           "DETACH_ACK",
1035           "SIGNAL_ENCOUNTERED",
1036           "PROGRAM_EXITED",
1037           "VERSION_MSG",
1038           "VERSION_MSG_ACK",
1039           "GET_DEBUG_REGS",
1040           "GET_DEBUG_REGS_ACK",
1041           "SET_DEBUG_REGS",
1042           "SET_DEBUG_REGS_ACK",
1043           "GET_THREAD_INFO",
1044           "GET_THREAD_INFO_ACK",
1045           "THREAD_ALIVE",
1046           "THREAD_ALIVE_ACK",
1047           "GET_THREAD_ID",
1048           "GET_THREAD_ID_ACK",
1049           "SET_THREAD_OPS",
1050           "SET_THREAD_OPS_ACK",
1051           "GET_REGS_AND_FLOATS",
1052           "GET_REGS_AND_FLOATS_ACK",
1053           "GET_AUX_VECTORS",
1054           "GET_AUX_VECTORS_ACK",
1055           "GET_STACK_TRACE",
1056           "GET_STACK_TRACE_ACK",
1057           "END_DEBUG",
1058           "END_DEBUG_ACK",
1059           "GET_PROCESS_DATA",
1060           "GET_PROCESS_DATA_ACK",
1061           "GET_THREAD_DATA",
1062           "GET_THREAD_DATA_ACK",
1063           "HOLD_THREAD",
1064           "HOLD_THREAD_ACK",
1065           "RELEASE_THREAD",
1066           "RELEASE_THREAD_ACK",
1067           "SIGACTION",
1068           "SIGACTION_ACK",
1069           "MAP_MEM",
1070           "MAP_MEM_ACK",
1071           "FAST_TRAP",
1072           "FAST_TRAP_ACK",
1073           "DEBUG_IGNORE_SIG",
1074           "DEBUG_IGNORE_SIG_ACK"
1075        };
1076
1077        if ((type >= GET_REG) && (type < THIS_SPACE_FOR_RENT)) {
1078           return BG_Packet_Names[type];
1079        }
1080        else {
1081           return "UNKNOWN";
1082        }
1083
1084     }
1085
1086     //! \brief  Print details about a debugger message to standard output.
1087     //! \param  msg Reference to debugger message.
1088     //! \return Nothing.
1089
1090     static void dump( BG_Debugger_Msg &msg )
1091     {
1092        dump( msg, stdout );
1093     }
1094
1095     //! \brief  Print details about a debugger message to the specified file.
1096     //! \param  msg Reference to debugger message.
1097     //! \param  outfile Pointer to file for printing message.
1098     //! \return Nothing.
1099
1100     static void dump( BG_Debugger_Msg &msg, FILE *outfile )
1101     {
1102        fprintf( outfile, "\n" );
1103
1104        fprintf( outfile, "Type: %s from node: %d, return code: %d\n",
1105                 getMessageName(msg.header.messageType),
1106                 msg.header.nodeNumber,
1107                 msg.header.returnCode );
1108
1109        switch ( msg.header.messageType ) {
1110
1111          case GET_REG: {
1112            fprintf( outfile, "  Register number: %d\n", msg.dataArea.GET_REG.registerNumber );
1113            break;
1114          }
1115
1116          case GET_REG_ACK: {
1117            fprintf( outfile, "  Register number: %d    Value: %08x\n", msg.dataArea.GET_REG.registerNumber, msg.dataArea.GET_REG_ACK.value );
1118            break;
1119          }
1120
1121          case GET_ALL_REGS_ACK: {
1122            dumpGPRSet( &msg.dataArea.GET_ALL_REGS_ACK.gprs, outfile );
1123            break;
1124          }
1125
1126
1127          case SET_REG: {
1128            fprintf( outfile, "  Register number: %d    Value: %08x\n", msg.dataArea.SET_REG.registerNumber, msg.dataArea.SET_REG.value );
1129            break;
1130          }
1131
1132          case SET_REG_ACK: {
1133            fprintf( outfile, "  Register number: %d\n", msg.dataArea.SET_REG_ACK.registerNumber );
1134            break;
1135          }
1136
1137          case GET_MEM: {
1138            fprintf( outfile, "  Memory address: %08x    Length: %d\n  Vals: ", msg.dataArea.GET_MEM.addr, msg.dataArea.GET_MEM.len );
1139            break;
1140          }
1141
1142          case GET_MEM_ACK: {
1143            fprintf( outfile, "  Memory address: %08x    Length: %d\n  Vals: ", msg.dataArea.GET_MEM_ACK.addr, msg.dataArea.GET_MEM_ACK.len );
1144            for ( unsigned int i = 0; i < msg.dataArea.GET_MEM_ACK.len; i++ ) fprintf( outfile, "%02x ", msg.dataArea.GET_MEM_ACK.data[i] );
1145            fprintf( outfile, "\n" );
1146            break;
1147          }
1148
1149          case SET_MEM: {
1150            fprintf( outfile, "  Memory address: %08x    Length: %d\n  Vals: ", msg.dataArea.SET_MEM.addr, msg.dataArea.SET_MEM.len );
1151            for ( unsigned int i = 0; i < msg.dataArea.SET_MEM.len; i++ ) fprintf( outfile, "%02x ", msg.dataArea.SET_MEM.data[i] );
1152            fprintf( outfile, "\n" );
1153            break;
1154          }
1155
1156          case SET_MEM_ACK: {
1157            fprintf( outfile, "  Memory address: %08x    Length: %d\n", msg.dataArea.SET_MEM_ACK.addr, msg.dataArea.SET_MEM_ACK.len );
1158            break;
1159          }
1160
1161          case CONTINUE: {
1162            fprintf( outfile, "  Continue with signal number: %d\n", msg.dataArea.CONTINUE.signal );
1163            break;
1164          }
1165
1166          case KILL: {
1167            fprintf( outfile, "  Signal number: %d\n", msg.dataArea.KILL.signal );
1168            break;
1169          }
1170
1171          case SIGNAL_ENCOUNTERED: {
1172            fprintf( outfile, "  Signal number: %d\n", msg.dataArea.SIGNAL_ENCOUNTERED.signal );
1173            break;
1174          }
1175
1176          case PROGRAM_EXITED: {
1177            fprintf( outfile, "  Exit=0,Signal=1: %d   Return code: %d\n", msg.dataArea.PROGRAM_EXITED.type, msg.dataArea.PROGRAM_EXITED.rc );
1178            break;
1179          }
1180
1181          case GET_ALL_FLOAT_REGS_ACK: {
1182            dumpFPRSet( &msg.dataArea.GET_ALL_FLOAT_REGS_ACK.fprs, outfile );
1183            break;
1184          }
1185
1186          case VERSION_MSG_ACK: {
1187            fprintf( outfile, "  Protocol version: %u   Physical Processors: %u  Logical Processors: %u\n",
1188                     msg.dataArea.VERSION_MSG_ACK.protocolVersion,
1189                     msg.dataArea.VERSION_MSG_ACK.numPhysicalProcessors,
1190                     msg.dataArea.VERSION_MSG_ACK.numLogicalProcessors );
1191            break;
1192          }
1193
1194          case GET_DEBUG_REGS_ACK: {
1195            dumpDebugSet( &msg.dataArea.GET_DEBUG_REGS_ACK.debugRegisters, outfile );
1196            break;
1197          }
1198
1199          case SET_DEBUG_REGS: {
1200            dumpDebugSet( &msg.dataArea.SET_DEBUG_REGS.debugRegisters, outfile );
1201            break;
1202          }
1203
1204          case GET_THREAD_INFO_ACK: {
1205            fprintf( outfile, "  Number of threads: %u  TIDs:", msg.dataArea.GET_THREAD_INFO_ACK.numThreads );
1206            for ( unsigned int i = 0; i < msg.dataArea.GET_THREAD_INFO_ACK.numThreads; i++ ) {
1207              fprintf( outfile, " %u", msg.dataArea.GET_THREAD_INFO_ACK.threadIDS[i] );
1208            }
1209            fprintf( outfile, "\n");
1210            break;
1211          }
1212
1213          case THREAD_ALIVE: {
1214            fprintf( outfile, "  TID: %u\n", msg.dataArea.THREAD_ALIVE.tid );
1215            break;
1216          }
1217
1218          case GET_THREAD_ID_ACK: {
1219            fprintf( outfile, "  TID: %u\n", msg.dataArea.GET_THREAD_ID_ACK.tid );
1220            break;
1221          }
1222
1223          case SET_THREAD_OPS: {
1224            fprintf( outfile, "  TID: %u  Operation: %d\n", msg.dataArea.SET_THREAD_OPS.tid, msg.dataArea.SET_THREAD_OPS.operation );
1225            break;
1226          }
1227
1228          case GET_REGS_AND_FLOATS_ACK: {
1229            dumpGPRSet( &msg.dataArea.GET_REGS_AND_FLOATS_ACK.gprs, outfile );
1230            dumpFPRSet( &msg.dataArea.GET_REGS_AND_FLOATS_ACK.fprs, outfile );
1231            break;
1232          }
1233
1234          case GET_AUX_VECTORS: {
1235            fprintf( outfile, "  Offset: %08x    Requested Length: %d\n  Vals: ", msg.dataArea.GET_AUX_VECTORS.auxVecBufferOffset, msg.dataArea.GET_AUX_VECTORS.auxVecBufferLength );
1236            break;
1237          }
1238
1239          case GET_AUX_VECTORS_ACK: {
1240            fprintf( outfile, "  Offset: %08x    Length: %d\n  Vals: ", msg.dataArea.GET_AUX_VECTORS_ACK.auxVecBufferOffset, msg.dataArea.GET_AUX_VECTORS_ACK.auxVecBufferLength );
1241            for ( unsigned int i = 0; i < msg.dataArea.GET_AUX_VECTORS_ACK.auxVecBufferLength; i++ ) 
1242              fprintf( outfile, "%02x ", msg.dataArea.GET_AUX_VECTORS_ACK.auxVecData[i] );
1243            fprintf( outfile, "\n" );
1244            break;
1245          }
1246
1247          case GET_STACK_TRACE_ACK: {
1248            fprintf( outfile, "  LR: %08x  IAR: %08x  R1: %08x  Number of stack frames: %u\n",
1249                     msg.dataArea.GET_STACK_INFO_ACK.lr, msg.dataArea.GET_STACK_INFO_ACK.iar,
1250                     msg.dataArea.GET_STACK_INFO_ACK.stackFrame, msg.dataArea.GET_STACK_INFO_ACK.numStackFrames );
1251            for ( unsigned int i = 0; i < msg.dataArea.GET_STACK_INFO_ACK.numStackFrames; i++ ) {
1252              fprintf( outfile, "  Frame address: %08x  Saved LR: %08x\n", msg.dataArea.GET_STACK_INFO_ACK.stackInfo[i].frameAddr, msg.dataArea.GET_STACK_INFO_ACK.stackInfo[i].savedLR );
1253            }
1254            break;
1255          }
1256
1257          case GET_PROCESS_DATA_ACK: {
1258            fprintf( outfile, "  Rank: %u  TGID: %u  xCoord: %u  yCoord: %u  zCoord: %u  tCoord: %u\n",
1259                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.rank, msg.dataArea.GET_PROCESS_DATA_ACK.processData.tgid,
1260                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.xCoord, msg.dataArea.GET_PROCESS_DATA_ACK.processData.yCoord,
1261                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.zCoord, msg.dataArea.GET_PROCESS_DATA_ACK.processData.tCoord );
1262            fprintf( outfile, "  Shared memory start: %08x  Shared memory end: %08x  Persistent memory start: %08x  Persistent memory end: %08x\n",
1263                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.sharedMemoryStartAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.sharedMemoryEndAddr,
1264                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.persistMemoryStartAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.persistMemoryEndAddr );
1265            fprintf( outfile, "  Heap start: %08x  Heap end: %08x  Heap break: %08x  Mmap start: %08x  Mmap end: %08x\n",
1266                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.heapStartAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.heapEndAddr,
1267                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.heapBreakAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.mmapStartAddr,
1268                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.mmapEndAddr );
1269            fprintf( outfile, "  Number of threads: %u  TIDs:", msg.dataArea.GET_PROCESS_DATA_ACK.numThreads );
1270            for ( unsigned int i = 0; i < msg.dataArea.GET_PROCESS_DATA_ACK.numThreads; i++ ) {
1271              fprintf( outfile, " %u", msg.dataArea.GET_PROCESS_DATA_ACK.threadIDS[i] );
1272            }
1273            fprintf( outfile, "\n");
1274            break;
1275          }
1276
1277          case GET_THREAD_DATA_ACK: {
1278            fprintf( outfile, "  TID: %u  Core: %d  Stack start: %08x  Stack end: %08x  Guard start: %08x  Guard end: %08x\n",
1279                     msg.dataArea.GET_THREAD_DATA_ACK.threadData.threadID, msg.dataArea.GET_THREAD_DATA_ACK.threadData.core,
1280                     msg.dataArea.GET_THREAD_DATA_ACK.threadData.stackStartAddr, msg.dataArea.GET_THREAD_DATA_ACK.threadData.stackEndAddr,
1281                     msg.dataArea.GET_THREAD_DATA_ACK.threadData.guardStartAddr, msg.dataArea.GET_THREAD_DATA_ACK.threadData.guardEndAddr );
1282            dumpGPRSet( &msg.dataArea.GET_THREAD_DATA_ACK.threadData.gprs, outfile );
1283            dumpFPRSet( &msg.dataArea.GET_THREAD_DATA_ACK.threadData.fprs, outfile );
1284            dumpDebugSet( &msg.dataArea.GET_THREAD_DATA_ACK.threadData.debugRegisters, outfile );
1285            for ( unsigned int i = 0; i < msg.dataArea.GET_THREAD_DATA_ACK.threadData.numStackFrames; i++ ) {
1286              fprintf( outfile, "  Frame address: %08x  Saved LR: %08x\n", msg.dataArea.GET_THREAD_DATA_ACK.threadData.stackInfo[i].frameAddr, msg.dataArea.GET_THREAD_DATA_ACK.threadData.stackInfo[i].savedLR );
1287            }
1288            break;
1289          }
1290
1291          case HOLD_THREAD: {
1292              fprintf( outfile, "Timeout(usec): %08x\n", msg.dataArea.HOLD_THREAD.timeout);
1293              break;
1294          }
1295
1296          case SIGACTION: {
1297              fprintf( outfile, "Signum: %08x  flags: %08x mask: %08x\n", msg.dataArea.SIGACTION.signum, msg.dataArea.SIGACTION.flags, msg.dataArea.SIGACTION.mask);  
1298              break;
1299          }
1300
1301          case MAP_MEM: {
1302              fprintf( outfile, "MemMap size: %08x\n", msg.dataArea.MAP_MEM.len);
1303              break;
1304          }
1305          case FAST_TRAP: {
1306              fprintf( outfile, "FastTrap option: %d\n", msg.dataArea.FAST_TRAP.enable);
1307              break;
1308          }
1309
1310          case DEBUG_IGNORE_SIG: {
1311              fprintf( outfile, "Debug ignore signal option: \n");
1312              break;
1313          }
1314
1315          case GET_FLOAT_REG:
1316          case SET_FLOAT_REG:
1317          case GET_FLOAT_REG_ACK:
1318          case SET_FLOAT_REG_ACK:
1319          case GET_ALL_REGS:
1320          case GET_ALL_FLOAT_REGS:
1321          case SINGLE_STEP:
1322          case SINGLE_STEP_ACK:
1323          case CONTINUE_ACK:
1324          case KILL_ACK:
1325          case ATTACH:
1326          case ATTACH_ACK:
1327          case DETACH:
1328          case DETACH_ACK:
1329          case VERSION_MSG:
1330          case GET_DEBUG_REGS:
1331          case SET_DEBUG_REGS_ACK:
1332          case GET_THREAD_ID:
1333          case GET_THREAD_INFO:
1334          case THREAD_ALIVE_ACK:
1335          case SET_THREAD_OPS_ACK:
1336          case GET_REGS_AND_FLOATS:
1337          case GET_STACK_TRACE:
1338          case END_DEBUG:
1339          case END_DEBUG_ACK:
1340          case GET_PROCESS_DATA:
1341          case GET_THREAD_DATA:
1342          case HOLD_THREAD_ACK:
1343          case RELEASE_THREAD:
1344          case RELEASE_THREAD_ACK:
1345          case SIGACTION_ACK:
1346          case MAP_MEM_ACK:
1347          case FAST_TRAP_ACK:
1348          case DEBUG_IGNORE_SIG_ACK:
1349          case THIS_SPACE_FOR_RENT: {
1350            // Nothing to do for these packet types unless data is added to them
1351            break;
1352          }
1353
1354        }
1355
1356        return;
1357     }
1358
1359 private:
1360
1361    //! \brief  Read a debugger message from a descriptor.
1362    //! \param  fd Descriptor to read from.
1363    //! \param  msg Reference to debugger message.
1364    //! \param  abortPipeIO Pointer to integer that indicates whether to abort read on error.
1365    //! \return True when message was read succesfully, false if there was an error.
1366
1367    static bool readFromFd_p( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
1368    {
1369       // Read header first
1370       int headerBytesToRead = sizeof( msg.header );
1371       int headerBytesRead = 0;
1372
1373       while ( headerBytesRead < headerBytesToRead ) {
1374
1375          if ( (abortPipeIO != NULL) && (*abortPipeIO != 0) ) {
1376             *abortPipeIO = 0;
1377             return false;
1378          }
1379
1380          int headerRc = read( fd, ((unsigned char *)&msg.header)+headerBytesRead, headerBytesToRead - headerBytesRead );
1381
1382          if ( headerRc == 0 ) {
1383             // End of file
1384             return false;
1385          }
1386          else if ( headerRc == -1 ) {
1387
1388             // EINTR could be tolerable ... the others are not though
1389             if ( errno != EINTR ) {
1390                perror( "BG_Debugger_Msg::readFromFd" );
1391                return false;
1392             }
1393
1394          }
1395          else {
1396             headerBytesRead += headerRc;
1397          }
1398       }
1399
1400
1401       // Read the rest of the packet now
1402       uint32_t payloadBytesRead = 0;
1403
1404       while ( payloadBytesRead < msg.header.dataLength ) {
1405
1406          if ( (abortPipeIO != NULL) && (*abortPipeIO != 0) ) {
1407             *abortPipeIO = 0;
1408             return false;
1409          }
1410
1411          int payloadRc = read( fd, ((unsigned char *)&msg.dataArea)+payloadBytesRead, msg.header.dataLength - payloadBytesRead );
1412
1413          if ( payloadRc == 0 ) {
1414             // End of file
1415             return false;
1416          }
1417          else if ( payloadRc == -1 ) {
1418
1419            // EINTR could be tolerable ... the others are not though
1420            if ( errno != EINTR ) {
1421               int err = errno;
1422               perror( "BG_Debugger_Msg::readFromFd" );
1423               errno = err;
1424               return false;
1425            }
1426
1427          }
1428          else {
1429             payloadBytesRead += payloadRc;
1430          }
1431
1432       }
1433       return true;
1434    }
1435
1436    //! \brief  Write a debugger message to a descriptor.
1437    //! \param  fd Descriptor to write to.
1438    //! \param  msg Reference to debugger message.
1439    //! \param  abortPipeIO Pointer to integer that indicates whether to abort write on error.
1440    //! \return True when message was written successfully, false if there was an error.
1441
1442    static bool writeOnFd_p( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
1443    {
1444       int bytesToWrite = sizeof( msg.header ) + msg.header.dataLength;
1445       int bytesWritten = 0;
1446       while ( bytesWritten < bytesToWrite ) {
1447
1448          if ( (abortPipeIO != NULL) && (*abortPipeIO != 0) ) {
1449             *abortPipeIO = 0;
1450             return false;
1451          }
1452
1453          int writeRc = write( fd, ((unsigned char *)&msg)+bytesWritten, bytesToWrite - bytesWritten );
1454
1455          if ( writeRc == -1 ) {
1456
1457             if ( errno != EINTR ) {
1458                int err = errno;
1459                perror( "BG_Debugger_msg::writeOnFd" );
1460                errno = err;
1461                return false;
1462             }
1463
1464          }
1465          else {
1466             bytesWritten += writeRc;
1467          }
1468
1469        }
1470
1471       return true;
1472    }
1473
1474    //! \brief  Print the set of GPRs to the specified file.
1475    //! \param  gprs Pointer to set of GPRs.
1476    //! \param  outfile Pointer to file for printing message.
1477    //! \return Nothing.
1478
1479    static void dumpGPRSet( BG_GPRSet_t *gprs, FILE *outfile )
1480    {
1481      for ( int i=0; i < 8; i++ ) {
1482        for ( int j=0; j < 4; j++ ) {
1483          fprintf( outfile, "  r%02d: %08x    ", i*4+j, gprs->gpr[i*4+j] );
1484        }
1485        fprintf( outfile, "\n" );
1486      }
1487      fprintf( outfile, "FPSCR: %08x       LR: %08x       CR: %08x      XER: %08x\n",
1488               gprs->fpscr, gprs->lr, gprs->cr, gprs->xer );
1489      fprintf( outfile, "  CTR: %08x      IAR: %08x      MSR: %08x     DEAR: %08x\n",
1490               gprs->ctr, gprs->iar, gprs->msr, gprs->dear );
1491      fprintf( outfile, "  ESR: %08x\n", gprs->esr );
1492      return;
1493    }
1494
1495    //! \brief  Print the set of FPRs to the specified file.
1496    //! \param  fprs Pointer to set of FPRs.
1497    //! \param  outfile Pointer to file for printing message.
1498    //! \return Nothing.
1499
1500    static void dumpFPRSet( BG_FPRSet_t *fprs, FILE *outfile )
1501    {
1502      fprintf( outfile, "  Double hummer set 0:\n" );
1503      for ( int i=0; i < 8; i++ ) {
1504        for ( int j=0; j < 4; j++ ) {
1505          double val;
1506          memcpy( &val, &fprs->fprs[i*4+j].w0, sizeof( _QuadWord_t ) );
1507          fprintf( outfile, "  f%02d: %f    ", i*4+j, val );
1508        }
1509        fprintf( outfile, "\n" );
1510      }
1511      fprintf( outfile, "\n" );
1512      fprintf( outfile, "  Double hummer set 1:\n" );
1513      for ( int i=0; i < 8; i++ ) {
1514        for ( int j=0; j < 4; j++ ) {
1515          double val;
1516          memcpy( &val, &fprs->fprs[i*4+j].w2, sizeof( _QuadWord_t ) ); 
1517          fprintf( outfile, "  f%02d: %f    ", i*4+j, val );
1518        }
1519        fprintf( outfile, "\n" );
1520      }
1521      fprintf( outfile, "\n" );
1522      fprintf( outfile, "  Double hummer set 0 in hex:\n" );
1523      for ( int i=0; i < 8; i++ ) {
1524        for ( int j=0; j < 4; j++ ) {
1525          uint32_t val1 = fprs->fprs[i*4+j].w0;
1526          uint32_t val2 = fprs->fprs[i*4+j].w1;
1527          fprintf( outfile, "  f%02d: %08x%08x  ", i*4+j, val1, val2 );
1528        }
1529        fprintf( outfile, "\n" );
1530      }
1531      fprintf( outfile, "\n" );
1532      fprintf( outfile, "  Double hummer set 1 in hex:\n" );
1533      for ( int i=0; i < 8; i++ ) {
1534        for ( int j=0; j < 4; j++ ) {
1535          uint32_t val1 = fprs->fprs[i*4+j].w2;
1536          uint32_t val2 = fprs->fprs[i*4+j].w3;
1537          fprintf( outfile, "  f%02d: %08x%08x  ", i*4+j, val1, val2 );
1538        }
1539        fprintf( outfile, "\n" );
1540      }
1541      return;
1542    }
1543
1544    //! \brief  Print the set of debug registers to the specified file.
1545    //! \param  gprs Pointer to set of debug registers.
1546    //! \param  outfile Pointer to file for printing message.
1547    //! \return Nothing.
1548
1549    static void dumpDebugSet( BG_DebugSet_t *debugRegisters, FILE *outfile )
1550    {
1551      fprintf( outfile, "  DBCR0: %08x   DBCR1: %08x   DBCR2: %08x    DBSR: %08x\n",
1552               debugRegisters->DBCR0, debugRegisters->DBCR1, debugRegisters->DBCR2, debugRegisters->DBSR );
1553      fprintf( outfile, "   IAC1: %08x    IAC2: %08x    IAC3: %08x    IAC4: %08x\n",
1554               debugRegisters->IAC1, debugRegisters->IAC2, debugRegisters->IAC3, debugRegisters->IAC4 );
1555      fprintf( outfile, "   DAC1: %08x    DAC2: %08x    DVC1: %08x    DVC2: %08x\n",
1556               debugRegisters->DAC1, debugRegisters->DAC2, debugRegisters->DVC1, debugRegisters->DVC2 );
1557      return;
1558    }
1559
1560 };
1561
1562
1563 }
1564 #undef fprintf
1565
1566 #endif // CIODEBUGGERPROTOCOL_H