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