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