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