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