bgp-debugger-interface.h

Go to the documentation of this file.
00001 /* begin_generated_IBM_copyright_prolog                             */
00002 /*                                                                  */
00003 /* This is an automatically generated copyright prolog.             */
00004 /* After initializing,  DO NOT MODIFY OR MOVE                       */
00005 /*  --------------------------------------------------------------- */
00006 /*                                                                  */
00007 /* (C) Copyright IBM Corp.  2004, 2009                              */
00008 /* IBM CPL License                                                  */
00009 /*                                                                  */
00010 /*  --------------------------------------------------------------- */
00011 /*                                                                  */
00012 /* end_generated_IBM_copyright_prolog                               */
00013 
00014 #ifndef CIODEBUGGERPROTOCOL_H
00015 #define CIODEBUGGERPROTOCOL_H
00016 
00017 #include <stdint.h>
00018 #include <stdio.h>
00019 #include <time.h>
00020 #include <unistd.h>
00021 #include <string.h>
00022 #include <errno.h>
00023 #include <signal.h>
00024 #include <bpcore/bgp_types.h>
00025 
00026 //Printf wrapping added for ProcControlAPI
00027 #define fprintf wrap_fprintf
00028 
00029 namespace DebuggerInterface {
00030 
00031 /*
00032    Protocol Version Change Log:
00033    1 - Initial implementation
00034    2 - Thread id passed in message header to reduce message traffic
00035    3 - Added GET_STACK_TRACE and END_DEBUG messages, Signal for detach from nodes
00036    4-  Added GET_PROCESS_DATA and GET_THREAD_DATA messages
00037    5 - Added HOLD_THREAD, RELEASE_THREAD, SIGACTION, MAP_MEM and FAST_TRAP messages
00038    6 - Added debugger ignore sinal function - DEBUG_IGNORE_SIG message
00039 */
00040 #define BG_Debugger_PROTOCOL_VERSION 6
00041 
00042 #define BG_DEBUGGER_WRITE_PIPE 3
00043 #define BG_DEBUGGER_READ_PIPE  4
00044 #define BG_PIPE_TIMEOUT 10
00045 
00046 // Max threads passed on get active threads at one time
00047 #define BG_Debugger_MAX_THREAD_IDS   32
00048 
00049 //! Buffer size for GET_AUX_VECTORS request
00050 #define BG_Debugger_AUX_VECS_BUFFER 1024
00051 
00052 //! Number of stack frames returned from compute node
00053 #define BG_Debugger_MAX_STACK_FRAMES 400 
00054 
00055 
00056 // Some typedefs to insure consistency later.
00057 
00058 typedef uint32_t BG_NodeNum_t;    // Which compute node under an I/O node
00059 typedef uint32_t BG_ThreadID_t;   // Which thread in the compute node
00060 typedef uint32_t BG_GPR_t;        // GPRs are 32 bit unsigned
00061 typedef uint32_t BG_Addr_t;       // 32 bit virtual address
00062 
00063 
00064 
00065 /* Register numbers
00066 
00067    The value of each enum is magically the same as the offset in
00068    words into the GPRSet_t structure.  The system is similar to,
00069    but not necessarily the same as used by ptrace.h.
00070  
00071 */
00072 
00073 typedef enum {
00074 
00075   BG_GPR0 = 0,
00076   BG_GPR1,
00077   BG_GPR2,
00078   BG_GPR3,
00079   BG_GPR4,
00080   BG_GPR5,
00081   BG_GPR6,
00082   BG_GPR7,
00083   BG_GPR8,
00084   BG_GPR9,
00085   BG_GPR10,
00086   BG_GPR11,
00087   BG_GPR12,
00088   BG_GPR13,
00089   BG_GPR14,
00090   BG_GPR15,
00091   BG_GPR16,
00092   BG_GPR17,
00093   BG_GPR18,
00094   BG_GPR19,
00095   BG_GPR20,
00096   BG_GPR21,
00097   BG_GPR22,
00098   BG_GPR23,
00099   BG_GPR24,
00100   BG_GPR25,
00101   BG_GPR26,
00102   BG_GPR27,
00103   BG_GPR28,
00104   BG_GPR29,
00105   BG_GPR30,
00106   BG_GPR31 = 31,
00107 
00108   BG_FPSCR      = 32,
00109   BG_LR         = 33,
00110   BG_CR         = 34,
00111   BG_XER        = 35,
00112   BG_CTR        = 36,
00113   BG_IAR        = 37,
00114   BG_MSR        = 38,
00115   BG_DEAR       = 39,
00116   BG_ESR        = 40
00117 
00118 } BG_GPR_Num_t;
00119 
00120 
00121 
00122 
00123 
00124 /* Floating point register numbers
00125 
00126    We have 'double hummer'.  We will pretend that we have 32 registers,
00127    each 128 bits (4 words) wide.  Once again, the enum value is the
00128    offset into the FPRSet_t struct.
00129 
00130 */
00131 
00132 typedef enum {
00133 
00134   BG_FPR0 = 0,
00135   BG_FPR1,
00136   BG_FPR2,
00137   BG_FPR3,
00138   BG_FPR4,
00139   BG_FPR5,
00140   BG_FPR6,
00141   BG_FPR7,
00142   BG_FPR8,
00143   BG_FPR9,
00144   BG_FPR10,
00145   BG_FPR11,
00146   BG_FPR12,
00147   BG_FPR13,
00148   BG_FPR14,
00149   BG_FPR15,
00150   BG_FPR16,
00151   BG_FPR17,
00152   BG_FPR18,
00153   BG_FPR19,
00154   BG_FPR20,
00155   BG_FPR21,
00156   BG_FPR22,
00157   BG_FPR23,
00158   BG_FPR24,
00159   BG_FPR25,
00160   BG_FPR26,
00161   BG_FPR27,
00162   BG_FPR28,
00163   BG_FPR29,
00164   BG_FPR30,
00165   BG_FPR31 = 31
00166 
00167 } BG_FPR_Num_t;
00168 
00169 
00170 /* MsgType
00171 
00172    This doesn't match the ptrace interface very well.
00173    Ptrace doesn't define most of these primitives.
00174    Therefore, the enums are completely arbitrary.
00175 
00176    Notice that except for SIGNAL_ENCOUNTERED, each
00177    request from the debugger has a corresponding
00178    acknowledgement message.
00179 
00180 */
00181 
00182 typedef enum { GET_REG = 0,
00183                GET_ALL_REGS,        // request gprs and other non-fp regs 
00184                SET_REG,         // set a specific register
00185                GET_MEM,         // get memory values
00186                SET_MEM,         // set memory
00187                GET_FLOAT_REG,
00188                GET_ALL_FLOAT_REGS,
00189                SET_FLOAT_REG,
00190                SINGLE_STEP,     // step one instruction
00191                CONTINUE,        // tell compute node to continue running
00192                KILL,            // send a signal w/ implicit continue
00193                ATTACH,          // mark compute node
00194            DETACH,          // unmark compute node
00195 
00196                GET_REG_ACK,
00197                GET_ALL_REGS_ACK,    // sent when compute node responds
00198                SET_REG_ACK,     // send when compute node responds
00199                GET_MEM_ACK,     // sent when compute node responds
00200                SET_MEM_ACK,     // sent when compute node responds
00201                GET_FLOAT_REG_ACK,
00202                GET_ALL_FLOAT_REGS_ACK,
00203                SET_FLOAT_REG_ACK,
00204                SINGLE_STEP_ACK,     // sent when compute node completes step
00205                CONTINUE_ACK,        // sent when compute node is told
00206                KILL_ACK,        // send when signal is sent
00207                ATTACH_ACK,      // sent after compute node is marked
00208            DETACH_ACK,      // sent after compute node is unmarked
00209 
00210                SIGNAL_ENCOUNTERED,  // sent when a signal is encountered
00211 
00212                PROGRAM_EXITED,      // with implicit detach
00213 
00214                VERSION_MSG,
00215                VERSION_MSG_ACK,
00216 
00217                GET_DEBUG_REGS,
00218                GET_DEBUG_REGS_ACK,
00219 
00220                SET_DEBUG_REGS,
00221                SET_DEBUG_REGS_ACK,
00222 
00223                GET_THREAD_INFO,
00224                GET_THREAD_INFO_ACK,
00225                THREAD_ALIVE,
00226                THREAD_ALIVE_ACK,
00227                GET_THREAD_ID,
00228                GET_THREAD_ID_ACK,
00229                SET_THREAD_OPS,
00230                SET_THREAD_OPS_ACK,
00231 
00232                GET_REGS_AND_FLOATS,  // Get regs and floating point registers
00233                GET_REGS_AND_FLOATS_ACK,  // sent when compute node responds
00234 
00235                GET_AUX_VECTORS,  // Request to get the aux vectors
00236                GET_AUX_VECTORS_ACK, // Send when compute node responds 
00237               
00238                GET_STACK_TRACE,  // Request to get the stack traceback
00239                GET_STACK_TRACE_ACK,  // Sent when compute node responds
00240 
00241                END_DEBUG,  // Indicate done debugging
00242                END_DEBUG_ACK,  // Sent when CIOD acknowledges ending of debug
00243 
00244                GET_PROCESS_DATA,
00245                GET_PROCESS_DATA_ACK,
00246 
00247                GET_THREAD_DATA,
00248                GET_THREAD_DATA_ACK,
00249 
00250                HOLD_THREAD,
00251                HOLD_THREAD_ACK,
00252 
00253                RELEASE_THREAD,
00254                RELEASE_THREAD_ACK,
00255 
00256                SIGACTION,
00257                SIGACTION_ACK,
00258 
00259                MAP_MEM,
00260                MAP_MEM_ACK,
00261 
00262                FAST_TRAP,
00263                FAST_TRAP_ACK,
00264 
00265                DEBUG_IGNORE_SIG,
00266                DEBUG_IGNORE_SIG_ACK,
00267 
00268                THIS_SPACE_FOR_RENT
00269 
00270 } BG_MsgType_t;
00271 
00272 
00273 /* GPRSet_t
00274 
00275    This is the set of general purpose registers.
00276 
00277 */
00278 
00279 typedef struct {
00280 
00281   uint32_t gpr[32];     // gprs
00282   uint32_t fpscr;       // fpscr
00283   uint32_t lr;          // link
00284   uint32_t cr;          // condition reg
00285   uint32_t xer;         // xer
00286   uint32_t ctr;         // count register
00287   uint32_t iar;         // pc
00288   uint32_t msr;         // machine status register
00289   uint32_t dear;        // data exception address register
00290   uint32_t esr;         // exception syndrome register
00291   
00292 } BG_GPRSet_t;
00293 
00294 
00295 
00296 /* FPRSet_t
00297 
00298    Our FPRs are a little bit different because of the double hummer.
00299    We actually have 2 sets of FPRs.
00300 
00301    The convention that we'll use is to treat the FPRs as one set of
00302    32, with each FPR being four words instead of two.
00303 
00304 */
00305 
00306 
00307 typedef struct {
00308   uint32_t w0;    // First word of FPR in first FPR set
00309   uint32_t w1;    // Second word of FPR in first FPR set
00310   uint32_t w2;    // First word of FPR in second FPR set
00311   uint32_t w3;    // Second word of FPR in second FPR set
00312 } BG_FPR_t;
00313 
00314 typedef struct {
00315   BG_FPR_t fprs[32];
00316 } BG_FPRSet_t;
00317 
00318 
00319 
00320 typedef struct {
00321   uint32_t DBCR0;    // Debug Control Register 0
00322   uint32_t DBCR1;    // Debug Control Register 1
00323   uint32_t DBCR2;    // Debug Control Register 2
00324   uint32_t DBSR;     // Debug Status Register
00325   uint32_t IAC1;     // Instruction Address Compare Register 1
00326   uint32_t IAC2;     // Instruction Address Compare Register 2
00327   uint32_t IAC3;     // Instruction Address Compare Register 3
00328   uint32_t IAC4;     // Instruction Address Compare Register 4
00329   uint32_t DAC1;     // Data Address Compare Register 1
00330   uint32_t DAC2;     // Data Address Compare Register 2
00331   uint32_t DVC1;     // Data Value Compare Register 1
00332   uint32_t DVC2;     // Data Value Compare Register 2
00333 } BG_DebugSet_t;
00334 
00335 
00336 
00337 // Structure for stack data
00338 typedef struct
00339 {
00340   BG_Addr_t frameAddr;
00341   BG_Addr_t savedLR;
00342 } BG_Stack_Info_t;
00343 
00344 
00345 // Structure for process data.
00346 typedef struct {
00347   uint32_t rank;                       // MPI rank
00348   uint32_t tgid;                       // Thread group id
00349   uint32_t xCoord;                     // X coordinate
00350   uint32_t yCoord;                     // Y coordinate
00351   uint32_t zCoord;                     // Z coordinate
00352   uint32_t tCoord;                     // T coordinate
00353   BG_Addr_t sharedMemoryStartAddr;     // Shared memory region start address
00354   BG_Addr_t sharedMemoryEndAddr;       // Shared memory region end address
00355   BG_Addr_t persistMemoryStartAddr;    // Persistent memory region start address
00356   BG_Addr_t persistMemoryEndAddr;      // Persistent memory region end address
00357   BG_Addr_t heapStartAddr;             // Heap start address
00358   BG_Addr_t heapEndAddr;               // Heap end address 
00359   BG_Addr_t heapBreakAddr;             // Heap break address
00360   BG_Addr_t mmapStartAddr;             // Memory map start address
00361   BG_Addr_t mmapEndAddr;               // Memory map end address
00362   struct timeval jobTime;              // Time job has been running
00363 } BG_Process_Data_t;
00364 
00365 // State of a thread.
00366 typedef enum {
00367   Running = 1,                         // Thread is running executable code
00368   Sleeping,                            // Thread is sleeping
00369   Waiting,                             // Thread is waiting for event
00370   Zombie,                              // Thread is ended
00371   Idle                                 // Thread is available 
00372 } BG_Thread_State_t;
00373 
00374 // Structure for thread data.
00375 typedef struct {
00376   BG_ThreadID_t threadID;              // Thread id
00377   int core;                            // Core number
00378   BG_Thread_State_t state;             // Thread state
00379   BG_Addr_t stackStartAddr;            // Stack start address
00380   BG_Addr_t stackEndAddr;              // Stack end address
00381   BG_Addr_t guardStartAddr;            // Guard page start address
00382   BG_Addr_t guardEndAddr;              // Guard page end address
00383   BG_GPRSet_t gprs;                    // Set of general purpose registers
00384   BG_FPRSet_t fprs;                    // Set of floating point registers
00385   BG_DebugSet_t debugRegisters;        // Set of debug registers
00386   uint32_t numStackFrames;             // Number of stack frame addr/saved lr entries returned
00387   BG_Stack_Info_t stackInfo[BG_Debugger_MAX_STACK_FRAMES]; // Stack trace back
00388 } BG_Thread_Data_t;
00389 
00390 
00391 typedef enum {
00392 
00393   RC_NO_ERROR          = 0,
00394   RC_NOT_ATTACHED      = 1,
00395   RC_NOT_RUNNING       = 2,
00396   RC_BAD_NODE          = 3,
00397   RC_BAD_THREAD        = 4,
00398   RC_BAD_COMMAND       = 5,
00399   RC_BAD_REGISTER      = 6,
00400   RC_NOT_APP_SPACE     = 7,
00401   RC_LEN_TOO_LONG      = 8,
00402   RC_DENIED            = 9,
00403   RC_BAD_SIGNAL        = 10,
00404   RC_NOT_STOPPED       = 11,
00405   RC_NOT_INITIALIZED   = 12,
00406   RC_TIMEOUT           = 13
00407   
00408 } BG_ErrorCode_t;
00409 
00410 
00411 
00412 
00413 // Externs for managing the pipe.  Use by a client is optional.
00414 //
00415 // DebuggerReadStarted and DebuggerWriteStarted: get set whenever you call
00416 // our public method to read or write on the debugger pipe.  An alarm
00417 // handler can look to see how long you've been waiting on the pipe.
00418 //
00419 // AbortPipeIO: If the alarm handler wants to abort a read or write on
00420 // the pipe it can set this.  When the loop is resumed it will check
00421 // this flag and end the loop if necessary.
00422 
00423 extern volatile time_t DebuggerReadStarted;
00424 extern volatile time_t DebuggerWriteStarted;
00425 extern volatile int AbortPipeIO;
00426 
00427 
00428 /* Debugger_Msg_t
00429 
00430    This is the packet header for the pipe.  All messages use this.
00431 
00432      messageType is self explanatory
00433      nodeNumber is the target compute node
00434      thread is the thread on the compute node
00435      sequence can be used to keep track of packet flow
00436      returnCode might be needed
00437      dataLength is the size in chars of the payload
00438 
00439    The 'payload' should follow the message header, and be received
00440    into a buffer of size dataLength.
00441 
00442    Not all messages have payloads.  If your message doesn't have
00443    a payload, set dataLength to 0.
00444 
00445    'sequence' is probably best used as a 'packet count' or a sequence
00446    number.  This way you can match acknowledgement packets with the
00447    original packet if things aren't being done in lockstep.
00448 
00449    'returnCode' isn't architected yet, but we probably need it.  If your
00450    GET_MEM request fails how else will you know?
00451 
00452    'dataStartsHere' is a placeholder.  As a result, to get the true size
00453    of this data structure you have to subtract 1 byte.
00454 
00455 */
00456 
00457 #define BG_Debugger_Msg_MAX_SIZE     4096
00458 #define BG_Debugger_Msg_HEADER_SIZE    24
00459 #define BG_Debugger_Msg_MAX_PAYLOAD_SIZE (BG_Debugger_Msg_MAX_SIZE-BG_Debugger_Msg_HEADER_SIZE)
00460 #define BG_Debugger_Msg_MAX_MEM_SIZE 4064
00461 
00462 
00463 
00464 class BG_Debugger_Msg {
00465 
00466   public:
00467 
00468     typedef struct {
00469 
00470       BG_MsgType_t      messageType;
00471       BG_NodeNum_t      nodeNumber;
00472       BG_ThreadID_t     thread;
00473       uint32_t           sequence;
00474       uint32_t           returnCode;
00475       uint32_t           dataLength;   // excluding this header
00476 
00477     } Header;
00478 
00479     Header header;
00480 
00481     typedef union {
00482 
00483       struct {
00484         BG_GPR_Num_t      registerNumber;
00485       } GET_REG;
00486 
00487       struct {
00488         BG_GPR_Num_t      registerNumber;
00489         BG_GPR_t          value;
00490       } GET_REG_ACK;
00491 
00492       struct {
00493       } GET_ALL_REGS;
00494 
00495       struct {
00496         BG_GPRSet_t       gprs;
00497       } GET_ALL_REGS_ACK;
00498 
00499       struct {
00500         BG_GPR_Num_t     registerNumber;
00501         BG_GPR_t         value;
00502       } SET_REG;
00503 
00504       struct {
00505         BG_GPR_Num_t     registerNumber;
00506       } SET_REG_ACK;  
00507 
00508       struct {
00509         BG_Addr_t        addr;
00510         uint32_t          len;
00511       } GET_MEM;
00512 
00513       struct {
00514         BG_Addr_t        addr;
00515         uint32_t          len;
00516         unsigned char     data[BG_Debugger_Msg_MAX_MEM_SIZE];
00517       } GET_MEM_ACK;
00518 
00519       struct {
00520         BG_Addr_t        addr;
00521         uint32_t          len;
00522         unsigned char     data[BG_Debugger_Msg_MAX_MEM_SIZE];
00523       } SET_MEM;
00524 
00525       struct {
00526         BG_Addr_t        addr;
00527         uint32_t          len;
00528       } SET_MEM_ACK;
00529 
00530       struct {
00531         BG_FPR_Num_t     registerNumber;
00532       } GET_FLOAT_REG;
00533 
00534       struct {
00535         BG_FPR_Num_t     registerNumber;
00536         BG_FPR_t         value;
00537       } GET_FLOAT_REG_ACK;  
00538 
00539       struct {
00540       } GET_ALL_FLOAT_REGS;
00541 
00542       struct {
00543         BG_FPRSet_t      fprs;
00544       } GET_ALL_FLOAT_REGS_ACK;
00545 
00546       struct {
00547         BG_FPR_Num_t     registerNumber;
00548         BG_FPR_t         value;
00549       } SET_FLOAT_REG;
00550 
00551       struct {
00552         BG_FPR_Num_t     registerNumber;
00553       } SET_FLOAT_REG_ACK;  
00554 
00555       struct {
00556       } SINGLE_STEP;
00557 
00558       struct {
00559       } SINGLE_STEP_ACK;
00560 
00561       struct {
00562          uint32_t          signal;
00563       } CONTINUE;
00564 
00565       struct {
00566       } CONTINUE_ACK;
00567 
00568       struct {
00569          uint32_t          signal;
00570       } KILL;
00571 
00572       struct {
00573       } KILL_ACK;
00574 
00575       struct {
00576       } ATTACH;
00577 
00578       struct {
00579       } ATTACH_ACK;
00580 
00581       struct {
00582       } DETACH;
00583 
00584       struct {
00585       } DETACH_ACK;
00586 
00587       struct {
00588         uint32_t          signal;
00589       } SIGNAL_ENCOUNTERED;
00590 
00591       struct {
00592         int32_t           type;  // 0 = exit, 1 = signal
00593         int32_t           rc;
00594       } PROGRAM_EXITED;
00595 
00596       struct {
00597       } VERSION_MSG;
00598 
00599       struct {
00600         uint32_t          protocolVersion;
00601         uint32_t          numPhysicalProcessors;
00602         uint32_t          numLogicalProcessors;
00603       } VERSION_MSG_ACK;
00604 
00605       struct {
00606       } GET_DEBUG_REGS;
00607 
00608       struct {
00609         BG_DebugSet_t   debugRegisters;
00610       } GET_DEBUG_REGS_ACK;
00611 
00612       struct {
00613         BG_DebugSet_t   debugRegisters;
00614       } SET_DEBUG_REGS;
00615 
00616       struct {
00617       } SET_DEBUG_REGS_ACK;
00618 
00619       struct {
00620       } GET_THREAD_INFO;
00621 
00622       struct {
00623         uint32_t numThreads;
00624         uint32_t threadIDS[BG_Debugger_MAX_THREAD_IDS];
00625       } GET_THREAD_INFO_ACK;
00626 
00627       struct {
00628         uint32_t tid;
00629       } THREAD_ALIVE;
00630 
00631       struct {
00632       } THREAD_ALIVE_ACK;
00633 
00634       struct {
00635       } GET_THREAD_ID;
00636 
00637       struct {
00638         uint32_t tid;
00639       } GET_THREAD_ID_ACK;
00640 
00641       struct {
00642         uint32_t tid;
00643         int32_t operation;  // 0='g' operations 1='c' operations
00644       } SET_THREAD_OPS;
00645 
00646       struct {
00647       } SET_THREAD_OPS_ACK;
00648 
00649       struct {
00650       } GET_REGS_AND_FLOATS;
00651 
00652       struct {
00653         BG_GPRSet_t      gprs;
00654         BG_FPRSet_t      fprs;
00655       } GET_REGS_AND_FLOATS_ACK;
00656 
00657       struct {
00658         uint32_t auxVecBufferOffset; // Requested offset within the available AuxVec data to begin retrieval
00659         uint32_t auxVecBufferLength; // Requested length of data to be returned
00660       } GET_AUX_VECTORS;
00661 
00662       struct {
00663         uint32_t auxVecData[BG_Debugger_AUX_VECS_BUFFER/sizeof(uint32_t)]; 
00664         uint32_t auxVecBufferOffset; // Offset within the available AuxVec data of retrieved data
00665         uint32_t auxVecBufferLength; // Number of bytes of aux vec data stored within the auxVecData buffer
00666         bool endOfVecData;           // Indicator set to true if the end of the AuxVec data was reached
00667       } GET_AUX_VECTORS_ACK;
00668 
00669       struct {
00670       } GET_STACK_INFO;
00671 
00672       struct {
00673         uint32_t lr;  // Current link register
00674         uint32_t iar;  // Current instruction address
00675         uint32_t stackFrame;  // Current stack frame pointer(R1)
00676         uint32_t numStackFrames;  // Number of stack frame addr/saved lr entries returned
00677         BG_Stack_Info_t stackInfo[ BG_Debugger_MAX_STACK_FRAMES ];
00678       } GET_STACK_INFO_ACK;
00679 
00680       struct {
00681       } END_DEBUG;
00682 
00683       struct {
00684       } END_DEBUG_ACK;
00685 
00686       struct {
00687       } GET_PROCESS_DATA;
00688 
00689       struct {
00690         BG_Process_Data_t processData;
00691         uint32_t numThreads;
00692         BG_ThreadID_t threadIDS[BG_Debugger_MAX_THREAD_IDS];
00693       } GET_PROCESS_DATA_ACK;
00694 
00695       struct {
00696       } GET_THREAD_DATA;
00697 
00698       struct {
00699          BG_Thread_Data_t threadData;
00700       } GET_THREAD_DATA_ACK;
00701 
00702       struct {
00703         uint32_t timeout;
00704       } HOLD_THREAD;
00705 
00706       struct {
00707       } HOLD_THREAD_ACK;
00708 
00709       struct {
00710       } RELEASE_THREAD;
00711 
00712       struct {
00713       } RELEASE_THREAD_ACK;
00714 
00715       struct {
00716         uint32_t signum;        // signal number. Only supported value is SIGTRAP
00717         __sighandler_t handler; // SIGTRAP signal handler function
00718         uint32_t       mask;    // signal mask  (see syscall sigaction)
00719         uint32_t       flags;   // signal flags (see syscall sigaction)
00720       } SIGACTION;
00721 
00722       struct {
00723       } SIGACTION_ACK;
00724 
00725       struct {
00726         uint32_t          len;
00727       } MAP_MEM;
00728 
00729       struct {
00730         BG_Addr_t        addr;
00731       } MAP_MEM_ACK;
00732 
00733       struct {
00734         bool         enable;
00735       } FAST_TRAP;
00736 
00737       struct {
00738       } FAST_TRAP_ACK;
00739 
00740       struct {
00741         sigset_t     ignoreSet;
00742       } DEBUG_IGNORE_SIG;
00743 
00744       struct {
00745       } DEBUG_IGNORE_SIG_ACK;
00746 
00747       unsigned char      dataStartsHere;
00748 
00749     } DataArea;
00750 
00751     DataArea dataArea;
00752 
00753     // Ctor
00754 
00755     BG_Debugger_Msg( void ) { header.messageType = THIS_SPACE_FOR_RENT; }
00756 
00757 
00758     BG_Debugger_Msg( BG_MsgType_t type,
00759                 BG_NodeNum_t node,
00760                 BG_ThreadID_t thread,
00761                 uint32_t sequence,
00762                 uint32_t returnCode )
00763     {
00764       header.messageType = type;
00765       header.nodeNumber = node;
00766       header.thread = thread;
00767       header.sequence = sequence;
00768       header.returnCode = returnCode;
00769     } 
00770 
00771     static BG_Debugger_Msg generateErrorPacket( BG_Debugger_Msg &original, BG_ErrorCode_t ec )
00772     {
00773 
00774        BG_Debugger_Msg errMsg;
00775 
00776        errMsg.header.nodeNumber = original.header.nodeNumber;
00777        errMsg.header.thread     = original.header.thread;
00778        errMsg.header.sequence   = original.header.sequence;
00779        errMsg.header.returnCode = ec;
00780 
00781 
00782        switch ( original.header.messageType ) {
00783 
00784          case GET_REG: {
00785            errMsg.header.messageType = GET_REG_ACK;
00786            errMsg.header.dataLength  = sizeof( errMsg.dataArea.GET_REG_ACK );
00787            errMsg.dataArea.GET_REG_ACK.registerNumber = original.dataArea.GET_REG.registerNumber;
00788            errMsg.dataArea.GET_REG_ACK.value = 0xDEADBEEF;
00789            break;
00790          }
00791 
00792          case GET_ALL_REGS: {
00793            errMsg.header.messageType = GET_ALL_REGS_ACK;
00794            errMsg.header.dataLength = 0;
00795            break;
00796          }
00797 
00798          case SET_REG: {
00799            errMsg.header.messageType = SET_REG_ACK;
00800            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SET_REG_ACK );
00801            errMsg.dataArea.SET_REG_ACK.registerNumber = original.dataArea.SET_REG.registerNumber;
00802            break;
00803          }
00804 
00805          case GET_MEM: {
00806            errMsg.header.messageType = GET_MEM_ACK;
00807            errMsg.header.dataLength  = sizeof( errMsg.dataArea.GET_MEM_ACK ) - BG_Debugger_Msg_MAX_MEM_SIZE;
00808            errMsg.dataArea.GET_MEM_ACK.addr = original.dataArea.GET_MEM.addr;
00809            errMsg.dataArea.GET_MEM_ACK.len  = original.dataArea.GET_MEM.len;
00810            break;
00811          }
00812 
00813          case SET_MEM: {
00814            errMsg.header.messageType = SET_MEM_ACK;
00815            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SET_MEM_ACK );
00816            errMsg.dataArea.SET_MEM_ACK.addr = original.dataArea.SET_MEM.addr;
00817            errMsg.dataArea.SET_MEM_ACK.len  = original.dataArea.SET_MEM.len;
00818            break;
00819          }
00820 
00821          case GET_FLOAT_REG: {
00822            errMsg.header.messageType = GET_FLOAT_REG_ACK;
00823            errMsg.header.dataLength  = sizeof( errMsg.dataArea.GET_FLOAT_REG_ACK );
00824            errMsg.dataArea.GET_FLOAT_REG_ACK.registerNumber = original.dataArea.GET_FLOAT_REG.registerNumber;
00825            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w0 = 0xDEADBEEF;
00826            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w1 = 0xDEADBEEF;
00827            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w2 = 0xDEADBEEF;
00828            errMsg.dataArea.GET_FLOAT_REG_ACK.value.w3 = 0xDEADBEEF;
00829            break;
00830          }
00831 
00832          case GET_ALL_FLOAT_REGS: {
00833            errMsg.header.messageType = GET_ALL_FLOAT_REGS_ACK;
00834            errMsg.header.dataLength  = 0;
00835            break;
00836          }
00837 
00838          case SET_FLOAT_REG: {
00839            errMsg.header.messageType = SET_FLOAT_REG_ACK;
00840            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SET_FLOAT_REG_ACK );
00841            errMsg.dataArea.SET_FLOAT_REG_ACK.registerNumber = original.dataArea.SET_FLOAT_REG.registerNumber;
00842            break;
00843          }
00844 
00845          case SINGLE_STEP: {
00846            errMsg.header.messageType = SINGLE_STEP_ACK;
00847            errMsg.header.dataLength  = sizeof( errMsg.dataArea.SINGLE_STEP_ACK );
00848            break;
00849          }
00850 
00851          case CONTINUE: {
00852            errMsg.header.messageType = CONTINUE_ACK;
00853            errMsg.header.dataLength  = sizeof( errMsg.dataArea.CONTINUE_ACK );
00854            break;
00855          }
00856 
00857          case KILL: {
00858            errMsg.header.messageType = KILL_ACK;
00859            errMsg.header.dataLength  = sizeof( errMsg.dataArea.KILL_ACK );
00860            break;
00861          }
00862 
00863          case ATTACH: {
00864            errMsg.header.messageType = ATTACH_ACK;
00865            errMsg.header.dataLength  = sizeof( errMsg.dataArea.ATTACH_ACK );
00866            break;
00867          }
00868 
00869          case DETACH: {
00870            errMsg.header.messageType = DETACH_ACK;
00871            errMsg.header.dataLength  = sizeof( errMsg.dataArea.DETACH_ACK );
00872            break;
00873          }
00874 
00875          case GET_DEBUG_REGS: {
00876            errMsg.header.messageType = GET_DEBUG_REGS_ACK;
00877            errMsg.header.dataLength  = 0;
00878            break;
00879          }
00880 
00881          case SET_DEBUG_REGS: {
00882            errMsg.header.messageType = SET_DEBUG_REGS_ACK;
00883            errMsg.header.dataLength  = 0;
00884            break;
00885          }
00886 
00887          case GET_THREAD_INFO: {
00888            errMsg.header.messageType = GET_THREAD_INFO_ACK;
00889            errMsg.header.dataLength  = 0;
00890            break;
00891          }
00892 
00893          case THREAD_ALIVE: {
00894            errMsg.header.messageType = THREAD_ALIVE_ACK;
00895            errMsg.header.dataLength  = sizeof( errMsg.dataArea.THREAD_ALIVE_ACK );
00896            break;
00897          }
00898 
00899          case GET_THREAD_ID: {
00900            errMsg.header.messageType = GET_THREAD_ID_ACK;
00901            errMsg.header.dataLength  = 0;
00902            break;
00903          }
00904 
00905          case SET_THREAD_OPS: {
00906            errMsg.header.messageType = SET_THREAD_OPS_ACK;
00907            errMsg.header.dataLength  = 0;
00908            break;
00909          }
00910 
00911          case GET_REGS_AND_FLOATS: {
00912            errMsg.header.messageType = GET_ALL_REGS_ACK;
00913            errMsg.header.dataLength = 0;
00914            break;
00915          }
00916 
00917          case GET_AUX_VECTORS: {
00918            errMsg.header.messageType = GET_AUX_VECTORS_ACK;
00919            errMsg.header.dataLength = 0;
00920            break;
00921          }
00922 
00923          case GET_STACK_TRACE: {
00924            errMsg.header.messageType = GET_STACK_TRACE_ACK;
00925            errMsg.header.dataLength = 0;
00926            break;
00927          }
00928 
00929          case END_DEBUG: {
00930            errMsg.header.messageType = END_DEBUG_ACK;
00931            errMsg.header.dataLength  = 0;
00932            break;
00933          }
00934 
00935          case GET_PROCESS_DATA: {
00936            errMsg.header.messageType = GET_PROCESS_DATA_ACK;
00937            errMsg.header.dataLength = 0;
00938            break;
00939          }
00940 
00941          case GET_THREAD_DATA: {
00942            errMsg.header.messageType = GET_THREAD_DATA_ACK;
00943            errMsg.header.dataLength = 0;
00944            break;
00945          }
00946 
00947          default: {
00948            errMsg.header.messageType = original.header.messageType;
00949            errMsg.header.dataLength = 0;
00950            break;
00951          }
00952 
00953        }
00954 
00955        return errMsg;
00956 
00957     }
00958 
00959     //! \brief  Read a debugger message from a descriptor.
00960     //! \param  fd Descriptor to read from.
00961     //! \param  msg Reference to debugger message.
00962     //! \return True when message was read successfully, false if there was an error.
00963 
00964     static bool readFromFd( int fd, BG_Debugger_Msg &msg )
00965     {
00966        return readFromFd_p( fd, msg, NULL );
00967     }
00968 
00969     //! \brief  Read a debugger message from a descriptor.
00970     //! \param  fd Descriptor to read from.
00971     //! \param  msg Reference to debugger message.
00972     //! \param  abortPipeIO Pointer to integer that indicates whether to abort read on error.
00973     //! \return True when message was read successfully, false if there was an error.
00974 
00975     static bool readFromFd( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
00976     {
00977        return readFromFd_p( fd, msg, abortPipeIO );
00978     }
00979 
00980     //! \brief  Write a debugger message to a descriptor.
00981     //! \param  fd Descriptor to write to.
00982     //! \param  msg Reference to debugger message.
00983     //! \return True when message was written successfully, false if there was an error.
00984 
00985     static bool writeOnFd( int fd, BG_Debugger_Msg &msg )
00986     {
00987        return writeOnFd_p( fd, msg, NULL );
00988     }
00989 
00990     //! \brief  Write a debugger message to a descriptor.
00991     //! \param  fd Descriptor to write to.
00992     //! \param  msg Reference to debugger message.
00993     //! \param  abortPipeIO Pointer to integer that indicates whether to abort read on error.
00994     //! \return True when message was written successfully, false if there was an error.
00995 
00996     static bool writeOnFd( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
00997     {
00998        return writeOnFd_p( fd, msg, abortPipeIO );
00999     }
01000 
01001     //! \brief  Get a string describing a debugger message type.
01002     //! \param  type Debugger message type.
01003     //! \return Pointer to string.
01004 
01005     static const char *getMessageName(BG_MsgType_t type)
01006     {
01007        static const char *BG_Packet_Names[] = 
01008        {
01009           "GET_REG",
01010           "GET_ALL_REGS",
01011           "SET_REG",
01012           "GET_MEM",
01013           "SET_MEM",
01014           "GET_FLOAT_REG",
01015           "GET_ALL_FLOAT_REGS",
01016           "SET_FLOAT_REG",
01017           "SINGLE_STEP",
01018           "CONTINUE",
01019           "KILL",
01020           "ATTACH",
01021           "DETACH",
01022           "GET_REG_ACK",
01023           "GET_ALL_REGS_ACK",
01024           "SET_REG_ACK",
01025           "GET_MEM_ACK",
01026           "SET_MEM_ACK",
01027           "GET_FLOAT_REG_ACK",
01028           "GET_ALL_FLOAT_REGS_ACK",
01029           "SET_FLOAT_REG_ACK",
01030           "SINGLE_STEP_ACK",
01031           "CONTINUE_ACK",
01032           "KILL_ACK",
01033           "ATTACH_ACK",
01034           "DETACH_ACK",
01035           "SIGNAL_ENCOUNTERED",
01036           "PROGRAM_EXITED",
01037           "VERSION_MSG",
01038           "VERSION_MSG_ACK",
01039           "GET_DEBUG_REGS",
01040           "GET_DEBUG_REGS_ACK",
01041           "SET_DEBUG_REGS",
01042           "SET_DEBUG_REGS_ACK",
01043           "GET_THREAD_INFO",
01044           "GET_THREAD_INFO_ACK",
01045           "THREAD_ALIVE",
01046           "THREAD_ALIVE_ACK",
01047           "GET_THREAD_ID",
01048           "GET_THREAD_ID_ACK",
01049           "SET_THREAD_OPS",
01050           "SET_THREAD_OPS_ACK",
01051           "GET_REGS_AND_FLOATS",
01052           "GET_REGS_AND_FLOATS_ACK",
01053           "GET_AUX_VECTORS",
01054           "GET_AUX_VECTORS_ACK",
01055           "GET_STACK_TRACE",
01056           "GET_STACK_TRACE_ACK",
01057           "END_DEBUG",
01058           "END_DEBUG_ACK",
01059           "GET_PROCESS_DATA",
01060           "GET_PROCESS_DATA_ACK",
01061           "GET_THREAD_DATA",
01062           "GET_THREAD_DATA_ACK",
01063           "HOLD_THREAD",
01064           "HOLD_THREAD_ACK",
01065           "RELEASE_THREAD",
01066           "RELEASE_THREAD_ACK",
01067           "SIGACTION",
01068           "SIGACTION_ACK",
01069           "MAP_MEM",
01070           "MAP_MEM_ACK",
01071           "FAST_TRAP",
01072           "FAST_TRAP_ACK",
01073           "DEBUG_IGNORE_SIG",
01074           "DEBUG_IGNORE_SIG_ACK"
01075        };
01076 
01077        if ((type >= GET_REG) && (type < THIS_SPACE_FOR_RENT)) {
01078           return BG_Packet_Names[type];
01079        }
01080        else {
01081           return "UNKNOWN";
01082        }
01083 
01084     }
01085 
01086     //! \brief  Print details about a debugger message to standard output.
01087     //! \param  msg Reference to debugger message.
01088     //! \return Nothing.
01089 
01090     static void dump( BG_Debugger_Msg &msg )
01091     {
01092        dump( msg, stdout );
01093     }
01094 
01095     //! \brief  Print details about a debugger message to the specified file.
01096     //! \param  msg Reference to debugger message.
01097     //! \param  outfile Pointer to file for printing message.
01098     //! \return Nothing.
01099 
01100     static void dump( BG_Debugger_Msg &msg, FILE *outfile )
01101     {
01102        fprintf( outfile, "\n" );
01103 
01104        fprintf( outfile, "Type: %s from node: %d, return code: %d\n",
01105                 getMessageName(msg.header.messageType),
01106                 msg.header.nodeNumber,
01107                 msg.header.returnCode );
01108 
01109        switch ( msg.header.messageType ) {
01110 
01111          case GET_REG: {
01112            fprintf( outfile, "  Register number: %d\n", msg.dataArea.GET_REG.registerNumber );
01113            break;
01114          }
01115 
01116          case GET_REG_ACK: {
01117            fprintf( outfile, "  Register number: %d    Value: %08x\n", msg.dataArea.GET_REG.registerNumber, msg.dataArea.GET_REG_ACK.value );
01118            break;
01119          }
01120 
01121          case GET_ALL_REGS_ACK: {
01122            dumpGPRSet( &msg.dataArea.GET_ALL_REGS_ACK.gprs, outfile );
01123            break;
01124          }
01125 
01126 
01127          case SET_REG: {
01128            fprintf( outfile, "  Register number: %d    Value: %08x\n", msg.dataArea.SET_REG.registerNumber, msg.dataArea.SET_REG.value );
01129            break;
01130          }
01131 
01132          case SET_REG_ACK: {
01133            fprintf( outfile, "  Register number: %d\n", msg.dataArea.SET_REG_ACK.registerNumber );
01134            break;
01135          }
01136 
01137          case GET_MEM: {
01138            fprintf( outfile, "  Memory address: %08x    Length: %d\n  Vals: ", msg.dataArea.GET_MEM.addr, msg.dataArea.GET_MEM.len );
01139            break;
01140          }
01141 
01142          case GET_MEM_ACK: {
01143            fprintf( outfile, "  Memory address: %08x    Length: %d\n  Vals: ", msg.dataArea.GET_MEM_ACK.addr, msg.dataArea.GET_MEM_ACK.len );
01144            for ( unsigned int i = 0; i < msg.dataArea.GET_MEM_ACK.len; i++ ) fprintf( outfile, "%02x ", msg.dataArea.GET_MEM_ACK.data[i] );
01145            fprintf( outfile, "\n" );
01146            break;
01147          }
01148 
01149          case SET_MEM: {
01150            fprintf( outfile, "  Memory address: %08x    Length: %d\n  Vals: ", msg.dataArea.SET_MEM.addr, msg.dataArea.SET_MEM.len );
01151            for ( unsigned int i = 0; i < msg.dataArea.SET_MEM.len; i++ ) fprintf( outfile, "%02x ", msg.dataArea.SET_MEM.data[i] );
01152            fprintf( outfile, "\n" );
01153            break;
01154          }
01155 
01156          case SET_MEM_ACK: {
01157            fprintf( outfile, "  Memory address: %08x    Length: %d\n", msg.dataArea.SET_MEM_ACK.addr, msg.dataArea.SET_MEM_ACK.len );
01158            break;
01159          }
01160 
01161          case CONTINUE: {
01162            fprintf( outfile, "  Continue with signal number: %d\n", msg.dataArea.CONTINUE.signal );
01163            break;
01164          }
01165 
01166          case KILL: {
01167            fprintf( outfile, "  Signal number: %d\n", msg.dataArea.KILL.signal );
01168            break;
01169          }
01170 
01171          case SIGNAL_ENCOUNTERED: {
01172            fprintf( outfile, "  Signal number: %d\n", msg.dataArea.SIGNAL_ENCOUNTERED.signal );
01173            break;
01174          }
01175 
01176          case PROGRAM_EXITED: {
01177            fprintf( outfile, "  Exit=0,Signal=1: %d   Return code: %d\n", msg.dataArea.PROGRAM_EXITED.type, msg.dataArea.PROGRAM_EXITED.rc );
01178            break;
01179          }
01180 
01181          case GET_ALL_FLOAT_REGS_ACK: {
01182            dumpFPRSet( &msg.dataArea.GET_ALL_FLOAT_REGS_ACK.fprs, outfile );
01183            break;
01184          }
01185 
01186          case VERSION_MSG_ACK: {
01187            fprintf( outfile, "  Protocol version: %u   Physical Processors: %u  Logical Processors: %u\n",
01188                     msg.dataArea.VERSION_MSG_ACK.protocolVersion,
01189                     msg.dataArea.VERSION_MSG_ACK.numPhysicalProcessors,
01190                     msg.dataArea.VERSION_MSG_ACK.numLogicalProcessors );
01191            break;
01192          }
01193 
01194          case GET_DEBUG_REGS_ACK: {
01195            dumpDebugSet( &msg.dataArea.GET_DEBUG_REGS_ACK.debugRegisters, outfile );
01196            break;
01197          }
01198 
01199          case SET_DEBUG_REGS: {
01200            dumpDebugSet( &msg.dataArea.SET_DEBUG_REGS.debugRegisters, outfile );
01201            break;
01202          }
01203 
01204          case GET_THREAD_INFO_ACK: {
01205            fprintf( outfile, "  Number of threads: %u  TIDs:", msg.dataArea.GET_THREAD_INFO_ACK.numThreads );
01206            for ( unsigned int i = 0; i < msg.dataArea.GET_THREAD_INFO_ACK.numThreads; i++ ) {
01207              fprintf( outfile, " %u", msg.dataArea.GET_THREAD_INFO_ACK.threadIDS[i] );
01208            }
01209            fprintf( outfile, "\n");
01210            break;
01211          }
01212 
01213          case THREAD_ALIVE: {
01214            fprintf( outfile, "  TID: %u\n", msg.dataArea.THREAD_ALIVE.tid );
01215            break;
01216          }
01217 
01218          case GET_THREAD_ID_ACK: {
01219            fprintf( outfile, "  TID: %u\n", msg.dataArea.GET_THREAD_ID_ACK.tid );
01220            break;
01221          }
01222 
01223          case SET_THREAD_OPS: {
01224            fprintf( outfile, "  TID: %u  Operation: %d\n", msg.dataArea.SET_THREAD_OPS.tid, msg.dataArea.SET_THREAD_OPS.operation );
01225            break;
01226          }
01227 
01228          case GET_REGS_AND_FLOATS_ACK: {
01229            dumpGPRSet( &msg.dataArea.GET_REGS_AND_FLOATS_ACK.gprs, outfile );
01230            dumpFPRSet( &msg.dataArea.GET_REGS_AND_FLOATS_ACK.fprs, outfile );
01231            break;
01232          }
01233 
01234          case GET_AUX_VECTORS: {
01235            fprintf( outfile, "  Offset: %08x    Requested Length: %d\n  Vals: ", msg.dataArea.GET_AUX_VECTORS.auxVecBufferOffset, msg.dataArea.GET_AUX_VECTORS.auxVecBufferLength );
01236            break;
01237          }
01238 
01239          case GET_AUX_VECTORS_ACK: {
01240            fprintf( outfile, "  Offset: %08x    Length: %d\n  Vals: ", msg.dataArea.GET_AUX_VECTORS_ACK.auxVecBufferOffset, msg.dataArea.GET_AUX_VECTORS_ACK.auxVecBufferLength );
01241            for ( unsigned int i = 0; i < msg.dataArea.GET_AUX_VECTORS_ACK.auxVecBufferLength; i++ ) 
01242              fprintf( outfile, "%02x ", msg.dataArea.GET_AUX_VECTORS_ACK.auxVecData[i] );
01243            fprintf( outfile, "\n" );
01244            break;
01245          }
01246 
01247          case GET_STACK_TRACE_ACK: {
01248            fprintf( outfile, "  LR: %08x  IAR: %08x  R1: %08x  Number of stack frames: %u\n",
01249                     msg.dataArea.GET_STACK_INFO_ACK.lr, msg.dataArea.GET_STACK_INFO_ACK.iar,
01250                     msg.dataArea.GET_STACK_INFO_ACK.stackFrame, msg.dataArea.GET_STACK_INFO_ACK.numStackFrames );
01251            for ( unsigned int i = 0; i < msg.dataArea.GET_STACK_INFO_ACK.numStackFrames; i++ ) {
01252              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 );
01253            }
01254            break;
01255          }
01256 
01257          case GET_PROCESS_DATA_ACK: {
01258            fprintf( outfile, "  Rank: %u  TGID: %u  xCoord: %u  yCoord: %u  zCoord: %u  tCoord: %u\n",
01259                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.rank, msg.dataArea.GET_PROCESS_DATA_ACK.processData.tgid,
01260                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.xCoord, msg.dataArea.GET_PROCESS_DATA_ACK.processData.yCoord,
01261                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.zCoord, msg.dataArea.GET_PROCESS_DATA_ACK.processData.tCoord );
01262            fprintf( outfile, "  Shared memory start: %08x  Shared memory end: %08x  Persistent memory start: %08x  Persistent memory end: %08x\n",
01263                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.sharedMemoryStartAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.sharedMemoryEndAddr,
01264                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.persistMemoryStartAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.persistMemoryEndAddr );
01265            fprintf( outfile, "  Heap start: %08x  Heap end: %08x  Heap break: %08x  Mmap start: %08x  Mmap end: %08x\n",
01266                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.heapStartAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.heapEndAddr,
01267                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.heapBreakAddr, msg.dataArea.GET_PROCESS_DATA_ACK.processData.mmapStartAddr,
01268                     msg.dataArea.GET_PROCESS_DATA_ACK.processData.mmapEndAddr );
01269            fprintf( outfile, "  Number of threads: %u  TIDs:", msg.dataArea.GET_PROCESS_DATA_ACK.numThreads );
01270            for ( unsigned int i = 0; i < msg.dataArea.GET_PROCESS_DATA_ACK.numThreads; i++ ) {
01271              fprintf( outfile, " %u", msg.dataArea.GET_PROCESS_DATA_ACK.threadIDS[i] );
01272            }
01273            fprintf( outfile, "\n");
01274            break;
01275          }
01276 
01277          case GET_THREAD_DATA_ACK: {
01278            fprintf( outfile, "  TID: %u  Core: %d  Stack start: %08x  Stack end: %08x  Guard start: %08x  Guard end: %08x\n",
01279                     msg.dataArea.GET_THREAD_DATA_ACK.threadData.threadID, msg.dataArea.GET_THREAD_DATA_ACK.threadData.core,
01280                     msg.dataArea.GET_THREAD_DATA_ACK.threadData.stackStartAddr, msg.dataArea.GET_THREAD_DATA_ACK.threadData.stackEndAddr,
01281                     msg.dataArea.GET_THREAD_DATA_ACK.threadData.guardStartAddr, msg.dataArea.GET_THREAD_DATA_ACK.threadData.guardEndAddr );
01282            dumpGPRSet( &msg.dataArea.GET_THREAD_DATA_ACK.threadData.gprs, outfile );
01283            dumpFPRSet( &msg.dataArea.GET_THREAD_DATA_ACK.threadData.fprs, outfile );
01284            dumpDebugSet( &msg.dataArea.GET_THREAD_DATA_ACK.threadData.debugRegisters, outfile );
01285            for ( unsigned int i = 0; i < msg.dataArea.GET_THREAD_DATA_ACK.threadData.numStackFrames; i++ ) {
01286              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 );
01287            }
01288            break;
01289          }
01290 
01291          case HOLD_THREAD: {
01292              fprintf( outfile, "Timeout(usec): %08x\n", msg.dataArea.HOLD_THREAD.timeout);
01293              break;
01294          }
01295 
01296          case SIGACTION: {
01297              fprintf( outfile, "Signum: %08x  flags: %08x mask: %08x\n", msg.dataArea.SIGACTION.signum, msg.dataArea.SIGACTION.flags, msg.dataArea.SIGACTION.mask);  
01298              break;
01299          }
01300 
01301          case MAP_MEM: {
01302              fprintf( outfile, "MemMap size: %08x\n", msg.dataArea.MAP_MEM.len);
01303              break;
01304          }
01305          case FAST_TRAP: {
01306              fprintf( outfile, "FastTrap option: %d\n", msg.dataArea.FAST_TRAP.enable);
01307              break;
01308          }
01309 
01310          case DEBUG_IGNORE_SIG: {
01311              fprintf( outfile, "Debug ignore signal option: \n");
01312              break;
01313          }
01314 
01315          case GET_FLOAT_REG:
01316          case SET_FLOAT_REG:
01317          case GET_FLOAT_REG_ACK:
01318          case SET_FLOAT_REG_ACK:
01319          case GET_ALL_REGS:
01320          case GET_ALL_FLOAT_REGS:
01321          case SINGLE_STEP:
01322          case SINGLE_STEP_ACK:
01323          case CONTINUE_ACK:
01324          case KILL_ACK:
01325          case ATTACH:
01326          case ATTACH_ACK:
01327          case DETACH:
01328          case DETACH_ACK:
01329          case VERSION_MSG:
01330          case GET_DEBUG_REGS:
01331          case SET_DEBUG_REGS_ACK:
01332          case GET_THREAD_ID:
01333          case GET_THREAD_INFO:
01334          case THREAD_ALIVE_ACK:
01335          case SET_THREAD_OPS_ACK:
01336          case GET_REGS_AND_FLOATS:
01337          case GET_STACK_TRACE:
01338          case END_DEBUG:
01339          case END_DEBUG_ACK:
01340          case GET_PROCESS_DATA:
01341          case GET_THREAD_DATA:
01342          case HOLD_THREAD_ACK:
01343          case RELEASE_THREAD:
01344          case RELEASE_THREAD_ACK:
01345          case SIGACTION_ACK:
01346          case MAP_MEM_ACK:
01347          case FAST_TRAP_ACK:
01348          case DEBUG_IGNORE_SIG_ACK:
01349          case THIS_SPACE_FOR_RENT: {
01350            // Nothing to do for these packet types unless data is added to them
01351            break;
01352          }
01353 
01354        }
01355 
01356        return;
01357     }
01358 
01359 private:
01360 
01361    //! \brief  Read a debugger message from a descriptor.
01362    //! \param  fd Descriptor to read from.
01363    //! \param  msg Reference to debugger message.
01364    //! \param  abortPipeIO Pointer to integer that indicates whether to abort read on error.
01365    //! \return True when message was read succesfully, false if there was an error.
01366 
01367    static bool readFromFd_p( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
01368    {
01369       // Read header first
01370       int headerBytesToRead = sizeof( msg.header );
01371       int headerBytesRead = 0;
01372 
01373       while ( headerBytesRead < headerBytesToRead ) {
01374 
01375          if ( (abortPipeIO != NULL) && (*abortPipeIO != 0) ) {
01376             *abortPipeIO = 0;
01377             return false;
01378          }
01379 
01380          int headerRc = read( fd, ((unsigned char *)&msg.header)+headerBytesRead, headerBytesToRead - headerBytesRead );
01381 
01382          if ( headerRc == 0 ) {
01383             // End of file
01384             return false;
01385          }
01386          else if ( headerRc == -1 ) {
01387 
01388             // EINTR could be tolerable ... the others are not though
01389             if ( errno != EINTR ) {
01390                perror( "BG_Debugger_Msg::readFromFd" );
01391                return false;
01392             }
01393 
01394          }
01395          else {
01396             headerBytesRead += headerRc;
01397          }
01398       }
01399 
01400 
01401       // Read the rest of the packet now
01402       uint32_t payloadBytesRead = 0;
01403 
01404       while ( payloadBytesRead < msg.header.dataLength ) {
01405 
01406          if ( (abortPipeIO != NULL) && (*abortPipeIO != 0) ) {
01407             *abortPipeIO = 0;
01408             return false;
01409          }
01410 
01411          int payloadRc = read( fd, ((unsigned char *)&msg.dataArea)+payloadBytesRead, msg.header.dataLength - payloadBytesRead );
01412 
01413          if ( payloadRc == 0 ) {
01414             // End of file
01415             return false;
01416          }
01417          else if ( payloadRc == -1 ) {
01418 
01419            // EINTR could be tolerable ... the others are not though
01420            if ( errno != EINTR ) {
01421               int err = errno;
01422               perror( "BG_Debugger_Msg::readFromFd" );
01423               errno = err;
01424               return false;
01425            }
01426 
01427          }
01428          else {
01429             payloadBytesRead += payloadRc;
01430          }
01431 
01432       }
01433       return true;
01434    }
01435 
01436    //! \brief  Write a debugger message to a descriptor.
01437    //! \param  fd Descriptor to write to.
01438    //! \param  msg Reference to debugger message.
01439    //! \param  abortPipeIO Pointer to integer that indicates whether to abort write on error.
01440    //! \return True when message was written successfully, false if there was an error.
01441 
01442    static bool writeOnFd_p( int fd, BG_Debugger_Msg &msg, volatile int *abortPipeIO )
01443    {
01444       int bytesToWrite = sizeof( msg.header ) + msg.header.dataLength;
01445       int bytesWritten = 0;
01446       while ( bytesWritten < bytesToWrite ) {
01447 
01448          if ( (abortPipeIO != NULL) && (*abortPipeIO != 0) ) {
01449             *abortPipeIO = 0;
01450             return false;
01451          }
01452 
01453          int writeRc = write( fd, ((unsigned char *)&msg)+bytesWritten, bytesToWrite - bytesWritten );
01454 
01455          if ( writeRc == -1 ) {
01456 
01457             if ( errno != EINTR ) {
01458                int err = errno;
01459                perror( "BG_Debugger_msg::writeOnFd" );
01460                errno = err;
01461                return false;
01462             }
01463 
01464          }
01465          else {
01466             bytesWritten += writeRc;
01467          }
01468 
01469        }
01470 
01471       return true;
01472    }
01473 
01474    //! \brief  Print the set of GPRs to the specified file.
01475    //! \param  gprs Pointer to set of GPRs.
01476    //! \param  outfile Pointer to file for printing message.
01477    //! \return Nothing.
01478 
01479    static void dumpGPRSet( BG_GPRSet_t *gprs, FILE *outfile )
01480    {
01481      for ( int i=0; i < 8; i++ ) {
01482        for ( int j=0; j < 4; j++ ) {
01483          fprintf( outfile, "  r%02d: %08x    ", i*4+j, gprs->gpr[i*4+j] );
01484        }
01485        fprintf( outfile, "\n" );
01486      }
01487      fprintf( outfile, "FPSCR: %08x       LR: %08x       CR: %08x      XER: %08x\n",
01488               gprs->fpscr, gprs->lr, gprs->cr, gprs->xer );
01489      fprintf( outfile, "  CTR: %08x      IAR: %08x      MSR: %08x     DEAR: %08x\n",
01490               gprs->ctr, gprs->iar, gprs->msr, gprs->dear );
01491      fprintf( outfile, "  ESR: %08x\n", gprs->esr );
01492      return;
01493    }
01494 
01495    //! \brief  Print the set of FPRs to the specified file.
01496    //! \param  fprs Pointer to set of FPRs.
01497    //! \param  outfile Pointer to file for printing message.
01498    //! \return Nothing.
01499 
01500    static void dumpFPRSet( BG_FPRSet_t *fprs, FILE *outfile )
01501    {
01502      fprintf( outfile, "  Double hummer set 0:\n" );
01503      for ( int i=0; i < 8; i++ ) {
01504        for ( int j=0; j < 4; j++ ) {
01505          double val;
01506          memcpy( &val, &fprs->fprs[i*4+j].w0, sizeof( _QuadWord_t ) );
01507          fprintf( outfile, "  f%02d: %f    ", i*4+j, val );
01508        }
01509        fprintf( outfile, "\n" );
01510      }
01511      fprintf( outfile, "\n" );
01512      fprintf( outfile, "  Double hummer set 1:\n" );
01513      for ( int i=0; i < 8; i++ ) {
01514        for ( int j=0; j < 4; j++ ) {
01515          double val;
01516          memcpy( &val, &fprs->fprs[i*4+j].w2, sizeof( _QuadWord_t ) ); 
01517          fprintf( outfile, "  f%02d: %f    ", i*4+j, val );
01518        }
01519        fprintf( outfile, "\n" );
01520      }
01521      fprintf( outfile, "\n" );
01522      fprintf( outfile, "  Double hummer set 0 in hex:\n" );
01523      for ( int i=0; i < 8; i++ ) {
01524        for ( int j=0; j < 4; j++ ) {
01525          uint32_t val1 = fprs->fprs[i*4+j].w0;
01526          uint32_t val2 = fprs->fprs[i*4+j].w1;
01527          fprintf( outfile, "  f%02d: %08x%08x  ", i*4+j, val1, val2 );
01528        }
01529        fprintf( outfile, "\n" );
01530      }
01531      fprintf( outfile, "\n" );
01532      fprintf( outfile, "  Double hummer set 1 in hex:\n" );
01533      for ( int i=0; i < 8; i++ ) {
01534        for ( int j=0; j < 4; j++ ) {
01535          uint32_t val1 = fprs->fprs[i*4+j].w2;
01536          uint32_t val2 = fprs->fprs[i*4+j].w3;
01537          fprintf( outfile, "  f%02d: %08x%08x  ", i*4+j, val1, val2 );
01538        }
01539        fprintf( outfile, "\n" );
01540      }
01541      return;
01542    }
01543 
01544    //! \brief  Print the set of debug registers to the specified file.
01545    //! \param  gprs Pointer to set of debug registers.
01546    //! \param  outfile Pointer to file for printing message.
01547    //! \return Nothing.
01548 
01549    static void dumpDebugSet( BG_DebugSet_t *debugRegisters, FILE *outfile )
01550    {
01551      fprintf( outfile, "  DBCR0: %08x   DBCR1: %08x   DBCR2: %08x    DBSR: %08x\n",
01552               debugRegisters->DBCR0, debugRegisters->DBCR1, debugRegisters->DBCR2, debugRegisters->DBSR );
01553      fprintf( outfile, "   IAC1: %08x    IAC2: %08x    IAC3: %08x    IAC4: %08x\n",
01554               debugRegisters->IAC1, debugRegisters->IAC2, debugRegisters->IAC3, debugRegisters->IAC4 );
01555      fprintf( outfile, "   DAC1: %08x    DAC2: %08x    DVC1: %08x    DVC2: %08x\n",
01556               debugRegisters->DAC1, debugRegisters->DAC2, debugRegisters->DVC1, debugRegisters->DVC2 );
01557      return;
01558    }
01559 
01560 };
01561 
01562 
01563 }
01564 #undef fprintf
01565 
01566 #endif // CIODEBUGGERPROTOCOL_H
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1