/* Handle the 'C' command which is sent from gdb to tell the debugger to continue execution of the currently halted program. It is similar to the 'c' command but it also provides a signal level, which MRI ignores. Command Format: cAA;BBBBBBBB Response Format: Blank until the next exception, at which time a 'T' stop response packet will be sent. Where AA is the signal to be set, and BBBBBBBB is an optional value to be used for the Program Counter when restarting the program. */ uint32_t HandleContinueWithSignalCommand(void) { Buffer* pBuffer = GetBuffer(); uint32_t returnValue = 0; uint32_t newPC; returnValue |= skipHardcodedBreakpoint(); __try { /* Fetch signal value but ignore it. */ __throwing_func( ReadUIntegerArgument(pBuffer) ); if (Buffer_BytesLeft(pBuffer) && Buffer_IsNextCharEqualTo(pBuffer, ';')) { __throwing_func( newPC = ReadUIntegerArgument(pBuffer) ); Platform_SetProgramCounter(newPC); } } __catch { PrepareStringResponse(MRI_ERROR_INVALID_ARGUMENT); return 0; } return (returnValue | HANDLER_RETURN_RESUME_PROGRAM | HANDLER_RETURN_RETURN_IMMEDIATELY); }
/* Handle the "qXfer" command used by gdb to transfer data to and from the stub for special functionality. Command Format: qXfer:object:read:annex:offset,length Where supported objects are currently: memory-map */ static uint32_t handleQueryTransferCommand(void) { Buffer* pBuffer =GetBuffer(); static const char memoryMapObject[] = "memory-map"; static const char featureObject[] = "features"; if (!Buffer_IsNextCharEqualTo(pBuffer, ':')) { PrepareStringResponse(MRI_ERROR_INVALID_ARGUMENT); return 0; } if (Buffer_MatchesString(pBuffer, memoryMapObject, sizeof(memoryMapObject)-1)) { return handleQueryTransferMemoryMapCommand(); } else if (Buffer_MatchesString(pBuffer, featureObject, sizeof(featureObject)-1)) { return handleQueryTransferFeaturesCommand(); } else { PrepareEmptyResponseForUnknownCommand(); return 0; } }
static const char* readQueryTransferAnnexArgument(Buffer* pBuffer) { static const char targetXmlAnnex[] = "target.xml"; const char* pReturn = NULL; if (Buffer_MatchesString(pBuffer, targetXmlAnnex, sizeof(targetXmlAnnex)-1)) pReturn = targetXmlAnnex; if (pReturn && !Buffer_IsNextCharEqualTo(pBuffer, ':')) __throw_and_return(invalidArgumentException, NULL); else if (!pReturn && Buffer_IsNextCharEqualTo(pBuffer, ':')) return NULL; else if (!pReturn) __throw_and_return(invalidArgumentException, NULL); else return pReturn; }
static void readQueryTransferReadArguments(Buffer* pBuffer, AnnexOffsetLength* pAnnexOffsetLength) { static const char readCommand[] = "read"; memset(pAnnexOffsetLength, 0, sizeof(*pAnnexOffsetLength)); if (!Buffer_IsNextCharEqualTo(pBuffer, ':') || !Buffer_MatchesString(pBuffer, readCommand, sizeof(readCommand)-1) || !Buffer_IsNextCharEqualTo(pBuffer, ':') ) { __throw(invalidArgumentException); } __try { __throwing_func( pAnnexOffsetLength->pAnnex = readQueryTransferAnnexArgument(pBuffer) ); __throwing_func( readQueryTransferOffsetLengthArguments(pBuffer, pAnnexOffsetLength) ); } __catch { __rethrow; } }
/* Handle the 'F' command which is sent from gdb in response to a previously sent File I/O command from mri. Command Format: Frr[,ee[,C]] Where rr is the hexadecimal representation of the return code from the last requested file I/O command. ee is the optional hexadecimal value for the errorno associated with the call if rr indicates error. C is the optional 'C' character sent by gdb to indicate that CTRL+C was pressed by user while gdb was processing the current file I/O request. */ uint32_t HandleFileIOCommand(void) { static const char controlCFlag[] = ",C"; Buffer* pBuffer = GetBuffer(); int returnCode = -1; int errNo = 0; int controlC = 0; returnCode = Buffer_ReadIntegerAsHex(pBuffer); if (Buffer_IsNextCharEqualTo(pBuffer, ',')) { errNo = Buffer_ReadIntegerAsHex(pBuffer); controlC = Buffer_MatchesString(pBuffer, controlCFlag, sizeof(controlCFlag)-1); } SetSemihostReturnValues(returnCode, errNo); RecordControlCFlagSentFromGdb(controlC); return (HANDLER_RETURN_RESUME_PROGRAM | HANDLER_RETURN_RETURN_IMMEDIATELY); }